diff --git a/.gitattributes b/.gitattributes index e69de29..3e7d094 100644 --- a/.gitattributes +++ b/.gitattributes @@ -0,0 +1,16 @@ +*.php diff=php + +/.github export-ignore +/bin export-ignore +/scripts export-ignore +/tests export-ignore + +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.dist.php export-ignore +/.phpactor.json export-ignore +/.release-please-manifest.json export-ignore +/.stats.yml export-ignore +/phpstan.dist.neon export-ignore +/phpunit.xml.dist export-ignore +/release-please-config.json export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5392f5b..3459c22 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up PHP uses: 'shivammathur/setup-php@v2' @@ -38,7 +38,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/cas-parser-php' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up PHP uses: 'shivammathur/setup-php@v2' diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 8dec9f0..99587de 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,8 +12,11 @@ jobs: if: github.repository == 'CASParser/cas-parser-php' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Check release environment run: | bash ./bin/check-release-environment + env: + PACKAGIST_USERNAME: ${{ secrets.CAS_PARSER_PACKAGIST_USERNAME || secrets.PACKAGIST_USERNAME }} + PACKAGIST_SAFE_KEY: ${{ secrets.CAS_PARSER_PACKAGIST_SAFE_KEY || secrets.PACKAGIST_SAFE_KEY }} diff --git a/.gitignore b/.gitignore index 6739884..71d6d15 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -composer.lock docs/ .idea/ .php-cs-fixer.cache @@ -9,3 +8,6 @@ playground/ *.swo *.swp vendor/ + +# do not edit! excludes generated files used internally +.artifacts/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index a2b062b..d46a37f 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,7 +4,9 @@ use PhpCsFixer\Finder; use PhpCsFixer\Runner\Parallel\ParallelConfigFactory; -return (new Config()) +ini_set('memory_limit', -1); + +return (new Config) ->setParallelConfig(ParallelConfigFactory::detect()) ->setFinder(Finder::create()->in([__DIR__.'/src', __DIR__.'/tests'])) ->setRules([ diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 10f3091..6b7b74c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0" + ".": "0.3.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 92721c7..4d62cd0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 5 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-b7fdba3d3f97c7debc22c7ca30b828bce81bcd64648df8c94029b27a3321ebb9.yml -openapi_spec_hash: 03f1315f1d32ada42445ca920f047dff -config_hash: cb5d75abef6264b5d86448caf7295afa +configured_endpoints: 17 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml +openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f +config_hash: 1af2e938c93ea4ec25fc633469072c43 diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b6fa7..3b67c23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## 0.3.0 (2026-02-14) + +Full Changelog: [v0.2.0...v0.3.0](https://github.com/CASParser/cas-parser-php/compare/v0.2.0...v0.3.0) + +### ⚠ BREAKING CHANGES + +* **client:** redesign methods +* remove confusing `toArray()` alias to `__serialize()` in favour of `toProperties()` + +### Features + +* **api:** api update ([bbcfa14](https://github.com/CASParser/cas-parser-php/commit/bbcfa141a593d0d34c361c8ff2192dbd9e1ff0e3)) +* **api:** api update ([7bb648b](https://github.com/CASParser/cas-parser-php/commit/7bb648b9b9d87fa14c75e16628fe6d01e99f1198)) +* **api:** api update ([43a24ef](https://github.com/CASParser/cas-parser-php/commit/43a24ef1b13a87d203170dcc187c90045472cdea)) +* **api:** api update ([a45d08d](https://github.com/CASParser/cas-parser-php/commit/a45d08d64d5a4ad700f31d9180d5f79ce5ef06f2)) +* **api:** api update ([90a131a](https://github.com/CASParser/cas-parser-php/commit/90a131ad218e94a908056b01fb8425ab8783bbd4)) +* **api:** api update ([da8b838](https://github.com/CASParser/cas-parser-php/commit/da8b83821dab28680f72e98a943af25df296e314)) +* **api:** manual updates ([ef87761](https://github.com/CASParser/cas-parser-php/commit/ef877615b3b873e5f2cf3a3dfeb37f50dbaf71d5)) +* **client:** redesign methods ([5bc4f8f](https://github.com/CASParser/cas-parser-php/commit/5bc4f8fbca8bd998535963059460dcc2285c479e)) +* remove confusing `toArray()` alias to `__serialize()` in favour of `toProperties()` ([84053c4](https://github.com/CASParser/cas-parser-php/commit/84053c4b32db33f341e5e9bf89f2aabe982a2695)) + + +### Bug Fixes + +* **ci:** release doctor workflow ([d7d0f00](https://github.com/CASParser/cas-parser-php/commit/d7d0f005e9022cce83d3316626e5746a3a02b694)) +* ensure auth methods return non-nullable arrays ([fd0ab3b](https://github.com/CASParser/cas-parser-php/commit/fd0ab3bb4232369f31350fb47d0aca4d916f5739)) +* inverted retry condition ([0112a9a](https://github.com/CASParser/cas-parser-php/commit/0112a9a50be77cb4681413034b3d88d791774f6c)) +* rename invalid types ([6b7a996](https://github.com/CASParser/cas-parser-php/commit/6b7a99682bfce707850bfddeb41d2474f109ba83)) + + +### Chores + +* add license ([7742369](https://github.com/CASParser/cas-parser-php/commit/7742369f0a91046a7aa843391627e8931c6280f8)) +* **client:** send metadata headers ([9a72241](https://github.com/CASParser/cas-parser-php/commit/9a72241ae57939ae08709709a26a87f1ad83d9e2)) +* **docs:** update readme formatting ([f992e92](https://github.com/CASParser/cas-parser-php/commit/f992e921cd7043ea562ad58fb01905bd2039fa50)) +* **internal:** codegen related update ([c124b7b](https://github.com/CASParser/cas-parser-php/commit/c124b7bdd9b7d6f7bbef3d386f9eb4038a6b20f3)) +* refactor methods ([e25fa02](https://github.com/CASParser/cas-parser-php/commit/e25fa02ca0d7d49d88f1859c99e2db925a74e722)) +* update SDK settings ([66215fb](https://github.com/CASParser/cas-parser-php/commit/66215fb06d105b7678b59b7de76f68181d0c24fa)) +* use pascal case for phpstan typedefs ([574d168](https://github.com/CASParser/cas-parser-php/commit/574d1680fbbaccfc4281a98e33d205f4d8a7e043)) + ## 0.2.0 (2025-09-13) Full Changelog: [v0.1.0...v0.2.0](https://github.com/CASParser/cas-parser-php/compare/v0.1.0...v0.2.0) diff --git a/LICENSE b/LICENSE index f1756ce..6bbb512 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2025 Cas Parser + Copyright 2026 Cas Parser Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 75f8882..5de6243 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,11 @@ # Cas Parser PHP API library -> [!NOTE] -> The Cas Parser PHP API Library is currently in **beta** and we're excited for you to experiment with it! -> -> This library has not yet been exhaustively tested in production environments and may be missing some features you'd expect in a stable release. As we continue development, there may be breaking changes that require updates to your code. -> -> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/CASParser/cas-parser-php/issues/new). - The Cas Parser PHP library provides convenient access to the Cas Parser REST API from any PHP 8.1.0+ application. It is generated with [Stainless](https://www.stainless.com/). ## Documentation -The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). - ## Installation To use this package, install via Composer by adding the following to your application's `composer.json`: @@ -47,11 +38,14 @@ Parameters with a default value must be set by name. use CasParser\Client; -$client = new Client(apiKey: getenv("CAS_PARSER_API_KEY") ?: "My API Key"); +$client = new Client( + apiKey: getenv('CAS_PARSER_API_KEY') ?: 'My API Key', + environment: 'environment_1', +); -$unifiedResponse = $client->casParser->smartParse(); +$response = $client->credits->check(); -var_dump($unifiedResponse->demat_accounts); +var_dump($response->enabled_features); ``` ### Value Objects @@ -69,15 +63,17 @@ When the library is unable to connect to the API, or if the API returns a non-su casParser->smartParse(); + $response = $client->credits->check(); } catch (APIConnectionException $e) { echo "The server could not be reached", PHP_EOL; var_dump($e->getPrevious()); -} catch (RateLimitError $_) { +} catch (RateLimitException $e) { echo "A 429 status code was received; we should back off a bit.", PHP_EOL; -} catch (APIStatusError $e) { +} catch (APIStatusException $e) { echo "Another non-200-range status code was received", PHP_EOL; echo $e->getMessage(); } @@ -111,16 +107,12 @@ You can use the `maxRetries` option to configure or disable this: 0]); // Or, configure per-request: - -$result = $client->casParser->smartParse( - requestOptions: RequestOptions::with(maxRetries: 5) -); +$result = $client->credits->check(requestOptions: ['maxRetries' => 5]); ``` ## Advanced concepts @@ -136,17 +128,13 @@ Note: the `extra*` parameters of the same name overrides the documented paramete ```php casParser->smartParse( - requestOptions: RequestOptions::with( - extraQueryParams: ["my_query_parameter" => "value"], - extraBodyParams: ["my_body_parameter" => "value"], - extraHeaders: ["my-header" => "value"], - ), +$response = $client->credits->check( + requestOptions: [ + 'extraQueryParams' => ['my_query_parameter' => 'value'], + 'extraBodyParams' => ['my_body_parameter' => 'value'], + 'extraHeaders' => ['my-header' => 'value'], + ], ); - -var_dump($unifiedResponse["my_undocumented_property"]); ``` #### Undocumented request params diff --git a/composer.json b/composer.json index 7163498..1fee198 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,10 @@ { "$schema": "https://getcomposer.org/schema.json", + "license": "Apache-2.0", "autoload": { - "files": ["src/Core.php", "src/Client.php"], + "files": [ + "src/Version.php" + ], "psr-4": { "CasParser\\": "src/" } @@ -37,6 +40,7 @@ "friendsofphp/php-cs-fixer": "^3", "nyholm/psr7": "^1", "pestphp/pest": "^3", + "php-http/mock-client": "^1", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^2", "phpstan/phpstan-phpunit": "^2", diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3f6c209 --- /dev/null +++ b/composer.lock @@ -0,0 +1,6672 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "5fc63f7c84d94b42416689723c547f69", + "packages": [ + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + } + ], + "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v7.8.4", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/130a9bf0e269ee5f5b320108f794ad03e275cad4", + "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.2.0", + "jean85/pretty-package-versions": "^2.1.1", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.5.24", + "sebastian/environment": "^7.2.1", + "symfony/console": "^6.4.22 || ^7.3.0", + "symfony/process": "^6.4.20 || ^7.3.0" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^2.1.17", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.6", + "phpstan/phpstan-strict-rules": "^2.0.4", + "squizlabs/php_codesniffer": "^3.13.2", + "symfony/filesystem": "^6.4.13 || ^7.3.0" + }, + "bin": [ + "bin/paratest", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.8.4" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2025-06-23T06:07:21+00:00" + }, + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "clue/stream-filter", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/clue/stream-filter.git", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.7.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2023-12-20T15:40:13+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + }, + "time": "2025-04-07T20:06:18+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "filp/whoops", + "version": "2.18.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.18.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2025-08-08T12:00:00+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.92.5", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58", + "reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.3", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.33", + "symfony/polyfill-php80": "^1.33", + "symfony/polyfill-php81": "^1.33", + "symfony/polyfill-php84": "^1.33", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.7", + "infection/infection": "^0.31", + "justinrainbow/json-schema": "^6.6", + "keradus/cli-executor": "^2.3", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.9", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.46", + "symfony/polyfill-php85": "^1.33", + "symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0", + "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/**/Internal/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.5" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2026-01-08T21:57:37+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "rector/rector": "^2.0", + "vimeo/psalm": "^4.3 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1" + }, + "time": "2025-03-19T14:43:43+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.8.3", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/1dc9e88d105699d0fee8bb18890f41b274f6b4c4", + "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.18.1", + "nunomaduro/termwind": "^2.3.1", + "php": "^8.2.0", + "symfony/console": "^7.3.0" + }, + "conflict": { + "laravel/framework": "<11.44.2 || >=13.0.0", + "phpunit/phpunit": "<11.5.15 || >=13.0.0" + }, + "require-dev": { + "brianium/paratest": "^7.8.3", + "larastan/larastan": "^3.4.2", + "laravel/framework": "^11.44.2 || ^12.18", + "laravel/pint": "^1.22.1", + "laravel/sail": "^1.43.1", + "laravel/sanctum": "^4.1.1", + "laravel/tinker": "^2.10.1", + "orchestra/testbench-core": "^9.12.0 || ^10.4", + "pestphp/pest": "^3.8.2 || ^4.0.0", + "sebastian/environment": "^7.2.1 || ^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "dev", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2025-11-20T02:55:25+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.3.3", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017", + "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.3.6" + }, + "require-dev": { + "illuminate/console": "^11.46.1", + "laravel/pint": "^1.25.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3", + "phpstan/phpstan": "^1.12.32", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.3.5", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.3" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2025-11-20T02:34:59+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2024-09-09T07:06:30+00:00" + }, + { + "name": "pestphp/pest", + "version": "v3.8.4", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "72cf695554420e21858cda831d5db193db102574" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/72cf695554420e21858cda831d5db193db102574", + "reference": "72cf695554420e21858cda831d5db193db102574", + "shasum": "" + }, + "require": { + "brianium/paratest": "^7.8.4", + "nunomaduro/collision": "^8.8.2", + "nunomaduro/termwind": "^2.3.1", + "pestphp/pest-plugin": "^3.0.0", + "pestphp/pest-plugin-arch": "^3.1.1", + "pestphp/pest-plugin-mutate": "^3.0.5", + "php": "^8.2.0", + "phpunit/phpunit": "^11.5.33" + }, + "conflict": { + "filp/whoops": "<2.16.0", + "phpunit/phpunit": ">11.5.33", + "sebastian/exporter": "<6.0.0", + "webmozart/assert": "<1.11.0" + }, + "require-dev": { + "pestphp/pest-dev-tools": "^3.4.0", + "pestphp/pest-plugin-type-coverage": "^3.6.1", + "symfony/process": "^7.3.0" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v3.8.4" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2025-08-20T19:12:42+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.2" + }, + "conflict": { + "pestphp/pest": "<3.0.0" + }, + "require-dev": { + "composer/composer": "^2.7.9", + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-08T23:21:41+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "db7bd9cb1612b223e16618d85475c6f63b9c8daa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/db7bd9cb1612b223e16618d85475c6f63b9c8daa", + "reference": "db7bd9cb1612b223e16618d85475c6f63b9c8daa", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "ta-tikoma/phpunit-architecture-test": "^0.8.4" + }, + "require-dev": { + "pestphp/pest": "^3.8.1", + "pestphp/pest-dev-tools": "^3.4.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2025-04-16T22:59:48+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.2.0", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^3.0.8", + "pestphp/pest-dev-tools": "^3.0.0", + "pestphp/pest-plugin-type-coverage": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-22T07:54:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.7.3", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/dcc6de29c90dd74faab55f71b79d89409c4bf0c1", + "reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "support": { + "issues": "https://github.com/php-http/client-common/issues", + "source": "https://github.com/php-http/client-common/tree/2.7.3" + }, + "time": "2025-11-29T19:12:34+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/5cad731844891a4c282f3f3e1b582c46839d22f4", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.1" + }, + "time": "2024-09-23T11:39:58+00:00" + }, + { + "name": "php-http/message", + "version": "1.16.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/06dd5e8562f84e641bf929bfe699ee0f5ce8080a", + "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.5", + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.6", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0 || ^2.0", + "laminas/laminas-diactoros": "^2.0 || ^3.0", + "php-http/message-factory": "^1.0.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "slim/slim": "^3.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "laminas/laminas-diactoros": "Used with Diactoros Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation" + }, + "type": "library", + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/1.16.2" + }, + "time": "2024-10-02T11:34:13+00:00" + }, + { + "name": "php-http/mock-client", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/mock-client.git", + "reference": "81f558234421f7da58ed015604a03808996017d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/mock-client/zipball/81f558234421f7da58ed015604a03808996017d0", + "reference": "81f558234421f7da58ed015604a03808996017d0", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/client-common": "^2.0", + "php-http/discovery": "^1.16", + "php-http/httplug": "^2.0", + "psr/http-client": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "symfony/polyfill-php80": "^1.17" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0", + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Mock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "David de Boer", + "email": "david@ddeboer.nl" + } + ], + "description": "Mock HTTP client", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http", + "mock", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/mock-client/issues", + "source": "https://github.com/php-http/mock-client/tree/1.6.1" + }, + "time": "2024-10-31T10:30:18+00:00" + }, + { + "name": "php-http/promise", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.3.1" + }, + "time": "2024-03-15T13:55:21+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.6", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1 || ^2" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" + }, + "time": "2025-12-22T21:13:58+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + }, + "time": "2025-11-21T15:09:14+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "time": "2024-09-04T20:21:43+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + }, + "time": "2025-08-30T15:50:23+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.33", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f", + "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-12-05T10:24:31+00:00" + }, + { + "name": "phpstan/phpstan-phpunit", + "version": "2.0.11", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-phpunit.git", + "reference": "5e30669bef866eff70db8b58d72a5c185aa82414" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/5e30669bef866eff70db8b58d72a5c185aa82414", + "reference": "5e30669bef866eff70db8b58d72a5c185aa82414", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.32" + }, + "conflict": { + "phpunit/phpunit": "<7.0" + }, + "require-dev": { + "nikic/php-parser": "^5", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPUnit extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-phpunit/issues", + "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.11" + }, + "time": "2025-12-19T09:05:35+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.1", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.3.1" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.46" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-12-24T07:01:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.33", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", + "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.2", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.33" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-08-16T05:19:02+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.7", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.7" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-12-23T15:25:20+00:00" + }, + { + "name": "react/dns", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.14.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-18T19:34:28+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-17T20:46:25+00:00" + }, + { + "name": "react/promise", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" + }, + { + "name": "react/socket", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.17.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-19T20:47:34+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-19T07:56:08+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2025-08-10T08:07:46+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-05-21T11:55:47+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:12:51+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-13T04:42:22+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" + } + ], + "time": "2025-08-09T06:55:48+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/console", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/732a9ca6cd9dfd940c639062d5edbde2f6727fb6", + "reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-23T14:50:43+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d", + "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-10-28T09:38:46+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-27T13:27:24+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "fffe05569336549b20a1be64250b40516d6e8d06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/fffe05569336549b20a1be64250b40516d6e8d06", + "reference": "fffe05569336549b20a1be64250b40516d6e8d06", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-23T14:50:43+00:00" + }, + { + "name": "symfony/http-client", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d01dfac1e0dc99f18da48b18101c23ce57929616", + "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "amphp/socket": "<1.1", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-23T14:50:43+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "75d7043853a42837e68111812f4d964b01e5101c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c", + "reference": "75d7043853a42837e68111812f4d964b01e5101c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-29T11:18:49+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "b38026df55197f9e39a44f3215788edf83187b80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b38026df55197f9e39a44f3215788edf83187b80", + "reference": "b38026df55197f9e39a44f3215788edf83187b80", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-12T15:39:26+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-08T02:45:35+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, + { + "name": "symfony/process", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/2f8e1a6cdf590ca63715da4d3a7a3327404a523f", + "reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-19T10:00:43+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "8a24af0a2e8a872fb745047180649b8418303084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/8a24af0a2e8a872fb745047180649b8418303084", + "reference": "8a24af0a2e8a872fb745047180649b8418303084", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-04T07:05:15+00:00" + }, + { + "name": "symfony/string", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003", + "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.33", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-27T13:27:24+00:00" + }, + { + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.5", + "source": { + "type": "git", + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "cf6fb197b676ba716837c886baca842e4db29005" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/cf6fb197b676ba716837c886baca842e4db29005", + "reference": "cf6fb197b676ba716837c886baca842e4db29005", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0" + }, + "require-dev": { + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPUnit\\Architecture\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], + "support": { + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.5" + }, + "time": "2025-04-20T20:23:40+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" + }, + { + "name": "webmozart/assert", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "bdbabc199a7ba9965484e4725d66170e5711323b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bdbabc199a7ba9965484e4725d66170e5711323b", + "reference": "bdbabc199a7ba9965484e4725d66170e5711323b", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^8.2" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-feature/2-0": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/2.1.1" + }, + "time": "2026-01-08T11:28:40+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.1" + }, + "platform-dev": {}, + "platform-overrides": { + "php": "8.3" + }, + "plugin-api-version": "2.6.0" +} diff --git a/release-please-config.json b/release-please-config.json index 1891660..83bea62 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -61,6 +61,7 @@ ], "release-type": "php", "extra-files": [ - "README.md" + "README.md", + "src/Version.php" ] } \ No newline at end of file diff --git a/scripts/lint b/scripts/lint index 6d629c2..211ce90 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,4 +5,4 @@ set -e cd -- "$(dirname -- "$0")/.." echo "==> Running PHPStan" -exec -- ./vendor/bin/phpstan analyse --memory-limit=1G +exec -- ./vendor/bin/phpstan analyse --memory-limit=12G diff --git a/scripts/test b/scripts/test index a8dc7cd..4b777e0 100755 --- a/scripts/test +++ b/scripts/test @@ -10,7 +10,7 @@ YELLOW='\033[0;33m' NC='\033[0m' # No Color function prism_is_running() { - curl --silent "http://localhost:4010" > /dev/null 2>&1 + curl --silent "http://localhost:4010" >/dev/null 2>&1 } kill_server_on_port() { @@ -25,7 +25,7 @@ function is_overriding_api_base_url() { [ -n "$TEST_API_BASE_URL" ] } -if ! is_overriding_api_base_url && ! prism_is_running; then +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 @@ -33,10 +33,10 @@ if ! is_overriding_api_base_url && ! prism_is_running; then ./scripts/mock --daemon fi -if is_overriding_api_base_url; then +if is_overriding_api_base_url ; then echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" echo -elif ! prism_is_running; then +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 diff --git a/src/AccessToken/AccessTokenCreateParams.php b/src/AccessToken/AccessTokenCreateParams.php new file mode 100644 index 0000000..f433ba8 --- /dev/null +++ b/src/AccessToken/AccessTokenCreateParams.php @@ -0,0 +1,68 @@ + */ + 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/CamsKfintech/CamsKfintechParseParams.php b/src/CamsKfintech/CamsKfintechParseParams.php new file mode 100644 index 0000000..b1e8bd6 --- /dev/null +++ b/src/CamsKfintech/CamsKfintechParseParams.php @@ -0,0 +1,102 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Password for the PDF file (if required). + */ + #[Optional] + public ?string $password; + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + #[Optional('pdf_file')] + public ?string $pdfFile; + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + #[Optional('pdf_url')] + public ?string $pdfURL; + + 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 $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null + ): self { + $self = new self; + + null !== $password && $self['password'] = $password; + null !== $pdfFile && $self['pdfFile'] = $pdfFile; + null !== $pdfURL && $self['pdfURL'] = $pdfURL; + + return $self; + } + + /** + * Password for the PDF file (if required). + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + public function withPdfFile(string $pdfFile): self + { + $self = clone $this; + $self['pdfFile'] = $pdfFile; + + return $self; + } + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + public function withPdfURL(string $pdfURL): self + { + $self = clone $this; + $self['pdfURL'] = $pdfURL; + + return $self; + } +} diff --git a/src/CamsKfintech/LinkedHolder.php b/src/CamsKfintech/LinkedHolder.php new file mode 100644 index 0000000..a7faa68 --- /dev/null +++ b/src/CamsKfintech/LinkedHolder.php @@ -0,0 +1,72 @@ + */ + use SdkModel; + + /** + * Name of the account holder. + */ + #[Optional] + public ?string $name; + + /** + * PAN of the account holder. + */ + #[Optional] + public ?string $pan; + + 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 $name = null, ?string $pan = null): self + { + $self = new self; + + null !== $name && $self['name'] = $name; + null !== $pan && $self['pan'] = $pan; + + return $self; + } + + /** + * Name of the account holder. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * PAN of the account holder. + */ + public function withPan(string $pan): self + { + $self = clone $this; + $self['pan'] = $pan; + + return $self; + } +} diff --git a/src/CamsKfintech/Transaction.php b/src/CamsKfintech/Transaction.php new file mode 100644 index 0000000..8a37ce4 --- /dev/null +++ b/src/CamsKfintech/Transaction.php @@ -0,0 +1,233 @@ +, + * units?: float|null, + * } + */ +final class Transaction implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional transaction-specific fields that vary by source. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * Transaction amount in currency (computed from units × price/NAV). + */ + #[Optional(nullable: true)] + public ?float $amount; + + /** + * Balance units after transaction. + */ + #[Optional] + public ?float $balance; + + /** + * Transaction date (YYYY-MM-DD). + */ + #[Optional] + public ?string $date; + + /** + * Transaction description/particulars. + */ + #[Optional] + public ?string $description; + + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions). + */ + #[Optional('dividend_rate', nullable: true)] + public ?float $dividendRate; + + /** + * NAV/price per unit on transaction date. + */ + #[Optional(nullable: true)] + public ?float $nav; + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, UNKNOWN. + * + * @var value-of|null $type + */ + #[Optional(enum: Type::class)] + public ?string $type; + + /** + * Number of units involved in transaction. + */ + #[Optional] + public ?float $units; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param Type|value-of|null $type + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?float $amount = null, + ?float $balance = null, + ?string $date = null, + ?string $description = null, + ?float $dividendRate = null, + ?float $nav = null, + Type|string|null $type = null, + ?float $units = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $amount && $self['amount'] = $amount; + null !== $balance && $self['balance'] = $balance; + null !== $date && $self['date'] = $date; + null !== $description && $self['description'] = $description; + null !== $dividendRate && $self['dividendRate'] = $dividendRate; + null !== $nav && $self['nav'] = $nav; + null !== $type && $self['type'] = $type; + null !== $units && $self['units'] = $units; + + return $self; + } + + /** + * Additional transaction-specific fields that vary by source. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Transaction amount in currency (computed from units × price/NAV). + */ + public function withAmount(?float $amount): self + { + $self = clone $this; + $self['amount'] = $amount; + + return $self; + } + + /** + * Balance units after transaction. + */ + public function withBalance(float $balance): self + { + $self = clone $this; + $self['balance'] = $balance; + + return $self; + } + + /** + * Transaction date (YYYY-MM-DD). + */ + public function withDate(string $date): self + { + $self = clone $this; + $self['date'] = $date; + + return $self; + } + + /** + * Transaction description/particulars. + */ + public function withDescription(string $description): self + { + $self = clone $this; + $self['description'] = $description; + + return $self; + } + + /** + * Dividend rate (for DIVIDEND_PAYOUT transactions). + */ + public function withDividendRate(?float $dividendRate): self + { + $self = clone $this; + $self['dividendRate'] = $dividendRate; + + return $self; + } + + /** + * NAV/price per unit on transaction date. + */ + public function withNav(?float $nav): self + { + $self = clone $this; + $self['nav'] = $nav; + + return $self; + } + + /** + * Transaction type. Possible values are PURCHASE, PURCHASE_SIP, REDEMPTION, SWITCH_IN, SWITCH_IN_MERGER, SWITCH_OUT, SWITCH_OUT_MERGER, DIVIDEND_PAYOUT, DIVIDEND_REINVEST, SEGREGATION, STAMP_DUTY_TAX, TDS_TAX, STT_TAX, MISC, REVERSAL, UNKNOWN. + * + * @param Type|value-of $type + */ + public function withType(Type|string $type): self + { + $self = clone $this; + $self['type'] = $type; + + return $self; + } + + /** + * Number of units involved in transaction. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } +} diff --git a/src/CamsKfintech/Transaction/AdditionalInfo.php b/src/CamsKfintech/Transaction/AdditionalInfo.php new file mode 100644 index 0000000..8e62289 --- /dev/null +++ b/src/CamsKfintech/Transaction/AdditionalInfo.php @@ -0,0 +1,179 @@ + */ + use SdkModel; + + /** + * Capital withdrawal amount (CDSL MF transactions). + */ + #[Optional('capital_withdrawal')] + public ?float $capitalWithdrawal; + + /** + * Units credited (demat transactions). + */ + #[Optional] + public ?float $credit; + + /** + * Units debited (demat transactions). + */ + #[Optional] + public ?float $debit; + + /** + * Income distribution amount (CDSL MF transactions). + */ + #[Optional('income_distribution')] + public ?float $incomeDistribution; + + /** + * Order/transaction reference number (demat transactions). + */ + #[Optional('order_no')] + public ?string $orderNo; + + /** + * Price per unit (NSDL/CDSL MF transactions). + */ + #[Optional] + public ?float $price; + + /** + * Stamp duty charged. + */ + #[Optional('stamp_duty')] + public ?float $stampDuty; + + 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 $capitalWithdrawal = null, + ?float $credit = null, + ?float $debit = null, + ?float $incomeDistribution = null, + ?string $orderNo = null, + ?float $price = null, + ?float $stampDuty = null, + ): self { + $self = new self; + + null !== $capitalWithdrawal && $self['capitalWithdrawal'] = $capitalWithdrawal; + null !== $credit && $self['credit'] = $credit; + null !== $debit && $self['debit'] = $debit; + null !== $incomeDistribution && $self['incomeDistribution'] = $incomeDistribution; + null !== $orderNo && $self['orderNo'] = $orderNo; + null !== $price && $self['price'] = $price; + null !== $stampDuty && $self['stampDuty'] = $stampDuty; + + return $self; + } + + /** + * Capital withdrawal amount (CDSL MF transactions). + */ + public function withCapitalWithdrawal(float $capitalWithdrawal): self + { + $self = clone $this; + $self['capitalWithdrawal'] = $capitalWithdrawal; + + return $self; + } + + /** + * Units credited (demat transactions). + */ + public function withCredit(float $credit): self + { + $self = clone $this; + $self['credit'] = $credit; + + return $self; + } + + /** + * Units debited (demat transactions). + */ + public function withDebit(float $debit): self + { + $self = clone $this; + $self['debit'] = $debit; + + return $self; + } + + /** + * Income distribution amount (CDSL MF transactions). + */ + public function withIncomeDistribution(float $incomeDistribution): self + { + $self = clone $this; + $self['incomeDistribution'] = $incomeDistribution; + + return $self; + } + + /** + * Order/transaction reference number (demat transactions). + */ + public function withOrderNo(string $orderNo): self + { + $self = clone $this; + $self['orderNo'] = $orderNo; + + return $self; + } + + /** + * Price per unit (NSDL/CDSL MF transactions). + */ + public function withPrice(float $price): self + { + $self = clone $this; + $self['price'] = $price; + + return $self; + } + + /** + * Stamp duty charged. + */ + public function withStampDuty(float $stampDuty): self + { + $self = clone $this; + $self['stampDuty'] = $stampDuty; + + return $self; + } +} diff --git a/src/CamsKfintech/Transaction/Type.php b/src/CamsKfintech/Transaction/Type.php new file mode 100644 index 0000000..b6b9e71 --- /dev/null +++ b/src/CamsKfintech/Transaction/Type.php @@ -0,0 +1,43 @@ +|null, + * insurance?: null|Insurance|InsuranceShape, + * investor?: null|Investor|InvestorShape, + * meta?: null|Meta|MetaShape, + * mutualFunds?: list|null, + * nps?: list|null, + * summary?: null|Summary|SummaryShape, + * } + */ +final class UnifiedResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** @var list|null $dematAccounts */ + #[Optional('demat_accounts', list: DematAccount::class)] + public ?array $dematAccounts; + + #[Optional] + public ?Insurance $insurance; + + #[Optional] + public ?Investor $investor; + + #[Optional] + public ?Meta $meta; + + /** @var list|null $mutualFunds */ + #[Optional('mutual_funds', list: MutualFund::class)] + public ?array $mutualFunds; + + /** + * List of NPS accounts. + * + * @var list|null $nps + */ + #[Optional(list: Np::class)] + public ?array $nps; + + #[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 list|null $dematAccounts + * @param Insurance|InsuranceShape|null $insurance + * @param Investor|InvestorShape|null $investor + * @param Meta|MetaShape|null $meta + * @param list|null $mutualFunds + * @param list|null $nps + * @param Summary|SummaryShape|null $summary + */ + public static function with( + ?array $dematAccounts = null, + Insurance|array|null $insurance = null, + Investor|array|null $investor = null, + Meta|array|null $meta = null, + ?array $mutualFunds = null, + ?array $nps = null, + Summary|array|null $summary = null, + ): self { + $self = new self; + + null !== $dematAccounts && $self['dematAccounts'] = $dematAccounts; + null !== $insurance && $self['insurance'] = $insurance; + null !== $investor && $self['investor'] = $investor; + null !== $meta && $self['meta'] = $meta; + null !== $mutualFunds && $self['mutualFunds'] = $mutualFunds; + null !== $nps && $self['nps'] = $nps; + null !== $summary && $self['summary'] = $summary; + + return $self; + } + + /** + * @param list $dematAccounts + */ + public function withDematAccounts(array $dematAccounts): self + { + $self = clone $this; + $self['dematAccounts'] = $dematAccounts; + + return $self; + } + + /** + * @param Insurance|InsuranceShape $insurance + */ + public function withInsurance(Insurance|array $insurance): self + { + $self = clone $this; + $self['insurance'] = $insurance; + + return $self; + } + + /** + * @param Investor|InvestorShape $investor + */ + public function withInvestor(Investor|array $investor): self + { + $self = clone $this; + $self['investor'] = $investor; + + return $self; + } + + /** + * @param Meta|MetaShape $meta + */ + public function withMeta(Meta|array $meta): self + { + $self = clone $this; + $self['meta'] = $meta; + + return $self; + } + + /** + * @param list $mutualFunds + */ + public function withMutualFunds(array $mutualFunds): self + { + $self = clone $this; + $self['mutualFunds'] = $mutualFunds; + + return $self; + } + + /** + * List of NPS accounts. + * + * @param list $nps + */ + public function withNps(array $nps): self + { + $self = clone $this; + $self['nps'] = $nps; + + 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/CamsKfintech/UnifiedResponse/DematAccount.php b/src/CamsKfintech/UnifiedResponse/DematAccount.php new file mode 100644 index 0000000..715dd3d --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount.php @@ -0,0 +1,238 @@ +, + * dpID?: string|null, + * dpName?: string|null, + * holdings?: null|Holdings|HoldingsShape, + * linkedHolders?: list|null, + * value?: float|null, + * } + */ +final class DematAccount implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the demat account type. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * Beneficiary Owner ID (primarily for CDSL). + */ + #[Optional('bo_id')] + public ?string $boID; + + /** + * Client ID. + */ + #[Optional('client_id')] + public ?string $clientID; + + /** + * Type of demat account. + * + * @var value-of|null $dematType + */ + #[Optional('demat_type', enum: DematType::class)] + public ?string $dematType; + + /** + * Depository Participant ID. + */ + #[Optional('dp_id')] + public ?string $dpID; + + /** + * Depository Participant name. + */ + #[Optional('dp_name')] + public ?string $dpName; + + #[Optional] + public ?Holdings $holdings; + + /** + * List of account holders linked to this demat account. + * + * @var list|null $linkedHolders + */ + #[Optional('linked_holders', list: LinkedHolder::class)] + public ?array $linkedHolders; + + /** + * Total value of the demat account. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param DematType|value-of|null $dematType + * @param Holdings|HoldingsShape|null $holdings + * @param list|null $linkedHolders + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $boID = null, + ?string $clientID = null, + DematType|string|null $dematType = null, + ?string $dpID = null, + ?string $dpName = null, + Holdings|array|null $holdings = null, + ?array $linkedHolders = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $boID && $self['boID'] = $boID; + null !== $clientID && $self['clientID'] = $clientID; + null !== $dematType && $self['dematType'] = $dematType; + null !== $dpID && $self['dpID'] = $dpID; + null !== $dpName && $self['dpName'] = $dpName; + null !== $holdings && $self['holdings'] = $holdings; + null !== $linkedHolders && $self['linkedHolders'] = $linkedHolders; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the demat account type. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Beneficiary Owner ID (primarily for CDSL). + */ + public function withBoID(string $boID): self + { + $self = clone $this; + $self['boID'] = $boID; + + return $self; + } + + /** + * Client ID. + */ + public function withClientID(string $clientID): self + { + $self = clone $this; + $self['clientID'] = $clientID; + + return $self; + } + + /** + * Type of demat account. + * + * @param DematType|value-of $dematType + */ + public function withDematType(DematType|string $dematType): self + { + $self = clone $this; + $self['dematType'] = $dematType; + + return $self; + } + + /** + * Depository Participant ID. + */ + public function withDpID(string $dpID): self + { + $self = clone $this; + $self['dpID'] = $dpID; + + return $self; + } + + /** + * Depository Participant name. + */ + public function withDpName(string $dpName): self + { + $self = clone $this; + $self['dpName'] = $dpName; + + return $self; + } + + /** + * @param Holdings|HoldingsShape $holdings + */ + public function withHoldings(Holdings|array $holdings): self + { + $self = clone $this; + $self['holdings'] = $holdings; + + return $self; + } + + /** + * List of account holders linked to this demat account. + * + * @param list $linkedHolders + */ + public function withLinkedHolders(array $linkedHolders): self + { + $self = clone $this; + $self['linkedHolders'] = $linkedHolders; + + return $self; + } + + /** + * Total value of the demat account. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/DematAccount/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/AdditionalInfo.php similarity index 58% rename from src/CasParser/UnifiedResponse/DematAccount/AdditionalInfo.php rename to src/CamsKfintech/UnifiedResponse/DematAccount/AdditionalInfo.php index c7a8be5..94649cf 100644 --- a/src/CasParser/UnifiedResponse/DematAccount/AdditionalInfo.php +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/AdditionalInfo.php @@ -2,59 +2,59 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\DematAccount; +namespace CasParser\CamsKfintech\UnifiedResponse\DematAccount; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** * Additional information specific to the demat account type. * - * @phpstan-type additional_info = array{ - * boStatus?: string, - * boSubStatus?: string, - * boType?: string, - * bsda?: string, - * email?: string, - * linkedPans?: list, - * nominee?: string, - * status?: string, + * @phpstan-type AdditionalInfoShape = array{ + * boStatus?: string|null, + * boSubStatus?: string|null, + * boType?: string|null, + * bsda?: string|null, + * email?: string|null, + * linkedPans?: list|null, + * nominee?: string|null, + * status?: string|null, * } */ final class AdditionalInfo implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Beneficiary Owner status (CDSL). */ - #[Api('bo_status', optional: true)] + #[Optional('bo_status')] public ?string $boStatus; /** * Beneficiary Owner sub-status (CDSL). */ - #[Api('bo_sub_status', optional: true)] + #[Optional('bo_sub_status')] public ?string $boSubStatus; /** * Beneficiary Owner type (CDSL). */ - #[Api('bo_type', optional: true)] + #[Optional('bo_type')] public ?string $boType; /** * Basic Services Demat Account status (CDSL). */ - #[Api(optional: true)] + #[Optional] public ?string $bsda; /** * Email associated with the demat account (CDSL). */ - #[Api(optional: true)] + #[Optional] public ?string $email; /** @@ -62,19 +62,19 @@ final class AdditionalInfo implements BaseModel * * @var list|null $linkedPans */ - #[Api('linked_pans', list: 'string', optional: true)] + #[Optional('linked_pans', list: 'string')] public ?array $linkedPans; /** * Nominee details (CDSL). */ - #[Api(optional: true)] + #[Optional] public ?string $nominee; /** * Account status (CDSL). */ - #[Api(optional: true)] + #[Optional] public ?string $status; public function __construct() @@ -87,7 +87,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param list $linkedPans + * @param list|null $linkedPans */ public static function with( ?string $boStatus = null, @@ -99,18 +99,18 @@ public static function with( ?string $nominee = null, ?string $status = null, ): self { - $obj = new self; - - null !== $boStatus && $obj->boStatus = $boStatus; - null !== $boSubStatus && $obj->boSubStatus = $boSubStatus; - null !== $boType && $obj->boType = $boType; - null !== $bsda && $obj->bsda = $bsda; - null !== $email && $obj->email = $email; - null !== $linkedPans && $obj->linkedPans = $linkedPans; - null !== $nominee && $obj->nominee = $nominee; - null !== $status && $obj->status = $status; - - return $obj; + $self = new self; + + null !== $boStatus && $self['boStatus'] = $boStatus; + null !== $boSubStatus && $self['boSubStatus'] = $boSubStatus; + null !== $boType && $self['boType'] = $boType; + null !== $bsda && $self['bsda'] = $bsda; + null !== $email && $self['email'] = $email; + null !== $linkedPans && $self['linkedPans'] = $linkedPans; + null !== $nominee && $self['nominee'] = $nominee; + null !== $status && $self['status'] = $status; + + return $self; } /** @@ -118,10 +118,10 @@ public static function with( */ public function withBoStatus(string $boStatus): self { - $obj = clone $this; - $obj->boStatus = $boStatus; + $self = clone $this; + $self['boStatus'] = $boStatus; - return $obj; + return $self; } /** @@ -129,10 +129,10 @@ public function withBoStatus(string $boStatus): self */ public function withBoSubStatus(string $boSubStatus): self { - $obj = clone $this; - $obj->boSubStatus = $boSubStatus; + $self = clone $this; + $self['boSubStatus'] = $boSubStatus; - return $obj; + return $self; } /** @@ -140,10 +140,10 @@ public function withBoSubStatus(string $boSubStatus): self */ public function withBoType(string $boType): self { - $obj = clone $this; - $obj->boType = $boType; + $self = clone $this; + $self['boType'] = $boType; - return $obj; + return $self; } /** @@ -151,10 +151,10 @@ public function withBoType(string $boType): self */ public function withBsda(string $bsda): self { - $obj = clone $this; - $obj->bsda = $bsda; + $self = clone $this; + $self['bsda'] = $bsda; - return $obj; + return $self; } /** @@ -162,10 +162,10 @@ public function withBsda(string $bsda): self */ public function withEmail(string $email): self { - $obj = clone $this; - $obj->email = $email; + $self = clone $this; + $self['email'] = $email; - return $obj; + return $self; } /** @@ -175,10 +175,10 @@ public function withEmail(string $email): self */ public function withLinkedPans(array $linkedPans): self { - $obj = clone $this; - $obj->linkedPans = $linkedPans; + $self = clone $this; + $self['linkedPans'] = $linkedPans; - return $obj; + return $self; } /** @@ -186,10 +186,10 @@ public function withLinkedPans(array $linkedPans): self */ public function withNominee(string $nominee): self { - $obj = clone $this; - $obj->nominee = $nominee; + $self = clone $this; + $self['nominee'] = $nominee; - return $obj; + return $self; } /** @@ -197,9 +197,9 @@ public function withNominee(string $nominee): self */ public function withStatus(string $status): self { - $obj = clone $this; - $obj->status = $status; + $self = clone $this; + $self['status'] = $status; - return $obj; + return $self; } } diff --git a/src/CasParser/UnifiedResponse/DematAccount/DematType.php b/src/CamsKfintech/UnifiedResponse/DematAccount/DematType.php similarity index 69% rename from src/CasParser/UnifiedResponse/DematAccount/DematType.php rename to src/CamsKfintech/UnifiedResponse/DematAccount/DematType.php index 53bf589..f7fb4ab 100644 --- a/src/CasParser/UnifiedResponse/DematAccount/DematType.php +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/DematType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\DematAccount; +namespace CasParser\CamsKfintech\UnifiedResponse\DematAccount; /** * Type of demat account. diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings.php new file mode 100644 index 0000000..f6e55ef --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings.php @@ -0,0 +1,144 @@ +|null, + * corporateBonds?: list|null, + * dematMutualFunds?: list|null, + * equities?: list|null, + * governmentSecurities?: list|null, + * } + */ +final class Holdings implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** @var list|null $aifs */ + #[Optional(list: Aif::class)] + public ?array $aifs; + + /** @var list|null $corporateBonds */ + #[Optional('corporate_bonds', list: CorporateBond::class)] + public ?array $corporateBonds; + + /** @var list|null $dematMutualFunds */ + #[Optional('demat_mutual_funds', list: DematMutualFund::class)] + public ?array $dematMutualFunds; + + /** @var list|null $equities */ + #[Optional(list: Equity::class)] + public ?array $equities; + + /** @var list|null $governmentSecurities */ + #[Optional('government_securities', list: GovernmentSecurity::class)] + public ?array $governmentSecurities; + + 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 $aifs + * @param list|null $corporateBonds + * @param list|null $dematMutualFunds + * @param list|null $equities + * @param list|null $governmentSecurities + */ + public static function with( + ?array $aifs = null, + ?array $corporateBonds = null, + ?array $dematMutualFunds = null, + ?array $equities = null, + ?array $governmentSecurities = null, + ): self { + $self = new self; + + null !== $aifs && $self['aifs'] = $aifs; + null !== $corporateBonds && $self['corporateBonds'] = $corporateBonds; + null !== $dematMutualFunds && $self['dematMutualFunds'] = $dematMutualFunds; + null !== $equities && $self['equities'] = $equities; + null !== $governmentSecurities && $self['governmentSecurities'] = $governmentSecurities; + + return $self; + } + + /** + * @param list $aifs + */ + public function withAifs(array $aifs): self + { + $self = clone $this; + $self['aifs'] = $aifs; + + return $self; + } + + /** + * @param list $corporateBonds + */ + public function withCorporateBonds(array $corporateBonds): self + { + $self = clone $this; + $self['corporateBonds'] = $corporateBonds; + + return $self; + } + + /** + * @param list $dematMutualFunds + */ + public function withDematMutualFunds(array $dematMutualFunds): self + { + $self = clone $this; + $self['dematMutualFunds'] = $dematMutualFunds; + + return $self; + } + + /** + * @param list $equities + */ + public function withEquities(array $equities): self + { + $self = clone $this; + $self['equities'] = $equities; + + return $self; + } + + /** + * @param list $governmentSecurities + */ + public function withGovernmentSecurities(array $governmentSecurities): self + { + $self = clone $this; + $self['governmentSecurities'] = $governmentSecurities; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif.php new file mode 100644 index 0000000..8bf43fb --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif.php @@ -0,0 +1,172 @@ +|null, + * units?: float|null, + * value?: float|null, + * } + */ +final class Aif implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the AIF. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * ISIN code of the AIF. + */ + #[Optional] + public ?string $isin; + + /** + * Name of the AIF. + */ + #[Optional] + public ?string $name; + + /** + * List of transactions for this holding (beta). + * + * @var list|null $transactions + */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $transactions + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $isin = null, + ?string $name = null, + ?array $transactions = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $transactions && $self['transactions'] = $transactions; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the AIF. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * ISIN code of the AIF. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Name of the AIF. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * List of transactions for this holding (beta). + * + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif/AdditionalInfo.php new file mode 100644 index 0000000..6ec556c --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Aif/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Closing balance units for the statement period (beta). + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period (beta). + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + 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 $closeUnits = null, + ?float $openUnits = null + ): self { + $self = new self; + + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * Closing balance units for the statement period (beta). + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period (beta). + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond.php new file mode 100644 index 0000000..9be7cd6 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond.php @@ -0,0 +1,172 @@ +|null, + * units?: float|null, + * value?: float|null, + * } + */ +final class CorporateBond implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the corporate bond. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * ISIN code of the corporate bond. + */ + #[Optional] + public ?string $isin; + + /** + * Name of the corporate bond. + */ + #[Optional] + public ?string $name; + + /** + * List of transactions for this holding (beta). + * + * @var list|null $transactions + */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $transactions + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $isin = null, + ?string $name = null, + ?array $transactions = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $transactions && $self['transactions'] = $transactions; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the corporate bond. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * ISIN code of the corporate bond. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Name of the corporate bond. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * List of transactions for this holding (beta). + * + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond/AdditionalInfo.php new file mode 100644 index 0000000..01f8b33 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/CorporateBond/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Closing balance units for the statement period (beta). + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period (beta). + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + 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 $closeUnits = null, + ?float $openUnits = null + ): self { + $self = new self; + + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * Closing balance units for the statement period (beta). + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period (beta). + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php new file mode 100644 index 0000000..9719ece --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php @@ -0,0 +1,172 @@ +|null, + * units?: float|null, + * value?: float|null, + * } + */ +final class DematMutualFund implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the mutual fund. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * ISIN code of the mutual fund. + */ + #[Optional] + public ?string $isin; + + /** + * Name of the mutual fund. + */ + #[Optional] + public ?string $name; + + /** + * List of transactions for this holding (beta). + * + * @var list|null $transactions + */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $transactions + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $isin = null, + ?string $name = null, + ?array $transactions = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $transactions && $self['transactions'] = $transactions; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the mutual fund. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * ISIN code of the mutual fund. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Name of the mutual fund. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * List of transactions for this holding (beta). + * + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund/AdditionalInfo.php new file mode 100644 index 0000000..85f2b12 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/DematMutualFund/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Closing balance units for the statement period (beta). + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period (beta). + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + 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 $closeUnits = null, + ?float $openUnits = null + ): self { + $self = new self; + + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * Closing balance units for the statement period (beta). + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period (beta). + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity.php new file mode 100644 index 0000000..49a9137 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity.php @@ -0,0 +1,172 @@ +|null, + * units?: float|null, + * value?: float|null, + * } + */ +final class Equity implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the equity. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * ISIN code of the equity. + */ + #[Optional] + public ?string $isin; + + /** + * Name of the equity. + */ + #[Optional] + public ?string $name; + + /** + * List of transactions for this holding (beta). + * + * @var list|null $transactions + */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $transactions + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $isin = null, + ?string $name = null, + ?array $transactions = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $transactions && $self['transactions'] = $transactions; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the equity. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * ISIN code of the equity. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Name of the equity. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * List of transactions for this holding (beta). + * + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity/AdditionalInfo.php new file mode 100644 index 0000000..37971ea --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/Equity/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Closing balance units for the statement period (beta). + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period (beta). + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + 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 $closeUnits = null, + ?float $openUnits = null + ): self { + $self = new self; + + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * Closing balance units for the statement period (beta). + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period (beta). + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php new file mode 100644 index 0000000..b245321 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php @@ -0,0 +1,172 @@ +|null, + * units?: float|null, + * value?: float|null, + * } + */ +final class GovernmentSecurity implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the government security. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * ISIN code of the government security. + */ + #[Optional] + public ?string $isin; + + /** + * Name of the government security. + */ + #[Optional] + public ?string $name; + + /** + * List of transactions for this holding (beta). + * + * @var list|null $transactions + */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $transactions + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $isin = null, + ?string $name = null, + ?array $transactions = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $transactions && $self['transactions'] = $transactions; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the government security. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * ISIN code of the government security. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Name of the government security. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * List of transactions for this holding (beta). + * + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity/AdditionalInfo.php new file mode 100644 index 0000000..f2c0690 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Closing balance units for the statement period (beta). + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period (beta). + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + 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 $closeUnits = null, + ?float $openUnits = null + ): self { + $self = new self; + + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * Closing balance units for the statement period (beta). + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period (beta). + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/Insurance.php b/src/CamsKfintech/UnifiedResponse/Insurance.php new file mode 100644 index 0000000..41fcad7 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Insurance.php @@ -0,0 +1,60 @@ +|null, + * } + */ +final class Insurance implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** @var list|null $lifeInsurancePolicies */ + #[Optional('life_insurance_policies', list: LifeInsurancePolicy::class)] + public ?array $lifeInsurancePolicies; + + 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 $lifeInsurancePolicies + */ + public static function with(?array $lifeInsurancePolicies = null): self + { + $self = new self; + + null !== $lifeInsurancePolicies && $self['lifeInsurancePolicies'] = $lifeInsurancePolicies; + + return $self; + } + + /** + * @param list $lifeInsurancePolicies + */ + public function withLifeInsurancePolicies( + array $lifeInsurancePolicies + ): self { + $self = clone $this; + $self['lifeInsurancePolicies'] = $lifeInsurancePolicies; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/Insurance/LifeInsurancePolicy.php b/src/CamsKfintech/UnifiedResponse/Insurance/LifeInsurancePolicy.php similarity index 55% rename from src/CasParser/UnifiedResponse/Insurance/LifeInsurancePolicy.php rename to src/CamsKfintech/UnifiedResponse/Insurance/LifeInsurancePolicy.php index c106c9c..0e8fc3d 100644 --- a/src/CasParser/UnifiedResponse/Insurance/LifeInsurancePolicy.php +++ b/src/CamsKfintech/UnifiedResponse/Insurance/LifeInsurancePolicy.php @@ -2,82 +2,82 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\Insurance; +namespace CasParser\CamsKfintech\UnifiedResponse\Insurance; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type life_insurance_policy = array{ + * @phpstan-type LifeInsurancePolicyShape = array{ * additionalInfo?: mixed, - * lifeAssured?: string, - * policyName?: string, - * policyNumber?: string, - * premiumAmount?: float, - * premiumFrequency?: string, - * provider?: string, - * status?: string, - * sumAssured?: float, + * lifeAssured?: string|null, + * policyName?: string|null, + * policyNumber?: string|null, + * premiumAmount?: float|null, + * premiumFrequency?: string|null, + * provider?: string|null, + * status?: string|null, + * sumAssured?: float|null, * } */ final class LifeInsurancePolicy implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Additional information specific to the policy. */ - #[Api('additional_info', optional: true)] + #[Optional('additional_info')] public mixed $additionalInfo; /** * Name of the life assured. */ - #[Api('life_assured', optional: true)] + #[Optional('life_assured')] public ?string $lifeAssured; /** * Name of the insurance policy. */ - #[Api('policy_name', optional: true)] + #[Optional('policy_name')] public ?string $policyName; /** * Insurance policy number. */ - #[Api('policy_number', optional: true)] + #[Optional('policy_number')] public ?string $policyNumber; /** * Premium amount. */ - #[Api('premium_amount', optional: true)] + #[Optional('premium_amount')] public ?float $premiumAmount; /** * Frequency of premium payment (e.g., Annual, Monthly). */ - #[Api('premium_frequency', optional: true)] + #[Optional('premium_frequency')] public ?string $premiumFrequency; /** * Insurance company name. */ - #[Api(optional: true)] + #[Optional] public ?string $provider; /** * Status of the policy (e.g., Active, Lapsed). */ - #[Api(optional: true)] + #[Optional] public ?string $status; /** * Sum assured amount. */ - #[Api('sum_assured', optional: true)] + #[Optional('sum_assured')] public ?float $sumAssured; public function __construct() @@ -101,19 +101,19 @@ public static function with( ?string $status = null, ?float $sumAssured = null, ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $lifeAssured && $obj->lifeAssured = $lifeAssured; - null !== $policyName && $obj->policyName = $policyName; - null !== $policyNumber && $obj->policyNumber = $policyNumber; - null !== $premiumAmount && $obj->premiumAmount = $premiumAmount; - null !== $premiumFrequency && $obj->premiumFrequency = $premiumFrequency; - null !== $provider && $obj->provider = $provider; - null !== $status && $obj->status = $status; - null !== $sumAssured && $obj->sumAssured = $sumAssured; - - return $obj; + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $lifeAssured && $self['lifeAssured'] = $lifeAssured; + null !== $policyName && $self['policyName'] = $policyName; + null !== $policyNumber && $self['policyNumber'] = $policyNumber; + null !== $premiumAmount && $self['premiumAmount'] = $premiumAmount; + null !== $premiumFrequency && $self['premiumFrequency'] = $premiumFrequency; + null !== $provider && $self['provider'] = $provider; + null !== $status && $self['status'] = $status; + null !== $sumAssured && $self['sumAssured'] = $sumAssured; + + return $self; } /** @@ -121,10 +121,10 @@ public static function with( */ public function withAdditionalInfo(mixed $additionalInfo): self { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; - return $obj; + return $self; } /** @@ -132,10 +132,10 @@ public function withAdditionalInfo(mixed $additionalInfo): self */ public function withLifeAssured(string $lifeAssured): self { - $obj = clone $this; - $obj->lifeAssured = $lifeAssured; + $self = clone $this; + $self['lifeAssured'] = $lifeAssured; - return $obj; + return $self; } /** @@ -143,10 +143,10 @@ public function withLifeAssured(string $lifeAssured): self */ public function withPolicyName(string $policyName): self { - $obj = clone $this; - $obj->policyName = $policyName; + $self = clone $this; + $self['policyName'] = $policyName; - return $obj; + return $self; } /** @@ -154,10 +154,10 @@ public function withPolicyName(string $policyName): self */ public function withPolicyNumber(string $policyNumber): self { - $obj = clone $this; - $obj->policyNumber = $policyNumber; + $self = clone $this; + $self['policyNumber'] = $policyNumber; - return $obj; + return $self; } /** @@ -165,10 +165,10 @@ public function withPolicyNumber(string $policyNumber): self */ public function withPremiumAmount(float $premiumAmount): self { - $obj = clone $this; - $obj->premiumAmount = $premiumAmount; + $self = clone $this; + $self['premiumAmount'] = $premiumAmount; - return $obj; + return $self; } /** @@ -176,10 +176,10 @@ public function withPremiumAmount(float $premiumAmount): self */ public function withPremiumFrequency(string $premiumFrequency): self { - $obj = clone $this; - $obj->premiumFrequency = $premiumFrequency; + $self = clone $this; + $self['premiumFrequency'] = $premiumFrequency; - return $obj; + return $self; } /** @@ -187,10 +187,10 @@ public function withPremiumFrequency(string $premiumFrequency): self */ public function withProvider(string $provider): self { - $obj = clone $this; - $obj->provider = $provider; + $self = clone $this; + $self['provider'] = $provider; - return $obj; + return $self; } /** @@ -198,10 +198,10 @@ public function withProvider(string $provider): self */ public function withStatus(string $status): self { - $obj = clone $this; - $obj->status = $status; + $self = clone $this; + $self['status'] = $status; - return $obj; + return $self; } /** @@ -209,9 +209,9 @@ public function withStatus(string $status): self */ public function withSumAssured(float $sumAssured): self { - $obj = clone $this; - $obj->sumAssured = $sumAssured; + $self = clone $this; + $self['sumAssured'] = $sumAssured; - return $obj; + return $self; } } diff --git a/src/CasParser/UnifiedResponse/Investor.php b/src/CamsKfintech/UnifiedResponse/Investor.php similarity index 59% rename from src/CasParser/UnifiedResponse/Investor.php rename to src/CamsKfintech/UnifiedResponse/Investor.php index dd04ddc..f25328c 100644 --- a/src/CasParser/UnifiedResponse/Investor.php +++ b/src/CamsKfintech/UnifiedResponse/Investor.php @@ -2,68 +2,68 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse; +namespace CasParser\CamsKfintech\UnifiedResponse; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type investor_alias = array{ - * address?: string, - * casID?: string, - * email?: string, - * mobile?: string, - * name?: string, - * pan?: string, - * pincode?: string, + * @phpstan-type InvestorShape = array{ + * address?: string|null, + * casID?: string|null, + * email?: string|null, + * mobile?: string|null, + * name?: string|null, + * pan?: string|null, + * pincode?: string|null, * } */ final class Investor implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Address of the investor. */ - #[Api(optional: true)] + #[Optional] public ?string $address; /** * CAS ID of the investor (only for NSDL and CDSL). */ - #[Api('cas_id', optional: true)] + #[Optional('cas_id')] public ?string $casID; /** * Email address of the investor. */ - #[Api(optional: true)] + #[Optional] public ?string $email; /** * Mobile number of the investor. */ - #[Api(optional: true)] + #[Optional] public ?string $mobile; /** * Name of the investor. */ - #[Api(optional: true)] + #[Optional] public ?string $name; /** * PAN (Permanent Account Number) of the investor. */ - #[Api(optional: true)] + #[Optional] public ?string $pan; /** * Postal code of the investor's address. */ - #[Api(optional: true)] + #[Optional] public ?string $pincode; public function __construct() @@ -85,17 +85,17 @@ public static function with( ?string $pan = null, ?string $pincode = null, ): self { - $obj = new self; + $self = new self; - null !== $address && $obj->address = $address; - null !== $casID && $obj->casID = $casID; - null !== $email && $obj->email = $email; - null !== $mobile && $obj->mobile = $mobile; - null !== $name && $obj->name = $name; - null !== $pan && $obj->pan = $pan; - null !== $pincode && $obj->pincode = $pincode; + null !== $address && $self['address'] = $address; + null !== $casID && $self['casID'] = $casID; + null !== $email && $self['email'] = $email; + null !== $mobile && $self['mobile'] = $mobile; + null !== $name && $self['name'] = $name; + null !== $pan && $self['pan'] = $pan; + null !== $pincode && $self['pincode'] = $pincode; - return $obj; + return $self; } /** @@ -103,10 +103,10 @@ public static function with( */ public function withAddress(string $address): self { - $obj = clone $this; - $obj->address = $address; + $self = clone $this; + $self['address'] = $address; - return $obj; + return $self; } /** @@ -114,10 +114,10 @@ public function withAddress(string $address): self */ public function withCasID(string $casID): self { - $obj = clone $this; - $obj->casID = $casID; + $self = clone $this; + $self['casID'] = $casID; - return $obj; + return $self; } /** @@ -125,10 +125,10 @@ public function withCasID(string $casID): self */ public function withEmail(string $email): self { - $obj = clone $this; - $obj->email = $email; + $self = clone $this; + $self['email'] = $email; - return $obj; + return $self; } /** @@ -136,10 +136,10 @@ public function withEmail(string $email): self */ public function withMobile(string $mobile): self { - $obj = clone $this; - $obj->mobile = $mobile; + $self = clone $this; + $self['mobile'] = $mobile; - return $obj; + return $self; } /** @@ -147,10 +147,10 @@ public function withMobile(string $mobile): self */ public function withName(string $name): self { - $obj = clone $this; - $obj->name = $name; + $self = clone $this; + $self['name'] = $name; - return $obj; + return $self; } /** @@ -158,10 +158,10 @@ public function withName(string $name): self */ public function withPan(string $pan): self { - $obj = clone $this; - $obj->pan = $pan; + $self = clone $this; + $self['pan'] = $pan; - return $obj; + return $self; } /** @@ -169,9 +169,9 @@ public function withPan(string $pan): self */ public function withPincode(string $pincode): self { - $obj = clone $this; - $obj->pincode = $pincode; + $self = clone $this; + $self['pincode'] = $pincode; - return $obj; + return $self; } } diff --git a/src/CamsKfintech/UnifiedResponse/Meta.php b/src/CamsKfintech/UnifiedResponse/Meta.php new file mode 100644 index 0000000..79b2bf6 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Meta.php @@ -0,0 +1,106 @@ +, + * generatedAt?: \DateTimeInterface|null, + * statementPeriod?: null|StatementPeriod|StatementPeriodShape, + * } + */ +final class Meta implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Type of CAS detected and processed. + * + * @var value-of|null $casType + */ + #[Optional('cas_type', enum: CasType::class)] + public ?string $casType; + + /** + * Timestamp when the response was generated. + */ + #[Optional('generated_at')] + public ?\DateTimeInterface $generatedAt; + + #[Optional('statement_period')] + public ?StatementPeriod $statementPeriod; + + 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 CasType|value-of|null $casType + * @param StatementPeriod|StatementPeriodShape|null $statementPeriod + */ + public static function with( + CasType|string|null $casType = null, + ?\DateTimeInterface $generatedAt = null, + StatementPeriod|array|null $statementPeriod = null, + ): self { + $self = new self; + + null !== $casType && $self['casType'] = $casType; + null !== $generatedAt && $self['generatedAt'] = $generatedAt; + null !== $statementPeriod && $self['statementPeriod'] = $statementPeriod; + + return $self; + } + + /** + * Type of CAS detected and processed. + * + * @param CasType|value-of $casType + */ + public function withCasType(CasType|string $casType): self + { + $self = clone $this; + $self['casType'] = $casType; + + return $self; + } + + /** + * Timestamp when the response was generated. + */ + public function withGeneratedAt(\DateTimeInterface $generatedAt): self + { + $self = clone $this; + $self['generatedAt'] = $generatedAt; + + return $self; + } + + /** + * @param StatementPeriod|StatementPeriodShape $statementPeriod + */ + public function withStatementPeriod( + StatementPeriod|array $statementPeriod + ): self { + $self = clone $this; + $self['statementPeriod'] = $statementPeriod; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/Meta/CasType.php b/src/CamsKfintech/UnifiedResponse/Meta/CasType.php similarity index 78% rename from src/CasParser/UnifiedResponse/Meta/CasType.php rename to src/CamsKfintech/UnifiedResponse/Meta/CasType.php index bed4fed..eb7e339 100644 --- a/src/CasParser/UnifiedResponse/Meta/CasType.php +++ b/src/CamsKfintech/UnifiedResponse/Meta/CasType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\Meta; +namespace CasParser\CamsKfintech\UnifiedResponse\Meta; /** * Type of CAS detected and processed. diff --git a/src/CamsKfintech/UnifiedResponse/Meta/StatementPeriod.php b/src/CamsKfintech/UnifiedResponse/Meta/StatementPeriod.php new file mode 100644 index 0000000..4571451 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Meta/StatementPeriod.php @@ -0,0 +1,72 @@ + */ + use SdkModel; + + /** + * Start date of the statement period. + */ + #[Optional] + public ?string $from; + + /** + * End date of the statement period. + */ + #[Optional] + public ?string $to; + + 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 $from = null, ?string $to = null): self + { + $self = new self; + + null !== $from && $self['from'] = $from; + null !== $to && $self['to'] = $to; + + return $self; + } + + /** + * Start date of the statement period. + */ + public function withFrom(string $from): self + { + $self = clone $this; + $self['from'] = $from; + + return $self; + } + + /** + * End date of the statement period. + */ + public function withTo(string $to): self + { + $self = clone $this; + $self['to'] = $to; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/MutualFund.php b/src/CamsKfintech/UnifiedResponse/MutualFund.php new file mode 100644 index 0000000..5b911dc --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/MutualFund.php @@ -0,0 +1,193 @@ +|null, + * registrar?: string|null, + * schemes?: list|null, + * value?: float|null, + * } + */ +final class MutualFund implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional folio information. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * Asset Management Company name. + */ + #[Optional] + public ?string $amc; + + /** + * Folio number. + */ + #[Optional('folio_number')] + public ?string $folioNumber; + + /** + * List of account holders linked to this mutual fund folio. + * + * @var list|null $linkedHolders + */ + #[Optional('linked_holders', list: LinkedHolder::class)] + public ?array $linkedHolders; + + /** + * Registrar and Transfer Agent name. + */ + #[Optional] + public ?string $registrar; + + /** @var list|null $schemes */ + #[Optional(list: Scheme::class)] + public ?array $schemes; + + /** + * Total value of the folio. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param list|null $linkedHolders + * @param list|null $schemes + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?string $amc = null, + ?string $folioNumber = null, + ?array $linkedHolders = null, + ?string $registrar = null, + ?array $schemes = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $amc && $self['amc'] = $amc; + null !== $folioNumber && $self['folioNumber'] = $folioNumber; + null !== $linkedHolders && $self['linkedHolders'] = $linkedHolders; + null !== $registrar && $self['registrar'] = $registrar; + null !== $schemes && $self['schemes'] = $schemes; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional folio information. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Asset Management Company name. + */ + public function withAmc(string $amc): self + { + $self = clone $this; + $self['amc'] = $amc; + + return $self; + } + + /** + * Folio number. + */ + public function withFolioNumber(string $folioNumber): self + { + $self = clone $this; + $self['folioNumber'] = $folioNumber; + + return $self; + } + + /** + * List of account holders linked to this mutual fund folio. + * + * @param list $linkedHolders + */ + public function withLinkedHolders(array $linkedHolders): self + { + $self = clone $this; + $self['linkedHolders'] = $linkedHolders; + + return $self; + } + + /** + * Registrar and Transfer Agent name. + */ + public function withRegistrar(string $registrar): self + { + $self = clone $this; + $self['registrar'] = $registrar; + + return $self; + } + + /** + * @param list $schemes + */ + public function withSchemes(array $schemes): self + { + $self = clone $this; + $self['schemes'] = $schemes; + + return $self; + } + + /** + * Total value of the folio. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/MutualFund/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/MutualFund/AdditionalInfo.php similarity index 61% rename from src/CasParser/UnifiedResponse/MutualFund/AdditionalInfo.php rename to src/CamsKfintech/UnifiedResponse/MutualFund/AdditionalInfo.php index b79ad23..c213ed1 100644 --- a/src/CasParser/UnifiedResponse/MutualFund/AdditionalInfo.php +++ b/src/CamsKfintech/UnifiedResponse/MutualFund/AdditionalInfo.php @@ -2,40 +2,40 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\MutualFund; +namespace CasParser\CamsKfintech\UnifiedResponse\MutualFund; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** * Additional folio information. * - * @phpstan-type additional_info = array{ - * kyc?: string, pan?: string, pankyc?: string + * @phpstan-type AdditionalInfoShape = array{ + * kyc?: string|null, pan?: string|null, pankyc?: string|null * } */ final class AdditionalInfo implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * KYC status of the folio. */ - #[Api(optional: true)] + #[Optional] public ?string $kyc; /** * PAN associated with the folio. */ - #[Api(optional: true)] + #[Optional] public ?string $pan; /** * PAN KYC status. */ - #[Api(optional: true)] + #[Optional] public ?string $pankyc; public function __construct() @@ -53,13 +53,13 @@ public static function with( ?string $pan = null, ?string $pankyc = null ): self { - $obj = new self; + $self = new self; - null !== $kyc && $obj->kyc = $kyc; - null !== $pan && $obj->pan = $pan; - null !== $pankyc && $obj->pankyc = $pankyc; + null !== $kyc && $self['kyc'] = $kyc; + null !== $pan && $self['pan'] = $pan; + null !== $pankyc && $self['pankyc'] = $pankyc; - return $obj; + return $self; } /** @@ -67,10 +67,10 @@ public static function with( */ public function withKYC(string $kyc): self { - $obj = clone $this; - $obj->kyc = $kyc; + $self = clone $this; + $self['kyc'] = $kyc; - return $obj; + return $self; } /** @@ -78,10 +78,10 @@ public function withKYC(string $kyc): self */ public function withPan(string $pan): self { - $obj = clone $this; - $obj->pan = $pan; + $self = clone $this; + $self['pan'] = $pan; - return $obj; + return $self; } /** @@ -89,9 +89,9 @@ public function withPan(string $pan): self */ public function withPankyc(string $pankyc): self { - $obj = clone $this; - $obj->pankyc = $pankyc; + $self = clone $this; + $self['pankyc'] = $pankyc; - return $obj; + return $self; } } diff --git a/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme.php b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme.php new file mode 100644 index 0000000..bdc6424 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme.php @@ -0,0 +1,277 @@ +|null, + * transactions?: list|null, + * type?: null|Type|value-of, + * units?: float|null, + * value?: float|null, + * } + */ +final class Scheme implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the scheme. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * Cost of investment. + */ + #[Optional] + public ?float $cost; + + #[Optional] + public ?Gain $gain; + + /** + * ISIN code of the scheme. + */ + #[Optional] + public ?string $isin; + + /** + * Scheme name. + */ + #[Optional] + public ?string $name; + + /** + * Net Asset Value per unit. + */ + #[Optional] + public ?float $nav; + + /** + * List of nominees. + * + * @var list|null $nominees + */ + #[Optional(list: 'string')] + public ?array $nominees; + + /** @var list|null $transactions */ + #[Optional(list: Transaction::class)] + public ?array $transactions; + + /** + * Type of mutual fund scheme. + * + * @var value-of|null $type + */ + #[Optional(enum: Type::class)] + public ?string $type; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + * @param Gain|GainShape|null $gain + * @param list|null $nominees + * @param list|null $transactions + * @param Type|value-of|null $type + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?float $cost = null, + Gain|array|null $gain = null, + ?string $isin = null, + ?string $name = null, + ?float $nav = null, + ?array $nominees = null, + ?array $transactions = null, + Type|string|null $type = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $cost && $self['cost'] = $cost; + null !== $gain && $self['gain'] = $gain; + null !== $isin && $self['isin'] = $isin; + null !== $name && $self['name'] = $name; + null !== $nav && $self['nav'] = $nav; + null !== $nominees && $self['nominees'] = $nominees; + null !== $transactions && $self['transactions'] = $transactions; + null !== $type && $self['type'] = $type; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the scheme. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo, + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Cost of investment. + */ + public function withCost(float $cost): self + { + $self = clone $this; + $self['cost'] = $cost; + + return $self; + } + + /** + * @param Gain|GainShape $gain + */ + public function withGain(Gain|array $gain): self + { + $self = clone $this; + $self['gain'] = $gain; + + return $self; + } + + /** + * ISIN code of the scheme. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Scheme name. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * Net Asset Value per unit. + */ + public function withNav(float $nav): self + { + $self = clone $this; + $self['nav'] = $nav; + + return $self; + } + + /** + * List of nominees. + * + * @param list $nominees + */ + public function withNominees(array $nominees): self + { + $self = clone $this; + $self['nominees'] = $nominees; + + return $self; + } + + /** + * @param list $transactions + */ + public function withTransactions(array $transactions): self + { + $self = clone $this; + $self['transactions'] = $transactions; + + return $self; + } + + /** + * Type of mutual fund scheme. + * + * @param Type|value-of $type + */ + public function withType(Type|string $type): self + { + $self = clone $this; + $self['type'] = $type; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php new file mode 100644 index 0000000..91d9117 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php @@ -0,0 +1,139 @@ + */ + use SdkModel; + + /** + * Financial advisor name (CAMS/KFintech). + */ + #[Optional] + public ?string $advisor; + + /** + * AMFI code for the scheme (CAMS/KFintech). + */ + #[Optional] + public ?string $amfi; + + /** + * Closing balance units for the statement period. + */ + #[Optional('close_units', nullable: true)] + public ?float $closeUnits; + + /** + * Opening balance units for the statement period. + */ + #[Optional('open_units', nullable: true)] + public ?float $openUnits; + + /** + * RTA code for the scheme (CAMS/KFintech). + */ + #[Optional('rta_code')] + public ?string $rtaCode; + + 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 $advisor = null, + ?string $amfi = null, + ?float $closeUnits = null, + ?float $openUnits = null, + ?string $rtaCode = null, + ): self { + $self = new self; + + null !== $advisor && $self['advisor'] = $advisor; + null !== $amfi && $self['amfi'] = $amfi; + null !== $closeUnits && $self['closeUnits'] = $closeUnits; + null !== $openUnits && $self['openUnits'] = $openUnits; + null !== $rtaCode && $self['rtaCode'] = $rtaCode; + + return $self; + } + + /** + * Financial advisor name (CAMS/KFintech). + */ + public function withAdvisor(string $advisor): self + { + $self = clone $this; + $self['advisor'] = $advisor; + + return $self; + } + + /** + * AMFI code for the scheme (CAMS/KFintech). + */ + public function withAmfi(string $amfi): self + { + $self = clone $this; + $self['amfi'] = $amfi; + + return $self; + } + + /** + * Closing balance units for the statement period. + */ + public function withCloseUnits(?float $closeUnits): self + { + $self = clone $this; + $self['closeUnits'] = $closeUnits; + + return $self; + } + + /** + * Opening balance units for the statement period. + */ + public function withOpenUnits(?float $openUnits): self + { + $self = clone $this; + $self['openUnits'] = $openUnits; + + return $self; + } + + /** + * RTA code for the scheme (CAMS/KFintech). + */ + public function withRtaCode(string $rtaCode): self + { + $self = clone $this; + $self['rtaCode'] = $rtaCode; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Gain.php b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Gain.php similarity index 60% rename from src/CasParser/UnifiedResponse/MutualFund/Scheme/Gain.php rename to src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Gain.php index 8006cfa..d19f1ff 100644 --- a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Gain.php +++ b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Gain.php @@ -2,30 +2,30 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\MutualFund\Scheme; +namespace CasParser\CamsKfintech\UnifiedResponse\MutualFund\Scheme; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type gain_alias = array{absolute?: float, percentage?: float} + * @phpstan-type GainShape = array{absolute?: float|null, percentage?: float|null} */ final class Gain implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Absolute gain or loss. */ - #[Api(optional: true)] + #[Optional] public ?float $absolute; /** * Percentage gain or loss. */ - #[Api(optional: true)] + #[Optional] public ?float $percentage; public function __construct() @@ -42,12 +42,12 @@ public static function with( ?float $absolute = null, ?float $percentage = null ): self { - $obj = new self; + $self = new self; - null !== $absolute && $obj->absolute = $absolute; - null !== $percentage && $obj->percentage = $percentage; + null !== $absolute && $self['absolute'] = $absolute; + null !== $percentage && $self['percentage'] = $percentage; - return $obj; + return $self; } /** @@ -55,10 +55,10 @@ public static function with( */ public function withAbsolute(float $absolute): self { - $obj = clone $this; - $obj->absolute = $absolute; + $self = clone $this; + $self['absolute'] = $absolute; - return $obj; + return $self; } /** @@ -66,9 +66,9 @@ public function withAbsolute(float $absolute): self */ public function withPercentage(float $percentage): self { - $obj = clone $this; - $obj->percentage = $percentage; + $self = clone $this; + $self['percentage'] = $percentage; - return $obj; + return $self; } } diff --git a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Type.php b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Type.php similarity index 75% rename from src/CasParser/UnifiedResponse/MutualFund/Scheme/Type.php rename to src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Type.php index 76f8faf..6255662 100644 --- a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Type.php +++ b/src/CamsKfintech/UnifiedResponse/MutualFund/Scheme/Type.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\MutualFund\Scheme; +namespace CasParser\CamsKfintech\UnifiedResponse\MutualFund\Scheme; /** * Type of mutual fund scheme. diff --git a/src/CamsKfintech/UnifiedResponse/Np.php b/src/CamsKfintech/UnifiedResponse/Np.php new file mode 100644 index 0000000..e96e0a8 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Np.php @@ -0,0 +1,167 @@ +|null, + * linkedHolders?: list|null, + * pran?: string|null, + * value?: float|null, + * } + */ +final class Np implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Additional information specific to the NPS account. + */ + #[Optional('additional_info')] + public mixed $additionalInfo; + + /** + * Central Record Keeping Agency name. + */ + #[Optional] + public ?string $cra; + + /** @var list|null $funds */ + #[Optional(list: Fund::class)] + public ?array $funds; + + /** + * List of account holders linked to this NPS account. + * + * @var list|null $linkedHolders + */ + #[Optional('linked_holders', list: LinkedHolder::class)] + public ?array $linkedHolders; + + /** + * Permanent Retirement Account Number (PRAN). + */ + #[Optional] + public ?string $pran; + + /** + * Total value of the NPS account. + */ + #[Optional] + public ?float $value; + + 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 $funds + * @param list|null $linkedHolders + */ + public static function with( + mixed $additionalInfo = null, + ?string $cra = null, + ?array $funds = null, + ?array $linkedHolders = null, + ?string $pran = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $cra && $self['cra'] = $cra; + null !== $funds && $self['funds'] = $funds; + null !== $linkedHolders && $self['linkedHolders'] = $linkedHolders; + null !== $pran && $self['pran'] = $pran; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the NPS account. + */ + public function withAdditionalInfo(mixed $additionalInfo): self + { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Central Record Keeping Agency name. + */ + public function withCra(string $cra): self + { + $self = clone $this; + $self['cra'] = $cra; + + return $self; + } + + /** + * @param list $funds + */ + public function withFunds(array $funds): self + { + $self = clone $this; + $self['funds'] = $funds; + + return $self; + } + + /** + * List of account holders linked to this NPS account. + * + * @param list $linkedHolders + */ + public function withLinkedHolders(array $linkedHolders): self + { + $self = clone $this; + $self['linkedHolders'] = $linkedHolders; + + return $self; + } + + /** + * Permanent Retirement Account Number (PRAN). + */ + public function withPran(string $pran): self + { + $self = clone $this; + $self['pran'] = $pran; + + return $self; + } + + /** + * Total value of the NPS account. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/Np/Fund.php b/src/CamsKfintech/UnifiedResponse/Np/Fund.php new file mode 100644 index 0000000..3a2d2e7 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Np/Fund.php @@ -0,0 +1,165 @@ + */ + use SdkModel; + + /** + * Additional information specific to the NPS fund. + */ + #[Optional('additional_info')] + public ?AdditionalInfo $additionalInfo; + + /** + * Cost of investment. + */ + #[Optional] + public ?float $cost; + + /** + * Name of the NPS fund. + */ + #[Optional] + public ?string $name; + + /** + * Net Asset Value per unit. + */ + #[Optional] + public ?float $nav; + + /** + * Number of units held. + */ + #[Optional] + public ?float $units; + + /** + * Current market value of the holding. + */ + #[Optional] + public ?float $value; + + 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 AdditionalInfo|AdditionalInfoShape|null $additionalInfo + */ + public static function with( + AdditionalInfo|array|null $additionalInfo = null, + ?float $cost = null, + ?string $name = null, + ?float $nav = null, + ?float $units = null, + ?float $value = null, + ): self { + $self = new self; + + null !== $additionalInfo && $self['additionalInfo'] = $additionalInfo; + null !== $cost && $self['cost'] = $cost; + null !== $name && $self['name'] = $name; + null !== $nav && $self['nav'] = $nav; + null !== $units && $self['units'] = $units; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * Additional information specific to the NPS fund. + * + * @param AdditionalInfo|AdditionalInfoShape $additionalInfo + */ + public function withAdditionalInfo( + AdditionalInfo|array $additionalInfo + ): self { + $self = clone $this; + $self['additionalInfo'] = $additionalInfo; + + return $self; + } + + /** + * Cost of investment. + */ + public function withCost(float $cost): self + { + $self = clone $this; + $self['cost'] = $cost; + + return $self; + } + + /** + * Name of the NPS fund. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * Net Asset Value per unit. + */ + public function withNav(float $nav): self + { + $self = clone $this; + $self['nav'] = $nav; + + return $self; + } + + /** + * Number of units held. + */ + public function withUnits(float $units): self + { + $self = clone $this; + $self['units'] = $units; + + return $self; + } + + /** + * Current market value of the holding. + */ + public function withValue(float $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/Np/Fund/AdditionalInfo.php b/src/CamsKfintech/UnifiedResponse/Np/Fund/AdditionalInfo.php new file mode 100644 index 0000000..406019e --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Np/Fund/AdditionalInfo.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + /** + * Fund manager name. + */ + #[Optional] + public ?string $manager; + + /** + * NPS tier (Tier I or Tier II). + */ + #[Optional(nullable: true)] + public ?float $tier; + + 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 $manager = null, + ?float $tier = null + ): self { + $self = new self; + + null !== $manager && $self['manager'] = $manager; + null !== $tier && $self['tier'] = $tier; + + return $self; + } + + /** + * Fund manager name. + */ + public function withManager(string $manager): self + { + $self = clone $this; + $self['manager'] = $manager; + + return $self; + } + + /** + * NPS tier (Tier I or Tier II). + */ + public function withTier(?float $tier): self + { + $self = clone $this; + $self['tier'] = $tier; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/Summary.php b/src/CamsKfintech/UnifiedResponse/Summary.php new file mode 100644 index 0000000..c8e4f1a --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Summary.php @@ -0,0 +1,78 @@ + */ + use SdkModel; + + #[Optional] + public ?Accounts $accounts; + + /** + * Total portfolio value across all accounts. + */ + #[Optional('total_value')] + public ?float $totalValue; + + 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 Accounts|AccountsShape|null $accounts + */ + public static function with( + Accounts|array|null $accounts = null, + ?float $totalValue = null + ): self { + $self = new self; + + null !== $accounts && $self['accounts'] = $accounts; + null !== $totalValue && $self['totalValue'] = $totalValue; + + return $self; + } + + /** + * @param Accounts|AccountsShape $accounts + */ + public function withAccounts(Accounts|array $accounts): self + { + $self = clone $this; + $self['accounts'] = $accounts; + + return $self; + } + + /** + * Total portfolio value across all accounts. + */ + public function withTotalValue(float $totalValue): self + { + $self = clone $this; + $self['totalValue'] = $totalValue; + + return $self; + } +} diff --git a/src/CamsKfintech/UnifiedResponse/Summary/Accounts.php b/src/CamsKfintech/UnifiedResponse/Summary/Accounts.php new file mode 100644 index 0000000..cab3c5d --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Summary/Accounts.php @@ -0,0 +1,119 @@ + */ + use SdkModel; + + #[Optional] + public ?Demat $demat; + + #[Optional] + public ?Insurance $insurance; + + #[Optional('mutual_funds')] + public ?MutualFunds $mutualFunds; + + #[Optional] + public ?Nps $nps; + + 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 Demat|DematShape|null $demat + * @param Insurance|InsuranceShape|null $insurance + * @param MutualFunds|MutualFundsShape|null $mutualFunds + * @param Nps|NpsShape|null $nps + */ + public static function with( + Demat|array|null $demat = null, + Insurance|array|null $insurance = null, + MutualFunds|array|null $mutualFunds = null, + Nps|array|null $nps = null, + ): self { + $self = new self; + + null !== $demat && $self['demat'] = $demat; + null !== $insurance && $self['insurance'] = $insurance; + null !== $mutualFunds && $self['mutualFunds'] = $mutualFunds; + null !== $nps && $self['nps'] = $nps; + + return $self; + } + + /** + * @param Demat|DematShape $demat + */ + public function withDemat(Demat|array $demat): self + { + $self = clone $this; + $self['demat'] = $demat; + + return $self; + } + + /** + * @param Insurance|InsuranceShape $insurance + */ + public function withInsurance(Insurance|array $insurance): self + { + $self = clone $this; + $self['insurance'] = $insurance; + + return $self; + } + + /** + * @param MutualFunds|MutualFundsShape $mutualFunds + */ + public function withMutualFunds(MutualFunds|array $mutualFunds): self + { + $self = clone $this; + $self['mutualFunds'] = $mutualFunds; + + return $self; + } + + /** + * @param Nps|NpsShape $nps + */ + public function withNps(Nps|array $nps): self + { + $self = clone $this; + $self['nps'] = $nps; + + return $self; + } +} diff --git a/src/CasParser/UnifiedResponse/Summary/Accounts/Demat.php b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Demat.php similarity index 60% rename from src/CasParser/UnifiedResponse/Summary/Accounts/Demat.php rename to src/CamsKfintech/UnifiedResponse/Summary/Accounts/Demat.php index 50165c2..d8585b8 100644 --- a/src/CasParser/UnifiedResponse/Summary/Accounts/Demat.php +++ b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Demat.php @@ -2,30 +2,30 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\Summary\Accounts; +namespace CasParser\CamsKfintech\UnifiedResponse\Summary\Accounts; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type demat_alias = array{count?: int, totalValue?: float} + * @phpstan-type DematShape = array{count?: int|null, totalValue?: float|null} */ final class Demat implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Number of demat accounts. */ - #[Api(optional: true)] + #[Optional] public ?int $count; /** * Total value of demat accounts. */ - #[Api('total_value', optional: true)] + #[Optional('total_value')] public ?float $totalValue; public function __construct() @@ -42,12 +42,12 @@ public static function with( ?int $count = null, ?float $totalValue = null ): self { - $obj = new self; + $self = new self; - null !== $count && $obj->count = $count; - null !== $totalValue && $obj->totalValue = $totalValue; + null !== $count && $self['count'] = $count; + null !== $totalValue && $self['totalValue'] = $totalValue; - return $obj; + return $self; } /** @@ -55,10 +55,10 @@ public static function with( */ public function withCount(int $count): self { - $obj = clone $this; - $obj->count = $count; + $self = clone $this; + $self['count'] = $count; - return $obj; + return $self; } /** @@ -66,9 +66,9 @@ public function withCount(int $count): self */ public function withTotalValue(float $totalValue): self { - $obj = clone $this; - $obj->totalValue = $totalValue; + $self = clone $this; + $self['totalValue'] = $totalValue; - return $obj; + return $self; } } diff --git a/src/CasParser/UnifiedResponse/Summary/Accounts/Insurance.php b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Insurance.php similarity index 60% rename from src/CasParser/UnifiedResponse/Summary/Accounts/Insurance.php rename to src/CamsKfintech/UnifiedResponse/Summary/Accounts/Insurance.php index a14d733..c0afd64 100644 --- a/src/CasParser/UnifiedResponse/Summary/Accounts/Insurance.php +++ b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Insurance.php @@ -2,30 +2,30 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\Summary\Accounts; +namespace CasParser\CamsKfintech\UnifiedResponse\Summary\Accounts; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type insurance_alias = array{count?: int, totalValue?: float} + * @phpstan-type InsuranceShape = array{count?: int|null, totalValue?: float|null} */ final class Insurance implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Number of insurance policies. */ - #[Api(optional: true)] + #[Optional] public ?int $count; /** * Total value of insurance policies. */ - #[Api('total_value', optional: true)] + #[Optional('total_value')] public ?float $totalValue; public function __construct() @@ -42,12 +42,12 @@ public static function with( ?int $count = null, ?float $totalValue = null ): self { - $obj = new self; + $self = new self; - null !== $count && $obj->count = $count; - null !== $totalValue && $obj->totalValue = $totalValue; + null !== $count && $self['count'] = $count; + null !== $totalValue && $self['totalValue'] = $totalValue; - return $obj; + return $self; } /** @@ -55,10 +55,10 @@ public static function with( */ public function withCount(int $count): self { - $obj = clone $this; - $obj->count = $count; + $self = clone $this; + $self['count'] = $count; - return $obj; + return $self; } /** @@ -66,9 +66,9 @@ public function withCount(int $count): self */ public function withTotalValue(float $totalValue): self { - $obj = clone $this; - $obj->totalValue = $totalValue; + $self = clone $this; + $self['totalValue'] = $totalValue; - return $obj; + return $self; } } diff --git a/src/CasParser/UnifiedResponse/Summary/Accounts/MutualFunds.php b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/MutualFunds.php similarity index 59% rename from src/CasParser/UnifiedResponse/Summary/Accounts/MutualFunds.php rename to src/CamsKfintech/UnifiedResponse/Summary/Accounts/MutualFunds.php index dc2f0c0..c82e422 100644 --- a/src/CasParser/UnifiedResponse/Summary/Accounts/MutualFunds.php +++ b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/MutualFunds.php @@ -2,30 +2,32 @@ declare(strict_types=1); -namespace CasParser\CasParser\UnifiedResponse\Summary\Accounts; +namespace CasParser\CamsKfintech\UnifiedResponse\Summary\Accounts; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; /** - * @phpstan-type mutual_funds = array{count?: int, totalValue?: float} + * @phpstan-type MutualFundsShape = array{ + * count?: int|null, totalValue?: float|null + * } */ final class MutualFunds implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; /** * Number of mutual fund folios. */ - #[Api(optional: true)] + #[Optional] public ?int $count; /** * Total value of mutual funds. */ - #[Api('total_value', optional: true)] + #[Optional('total_value')] public ?float $totalValue; public function __construct() @@ -42,12 +44,12 @@ public static function with( ?int $count = null, ?float $totalValue = null ): self { - $obj = new self; + $self = new self; - null !== $count && $obj->count = $count; - null !== $totalValue && $obj->totalValue = $totalValue; + null !== $count && $self['count'] = $count; + null !== $totalValue && $self['totalValue'] = $totalValue; - return $obj; + return $self; } /** @@ -55,10 +57,10 @@ public static function with( */ public function withCount(int $count): self { - $obj = clone $this; - $obj->count = $count; + $self = clone $this; + $self['count'] = $count; - return $obj; + return $self; } /** @@ -66,9 +68,9 @@ public function withCount(int $count): self */ public function withTotalValue(float $totalValue): self { - $obj = clone $this; - $obj->totalValue = $totalValue; + $self = clone $this; + $self['totalValue'] = $totalValue; - return $obj; + return $self; } } diff --git a/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Nps.php b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Nps.php new file mode 100644 index 0000000..c61e149 --- /dev/null +++ b/src/CamsKfintech/UnifiedResponse/Summary/Accounts/Nps.php @@ -0,0 +1,74 @@ + */ + use SdkModel; + + /** + * Number of NPS accounts. + */ + #[Optional] + public ?int $count; + + /** + * Total value of NPS accounts. + */ + #[Optional('total_value')] + public ?float $totalValue; + + 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 $count = null, + ?float $totalValue = null + ): self { + $self = new self; + + null !== $count && $self['count'] = $count; + null !== $totalValue && $self['totalValue'] = $totalValue; + + return $self; + } + + /** + * Number of NPS accounts. + */ + public function withCount(int $count): self + { + $self = clone $this; + $self['count'] = $count; + + return $self; + } + + /** + * Total value of NPS accounts. + */ + public function withTotalValue(float $totalValue): self + { + $self = clone $this; + $self['totalValue'] = $totalValue; + + return $self; + } +} diff --git a/src/CasGenerator/CasGeneratorGenerateCasParams.php b/src/CasGenerator/CasGeneratorGenerateCasParams.php deleted file mode 100644 index 3f3de18..0000000 --- a/src/CasGenerator/CasGeneratorGenerateCasParams.php +++ /dev/null @@ -1,203 +0,0 @@ -casGenerator->generateCas(...$params->toArray()); - * ``` - * This endpoint generates CAS (Consolidated Account Statement) documents by submitting a mailback request to the specified CAS authority. - * Currently only supports KFintech, with plans to support CAMS, CDSL, and NSDL in the future. - * - * @method toArray() - * Returns the parameters as an associative array suitable for passing to the client method. - * - * `$client->casGenerator->generateCas(...$params->toArray());` - * - * @see CasParser\CasGenerator->generateCas - * - * @phpstan-type cas_generator_generate_cas_params = array{ - * email: string, - * fromDate: string, - * password: string, - * toDate: string, - * casAuthority?: CasAuthority|value-of, - * panNo?: string, - * } - */ -final class CasGeneratorGenerateCasParams implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - use SdkParams; - - /** - * Email address to receive the CAS document. - */ - #[Api] - public string $email; - - /** - * Start date for the CAS period (format YYYY-MM-DD). - */ - #[Api('from_date')] - public string $fromDate; - - /** - * Password to protect the generated CAS PDF. - */ - #[Api] - public string $password; - - /** - * End date for the CAS period (format YYYY-MM-DD). - */ - #[Api('to_date')] - public string $toDate; - - /** - * CAS authority to generate the document from (currently only kfintech is supported). - * - * @var value-of|null $casAuthority - */ - #[Api('cas_authority', enum: CasAuthority::class, optional: true)] - public ?string $casAuthority; - - /** - * PAN number (optional for some CAS authorities). - */ - #[Api('pan_no', optional: true)] - public ?string $panNo; - - /** - * `new CasGeneratorGenerateCasParams()` is missing required properties by the API. - * - * To enforce required parameters use - * ``` - * CasGeneratorGenerateCasParams::with( - * email: ..., fromDate: ..., password: ..., toDate: ... - * ) - * ``` - * - * Otherwise ensure the following setters are called - * - * ``` - * (new CasGeneratorGenerateCasParams) - * ->withEmail(...) - * ->withFromDate(...) - * ->withPassword(...) - * ->withToDate(...) - * ``` - */ - 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 CasAuthority|value-of $casAuthority - */ - public static function with( - string $email, - string $fromDate, - string $password, - string $toDate, - CasAuthority|string|null $casAuthority = null, - ?string $panNo = null, - ): self { - $obj = new self; - - $obj->email = $email; - $obj->fromDate = $fromDate; - $obj->password = $password; - $obj->toDate = $toDate; - - null !== $casAuthority && $obj->casAuthority = $casAuthority instanceof CasAuthority ? $casAuthority->value : $casAuthority; - null !== $panNo && $obj->panNo = $panNo; - - return $obj; - } - - /** - * Email address to receive the CAS document. - */ - public function withEmail(string $email): self - { - $obj = clone $this; - $obj->email = $email; - - return $obj; - } - - /** - * Start date for the CAS period (format YYYY-MM-DD). - */ - public function withFromDate(string $fromDate): self - { - $obj = clone $this; - $obj->fromDate = $fromDate; - - return $obj; - } - - /** - * Password to protect the generated CAS PDF. - */ - public function withPassword(string $password): self - { - $obj = clone $this; - $obj->password = $password; - - return $obj; - } - - /** - * End date for the CAS period (format YYYY-MM-DD). - */ - public function withToDate(string $toDate): self - { - $obj = clone $this; - $obj->toDate = $toDate; - - return $obj; - } - - /** - * CAS authority to generate the document from (currently only kfintech is supported). - * - * @param CasAuthority|value-of $casAuthority - */ - public function withCasAuthority(CasAuthority|string $casAuthority): self - { - $obj = clone $this; - $obj->casAuthority = $casAuthority instanceof CasAuthority ? $casAuthority->value : $casAuthority; - - return $obj; - } - - /** - * PAN number (optional for some CAS authorities). - */ - public function withPanNo(string $panNo): self - { - $obj = clone $this; - $obj->panNo = $panNo; - - return $obj; - } -} diff --git a/src/CasGenerator/CasGeneratorGenerateCasParams/CasAuthority.php b/src/CasGenerator/CasGeneratorGenerateCasParams/CasAuthority.php deleted file mode 100644 index 8f84c5d..0000000 --- a/src/CasGenerator/CasGeneratorGenerateCasParams/CasAuthority.php +++ /dev/null @@ -1,19 +0,0 @@ - */ - use SdkModel; - - #[Api(optional: true)] - public ?string $msg; - - #[Api(optional: true)] - 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 - { - $obj = new self; - - null !== $msg && $obj->msg = $msg; - null !== $status && $obj->status = $status; - - return $obj; - } - - public function withMsg(string $msg): self - { - $obj = clone $this; - $obj->msg = $msg; - - return $obj; - } - - public function withStatus(string $status): self - { - $obj = clone $this; - $obj->status = $status; - - return $obj; - } -} diff --git a/src/CasParser/CasParserCamsKfintechParams.php b/src/CasParser/CasParserCamsKfintechParams.php deleted file mode 100644 index 8e09e3b..0000000 --- a/src/CasParser/CasParserCamsKfintechParams.php +++ /dev/null @@ -1,113 +0,0 @@ -casParser->camsKfintech(...$params->toArray()); - * ``` - * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF files and returns data in a unified format. - * Use this endpoint when you know the PDF is from CAMS or KFintech. - * - * @method toArray() - * Returns the parameters as an associative array suitable for passing to the client method. - * - * `$client->casParser->camsKfintech(...$params->toArray());` - * - * @see CasParser\CasParser->camsKfintech - * - * @phpstan-type cas_parser_cams_kfintech_params = array{ - * password?: string, pdfFile?: string, pdfURL?: string - * } - */ -final class CasParserCamsKfintechParams implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - use SdkParams; - - /** - * Password for the PDF file (if required). - */ - #[Api(optional: true)] - public ?string $password; - - /** - * Base64 encoded CAS PDF file. - */ - #[Api('pdf_file', optional: true)] - public ?string $pdfFile; - - /** - * URL to the CAS PDF file. - */ - #[Api('pdf_url', optional: true)] - public ?string $pdfURL; - - 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 $password = null, - ?string $pdfFile = null, - ?string $pdfURL = null - ): self { - $obj = new self; - - null !== $password && $obj->password = $password; - null !== $pdfFile && $obj->pdfFile = $pdfFile; - null !== $pdfURL && $obj->pdfURL = $pdfURL; - - return $obj; - } - - /** - * Password for the PDF file (if required). - */ - public function withPassword(string $password): self - { - $obj = clone $this; - $obj->password = $password; - - return $obj; - } - - /** - * Base64 encoded CAS PDF file. - */ - public function withPdfFile(string $pdfFile): self - { - $obj = clone $this; - $obj->pdfFile = $pdfFile; - - return $obj; - } - - /** - * URL to the CAS PDF file. - */ - public function withPdfURL(string $pdfURL): self - { - $obj = clone $this; - $obj->pdfURL = $pdfURL; - - return $obj; - } -} diff --git a/src/CasParser/CasParserCdslParams.php b/src/CasParser/CasParserCdslParams.php deleted file mode 100644 index d48b9b2..0000000 --- a/src/CasParser/CasParserCdslParams.php +++ /dev/null @@ -1,113 +0,0 @@ -casParser->cdsl(...$params->toArray()); - * ``` - * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. - * Use this endpoint when you know the PDF is from CDSL. - * - * @method toArray() - * Returns the parameters as an associative array suitable for passing to the client method. - * - * `$client->casParser->cdsl(...$params->toArray());` - * - * @see CasParser\CasParser->cdsl - * - * @phpstan-type cas_parser_cdsl_params = array{ - * password?: string, pdfFile?: string, pdfURL?: string - * } - */ -final class CasParserCdslParams implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - use SdkParams; - - /** - * Password for the PDF file (if required). - */ - #[Api(optional: true)] - public ?string $password; - - /** - * Base64 encoded CAS PDF file. - */ - #[Api('pdf_file', optional: true)] - public ?string $pdfFile; - - /** - * URL to the CAS PDF file. - */ - #[Api('pdf_url', optional: true)] - public ?string $pdfURL; - - 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 $password = null, - ?string $pdfFile = null, - ?string $pdfURL = null - ): self { - $obj = new self; - - null !== $password && $obj->password = $password; - null !== $pdfFile && $obj->pdfFile = $pdfFile; - null !== $pdfURL && $obj->pdfURL = $pdfURL; - - return $obj; - } - - /** - * Password for the PDF file (if required). - */ - public function withPassword(string $password): self - { - $obj = clone $this; - $obj->password = $password; - - return $obj; - } - - /** - * Base64 encoded CAS PDF file. - */ - public function withPdfFile(string $pdfFile): self - { - $obj = clone $this; - $obj->pdfFile = $pdfFile; - - return $obj; - } - - /** - * URL to the CAS PDF file. - */ - public function withPdfURL(string $pdfURL): self - { - $obj = clone $this; - $obj->pdfURL = $pdfURL; - - return $obj; - } -} diff --git a/src/CasParser/CasParserNsdlParams.php b/src/CasParser/CasParserNsdlParams.php deleted file mode 100644 index 98320b2..0000000 --- a/src/CasParser/CasParserNsdlParams.php +++ /dev/null @@ -1,113 +0,0 @@ -casParser->nsdl(...$params->toArray()); - * ``` - * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. - * Use this endpoint when you know the PDF is from NSDL. - * - * @method toArray() - * Returns the parameters as an associative array suitable for passing to the client method. - * - * `$client->casParser->nsdl(...$params->toArray());` - * - * @see CasParser\CasParser->nsdl - * - * @phpstan-type cas_parser_nsdl_params = array{ - * password?: string, pdfFile?: string, pdfURL?: string - * } - */ -final class CasParserNsdlParams implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - use SdkParams; - - /** - * Password for the PDF file (if required). - */ - #[Api(optional: true)] - public ?string $password; - - /** - * Base64 encoded CAS PDF file. - */ - #[Api('pdf_file', optional: true)] - public ?string $pdfFile; - - /** - * URL to the CAS PDF file. - */ - #[Api('pdf_url', optional: true)] - public ?string $pdfURL; - - 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 $password = null, - ?string $pdfFile = null, - ?string $pdfURL = null - ): self { - $obj = new self; - - null !== $password && $obj->password = $password; - null !== $pdfFile && $obj->pdfFile = $pdfFile; - null !== $pdfURL && $obj->pdfURL = $pdfURL; - - return $obj; - } - - /** - * Password for the PDF file (if required). - */ - public function withPassword(string $password): self - { - $obj = clone $this; - $obj->password = $password; - - return $obj; - } - - /** - * Base64 encoded CAS PDF file. - */ - public function withPdfFile(string $pdfFile): self - { - $obj = clone $this; - $obj->pdfFile = $pdfFile; - - return $obj; - } - - /** - * URL to the CAS PDF file. - */ - public function withPdfURL(string $pdfURL): self - { - $obj = clone $this; - $obj->pdfURL = $pdfURL; - - return $obj; - } -} diff --git a/src/CasParser/CasParserSmartParseParams.php b/src/CasParser/CasParserSmartParseParams.php deleted file mode 100644 index 525ebf1..0000000 --- a/src/CasParser/CasParserSmartParseParams.php +++ /dev/null @@ -1,113 +0,0 @@ -casParser->smartParse(...$params->toArray()); - * ``` - * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or CAMS/KFintech and returns data in a unified format. - * It auto-detects the CAS type and transforms the data into a consistent structure regardless of the source. - * - * @method toArray() - * Returns the parameters as an associative array suitable for passing to the client method. - * - * `$client->casParser->smartParse(...$params->toArray());` - * - * @see CasParser\CasParser->smartParse - * - * @phpstan-type cas_parser_smart_parse_params = array{ - * password?: string, pdfFile?: string, pdfURL?: string - * } - */ -final class CasParserSmartParseParams implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - use SdkParams; - - /** - * Password for the PDF file (if required). - */ - #[Api(optional: true)] - public ?string $password; - - /** - * Base64 encoded CAS PDF file. - */ - #[Api('pdf_file', optional: true)] - public ?string $pdfFile; - - /** - * URL to the CAS PDF file. - */ - #[Api('pdf_url', optional: true)] - public ?string $pdfURL; - - 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 $password = null, - ?string $pdfFile = null, - ?string $pdfURL = null - ): self { - $obj = new self; - - null !== $password && $obj->password = $password; - null !== $pdfFile && $obj->pdfFile = $pdfFile; - null !== $pdfURL && $obj->pdfURL = $pdfURL; - - return $obj; - } - - /** - * Password for the PDF file (if required). - */ - public function withPassword(string $password): self - { - $obj = clone $this; - $obj->password = $password; - - return $obj; - } - - /** - * Base64 encoded CAS PDF file. - */ - public function withPdfFile(string $pdfFile): self - { - $obj = clone $this; - $obj->pdfFile = $pdfFile; - - return $obj; - } - - /** - * URL to the CAS PDF file. - */ - public function withPdfURL(string $pdfURL): self - { - $obj = clone $this; - $obj->pdfURL = $pdfURL; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse.php b/src/CasParser/UnifiedResponse.php deleted file mode 100644 index 0eda57c..0000000 --- a/src/CasParser/UnifiedResponse.php +++ /dev/null @@ -1,142 +0,0 @@ -, - * insurance?: Insurance, - * investor?: Investor, - * meta?: Meta, - * mutualFunds?: list, - * summary?: Summary, - * } - * When used in a response, this type parameter can define a $rawResponse property. - * @template TRawResponse of object = object{} - * - * @mixin TRawResponse - */ -final class UnifiedResponse implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** @var list|null $dematAccounts */ - #[Api('demat_accounts', list: DematAccount::class, optional: true)] - public ?array $dematAccounts; - - #[Api(optional: true)] - public ?Insurance $insurance; - - #[Api(optional: true)] - public ?Investor $investor; - - #[Api(optional: true)] - public ?Meta $meta; - - /** @var list|null $mutualFunds */ - #[Api('mutual_funds', list: MutualFund::class, optional: true)] - public ?array $mutualFunds; - - #[Api(optional: true)] - 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 list $dematAccounts - * @param list $mutualFunds - */ - public static function with( - ?array $dematAccounts = null, - ?Insurance $insurance = null, - ?Investor $investor = null, - ?Meta $meta = null, - ?array $mutualFunds = null, - ?Summary $summary = null, - ): self { - $obj = new self; - - null !== $dematAccounts && $obj->dematAccounts = $dematAccounts; - null !== $insurance && $obj->insurance = $insurance; - null !== $investor && $obj->investor = $investor; - null !== $meta && $obj->meta = $meta; - null !== $mutualFunds && $obj->mutualFunds = $mutualFunds; - null !== $summary && $obj->summary = $summary; - - return $obj; - } - - /** - * @param list $dematAccounts - */ - public function withDematAccounts(array $dematAccounts): self - { - $obj = clone $this; - $obj->dematAccounts = $dematAccounts; - - return $obj; - } - - public function withInsurance(Insurance $insurance): self - { - $obj = clone $this; - $obj->insurance = $insurance; - - return $obj; - } - - public function withInvestor(Investor $investor): self - { - $obj = clone $this; - $obj->investor = $investor; - - return $obj; - } - - public function withMeta(Meta $meta): self - { - $obj = clone $this; - $obj->meta = $meta; - - return $obj; - } - - /** - * @param list $mutualFunds - */ - public function withMutualFunds(array $mutualFunds): self - { - $obj = clone $this; - $obj->mutualFunds = $mutualFunds; - - return $obj; - } - - public function withSummary(Summary $summary): self - { - $obj = clone $this; - $obj->summary = $summary; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount.php b/src/CasParser/UnifiedResponse/DematAccount.php deleted file mode 100644 index 0c57e41..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount.php +++ /dev/null @@ -1,200 +0,0 @@ -, - * dpID?: string, - * dpName?: string, - * holdings?: Holdings, - * value?: float, - * } - */ -final class DematAccount implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Additional information specific to the demat account type. - */ - #[Api('additional_info', optional: true)] - public ?AdditionalInfo $additionalInfo; - - /** - * Beneficiary Owner ID (primarily for CDSL). - */ - #[Api('bo_id', optional: true)] - public ?string $boID; - - /** - * Client ID. - */ - #[Api('client_id', optional: true)] - public ?string $clientID; - - /** - * Type of demat account. - * - * @var value-of|null $dematType - */ - #[Api('demat_type', enum: DematType::class, optional: true)] - public ?string $dematType; - - /** - * Depository Participant ID. - */ - #[Api('dp_id', optional: true)] - public ?string $dpID; - - /** - * Depository Participant name. - */ - #[Api('dp_name', optional: true)] - public ?string $dpName; - - #[Api(optional: true)] - public ?Holdings $holdings; - - /** - * Total value of the demat account. - */ - #[Api(optional: true)] - public ?float $value; - - 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 DematType|value-of $dematType - */ - public static function with( - ?AdditionalInfo $additionalInfo = null, - ?string $boID = null, - ?string $clientID = null, - DematType|string|null $dematType = null, - ?string $dpID = null, - ?string $dpName = null, - ?Holdings $holdings = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $boID && $obj->boID = $boID; - null !== $clientID && $obj->clientID = $clientID; - null !== $dematType && $obj->dematType = $dematType instanceof DematType ? $dematType->value : $dematType; - null !== $dpID && $obj->dpID = $dpID; - null !== $dpName && $obj->dpName = $dpName; - null !== $holdings && $obj->holdings = $holdings; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the demat account type. - */ - public function withAdditionalInfo(AdditionalInfo $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * Beneficiary Owner ID (primarily for CDSL). - */ - public function withBoID(string $boID): self - { - $obj = clone $this; - $obj->boID = $boID; - - return $obj; - } - - /** - * Client ID. - */ - public function withClientID(string $clientID): self - { - $obj = clone $this; - $obj->clientID = $clientID; - - return $obj; - } - - /** - * Type of demat account. - * - * @param DematType|value-of $dematType - */ - public function withDematType(DematType|string $dematType): self - { - $obj = clone $this; - $obj->dematType = $dematType instanceof DematType ? $dematType->value : $dematType; - - return $obj; - } - - /** - * Depository Participant ID. - */ - public function withDpID(string $dpID): self - { - $obj = clone $this; - $obj->dpID = $dpID; - - return $obj; - } - - /** - * Depository Participant name. - */ - public function withDpName(string $dpName): self - { - $obj = clone $this; - $obj->dpName = $dpName; - - return $obj; - } - - public function withHoldings(Holdings $holdings): self - { - $obj = clone $this; - $obj->holdings = $holdings; - - return $obj; - } - - /** - * Total value of the demat account. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings.php deleted file mode 100644 index eb3b0d1..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings.php +++ /dev/null @@ -1,142 +0,0 @@ -, - * corporateBonds?: list, - * dematMutualFunds?: list, - * equities?: list, - * governmentSecurities?: list, - * } - */ -final class Holdings implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** @var list|null $aifs */ - #[Api(list: Aif::class, optional: true)] - public ?array $aifs; - - /** @var list|null $corporateBonds */ - #[Api('corporate_bonds', list: CorporateBond::class, optional: true)] - public ?array $corporateBonds; - - /** @var list|null $dematMutualFunds */ - #[Api('demat_mutual_funds', list: DematMutualFund::class, optional: true)] - public ?array $dematMutualFunds; - - /** @var list|null $equities */ - #[Api(list: Equity::class, optional: true)] - public ?array $equities; - - /** @var list|null $governmentSecurities */ - #[Api( - 'government_securities', - list: GovernmentSecurity::class, - optional: true - )] - public ?array $governmentSecurities; - - 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 $aifs - * @param list $corporateBonds - * @param list $dematMutualFunds - * @param list $equities - * @param list $governmentSecurities - */ - public static function with( - ?array $aifs = null, - ?array $corporateBonds = null, - ?array $dematMutualFunds = null, - ?array $equities = null, - ?array $governmentSecurities = null, - ): self { - $obj = new self; - - null !== $aifs && $obj->aifs = $aifs; - null !== $corporateBonds && $obj->corporateBonds = $corporateBonds; - null !== $dematMutualFunds && $obj->dematMutualFunds = $dematMutualFunds; - null !== $equities && $obj->equities = $equities; - null !== $governmentSecurities && $obj->governmentSecurities = $governmentSecurities; - - return $obj; - } - - /** - * @param list $aifs - */ - public function withAifs(array $aifs): self - { - $obj = clone $this; - $obj->aifs = $aifs; - - return $obj; - } - - /** - * @param list $corporateBonds - */ - public function withCorporateBonds(array $corporateBonds): self - { - $obj = clone $this; - $obj->corporateBonds = $corporateBonds; - - return $obj; - } - - /** - * @param list $dematMutualFunds - */ - public function withDematMutualFunds(array $dematMutualFunds): self - { - $obj = clone $this; - $obj->dematMutualFunds = $dematMutualFunds; - - return $obj; - } - - /** - * @param list $equities - */ - public function withEquities(array $equities): self - { - $obj = clone $this; - $obj->equities = $equities; - - return $obj; - } - - /** - * @param list $governmentSecurities - */ - public function withGovernmentSecurities(array $governmentSecurities): self - { - $obj = clone $this; - $obj->governmentSecurities = $governmentSecurities; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings/Aif.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings/Aif.php deleted file mode 100644 index 1df6013..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings/Aif.php +++ /dev/null @@ -1,137 +0,0 @@ - */ - use SdkModel; - - /** - * Additional information specific to the AIF. - */ - #[Api('additional_info', optional: true)] - public mixed $additionalInfo; - - /** - * ISIN code of the AIF. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Name of the AIF. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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( - mixed $additionalInfo = null, - ?string $isin = null, - ?string $name = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the AIF. - */ - public function withAdditionalInfo(mixed $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * ISIN code of the AIF. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Name of the AIF. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings/CorporateBond.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings/CorporateBond.php deleted file mode 100644 index bfb4d84..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings/CorporateBond.php +++ /dev/null @@ -1,137 +0,0 @@ - */ - use SdkModel; - - /** - * Additional information specific to the corporate bond. - */ - #[Api('additional_info', optional: true)] - public mixed $additionalInfo; - - /** - * ISIN code of the corporate bond. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Name of the corporate bond. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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( - mixed $additionalInfo = null, - ?string $isin = null, - ?string $name = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the corporate bond. - */ - public function withAdditionalInfo(mixed $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * ISIN code of the corporate bond. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Name of the corporate bond. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php deleted file mode 100644 index 36015d7..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings/DematMutualFund.php +++ /dev/null @@ -1,137 +0,0 @@ - */ - use SdkModel; - - /** - * Additional information specific to the mutual fund. - */ - #[Api('additional_info', optional: true)] - public mixed $additionalInfo; - - /** - * ISIN code of the mutual fund. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Name of the mutual fund. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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( - mixed $additionalInfo = null, - ?string $isin = null, - ?string $name = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the mutual fund. - */ - public function withAdditionalInfo(mixed $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * ISIN code of the mutual fund. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Name of the mutual fund. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings/Equity.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings/Equity.php deleted file mode 100644 index 0c1b5c2..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings/Equity.php +++ /dev/null @@ -1,137 +0,0 @@ - */ - use SdkModel; - - /** - * Additional information specific to the equity. - */ - #[Api('additional_info', optional: true)] - public mixed $additionalInfo; - - /** - * ISIN code of the equity. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Name of the equity. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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( - mixed $additionalInfo = null, - ?string $isin = null, - ?string $name = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the equity. - */ - public function withAdditionalInfo(mixed $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * ISIN code of the equity. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Name of the equity. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php b/src/CasParser/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php deleted file mode 100644 index cd4249f..0000000 --- a/src/CasParser/UnifiedResponse/DematAccount/Holdings/GovernmentSecurity.php +++ /dev/null @@ -1,137 +0,0 @@ - */ - use SdkModel; - - /** - * Additional information specific to the government security. - */ - #[Api('additional_info', optional: true)] - public mixed $additionalInfo; - - /** - * ISIN code of the government security. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Name of the government security. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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( - mixed $additionalInfo = null, - ?string $isin = null, - ?string $name = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the government security. - */ - public function withAdditionalInfo(mixed $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * ISIN code of the government security. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Name of the government security. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/Insurance.php b/src/CasParser/UnifiedResponse/Insurance.php deleted file mode 100644 index 2a42859..0000000 --- a/src/CasParser/UnifiedResponse/Insurance.php +++ /dev/null @@ -1,62 +0,0 @@ - - * } - */ -final class Insurance implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** @var list|null $lifeInsurancePolicies */ - #[Api( - 'life_insurance_policies', - list: LifeInsurancePolicy::class, - optional: true - )] - public ?array $lifeInsurancePolicies; - - 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 $lifeInsurancePolicies - */ - public static function with(?array $lifeInsurancePolicies = null): self - { - $obj = new self; - - null !== $lifeInsurancePolicies && $obj->lifeInsurancePolicies = $lifeInsurancePolicies; - - return $obj; - } - - /** - * @param list $lifeInsurancePolicies - */ - public function withLifeInsurancePolicies( - array $lifeInsurancePolicies - ): self { - $obj = clone $this; - $obj->lifeInsurancePolicies = $lifeInsurancePolicies; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/Meta.php b/src/CasParser/UnifiedResponse/Meta.php deleted file mode 100644 index 7f55cb7..0000000 --- a/src/CasParser/UnifiedResponse/Meta.php +++ /dev/null @@ -1,99 +0,0 @@ -, - * generatedAt?: \DateTimeInterface, - * statementPeriod?: StatementPeriod, - * } - */ -final class Meta implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Type of CAS detected and processed. - * - * @var value-of|null $casType - */ - #[Api('cas_type', enum: CasType::class, optional: true)] - public ?string $casType; - - /** - * Timestamp when the response was generated. - */ - #[Api('generated_at', optional: true)] - public ?\DateTimeInterface $generatedAt; - - #[Api('statement_period', optional: true)] - public ?StatementPeriod $statementPeriod; - - 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 CasType|value-of $casType - */ - public static function with( - CasType|string|null $casType = null, - ?\DateTimeInterface $generatedAt = null, - ?StatementPeriod $statementPeriod = null, - ): self { - $obj = new self; - - null !== $casType && $obj->casType = $casType instanceof CasType ? $casType->value : $casType; - null !== $generatedAt && $obj->generatedAt = $generatedAt; - null !== $statementPeriod && $obj->statementPeriod = $statementPeriod; - - return $obj; - } - - /** - * Type of CAS detected and processed. - * - * @param CasType|value-of $casType - */ - public function withCasType(CasType|string $casType): self - { - $obj = clone $this; - $obj->casType = $casType instanceof CasType ? $casType->value : $casType; - - return $obj; - } - - /** - * Timestamp when the response was generated. - */ - public function withGeneratedAt(\DateTimeInterface $generatedAt): self - { - $obj = clone $this; - $obj->generatedAt = $generatedAt; - - return $obj; - } - - public function withStatementPeriod(StatementPeriod $statementPeriod): self - { - $obj = clone $this; - $obj->statementPeriod = $statementPeriod; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/Meta/StatementPeriod.php b/src/CasParser/UnifiedResponse/Meta/StatementPeriod.php deleted file mode 100644 index ebeb0f2..0000000 --- a/src/CasParser/UnifiedResponse/Meta/StatementPeriod.php +++ /dev/null @@ -1,76 +0,0 @@ - */ - use SdkModel; - - /** - * Start date of the statement period. - */ - #[Api(optional: true)] - public ?\DateTimeInterface $from; - - /** - * End date of the statement period. - */ - #[Api(optional: true)] - public ?\DateTimeInterface $to; - - 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 $from = null, - ?\DateTimeInterface $to = null - ): self { - $obj = new self; - - null !== $from && $obj->from = $from; - null !== $to && $obj->to = $to; - - return $obj; - } - - /** - * Start date of the statement period. - */ - public function withFrom(\DateTimeInterface $from): self - { - $obj = clone $this; - $obj->from = $from; - - return $obj; - } - - /** - * End date of the statement period. - */ - public function withTo(\DateTimeInterface $to): self - { - $obj = clone $this; - $obj->to = $to; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/MutualFund.php b/src/CasParser/UnifiedResponse/MutualFund.php deleted file mode 100644 index 2f1da0c..0000000 --- a/src/CasParser/UnifiedResponse/MutualFund.php +++ /dev/null @@ -1,159 +0,0 @@ -, - * value?: float, - * } - */ -final class MutualFund implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Additional folio information. - */ - #[Api('additional_info', optional: true)] - public ?AdditionalInfo $additionalInfo; - - /** - * Asset Management Company name. - */ - #[Api(optional: true)] - public ?string $amc; - - /** - * Folio number. - */ - #[Api('folio_number', optional: true)] - public ?string $folioNumber; - - /** - * Registrar and Transfer Agent name. - */ - #[Api(optional: true)] - public ?string $registrar; - - /** @var list|null $schemes */ - #[Api(list: Scheme::class, optional: true)] - public ?array $schemes; - - /** - * Total value of the folio. - */ - #[Api(optional: true)] - public ?float $value; - - 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 $schemes - */ - public static function with( - ?AdditionalInfo $additionalInfo = null, - ?string $amc = null, - ?string $folioNumber = null, - ?string $registrar = null, - ?array $schemes = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $amc && $obj->amc = $amc; - null !== $folioNumber && $obj->folioNumber = $folioNumber; - null !== $registrar && $obj->registrar = $registrar; - null !== $schemes && $obj->schemes = $schemes; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional folio information. - */ - public function withAdditionalInfo(AdditionalInfo $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * Asset Management Company name. - */ - public function withAmc(string $amc): self - { - $obj = clone $this; - $obj->amc = $amc; - - return $obj; - } - - /** - * Folio number. - */ - public function withFolioNumber(string $folioNumber): self - { - $obj = clone $this; - $obj->folioNumber = $folioNumber; - - return $obj; - } - - /** - * Registrar and Transfer Agent name. - */ - public function withRegistrar(string $registrar): self - { - $obj = clone $this; - $obj->registrar = $registrar; - - return $obj; - } - - /** - * @param list $schemes - */ - public function withSchemes(array $schemes): self - { - $obj = clone $this; - $obj->schemes = $schemes; - - return $obj; - } - - /** - * Total value of the folio. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/MutualFund/Scheme.php b/src/CasParser/UnifiedResponse/MutualFund/Scheme.php deleted file mode 100644 index 8775dbb..0000000 --- a/src/CasParser/UnifiedResponse/MutualFund/Scheme.php +++ /dev/null @@ -1,265 +0,0 @@ -, - * transactions?: list, - * type?: value-of, - * units?: float, - * value?: float, - * } - */ -final class Scheme implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Additional information specific to the scheme. - */ - #[Api('additional_info', optional: true)] - public ?AdditionalInfo $additionalInfo; - - /** - * Cost of investment. - */ - #[Api(optional: true)] - public ?float $cost; - - #[Api(optional: true)] - public ?Gain $gain; - - /** - * ISIN code of the scheme. - */ - #[Api(optional: true)] - public ?string $isin; - - /** - * Scheme name. - */ - #[Api(optional: true)] - public ?string $name; - - /** - * Net Asset Value per unit. - */ - #[Api(optional: true)] - public ?float $nav; - - /** - * List of nominees. - * - * @var list|null $nominees - */ - #[Api(list: 'string', optional: true)] - public ?array $nominees; - - /** @var list|null $transactions */ - #[Api(list: Transaction::class, optional: true)] - public ?array $transactions; - - /** - * Type of mutual fund scheme. - * - * @var value-of|null $type - */ - #[Api(enum: Type::class, optional: true)] - public ?string $type; - - /** - * Number of units held. - */ - #[Api(optional: true)] - public ?float $units; - - /** - * Current market value of the holding. - */ - #[Api(optional: true)] - public ?float $value; - - 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 $nominees - * @param list $transactions - * @param Type|value-of $type - */ - public static function with( - ?AdditionalInfo $additionalInfo = null, - ?float $cost = null, - ?Gain $gain = null, - ?string $isin = null, - ?string $name = null, - ?float $nav = null, - ?array $nominees = null, - ?array $transactions = null, - Type|string|null $type = null, - ?float $units = null, - ?float $value = null, - ): self { - $obj = new self; - - null !== $additionalInfo && $obj->additionalInfo = $additionalInfo; - null !== $cost && $obj->cost = $cost; - null !== $gain && $obj->gain = $gain; - null !== $isin && $obj->isin = $isin; - null !== $name && $obj->name = $name; - null !== $nav && $obj->nav = $nav; - null !== $nominees && $obj->nominees = $nominees; - null !== $transactions && $obj->transactions = $transactions; - null !== $type && $obj->type = $type instanceof Type ? $type->value : $type; - null !== $units && $obj->units = $units; - null !== $value && $obj->value = $value; - - return $obj; - } - - /** - * Additional information specific to the scheme. - */ - public function withAdditionalInfo(AdditionalInfo $additionalInfo): self - { - $obj = clone $this; - $obj->additionalInfo = $additionalInfo; - - return $obj; - } - - /** - * Cost of investment. - */ - public function withCost(float $cost): self - { - $obj = clone $this; - $obj->cost = $cost; - - return $obj; - } - - public function withGain(Gain $gain): self - { - $obj = clone $this; - $obj->gain = $gain; - - return $obj; - } - - /** - * ISIN code of the scheme. - */ - public function withIsin(string $isin): self - { - $obj = clone $this; - $obj->isin = $isin; - - return $obj; - } - - /** - * Scheme name. - */ - public function withName(string $name): self - { - $obj = clone $this; - $obj->name = $name; - - return $obj; - } - - /** - * Net Asset Value per unit. - */ - public function withNav(float $nav): self - { - $obj = clone $this; - $obj->nav = $nav; - - return $obj; - } - - /** - * List of nominees. - * - * @param list $nominees - */ - public function withNominees(array $nominees): self - { - $obj = clone $this; - $obj->nominees = $nominees; - - return $obj; - } - - /** - * @param list $transactions - */ - public function withTransactions(array $transactions): self - { - $obj = clone $this; - $obj->transactions = $transactions; - - return $obj; - } - - /** - * Type of mutual fund scheme. - * - * @param Type|value-of $type - */ - public function withType(Type|string $type): self - { - $obj = clone $this; - $obj->type = $type instanceof Type ? $type->value : $type; - - return $obj; - } - - /** - * Number of units held. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } - - /** - * Current market value of the holding. - */ - public function withValue(float $value): self - { - $obj = clone $this; - $obj->value = $value; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php b/src/CasParser/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php deleted file mode 100644 index e5f16cd..0000000 --- a/src/CasParser/UnifiedResponse/MutualFund/Scheme/AdditionalInfo.php +++ /dev/null @@ -1,139 +0,0 @@ - */ - use SdkModel; - - /** - * Financial advisor name (CAMS/KFintech). - */ - #[Api(optional: true)] - public ?string $advisor; - - /** - * AMFI code for the scheme (CAMS/KFintech). - */ - #[Api(optional: true)] - public ?string $amfi; - - /** - * Closing balance units (CAMS/KFintech). - */ - #[Api('close_units', optional: true)] - public ?float $closeUnits; - - /** - * Opening balance units (CAMS/KFintech). - */ - #[Api('open_units', optional: true)] - public ?float $openUnits; - - /** - * RTA code for the scheme (CAMS/KFintech). - */ - #[Api('rta_code', optional: true)] - public ?string $rtaCode; - - 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 $advisor = null, - ?string $amfi = null, - ?float $closeUnits = null, - ?float $openUnits = null, - ?string $rtaCode = null, - ): self { - $obj = new self; - - null !== $advisor && $obj->advisor = $advisor; - null !== $amfi && $obj->amfi = $amfi; - null !== $closeUnits && $obj->closeUnits = $closeUnits; - null !== $openUnits && $obj->openUnits = $openUnits; - null !== $rtaCode && $obj->rtaCode = $rtaCode; - - return $obj; - } - - /** - * Financial advisor name (CAMS/KFintech). - */ - public function withAdvisor(string $advisor): self - { - $obj = clone $this; - $obj->advisor = $advisor; - - return $obj; - } - - /** - * AMFI code for the scheme (CAMS/KFintech). - */ - public function withAmfi(string $amfi): self - { - $obj = clone $this; - $obj->amfi = $amfi; - - return $obj; - } - - /** - * Closing balance units (CAMS/KFintech). - */ - public function withCloseUnits(float $closeUnits): self - { - $obj = clone $this; - $obj->closeUnits = $closeUnits; - - return $obj; - } - - /** - * Opening balance units (CAMS/KFintech). - */ - public function withOpenUnits(float $openUnits): self - { - $obj = clone $this; - $obj->openUnits = $openUnits; - - return $obj; - } - - /** - * RTA code for the scheme (CAMS/KFintech). - */ - public function withRtaCode(string $rtaCode): self - { - $obj = clone $this; - $obj->rtaCode = $rtaCode; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Transaction.php b/src/CasParser/UnifiedResponse/MutualFund/Scheme/Transaction.php deleted file mode 100644 index 0ea64d4..0000000 --- a/src/CasParser/UnifiedResponse/MutualFund/Scheme/Transaction.php +++ /dev/null @@ -1,197 +0,0 @@ - */ - use SdkModel; - - /** - * Transaction amount. - */ - #[Api(optional: true)] - public ?float $amount; - - /** - * Balance units after transaction. - */ - #[Api(optional: true)] - public ?float $balance; - - /** - * Transaction date. - */ - #[Api(optional: true)] - public ?\DateTimeInterface $date; - - /** - * Transaction description. - */ - #[Api(optional: true)] - public ?string $description; - - /** - * Dividend rate (for dividend transactions). - */ - #[Api('dividend_rate', optional: true)] - public ?float $dividendRate; - - /** - * NAV on transaction date. - */ - #[Api(optional: true)] - public ?float $nav; - - /** - * Transaction type detected based on description. Possible values are PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. If dividend_rate is present, then possible values are dividend_rate is applicable only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. - */ - #[Api(optional: true)] - public ?string $type; - - /** - * Number of units involved. - */ - #[Api(optional: true)] - public ?float $units; - - 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 $amount = null, - ?float $balance = null, - ?\DateTimeInterface $date = null, - ?string $description = null, - ?float $dividendRate = null, - ?float $nav = null, - ?string $type = null, - ?float $units = null, - ): self { - $obj = new self; - - null !== $amount && $obj->amount = $amount; - null !== $balance && $obj->balance = $balance; - null !== $date && $obj->date = $date; - null !== $description && $obj->description = $description; - null !== $dividendRate && $obj->dividendRate = $dividendRate; - null !== $nav && $obj->nav = $nav; - null !== $type && $obj->type = $type; - null !== $units && $obj->units = $units; - - return $obj; - } - - /** - * Transaction amount. - */ - public function withAmount(float $amount): self - { - $obj = clone $this; - $obj->amount = $amount; - - return $obj; - } - - /** - * Balance units after transaction. - */ - public function withBalance(float $balance): self - { - $obj = clone $this; - $obj->balance = $balance; - - return $obj; - } - - /** - * Transaction date. - */ - public function withDate(\DateTimeInterface $date): self - { - $obj = clone $this; - $obj->date = $date; - - return $obj; - } - - /** - * Transaction description. - */ - public function withDescription(string $description): self - { - $obj = clone $this; - $obj->description = $description; - - return $obj; - } - - /** - * Dividend rate (for dividend transactions). - */ - public function withDividendRate(float $dividendRate): self - { - $obj = clone $this; - $obj->dividendRate = $dividendRate; - - return $obj; - } - - /** - * NAV on transaction date. - */ - public function withNav(float $nav): self - { - $obj = clone $this; - $obj->nav = $nav; - - return $obj; - } - - /** - * Transaction type detected based on description. Possible values are PURCHASE,PURCHASE_SIP,REDEMPTION,SWITCH_IN,SWITCH_IN_MERGER,SWITCH_OUT,SWITCH_OUT_MERGER,DIVIDEND_PAYOUT,DIVIDEND_REINVESTMENT,SEGREGATION,STAMP_DUTY_TAX,TDS_TAX,STT_TAX,MISC. If dividend_rate is present, then possible values are dividend_rate is applicable only for DIVIDEND_PAYOUT and DIVIDEND_REINVESTMENT. - */ - public function withType(string $type): self - { - $obj = clone $this; - $obj->type = $type; - - return $obj; - } - - /** - * Number of units involved. - */ - public function withUnits(float $units): self - { - $obj = clone $this; - $obj->units = $units; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/Summary.php b/src/CasParser/UnifiedResponse/Summary.php deleted file mode 100644 index 6b32295..0000000 --- a/src/CasParser/UnifiedResponse/Summary.php +++ /dev/null @@ -1,69 +0,0 @@ - */ - use SdkModel; - - #[Api(optional: true)] - public ?Accounts $accounts; - - /** - * Total portfolio value across all accounts. - */ - #[Api('total_value', optional: true)] - public ?float $totalValue; - - 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( - ?Accounts $accounts = null, - ?float $totalValue = null - ): self { - $obj = new self; - - null !== $accounts && $obj->accounts = $accounts; - null !== $totalValue && $obj->totalValue = $totalValue; - - return $obj; - } - - public function withAccounts(Accounts $accounts): self - { - $obj = clone $this; - $obj->accounts = $accounts; - - return $obj; - } - - /** - * Total portfolio value across all accounts. - */ - public function withTotalValue(float $totalValue): self - { - $obj = clone $this; - $obj->totalValue = $totalValue; - - return $obj; - } -} diff --git a/src/CasParser/UnifiedResponse/Summary/Accounts.php b/src/CasParser/UnifiedResponse/Summary/Accounts.php deleted file mode 100644 index 82b1f21..0000000 --- a/src/CasParser/UnifiedResponse/Summary/Accounts.php +++ /dev/null @@ -1,80 +0,0 @@ - */ - use SdkModel; - - #[Api(optional: true)] - public ?Demat $demat; - - #[Api(optional: true)] - public ?Insurance $insurance; - - #[Api('mutual_funds', optional: true)] - public ?MutualFunds $mutualFunds; - - 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( - ?Demat $demat = null, - ?Insurance $insurance = null, - ?MutualFunds $mutualFunds = null, - ): self { - $obj = new self; - - null !== $demat && $obj->demat = $demat; - null !== $insurance && $obj->insurance = $insurance; - null !== $mutualFunds && $obj->mutualFunds = $mutualFunds; - - return $obj; - } - - public function withDemat(Demat $demat): self - { - $obj = clone $this; - $obj->demat = $demat; - - return $obj; - } - - public function withInsurance(Insurance $insurance): self - { - $obj = clone $this; - $obj->insurance = $insurance; - - return $obj; - } - - public function withMutualFunds(MutualFunds $mutualFunds): self - { - $obj = clone $this; - $obj->mutualFunds = $mutualFunds; - - return $obj; - } -} diff --git a/src/Cdsl/CdslParsePdfParams.php b/src/Cdsl/CdslParsePdfParams.php new file mode 100644 index 0000000..7b65fe9 --- /dev/null +++ b/src/Cdsl/CdslParsePdfParams.php @@ -0,0 +1,102 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Password for the PDF file (if required). + */ + #[Optional] + public ?string $password; + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + #[Optional('pdf_file')] + public ?string $pdfFile; + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + #[Optional('pdf_url')] + public ?string $pdfURL; + + 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 $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null + ): self { + $self = new self; + + null !== $password && $self['password'] = $password; + null !== $pdfFile && $self['pdfFile'] = $pdfFile; + null !== $pdfURL && $self['pdfURL'] = $pdfURL; + + return $self; + } + + /** + * Password for the PDF file (if required). + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + public function withPdfFile(string $pdfFile): self + { + $self = clone $this; + $self['pdfFile'] = $pdfFile; + + return $self; + } + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + public function withPdfURL(string $pdfURL): self + { + $self = clone $this; + $self['pdfURL'] = $pdfURL; + + return $self; + } +} diff --git a/src/Cdsl/Fetch/FetchRequestOtpParams.php b/src/Cdsl/Fetch/FetchRequestOtpParams.php new file mode 100644 index 0000000..15c896f --- /dev/null +++ b/src/Cdsl/Fetch/FetchRequestOtpParams.php @@ -0,0 +1,119 @@ + */ + use SdkModel; + use SdkParams; + + /** + * CDSL BO ID (16 digits). + */ + #[Required('bo_id')] + public string $boID; + + /** + * Date of birth (YYYY-MM-DD). + */ + #[Required] + public string $dob; + + /** + * PAN number. + */ + #[Required] + public string $pan; + + /** + * `new FetchRequestOtpParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * FetchRequestOtpParams::with(boID: ..., dob: ..., pan: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new FetchRequestOtpParams)->withBoID(...)->withDob(...)->withPan(...) + * ``` + */ + 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 $boID, string $dob, string $pan): self + { + $self = new self; + + $self['boID'] = $boID; + $self['dob'] = $dob; + $self['pan'] = $pan; + + return $self; + } + + /** + * CDSL BO ID (16 digits). + */ + public function withBoID(string $boID): self + { + $self = clone $this; + $self['boID'] = $boID; + + return $self; + } + + /** + * Date of birth (YYYY-MM-DD). + */ + public function withDob(string $dob): self + { + $self = clone $this; + $self['dob'] = $dob; + + return $self; + } + + /** + * PAN number. + */ + public function withPan(string $pan): self + { + $self = clone $this; + $self['pan'] = $pan; + + return $self; + } +} diff --git a/src/Cdsl/Fetch/FetchRequestOtpResponse.php b/src/Cdsl/Fetch/FetchRequestOtpResponse.php new file mode 100644 index 0000000..9c01013 --- /dev/null +++ b/src/Cdsl/Fetch/FetchRequestOtpResponse.php @@ -0,0 +1,83 @@ + */ + use SdkModel; + + #[Optional] + public ?string $msg; + + /** + * Session ID for verify step. + */ + #[Optional('session_id')] + public ?string $sessionID; + + #[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 $sessionID = null, + ?string $status = null + ): self { + $self = new self; + + null !== $msg && $self['msg'] = $msg; + null !== $sessionID && $self['sessionID'] = $sessionID; + null !== $status && $self['status'] = $status; + + return $self; + } + + public function withMsg(string $msg): self + { + $self = clone $this; + $self['msg'] = $msg; + + return $self; + } + + /** + * Session ID for verify step. + */ + public function withSessionID(string $sessionID): self + { + $self = clone $this; + $self['sessionID'] = $sessionID; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/Cdsl/Fetch/FetchVerifyOtpParams.php b/src/Cdsl/Fetch/FetchVerifyOtpParams.php new file mode 100644 index 0000000..742b759 --- /dev/null +++ b/src/Cdsl/Fetch/FetchVerifyOtpParams.php @@ -0,0 +1,99 @@ + */ + use SdkModel; + use SdkParams; + + /** + * OTP received on mobile. + */ + #[Required] + public string $otp; + + /** + * Number of monthly statements to fetch (default 6). + */ + #[Optional('num_periods')] + public ?int $numPeriods; + + /** + * `new FetchVerifyOtpParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * FetchVerifyOtpParams::with(otp: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new FetchVerifyOtpParams)->withOtp(...) + * ``` + */ + 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 $otp, ?int $numPeriods = null): self + { + $self = new self; + + $self['otp'] = $otp; + + null !== $numPeriods && $self['numPeriods'] = $numPeriods; + + return $self; + } + + /** + * OTP received on mobile. + */ + public function withOtp(string $otp): self + { + $self = clone $this; + $self['otp'] = $otp; + + return $self; + } + + /** + * Number of monthly statements to fetch (default 6). + */ + public function withNumPeriods(int $numPeriods): self + { + $self = clone $this; + $self['numPeriods'] = $numPeriods; + + return $self; + } +} diff --git a/src/Cdsl/Fetch/FetchVerifyOtpResponse.php b/src/Cdsl/Fetch/FetchVerifyOtpResponse.php new file mode 100644 index 0000000..d09cde2 --- /dev/null +++ b/src/Cdsl/Fetch/FetchVerifyOtpResponse.php @@ -0,0 +1,86 @@ +|null, msg?: string|null, status?: string|null + * } + */ +final class FetchVerifyOtpResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** @var list|null $files */ + #[Optional(list: File::class)] + public ?array $files; + + #[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. + * + * @param list|null $files + */ + public static function with( + ?array $files = null, + ?string $msg = null, + ?string $status = null + ): self { + $self = new self; + + null !== $files && $self['files'] = $files; + null !== $msg && $self['msg'] = $msg; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * @param list $files + */ + public function withFiles(array $files): self + { + $self = clone $this; + $self['files'] = $files; + + 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/Cdsl/Fetch/FetchVerifyOtpResponse/File.php b/src/Cdsl/Fetch/FetchVerifyOtpResponse/File.php new file mode 100644 index 0000000..7d04a00 --- /dev/null +++ b/src/Cdsl/Fetch/FetchVerifyOtpResponse/File.php @@ -0,0 +1,68 @@ + */ + use SdkModel; + + #[Optional] + public ?string $filename; + + /** + * Direct download URL (cloud storage). + */ + #[Optional] + public ?string $url; + + 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 $filename = null, + ?string $url = null + ): self { + $self = new self; + + null !== $filename && $self['filename'] = $filename; + null !== $url && $self['url'] = $url; + + return $self; + } + + public function withFilename(string $filename): self + { + $self = clone $this; + $self['filename'] = $filename; + + return $self; + } + + /** + * Direct download URL (cloud storage). + */ + public function withURL(string $url): self + { + $self = clone $this; + $self['url'] = $url; + + return $self; + } +} diff --git a/src/Client.php b/src/Client.php index 947f3cc..d9c6aff 100644 --- a/src/Client.php +++ b/src/Client.php @@ -5,11 +5,25 @@ namespace CasParser; use CasParser\Core\BaseClient; -use CasParser\Services\CasGeneratorService; -use CasParser\Services\CasParserService; +use CasParser\Core\Util; +use CasParser\Services\AccessTokenService; +use CasParser\Services\CamsKfintechService; +use CasParser\Services\CdslService; +use CasParser\Services\ContractNoteService; +use CasParser\Services\CreditsService; +use CasParser\Services\InboxService; +use CasParser\Services\KfintechService; +use CasParser\Services\LogsService; +use CasParser\Services\NsdlService; +use CasParser\Services\SmartService; +use CasParser\Services\VerifyTokenService; use Http\Discovery\Psr17FactoryDiscovery; use Http\Discovery\Psr18ClientDiscovery; +/** + * @phpstan-import-type NormalizedRequest from \CasParser\Core\BaseClient + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ class Client extends BaseClient { public string $apiKey; @@ -17,43 +31,142 @@ class Client extends BaseClient /** * @api */ - public CasParserService $casParser; + public CreditsService $credits; /** * @api */ - public CasGeneratorService $casGenerator; + public LogsService $logs; - public function __construct(?string $apiKey = null, ?string $baseUrl = null) - { - $this->apiKey = (string) ($apiKey ?? getenv('CAS_PARSER_API_KEY')); + /** + * @api + */ + public AccessTokenService $accessToken; + + /** + * @api + */ + public VerifyTokenService $verifyToken; + + /** + * @api + */ + public CamsKfintechService $camsKfintech; + + /** + * @api + */ + public CdslService $cdsl; + + /** + * @api + */ + public ContractNoteService $contractNote; + + /** + * @api + */ + public InboxService $inbox; + + /** + * @api + */ + public KfintechService $kfintech; + + /** + * @api + */ + public NsdlService $nsdl; + + /** + * @api + */ + public SmartService $smart; + + /** + * @param RequestOpts|null $requestOptions + */ + public function __construct( + ?string $apiKey = null, + ?string $baseUrl = null, + RequestOptions|array|null $requestOptions = null, + ) { + $this->apiKey = (string) ($apiKey ?? Util::getenv('CAS_PARSER_API_KEY')); - $base = $baseUrl ?? getenv( + $baseUrl ??= Util::getenv( 'CAS_PARSER_BASE_URL' ) ?: 'https://portfolio-parser.api.casparser.in'; - $options = RequestOptions::with( - uriFactory: Psr17FactoryDiscovery::findUriFactory(), - streamFactory: Psr17FactoryDiscovery::findStreamFactory(), - requestFactory: Psr17FactoryDiscovery::findRequestFactory(), - transporter: Psr18ClientDiscovery::find(), + $options = RequestOptions::parse( + RequestOptions::with( + uriFactory: Psr17FactoryDiscovery::findUriFactory(), + streamFactory: Psr17FactoryDiscovery::findStreamFactory(), + requestFactory: Psr17FactoryDiscovery::findRequestFactory(), + transporter: Psr18ClientDiscovery::find(), + ), + $requestOptions, ); parent::__construct( headers: [ - 'Content-Type' => 'application/json', 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'User-Agent' => sprintf('cas-parser/PHP %s', VERSION), + 'X-Stainless-Lang' => 'php', + 'X-Stainless-Package-Version' => '0.0.1', + 'X-Stainless-Arch' => Util::machtype(), + 'X-Stainless-OS' => Util::ostype(), + 'X-Stainless-Runtime' => php_sapi_name(), + 'X-Stainless-Runtime-Version' => phpversion(), ], - baseUrl: $base, - options: $options, + baseUrl: $baseUrl, + options: $options ); - $this->casParser = new CasParserService($this); - $this->casGenerator = new CasGeneratorService($this); + $this->credits = new CreditsService($this); + $this->logs = new LogsService($this); + $this->accessToken = new AccessTokenService($this); + $this->verifyToken = new VerifyTokenService($this); + $this->camsKfintech = new CamsKfintechService($this); + $this->cdsl = new CdslService($this); + $this->contractNote = new ContractNoteService($this); + $this->inbox = new InboxService($this); + $this->kfintech = new KfintechService($this); + $this->nsdl = new NsdlService($this); + $this->smart = new SmartService($this); } - /** @return array */ + /** @return array */ protected function authHeaders(): array { - return ['x-api-key' => $this->apiKey]; + return $this->apiKey ? ['x-api-key' => $this->apiKey] : []; + } + + /** + * @internal + * + * @param string|list $path + * @param array $query + * @param array|null> $headers + * @param RequestOpts|null $opts + * + * @return array{NormalizedRequest, RequestOptions} + */ + protected function buildRequest( + string $method, + string|array $path, + array $query, + array $headers, + mixed $body, + RequestOptions|array|null $opts, + ): array { + return parent::buildRequest( + method: $method, + path: $path, + query: $query, + headers: [...$this->authHeaders(), ...$headers], + body: $body, + opts: $opts, + ); } } diff --git a/src/ContractNote/ContractNoteParseParams.php b/src/ContractNote/ContractNoteParseParams.php new file mode 100644 index 0000000..f2cda45 --- /dev/null +++ b/src/ContractNote/ContractNoteParseParams.php @@ -0,0 +1,152 @@ +, + * password?: string|null, + * pdfFile?: string|null, + * pdfURL?: string|null, + * } + */ +final class ContractNoteParseParams implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + use SdkParams; + + /** + * Optional broker type override. If not provided, system will auto-detect. + * + * @var value-of|null $brokerType + */ + #[Optional('broker_type', enum: BrokerType::class)] + public ?string $brokerType; + + /** + * Password for the PDF file (usually PAN number for Zerodha). + */ + #[Optional] + public ?string $password; + + /** + * Base64 encoded contract note PDF file. + */ + #[Optional('pdf_file')] + public ?string $pdfFile; + + /** + * URL to the contract note PDF file. + */ + #[Optional('pdf_url')] + public ?string $pdfURL; + + 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 BrokerType|value-of|null $brokerType + */ + public static function with( + BrokerType|string|null $brokerType = null, + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + ): self { + $self = new self; + + null !== $brokerType && $self['brokerType'] = $brokerType; + null !== $password && $self['password'] = $password; + null !== $pdfFile && $self['pdfFile'] = $pdfFile; + null !== $pdfURL && $self['pdfURL'] = $pdfURL; + + return $self; + } + + /** + * Optional broker type override. If not provided, system will auto-detect. + * + * @param BrokerType|value-of $brokerType + */ + public function withBrokerType(BrokerType|string $brokerType): self + { + $self = clone $this; + $self['brokerType'] = $brokerType; + + return $self; + } + + /** + * Password for the PDF file (usually PAN number for Zerodha). + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * Base64 encoded contract note PDF file. + */ + public function withPdfFile(string $pdfFile): self + { + $self = clone $this; + $self['pdfFile'] = $pdfFile; + + return $self; + } + + /** + * URL to the contract note PDF file. + */ + public function withPdfURL(string $pdfURL): self + { + $self = clone $this; + $self['pdfURL'] = $pdfURL; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseParams/BrokerType.php b/src/ContractNote/ContractNoteParseParams/BrokerType.php new file mode 100644 index 0000000..956d521 --- /dev/null +++ b/src/ContractNote/ContractNoteParseParams/BrokerType.php @@ -0,0 +1,19 @@ + */ + use SdkModel; + + #[Optional] + public ?Data $data; + + #[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. + * + * @param Data|DataShape|null $data + */ + public static function with( + Data|array|null $data = null, + ?string $msg = null, + ?string $status = null + ): self { + $self = new self; + + null !== $data && $self['data'] = $data; + null !== $msg && $self['msg'] = $msg; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * @param Data|DataShape $data + */ + public function withData(Data|array $data): self + { + $self = clone $this; + $self['data'] = $data; + + 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/ContractNote/ContractNoteParseResponse/Data.php b/src/ContractNote/ContractNoteParseResponse/Data.php new file mode 100644 index 0000000..e9f1c4f --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data.php @@ -0,0 +1,208 @@ +|null, + * detailedTrades?: list|null, + * equityTransactions?: list|null, + * } + */ +final class Data implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + #[Optional('broker_info')] + public ?BrokerInfo $brokerInfo; + + /** + * Breakdown of various charges and fees. + */ + #[Optional('charges_summary')] + public ?ChargesSummary $chargesSummary; + + #[Optional('client_info')] + public ?ClientInfo $clientInfo; + + #[Optional('contract_note_info')] + public ?ContractNoteInfo $contractNoteInfo; + + /** + * Summary of derivatives transactions. + * + * @var list|null $derivativesTransactions + */ + #[Optional('derivatives_transactions', list: DerivativesTransaction::class)] + public ?array $derivativesTransactions; + + /** + * Detailed breakdown of all individual trades. + * + * @var list|null $detailedTrades + */ + #[Optional('detailed_trades', list: DetailedTrade::class)] + public ?array $detailedTrades; + + /** + * Summary of equity transactions grouped by security. + * + * @var list|null $equityTransactions + */ + #[Optional('equity_transactions', list: EquityTransaction::class)] + public ?array $equityTransactions; + + 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 BrokerInfo|BrokerInfoShape|null $brokerInfo + * @param ChargesSummary|ChargesSummaryShape|null $chargesSummary + * @param ClientInfo|ClientInfoShape|null $clientInfo + * @param ContractNoteInfo|ContractNoteInfoShape|null $contractNoteInfo + * @param list|null $derivativesTransactions + * @param list|null $detailedTrades + * @param list|null $equityTransactions + */ + public static function with( + BrokerInfo|array|null $brokerInfo = null, + ChargesSummary|array|null $chargesSummary = null, + ClientInfo|array|null $clientInfo = null, + ContractNoteInfo|array|null $contractNoteInfo = null, + ?array $derivativesTransactions = null, + ?array $detailedTrades = null, + ?array $equityTransactions = null, + ): self { + $self = new self; + + null !== $brokerInfo && $self['brokerInfo'] = $brokerInfo; + null !== $chargesSummary && $self['chargesSummary'] = $chargesSummary; + null !== $clientInfo && $self['clientInfo'] = $clientInfo; + null !== $contractNoteInfo && $self['contractNoteInfo'] = $contractNoteInfo; + null !== $derivativesTransactions && $self['derivativesTransactions'] = $derivativesTransactions; + null !== $detailedTrades && $self['detailedTrades'] = $detailedTrades; + null !== $equityTransactions && $self['equityTransactions'] = $equityTransactions; + + return $self; + } + + /** + * @param BrokerInfo|BrokerInfoShape $brokerInfo + */ + public function withBrokerInfo(BrokerInfo|array $brokerInfo): self + { + $self = clone $this; + $self['brokerInfo'] = $brokerInfo; + + return $self; + } + + /** + * Breakdown of various charges and fees. + * + * @param ChargesSummary|ChargesSummaryShape $chargesSummary + */ + public function withChargesSummary( + ChargesSummary|array $chargesSummary + ): self { + $self = clone $this; + $self['chargesSummary'] = $chargesSummary; + + return $self; + } + + /** + * @param ClientInfo|ClientInfoShape $clientInfo + */ + public function withClientInfo(ClientInfo|array $clientInfo): self + { + $self = clone $this; + $self['clientInfo'] = $clientInfo; + + return $self; + } + + /** + * @param ContractNoteInfo|ContractNoteInfoShape $contractNoteInfo + */ + public function withContractNoteInfo( + ContractNoteInfo|array $contractNoteInfo + ): self { + $self = clone $this; + $self['contractNoteInfo'] = $contractNoteInfo; + + return $self; + } + + /** + * Summary of derivatives transactions. + * + * @param list $derivativesTransactions + */ + public function withDerivativesTransactions( + array $derivativesTransactions + ): self { + $self = clone $this; + $self['derivativesTransactions'] = $derivativesTransactions; + + return $self; + } + + /** + * Detailed breakdown of all individual trades. + * + * @param list $detailedTrades + */ + public function withDetailedTrades(array $detailedTrades): self + { + $self = clone $this; + $self['detailedTrades'] = $detailedTrades; + + return $self; + } + + /** + * Summary of equity transactions grouped by security. + * + * @param list $equityTransactions + */ + public function withEquityTransactions(array $equityTransactions): self + { + $self = clone $this; + $self['equityTransactions'] = $equityTransactions; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo.php b/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo.php new file mode 100644 index 0000000..2b54160 --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo.php @@ -0,0 +1,104 @@ +, + * name?: string|null, + * sebiRegistration?: string|null, + * } + */ +final class BrokerInfo implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Auto-detected or specified broker type. + * + * @var value-of|null $brokerType + */ + #[Optional('broker_type', enum: BrokerType::class)] + public ?string $brokerType; + + /** + * Broker company name. + */ + #[Optional] + public ?string $name; + + /** + * SEBI registration number of the broker. + */ + #[Optional('sebi_registration')] + public ?string $sebiRegistration; + + 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 BrokerType|value-of|null $brokerType + */ + public static function with( + BrokerType|string|null $brokerType = null, + ?string $name = null, + ?string $sebiRegistration = null, + ): self { + $self = new self; + + null !== $brokerType && $self['brokerType'] = $brokerType; + null !== $name && $self['name'] = $name; + null !== $sebiRegistration && $self['sebiRegistration'] = $sebiRegistration; + + return $self; + } + + /** + * Auto-detected or specified broker type. + * + * @param BrokerType|value-of $brokerType + */ + public function withBrokerType(BrokerType|string $brokerType): self + { + $self = clone $this; + $self['brokerType'] = $brokerType; + + return $self; + } + + /** + * Broker company name. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * SEBI registration number of the broker. + */ + public function withSebiRegistration(string $sebiRegistration): self + { + $self = clone $this; + $self['sebiRegistration'] = $sebiRegistration; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo/BrokerType.php b/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo/BrokerType.php new file mode 100644 index 0000000..38c5466 --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/BrokerInfo/BrokerType.php @@ -0,0 +1,21 @@ + */ + use SdkModel; + + /** + * Central GST amount. + */ + #[Optional] + public ?float $cgst; + + /** + * Exchange transaction charges. + */ + #[Optional('exchange_transaction_charges')] + public ?float $exchangeTransactionCharges; + + /** + * Integrated GST amount. + */ + #[Optional] + public ?float $igst; + + /** + * Final net amount receivable or payable. + */ + #[Optional('net_amount_receivable_payable')] + public ?float $netAmountReceivablePayable; + + /** + * Net pay-in/pay-out obligation. + */ + #[Optional('pay_in_pay_out_obligation')] + public ?float $payInPayOutObligation; + + /** + * SEBI turnover fees. + */ + #[Optional('sebi_turnover_fees')] + public ?float $sebiTurnoverFees; + + /** + * Securities Transaction Tax. + */ + #[Optional('securities_transaction_tax')] + public ?float $securitiesTransactionTax; + + /** + * State GST amount. + */ + #[Optional] + public ?float $sgst; + + /** + * Stamp duty charges. + */ + #[Optional('stamp_duty')] + public ?float $stampDuty; + + /** + * Taxable brokerage amount. + */ + #[Optional('taxable_value_brokerage')] + public ?float $taxableValueBrokerage; + + 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 $cgst = null, + ?float $exchangeTransactionCharges = null, + ?float $igst = null, + ?float $netAmountReceivablePayable = null, + ?float $payInPayOutObligation = null, + ?float $sebiTurnoverFees = null, + ?float $securitiesTransactionTax = null, + ?float $sgst = null, + ?float $stampDuty = null, + ?float $taxableValueBrokerage = null, + ): self { + $self = new self; + + null !== $cgst && $self['cgst'] = $cgst; + null !== $exchangeTransactionCharges && $self['exchangeTransactionCharges'] = $exchangeTransactionCharges; + null !== $igst && $self['igst'] = $igst; + null !== $netAmountReceivablePayable && $self['netAmountReceivablePayable'] = $netAmountReceivablePayable; + null !== $payInPayOutObligation && $self['payInPayOutObligation'] = $payInPayOutObligation; + null !== $sebiTurnoverFees && $self['sebiTurnoverFees'] = $sebiTurnoverFees; + null !== $securitiesTransactionTax && $self['securitiesTransactionTax'] = $securitiesTransactionTax; + null !== $sgst && $self['sgst'] = $sgst; + null !== $stampDuty && $self['stampDuty'] = $stampDuty; + null !== $taxableValueBrokerage && $self['taxableValueBrokerage'] = $taxableValueBrokerage; + + return $self; + } + + /** + * Central GST amount. + */ + public function withCgst(float $cgst): self + { + $self = clone $this; + $self['cgst'] = $cgst; + + return $self; + } + + /** + * Exchange transaction charges. + */ + public function withExchangeTransactionCharges( + float $exchangeTransactionCharges + ): self { + $self = clone $this; + $self['exchangeTransactionCharges'] = $exchangeTransactionCharges; + + return $self; + } + + /** + * Integrated GST amount. + */ + public function withIgst(float $igst): self + { + $self = clone $this; + $self['igst'] = $igst; + + return $self; + } + + /** + * Final net amount receivable or payable. + */ + public function withNetAmountReceivablePayable( + float $netAmountReceivablePayable + ): self { + $self = clone $this; + $self['netAmountReceivablePayable'] = $netAmountReceivablePayable; + + return $self; + } + + /** + * Net pay-in/pay-out obligation. + */ + public function withPayInPayOutObligation( + float $payInPayOutObligation + ): self { + $self = clone $this; + $self['payInPayOutObligation'] = $payInPayOutObligation; + + return $self; + } + + /** + * SEBI turnover fees. + */ + public function withSebiTurnoverFees(float $sebiTurnoverFees): self + { + $self = clone $this; + $self['sebiTurnoverFees'] = $sebiTurnoverFees; + + return $self; + } + + /** + * Securities Transaction Tax. + */ + public function withSecuritiesTransactionTax( + float $securitiesTransactionTax + ): self { + $self = clone $this; + $self['securitiesTransactionTax'] = $securitiesTransactionTax; + + return $self; + } + + /** + * State GST amount. + */ + public function withSgst(float $sgst): self + { + $self = clone $this; + $self['sgst'] = $sgst; + + return $self; + } + + /** + * Stamp duty charges. + */ + public function withStampDuty(float $stampDuty): self + { + $self = clone $this; + $self['stampDuty'] = $stampDuty; + + return $self; + } + + /** + * Taxable brokerage amount. + */ + public function withTaxableValueBrokerage( + float $taxableValueBrokerage + ): self { + $self = clone $this; + $self['taxableValueBrokerage'] = $taxableValueBrokerage; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/ClientInfo.php b/src/ContractNote/ContractNoteParseResponse/Data/ClientInfo.php new file mode 100644 index 0000000..667b62e --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/ClientInfo.php @@ -0,0 +1,157 @@ + */ + use SdkModel; + + /** + * Client address. + */ + #[Optional] + public ?string $address; + + /** + * GST state code. + */ + #[Optional('gst_state_code')] + public ?string $gstStateCode; + + /** + * Client name. + */ + #[Optional] + public ?string $name; + + /** + * Client PAN number. + */ + #[Optional] + public ?string $pan; + + /** + * GST place of supply. + */ + #[Optional('place_of_supply')] + public ?string $placeOfSupply; + + /** + * Unique Client Code. + */ + #[Optional] + public ?string $ucc; + + 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 $address = null, + ?string $gstStateCode = null, + ?string $name = null, + ?string $pan = null, + ?string $placeOfSupply = null, + ?string $ucc = null, + ): self { + $self = new self; + + null !== $address && $self['address'] = $address; + null !== $gstStateCode && $self['gstStateCode'] = $gstStateCode; + null !== $name && $self['name'] = $name; + null !== $pan && $self['pan'] = $pan; + null !== $placeOfSupply && $self['placeOfSupply'] = $placeOfSupply; + null !== $ucc && $self['ucc'] = $ucc; + + return $self; + } + + /** + * Client address. + */ + public function withAddress(string $address): self + { + $self = clone $this; + $self['address'] = $address; + + return $self; + } + + /** + * GST state code. + */ + public function withGstStateCode(string $gstStateCode): self + { + $self = clone $this; + $self['gstStateCode'] = $gstStateCode; + + return $self; + } + + /** + * Client name. + */ + public function withName(string $name): self + { + $self = clone $this; + $self['name'] = $name; + + return $self; + } + + /** + * Client PAN number. + */ + public function withPan(string $pan): self + { + $self = clone $this; + $self['pan'] = $pan; + + return $self; + } + + /** + * GST place of supply. + */ + public function withPlaceOfSupply(string $placeOfSupply): self + { + $self = clone $this; + $self['placeOfSupply'] = $placeOfSupply; + + return $self; + } + + /** + * Unique Client Code. + */ + public function withUcc(string $ucc): self + { + $self = clone $this; + $self['ucc'] = $ucc; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/ContractNoteInfo.php b/src/ContractNote/ContractNoteParseResponse/Data/ContractNoteInfo.php new file mode 100644 index 0000000..55ad858 --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/ContractNoteInfo.php @@ -0,0 +1,117 @@ + */ + use SdkModel; + + /** + * Contract note reference number. + */ + #[Optional('contract_note_number')] + public ?string $contractNoteNumber; + + /** + * Settlement date for the trades. + */ + #[Optional('settlement_date')] + public ?string $settlementDate; + + /** + * Settlement reference number. + */ + #[Optional('settlement_number')] + public ?string $settlementNumber; + + /** + * Date when trades were executed. + */ + #[Optional('trade_date')] + public ?string $tradeDate; + + 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 $contractNoteNumber = null, + ?string $settlementDate = null, + ?string $settlementNumber = null, + ?string $tradeDate = null, + ): self { + $self = new self; + + null !== $contractNoteNumber && $self['contractNoteNumber'] = $contractNoteNumber; + null !== $settlementDate && $self['settlementDate'] = $settlementDate; + null !== $settlementNumber && $self['settlementNumber'] = $settlementNumber; + null !== $tradeDate && $self['tradeDate'] = $tradeDate; + + return $self; + } + + /** + * Contract note reference number. + */ + public function withContractNoteNumber(string $contractNoteNumber): self + { + $self = clone $this; + $self['contractNoteNumber'] = $contractNoteNumber; + + return $self; + } + + /** + * Settlement date for the trades. + */ + public function withSettlementDate(string $settlementDate): self + { + $self = clone $this; + $self['settlementDate'] = $settlementDate; + + return $self; + } + + /** + * Settlement reference number. + */ + public function withSettlementNumber(string $settlementNumber): self + { + $self = clone $this; + $self['settlementNumber'] = $settlementNumber; + + return $self; + } + + /** + * Date when trades were executed. + */ + public function withTradeDate(string $tradeDate): self + { + $self = clone $this; + $self['tradeDate'] = $tradeDate; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/DerivativesTransaction.php b/src/ContractNote/ContractNoteParseResponse/Data/DerivativesTransaction.php new file mode 100644 index 0000000..ced57ba --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/DerivativesTransaction.php @@ -0,0 +1,177 @@ + */ + use SdkModel; + + /** + * Brokerage charged per unit. + */ + #[Optional('brokerage_per_unit')] + public ?float $brokeragePerUnit; + + /** + * Transaction type (Buy/Sell/Bring Forward/Carry Forward). + */ + #[Optional('buy_sell_bf_cf')] + public ?string $buySellBfCf; + + /** + * Closing rate per unit. + */ + #[Optional('closing_rate_per_unit')] + public ?float $closingRatePerUnit; + + /** + * Derivatives contract description. + */ + #[Optional('contract_description')] + public ?string $contractDescription; + + /** + * Net total amount. + */ + #[Optional('net_total')] + public ?float $netTotal; + + /** + * Quantity traded. + */ + #[Optional] + public ?float $quantity; + + /** + * Weighted Average Price per unit. + */ + #[Optional('wap_per_unit')] + public ?float $wapPerUnit; + + 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 $brokeragePerUnit = null, + ?string $buySellBfCf = null, + ?float $closingRatePerUnit = null, + ?string $contractDescription = null, + ?float $netTotal = null, + ?float $quantity = null, + ?float $wapPerUnit = null, + ): self { + $self = new self; + + null !== $brokeragePerUnit && $self['brokeragePerUnit'] = $brokeragePerUnit; + null !== $buySellBfCf && $self['buySellBfCf'] = $buySellBfCf; + null !== $closingRatePerUnit && $self['closingRatePerUnit'] = $closingRatePerUnit; + null !== $contractDescription && $self['contractDescription'] = $contractDescription; + null !== $netTotal && $self['netTotal'] = $netTotal; + null !== $quantity && $self['quantity'] = $quantity; + null !== $wapPerUnit && $self['wapPerUnit'] = $wapPerUnit; + + return $self; + } + + /** + * Brokerage charged per unit. + */ + public function withBrokeragePerUnit(float $brokeragePerUnit): self + { + $self = clone $this; + $self['brokeragePerUnit'] = $brokeragePerUnit; + + return $self; + } + + /** + * Transaction type (Buy/Sell/Bring Forward/Carry Forward). + */ + public function withBuySellBfCf(string $buySellBfCf): self + { + $self = clone $this; + $self['buySellBfCf'] = $buySellBfCf; + + return $self; + } + + /** + * Closing rate per unit. + */ + public function withClosingRatePerUnit(float $closingRatePerUnit): self + { + $self = clone $this; + $self['closingRatePerUnit'] = $closingRatePerUnit; + + return $self; + } + + /** + * Derivatives contract description. + */ + public function withContractDescription(string $contractDescription): self + { + $self = clone $this; + $self['contractDescription'] = $contractDescription; + + return $self; + } + + /** + * Net total amount. + */ + public function withNetTotal(float $netTotal): self + { + $self = clone $this; + $self['netTotal'] = $netTotal; + + return $self; + } + + /** + * Quantity traded. + */ + public function withQuantity(float $quantity): self + { + $self = clone $this; + $self['quantity'] = $quantity; + + return $self; + } + + /** + * Weighted Average Price per unit. + */ + public function withWapPerUnit(float $wapPerUnit): self + { + $self = clone $this; + $self['wapPerUnit'] = $wapPerUnit; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/DetailedTrade.php b/src/ContractNote/ContractNoteParseResponse/Data/DetailedTrade.php new file mode 100644 index 0000000..fc1db7c --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/DetailedTrade.php @@ -0,0 +1,297 @@ + */ + use SdkModel; + + /** + * Brokerage charged for this trade. + */ + #[Optional] + public ?float $brokerage; + + /** + * Transaction type (B for Buy, S for Sell). + */ + #[Optional('buy_sell')] + public ?string $buySell; + + /** + * Closing rate per unit. + */ + #[Optional('closing_rate_per_unit')] + public ?float $closingRatePerUnit; + + /** + * Exchange name. + */ + #[Optional] + public ?string $exchange; + + /** + * Net rate per unit. + */ + #[Optional('net_rate_per_unit')] + public ?float $netRatePerUnit; + + /** + * Net total for this trade. + */ + #[Optional('net_total')] + public ?float $netTotal; + + /** + * Order reference number. + */ + #[Optional('order_number')] + public ?string $orderNumber; + + /** + * Time when order was placed. + */ + #[Optional('order_time')] + public ?string $orderTime; + + /** + * Quantity traded. + */ + #[Optional] + public ?float $quantity; + + /** + * Additional remarks or notes. + */ + #[Optional] + public ?string $remarks; + + /** + * Security name with exchange and ISIN. + */ + #[Optional('security_description')] + public ?string $securityDescription; + + /** + * Trade reference number. + */ + #[Optional('trade_number')] + public ?string $tradeNumber; + + /** + * Time when trade was executed. + */ + #[Optional('trade_time')] + public ?string $tradeTime; + + 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 $brokerage = null, + ?string $buySell = null, + ?float $closingRatePerUnit = null, + ?string $exchange = null, + ?float $netRatePerUnit = null, + ?float $netTotal = null, + ?string $orderNumber = null, + ?string $orderTime = null, + ?float $quantity = null, + ?string $remarks = null, + ?string $securityDescription = null, + ?string $tradeNumber = null, + ?string $tradeTime = null, + ): self { + $self = new self; + + null !== $brokerage && $self['brokerage'] = $brokerage; + null !== $buySell && $self['buySell'] = $buySell; + null !== $closingRatePerUnit && $self['closingRatePerUnit'] = $closingRatePerUnit; + null !== $exchange && $self['exchange'] = $exchange; + null !== $netRatePerUnit && $self['netRatePerUnit'] = $netRatePerUnit; + null !== $netTotal && $self['netTotal'] = $netTotal; + null !== $orderNumber && $self['orderNumber'] = $orderNumber; + null !== $orderTime && $self['orderTime'] = $orderTime; + null !== $quantity && $self['quantity'] = $quantity; + null !== $remarks && $self['remarks'] = $remarks; + null !== $securityDescription && $self['securityDescription'] = $securityDescription; + null !== $tradeNumber && $self['tradeNumber'] = $tradeNumber; + null !== $tradeTime && $self['tradeTime'] = $tradeTime; + + return $self; + } + + /** + * Brokerage charged for this trade. + */ + public function withBrokerage(float $brokerage): self + { + $self = clone $this; + $self['brokerage'] = $brokerage; + + return $self; + } + + /** + * Transaction type (B for Buy, S for Sell). + */ + public function withBuySell(string $buySell): self + { + $self = clone $this; + $self['buySell'] = $buySell; + + return $self; + } + + /** + * Closing rate per unit. + */ + public function withClosingRatePerUnit(float $closingRatePerUnit): self + { + $self = clone $this; + $self['closingRatePerUnit'] = $closingRatePerUnit; + + return $self; + } + + /** + * Exchange name. + */ + public function withExchange(string $exchange): self + { + $self = clone $this; + $self['exchange'] = $exchange; + + return $self; + } + + /** + * Net rate per unit. + */ + public function withNetRatePerUnit(float $netRatePerUnit): self + { + $self = clone $this; + $self['netRatePerUnit'] = $netRatePerUnit; + + return $self; + } + + /** + * Net total for this trade. + */ + public function withNetTotal(float $netTotal): self + { + $self = clone $this; + $self['netTotal'] = $netTotal; + + return $self; + } + + /** + * Order reference number. + */ + public function withOrderNumber(string $orderNumber): self + { + $self = clone $this; + $self['orderNumber'] = $orderNumber; + + return $self; + } + + /** + * Time when order was placed. + */ + public function withOrderTime(string $orderTime): self + { + $self = clone $this; + $self['orderTime'] = $orderTime; + + return $self; + } + + /** + * Quantity traded. + */ + public function withQuantity(float $quantity): self + { + $self = clone $this; + $self['quantity'] = $quantity; + + return $self; + } + + /** + * Additional remarks or notes. + */ + public function withRemarks(string $remarks): self + { + $self = clone $this; + $self['remarks'] = $remarks; + + return $self; + } + + /** + * Security name with exchange and ISIN. + */ + public function withSecurityDescription(string $securityDescription): self + { + $self = clone $this; + $self['securityDescription'] = $securityDescription; + + return $self; + } + + /** + * Trade reference number. + */ + public function withTradeNumber(string $tradeNumber): self + { + $self = clone $this; + $self['tradeNumber'] = $tradeNumber; + + return $self; + } + + /** + * Time when trade was executed. + */ + public function withTradeTime(string $tradeTime): self + { + $self = clone $this; + $self['tradeTime'] = $tradeTime; + + return $self; + } +} diff --git a/src/ContractNote/ContractNoteParseResponse/Data/EquityTransaction.php b/src/ContractNote/ContractNoteParseResponse/Data/EquityTransaction.php new file mode 100644 index 0000000..d5247cc --- /dev/null +++ b/src/ContractNote/ContractNoteParseResponse/Data/EquityTransaction.php @@ -0,0 +1,237 @@ + */ + use SdkModel; + + /** + * Total quantity purchased. + */ + #[Optional('buy_quantity')] + public ?float $buyQuantity; + + /** + * Total value of buy transactions. + */ + #[Optional('buy_total_value')] + public ?float $buyTotalValue; + + /** + * Weighted Average Price for buy transactions. + */ + #[Optional('buy_wap')] + public ?float $buyWap; + + /** + * ISIN code of the security. + */ + #[Optional] + public ?string $isin; + + /** + * Net amount payable/receivable for this security. + */ + #[Optional('net_obligation')] + public ?float $netObligation; + + /** + * Name of the security. + */ + #[Optional('security_name')] + public ?string $securityName; + + /** + * Trading symbol. + */ + #[Optional('security_symbol')] + public ?string $securitySymbol; + + /** + * Total quantity sold. + */ + #[Optional('sell_quantity')] + public ?float $sellQuantity; + + /** + * Total value of sell transactions. + */ + #[Optional('sell_total_value')] + public ?float $sellTotalValue; + + /** + * Weighted Average Price for sell transactions. + */ + #[Optional('sell_wap')] + public ?float $sellWap; + + 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 $buyQuantity = null, + ?float $buyTotalValue = null, + ?float $buyWap = null, + ?string $isin = null, + ?float $netObligation = null, + ?string $securityName = null, + ?string $securitySymbol = null, + ?float $sellQuantity = null, + ?float $sellTotalValue = null, + ?float $sellWap = null, + ): self { + $self = new self; + + null !== $buyQuantity && $self['buyQuantity'] = $buyQuantity; + null !== $buyTotalValue && $self['buyTotalValue'] = $buyTotalValue; + null !== $buyWap && $self['buyWap'] = $buyWap; + null !== $isin && $self['isin'] = $isin; + null !== $netObligation && $self['netObligation'] = $netObligation; + null !== $securityName && $self['securityName'] = $securityName; + null !== $securitySymbol && $self['securitySymbol'] = $securitySymbol; + null !== $sellQuantity && $self['sellQuantity'] = $sellQuantity; + null !== $sellTotalValue && $self['sellTotalValue'] = $sellTotalValue; + null !== $sellWap && $self['sellWap'] = $sellWap; + + return $self; + } + + /** + * Total quantity purchased. + */ + public function withBuyQuantity(float $buyQuantity): self + { + $self = clone $this; + $self['buyQuantity'] = $buyQuantity; + + return $self; + } + + /** + * Total value of buy transactions. + */ + public function withBuyTotalValue(float $buyTotalValue): self + { + $self = clone $this; + $self['buyTotalValue'] = $buyTotalValue; + + return $self; + } + + /** + * Weighted Average Price for buy transactions. + */ + public function withBuyWap(float $buyWap): self + { + $self = clone $this; + $self['buyWap'] = $buyWap; + + return $self; + } + + /** + * ISIN code of the security. + */ + public function withIsin(string $isin): self + { + $self = clone $this; + $self['isin'] = $isin; + + return $self; + } + + /** + * Net amount payable/receivable for this security. + */ + public function withNetObligation(float $netObligation): self + { + $self = clone $this; + $self['netObligation'] = $netObligation; + + return $self; + } + + /** + * Name of the security. + */ + public function withSecurityName(string $securityName): self + { + $self = clone $this; + $self['securityName'] = $securityName; + + return $self; + } + + /** + * Trading symbol. + */ + public function withSecuritySymbol(string $securitySymbol): self + { + $self = clone $this; + $self['securitySymbol'] = $securitySymbol; + + return $self; + } + + /** + * Total quantity sold. + */ + public function withSellQuantity(float $sellQuantity): self + { + $self = clone $this; + $self['sellQuantity'] = $sellQuantity; + + return $self; + } + + /** + * Total value of sell transactions. + */ + public function withSellTotalValue(float $sellTotalValue): self + { + $self = clone $this; + $self['sellTotalValue'] = $sellTotalValue; + + return $self; + } + + /** + * Weighted Average Price for sell transactions. + */ + public function withSellWap(float $sellWap): self + { + $self = clone $this; + $self['sellWap'] = $sellWap; + + return $self; + } +} diff --git a/src/Core.php b/src/Core.php index 45dd12c..0300024 100644 --- a/src/Core.php +++ b/src/Core.php @@ -3,7 +3,3 @@ declare(strict_types=1); namespace CasParser\Core; - -use CasParser\Core\Implementation\Omit; - -const OMIT = Omit::omit; diff --git a/src/Core/Attributes/Optional.php b/src/Core/Attributes/Optional.php new file mode 100644 index 0000000..50d1e83 --- /dev/null +++ b/src/Core/Attributes/Optional.php @@ -0,0 +1,35 @@ +|Converter|string|null $type + * @param class-string<\BackedEnum>|Converter|null $enum + * @param class-string|Converter|null $union + * @param class-string|Converter|string|null $list + * @param class-string|Converter|string|null $map + */ + public function __construct( + ?string $apiName = null, + Converter|string|null $type = null, + Converter|string|null $enum = null, + Converter|string|null $union = null, + Converter|string|null $list = null, + Converter|string|null $map = null, + bool $nullable = false, + ) { + parent::__construct(apiName: $apiName, type: $type, enum: $enum, union: $union, list: $list, map: $map, nullable: $nullable); + $this->optional = true; + } +} diff --git a/src/Core/Attributes/Api.php b/src/Core/Attributes/Required.php similarity index 77% rename from src/Core/Attributes/Api.php rename to src/Core/Attributes/Required.php index c3f6875..589a017 100644 --- a/src/Core/Attributes/Api.php +++ b/src/Core/Attributes/Required.php @@ -14,11 +14,17 @@ * @internal */ #[\Attribute(\Attribute::TARGET_PROPERTY)] -final class Api +class Required { /** @var class-string|Converter|string|null */ public readonly Converter|string|null $type; + public readonly ?string $apiName; + + public bool $optional; + + public readonly bool $nullable; + /** @var array */ private static array $enumConverters = []; @@ -30,14 +36,13 @@ final class Api * @param class-string|Converter|string|null $map */ public function __construct( - public readonly ?string $apiName = null, + ?string $apiName = null, Converter|string|null $type = null, Converter|string|null $enum = null, Converter|string|null $union = null, Converter|string|null $list = null, Converter|string|null $map = null, - public readonly bool $nullable = false, - public readonly bool $optional = false, + bool $nullable = false, ) { $type ??= $union; if (null !== $list) { @@ -47,17 +52,21 @@ public function __construct( $type ??= new MapOf($map); } if (null !== $enum) { - $type ??= $enum instanceof Converter ? $enum : $this->getEnumConverter($enum); + $type ??= $enum instanceof Converter ? $enum : self::enumConverter($enum); } + $this->apiName = $apiName; $this->type = $type; + $this->optional = false; + $this->nullable = $nullable; } /** @property class-string<\BackedEnum> $enum */ - private function getEnumConverter(string $enum): Converter + private static function enumConverter(string $enum): Converter { if (!isset(self::$enumConverters[$enum])) { - $converter = new EnumOf(array_column($enum::cases(), 'value')); // @phpstan-ignore-line + // @phpstan-ignore-next-line argument.type + $converter = new EnumOf(array_column($enum::cases(), column_key: 'value')); self::$enumConverters[$enum] = $converter; } diff --git a/src/Core/BaseClient.php b/src/Core/BaseClient.php index cae68a4..50534bf 100644 --- a/src/Core/BaseClient.php +++ b/src/Core/BaseClient.php @@ -5,42 +5,43 @@ namespace CasParser\Core; use CasParser\Core\Contracts\BasePage; +use CasParser\Core\Contracts\BaseResponse; use CasParser\Core\Contracts\BaseStream; use CasParser\Core\Conversion\Contracts\Converter; use CasParser\Core\Conversion\Contracts\ConverterSource; use CasParser\Core\Exceptions\APIConnectionException; use CasParser\Core\Exceptions\APIStatusException; +use CasParser\Core\Implementation\RawResponse; use CasParser\RequestOptions; use Psr\Http\Client\ClientExceptionInterface; -use Psr\Http\Client\ClientInterface; -use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamFactoryInterface; -use Psr\Http\Message\UriFactoryInterface; use Psr\Http\Message\UriInterface; /** - * @phpstan-type normalized_request = array{ + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + * + * @phpstan-type NormalizedRequest = array{ * method: string, * path: string, - * query: array, - * headers: array>, + * query: array, + * headers: array>, * body: mixed, * } */ -class BaseClient +abstract class BaseClient { protected UriInterface $baseUrl; /** * @internal * - * @param array|null> $headers + * @param array|null> $headers */ public function __construct( protected array $headers, string $baseUrl, + protected ?string $idempotencyHeader = null, protected RequestOptions $options = new RequestOptions, ) { assert(!is_null($this->options->uriFactory)); @@ -49,11 +50,14 @@ public function __construct( /** * @param string|list $path - * @param array $query - * @param array $headers - * @param class-string> $page - * @param class-string> $stream - * @param RequestOptions|array|null $options + * @param array $query + * @param array $headers + * @param string|int|list|null $unwrap + * @param class-string>|null $page + * @param class-string>|null $stream + * @param RequestOptions|array|null $options + * + * @return BaseResponse */ public function request( string $method, @@ -61,77 +65,56 @@ public function request( array $query = [], array $headers = [], mixed $body = null, + string|int|array|null $unwrap = null, string|Converter|ConverterSource|null $convert = null, ?string $page = null, ?string $stream = null, RequestOptions|array|null $options = [], - ): mixed { - // @phpstan-ignore-next-line - [$req, $opts] = $this->buildRequest(method: $method, path: $path, query: $query, headers: $headers, body: $body, opts: $options); - ['method' => $method, 'path' => $uri, 'headers' => $headers] = $req; + ): BaseResponse { + [$req, $opts] = $this->buildRequest( + method: $method, + // @phpstan-ignore argument.type + path: $path, + query: $query, + // @phpstan-ignore argument.type + headers: $headers, + body: $body, + // @phpstan-ignore argument.type + opts: $options, + ); + ['method' => $method, 'path' => $uri, 'headers' => $headers, 'body' => $data] = $req; assert(!is_null($opts->requestFactory)); $request = $opts->requestFactory->createRequest($method, uri: $uri); $request = Util::withSetHeaders($request, headers: $headers); + $request = $this->transformRequest($request); - // @phpstan-ignore-next-line - $rsp = $this->sendRequest($opts, req: $request, data: $body, redirectCount: 0, retryCount: 0); - - $decoded = Util::decodeContent($rsp); - - if (!is_null($stream)) { - return new $stream( - convert: $convert, - request: $request, - response: $rsp, - stream: $decoded - ); - } - - if (!is_null($page)) { - return new $page( - convert: $convert, - client: $this, - request: $req, - options: $opts, - data: $decoded, - ); - } - - if (!is_null($convert)) { - return Conversion::coerce($convert, value: $decoded); - } + // @phpstan-ignore-next-line argument.type + $rsp = $this->sendRequest($opts, req: $request, data: $data, redirectCount: 0, retryCount: 0); - return $decoded; + // @phpstan-ignore-next-line argument.type + return new RawResponse(client: $this, request: $request, response: $rsp, options: $opts, requestInfo: $req, unwrap: $unwrap, stream: $stream, page: $page, convert: $convert ?? 'null'); } - /** @return array */ - protected function authHeaders(): array + /** + * @internal + */ + protected function generateIdempotencyKey(): string { - return []; + $hex = bin2hex(random_bytes(32)); + + return "stainless-php-retry-{$hex}"; } /** * @internal * * @param string|list $path - * @param array $query - * @param array|null> $headers - * @param array{ - * timeout?: float|null, - * maxRetries?: int|null, - * initialRetryDelay?: float|null, - * maxRetryDelay?: float|null, - * extraHeaders?: array|null>|null, - * extraQueryParams?: array|null, - * extraBodyParams?: mixed, - * transporter?: ClientInterface|null, - * uriFactory?: UriFactoryInterface|null, - * streamFactory?: StreamFactoryInterface|null, - * requestFactory?: RequestFactoryInterface|null, - * }|null $opts + * @param array $query + * @param array|null> $headers + * @param RequestOpts|null $opts * - * @return array{normalized_request, RequestOptions} + * @return array{NormalizedRequest, RequestOptions} */ protected function buildRequest( string $method, @@ -145,24 +128,35 @@ protected function buildRequest( $parsedPath = Util::parsePath($path); - /** @var array $mergedQuery */ + /** @var array $mergedQuery */ $mergedQuery = array_merge_recursive( $query, - $options->extraQueryParams ?? [], + $options->extraQueryParams ?? [] ); $uri = Util::joinUri($this->baseUrl, path: $parsedPath, query: $mergedQuery)->__toString(); + $idempotencyHeaders = $this->idempotencyHeader && !array_key_exists($this->idempotencyHeader, array: $headers) + ? [$this->idempotencyHeader => $this->generateIdempotencyKey()] + : []; - /** @var array|null> $mergedHeaders */ - $mergedHeaders = [...$this->headers, - ...$this->authHeaders(), + /** @var array|null> $mergedHeaders */ + $mergedHeaders = [ + ...$this->headers, ...$headers, - ...($options->extraHeaders ?? []), ]; + ...($options->extraHeaders ?? []), + ...$idempotencyHeaders, + ]; $req = ['method' => strtoupper($method), 'path' => $uri, 'query' => $mergedQuery, 'headers' => $mergedHeaders, 'body' => $body]; return [$req, $options]; } + protected function transformRequest( + RequestInterface $request + ): RequestInterface { + return $request; + } + /** * @internal */ @@ -232,8 +226,7 @@ protected function retryDelay( /** * @internal * - * @param bool|int|float|string|resource|\Traversable|array|null $data + * @param bool|int|float|string|resource|\Traversable|array|null $data */ protected function sendRequest( RequestOptions $opts, @@ -244,6 +237,8 @@ protected function sendRequest( ): ResponseInterface { assert(null !== $opts->streamFactory && null !== $opts->transporter); + /** @var RequestInterface */ + $req = $req->withHeader('X-Stainless-Retry-Count', strval($retryCount)); $req = Util::withSetBody($opts->streamFactory, req: $req, body: $data); $rsp = null; @@ -270,13 +265,13 @@ protected function sendRequest( } if ($code >= 400 || is_null($rsp)) { - if ($this->shouldRetry($opts, retryCount: $retryCount, rsp: $rsp)) { + if (!$this->shouldRetry($opts, retryCount: $retryCount, rsp: $rsp)) { $exn = is_null($rsp) ? new APIConnectionException($req, previous: $err) : APIStatusException::from(request: $req, response: $rsp); throw $exn; } - $seconds = $this->retryDelay($opts, retryCount: $redirectCount, rsp: $rsp); + $seconds = $this->retryDelay($opts, retryCount: $retryCount, rsp: $rsp); $floor = floor($seconds); time_nanosleep((int) $floor, nanoseconds: (int) ($seconds - $floor) * 10 ** 9); diff --git a/src/Core/Concerns/ResponseProxy.php b/src/Core/Concerns/ResponseProxy.php new file mode 100644 index 0000000..b0ca8af --- /dev/null +++ b/src/Core/Concerns/ResponseProxy.php @@ -0,0 +1,101 @@ +response->getProtocolVersion(); + } + + public function withProtocolVersion(string $version): static + { + $self = clone $this; + $self->response = $this->response->withProtocolVersion($version); + + return $self; + } + + public function getHeaders(): array + { + return $this->response->getHeaders(); + } + + public function hasHeader(string $name): bool + { + return $this->response->hasHeader($name); + } + + public function getHeader(string $name): array + { + return $this->response->getHeader($name); + } + + public function getHeaderLine(string $name): string + { + return $this->response->getHeaderLine($name); + } + + public function withHeader(string $name, $value): static + { + $self = clone $this; + $self->response = $this->response->withHeader($name, value: $value); + + return $self; + } + + public function withAddedHeader(string $name, $value): static + { + $self = clone $this; + $self->response = $this->response->withAddedHeader($name, value: $value); + + return $self; + } + + public function withoutHeader(string $name): static + { + $self = clone $this; + $self->response = $this->response->withoutHeader($name); + + return $self; + } + + public function getBody(): StreamInterface + { + return $this->response->getBody(); + } + + public function withBody(StreamInterface $body): static + { + $self = clone $this; + $self->response = $this->response->withBody($body); + + return $self; + } + + public function getStatusCode(): int + { + return $this->response->getStatusCode(); + } + + public function withStatus(int $code, string $reasonPhrase = ''): static + { + $self = clone $this; + $self->response = $this->response->withstatus($code, reasonPhrase: $reasonPhrase); + + return $self; + } + + public function getReasonPhrase(): string + { + return $this->response->getReasonPhrase(); + } +} diff --git a/src/Core/Concerns/SdkEnum.php b/src/Core/Concerns/SdkEnum.php index 9941eaf..467116e 100644 --- a/src/Core/Concerns/SdkEnum.php +++ b/src/Core/Concerns/SdkEnum.php @@ -28,6 +28,7 @@ public static function converter(): Converter } } - return static::$converter = new EnumOf($acc); // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return static::$converter = new EnumOf($acc); } } diff --git a/src/Core/Concerns/SdkModel.php b/src/Core/Concerns/SdkModel.php index 27f095b..a8548e1 100644 --- a/src/Core/Concerns/SdkModel.php +++ b/src/Core/Concerns/SdkModel.php @@ -32,9 +32,9 @@ trait SdkModel */ public function __serialize(): array { - $rows = [...Util::get_object_vars($this), ...$this->_data]; // @phpstan-ignore-line + $properties = $this->toProperties(); - return array_map(static fn ($v) => self::serialize($v), array: $rows); + return array_map(static fn ($v) => self::serialize($v), array: $properties); } /** @@ -45,7 +45,8 @@ public function __serialize(): array public function __unserialize(array $data): void { foreach ($data as $key => $value) { - $this->offsetSet($key, value: $value); // @phpstan-ignore-line + // @phpstan-ignore-next-line argument.type + $this->offsetSet($key, value: $value); } } @@ -74,8 +75,6 @@ public function __toString(): string * a native class property, indicating an omitted value, * or a property overridden with an incongruent type * - * @return value-of - * * @throws \Exception */ public function __get(string $key): mixed @@ -94,15 +93,19 @@ public function __get(string $key): mixed // An optional property which was unset to be omitted from serialized is being accessed. // Return null to match user's expectations. - return null; // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return null; } /** + * @internal + * * @return Shape */ - public function toArray(): array + public function toProperties(): array { - return $this->__serialize(); // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return [...Util::get_object_vars($this), ...$this->_data]; } /** @@ -112,7 +115,8 @@ public function toArray(): array */ public function offsetExists(mixed $offset): bool { - if (!is_string($offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (!is_string($offset)) { throw new \InvalidArgumentException; } @@ -140,19 +144,24 @@ public function offsetExists(mixed $offset): bool */ public function &offsetGet(mixed $offset): mixed { - if (!is_string($offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (!is_string($offset)) { throw new \InvalidArgumentException; } - if (!$this->offsetExists($offset)) { // @phpstan-ignore-line - return null; // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (!$this->offsetExists($offset)) { + // @phpstan-ignore-next-line return.type + return null; } if (array_key_exists($offset, array: $this->_data)) { - return $this->_data[$offset]; // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return $this->_data[$offset]; } - return $this->{$offset}; // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return $this->{$offset}; } /** @@ -162,7 +171,8 @@ public function &offsetGet(mixed $offset): mixed */ public function offsetSet(mixed $offset, mixed $value): void { - if (!is_string($offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (!is_string($offset)) { throw new \InvalidArgumentException; } @@ -172,13 +182,16 @@ public function offsetSet(mixed $offset, mixed $value): void $coerced = Conversion::coerce($type, value: $value, state: new CoerceState(translateNames: false)); - if (property_exists($this, property: $offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (property_exists($this, property: $offset)) { try { - $this->{$offset} = $coerced; // @phpstan-ignore-line + // @phpstan-ignore-next-line assign.propertyType + $this->{$offset} = $coerced; unset($this->_data[$offset]); return; - } catch (\TypeError) { // @phpstan-ignore-line + // @phpstan-ignore-next-line catch.neverThrown + } catch (\TypeError) { unset($this->{$offset}); } } @@ -193,11 +206,13 @@ public function offsetSet(mixed $offset, mixed $value): void */ public function offsetUnset(mixed $offset): void { - if (!is_string($offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (!is_string($offset)) { throw new \InvalidArgumentException; } - if (property_exists($this, property: $offset)) { // @phpstan-ignore-line + // @phpstan-ignore-next-line function.alreadyNarrowedType + if (property_exists($this, property: $offset)) { unset($this->{$offset}); } @@ -211,7 +226,7 @@ public function offsetUnset(mixed $offset): void */ public function jsonSerialize(): array { - // @phpstan-ignore-next-line + // @phpstan-ignore-next-line argument.type return Conversion::dump(self::converter(), value: $this->__serialize()); } @@ -220,7 +235,8 @@ public function jsonSerialize(): array */ public static function fromArray(array $data): static { - return self::converter()->from($data); // @phpstan-ignore-line + // @phpstan-ignore-next-line argument.type + return self::converter()->from($data); } /** @@ -257,7 +273,7 @@ private function initialize(): void private static function serialize(mixed $value): mixed { if ($value instanceof BaseModel) { - return $value->toArray(); + return $value->toProperties(); } if (is_array($value)) { diff --git a/src/Core/Concerns/SdkPage.php b/src/Core/Concerns/SdkPage.php index 20e1c71..29d3e7a 100644 --- a/src/Core/Concerns/SdkPage.php +++ b/src/Core/Concerns/SdkPage.php @@ -5,17 +5,18 @@ namespace CasParser\Core\Concerns; use CasParser\Client; +use CasParser\Core\Contracts\BaseResponse; use CasParser\Core\Conversion\Contracts\Converter; use CasParser\Core\Conversion\Contracts\ConverterSource; use CasParser\Core\Exceptions\APIStatusException; use CasParser\RequestOptions; /** + * @phpstan-import-type NormalizedRequest from \CasParser\Core\BaseClient + * * @internal * * @template Item - * - * @phpstan-import-type normalized_request from \CasParser\Core\BaseClient */ trait SdkPage { @@ -23,13 +24,6 @@ trait SdkPage private Client $client; - /** - * normalized_request $request. - */ - private array $request; - - private RequestOptions $options; - /** * @return list */ @@ -37,12 +31,7 @@ abstract public function getItems(): array; public function hasNextPage(): bool { - $items = $this->getItems(); - if (empty($items)) { - return false; - } - - return null != $this->nextRequest(); + return !is_null($this->nextRequest()); } /** @@ -65,8 +54,12 @@ public function getNextPage(): static [$req, $opts] = $next; - // @phpstan-ignore-next-line - return $this->client->request(...$req, convert: $this->convert, page: $this::class, options: $opts); + // @phpstan-ignore-next-line argument.type + /** @var BaseResponse */ + $response = $this->client->request(...$req, convert: $this->convert, page: $this::class, options: $opts); + + // @phpstan-ignore-next-line return.type + return $response->parse(); } /** @@ -103,16 +96,7 @@ public function pagingEachItem(): \Generator /** * @internal * - * @param array $data - * - * @return static - */ - abstract public static function fromArray(array $data): static; - - /** - * @internal - * - * @return array{normalized_request, RequestOptions} + * @return array{NormalizedRequest, RequestOptions} */ abstract protected function nextRequest(): ?array; } diff --git a/src/Core/Concerns/SdkParams.php b/src/Core/Concerns/SdkParams.php index 1010389..65f23d1 100644 --- a/src/Core/Concerns/SdkParams.php +++ b/src/Core/Concerns/SdkParams.php @@ -6,7 +6,6 @@ use CasParser\Core\Conversion; use CasParser\Core\Conversion\DumpState; -use CasParser\Core\Util; use CasParser\RequestOptions; /** @@ -15,23 +14,23 @@ trait SdkParams { /** - * @param array|self|null $params * @param array|RequestOptions|null $options * * @return array{array, RequestOptions} */ - public static function parseRequest(array|self|null $params, array|RequestOptions|null $options): array + public static function parseRequest(mixed $params, array|RequestOptions|null $options): array { - $value = is_array($params) ? Util::array_filter_omit($params) : $params; $converter = self::converter(); $state = new DumpState; - $dumped = (array) Conversion::dump($converter, value: $value, state: $state); - $opts = RequestOptions::parse($options); // @phpstan-ignore-line + $dumped = (array) Conversion::dump($converter, value: $params, state: $state); + // @phpstan-ignore-next-line argument.type + $opts = RequestOptions::parse($options); if (!$state->canRetry) { $opts->maxRetries = 0; } - return [$dumped, $opts]; // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return [$dumped, $opts]; } } diff --git a/src/Core/Concerns/SdkUnion.php b/src/Core/Concerns/SdkUnion.php index 6a073f8..b94173f 100644 --- a/src/Core/Concerns/SdkUnion.php +++ b/src/Core/Concerns/SdkUnion.php @@ -15,7 +15,7 @@ trait SdkUnion { private static Converter $converter; - public static function discriminator(): ?string // @phpstan-ignore-line + public static function discriminator(): ?string { return null; } @@ -34,7 +34,6 @@ public static function converter(): Converter return static::$converter; } - // @phpstan-ignore-next-line return static::$converter = new UnionOf(discriminator: static::discriminator(), variants: static::variants()); } } diff --git a/src/Core/Contracts/BaseModel.php b/src/Core/Contracts/BaseModel.php index a6b38d2..1938411 100644 --- a/src/Core/Contracts/BaseModel.php +++ b/src/Core/Contracts/BaseModel.php @@ -14,5 +14,5 @@ interface BaseModel extends \ArrayAccess, \JsonSerializable, \Stringable, ConverterSource { /** @return array */ - public function toArray(): array; + public function toProperties(): array; } diff --git a/src/Core/Contracts/BasePage.php b/src/Core/Contracts/BasePage.php index 40eecd6..54abffe 100644 --- a/src/Core/Contracts/BasePage.php +++ b/src/Core/Contracts/BasePage.php @@ -4,15 +4,10 @@ namespace CasParser\Core\Contracts; -use CasParser\Client; -use CasParser\Core\Conversion\Contracts\Converter; -use CasParser\Core\Conversion\Contracts\ConverterSource; -use CasParser\RequestOptions; - /** - * @internal + * @phpstan-import-type NormalizedRequest from \CasParser\Core\BaseClient * - * @phpstan-import-type normalized_request from \CasParser\Core\BaseClient + * @internal * * @template Item * @@ -20,19 +15,6 @@ */ interface BasePage extends \IteratorAggregate { - /** - * @internal - * - * @param normalized_request $request - */ - public function __construct( - Converter|ConverterSource|string $convert, - Client $client, - array $request, - RequestOptions $options, - mixed $data, - ); - public function hasNextPage(): bool; /** diff --git a/src/Core/Contracts/BaseResponse.php b/src/Core/Contracts/BaseResponse.php new file mode 100644 index 0000000..bd3f07b --- /dev/null +++ b/src/Core/Contracts/BaseResponse.php @@ -0,0 +1,21 @@ + $stream - */ public function __construct( Converter|ConverterSource|string $convert, RequestInterface $request, ResponseInterface $response, - \Generator $stream, + mixed $parsedBody, ); /** diff --git a/src/Core/Conversion.php b/src/Core/Conversion.php index e8c605e..bf56efa 100644 --- a/src/Core/Conversion.php +++ b/src/Core/Conversion.php @@ -9,6 +9,9 @@ use CasParser\Core\Conversion\Contracts\ConverterSource; use CasParser\Core\Conversion\DumpState; +/** + * @internal + */ final class Conversion { public static function dump_unknown(mixed $value, DumpState $state): mixed @@ -22,8 +25,12 @@ public static function dump_unknown(mixed $value, DumpState $state): mixed return $value::converter()->dump($value, state: $state); } + if (is_a($value, class: \BackedEnum::class)) { + return $value->value; + } + if (is_a($value, class: \DateTimeInterface::class)) { - return $value->format(format: \DateTimeInterface::RFC3339); + return date_format($value, format: \DateTimeInterface::RFC3339); } if (is_a($value, class: \JsonSerializable::class)) { @@ -54,6 +61,26 @@ public static function coerce(Converter|ConverterSource|string $target, mixed $v return $target->coerce($value, state: $state); } + return self::tryConvert($target, value: $value, state: $state); + } + + public static function dump(Converter|ConverterSource|string $target, mixed $value, DumpState $state = new DumpState): mixed + { + if ($target instanceof Converter) { + return $target->dump($value, state: $state); + } + + if (is_a($target, class: ConverterSource::class, allow_string: true)) { + return $target::converter()->dump($value, state: $state); + } + + self::tryConvert($target, value: $value, state: $state); + + return self::dump_unknown($value, state: $state); + } + + private static function tryConvert(Converter|ConverterSource|string $target, mixed $value, CoerceState|DumpState $state): mixed + { switch ($target) { case 'mixed': ++$state->yes; @@ -149,17 +176,4 @@ public static function coerce(Converter|ConverterSource|string $target, mixed $v return $value; } } - - public static function dump(Converter|ConverterSource|string $target, mixed $value, DumpState $state = new DumpState): mixed - { - if ($target instanceof Converter) { - return $target->dump($value, state: $state); - } - - if (is_a($target, class: ConverterSource::class, allow_string: true)) { - return $target::converter()->dump($value, state: $state); - } - - return self::dump_unknown($value, state: $state); - } } diff --git a/src/Core/Conversion/Concerns/ArrayOf.php b/src/Core/Conversion/Concerns/ArrayOf.php index e711b11..9321b52 100644 --- a/src/Core/Conversion/Concerns/ArrayOf.php +++ b/src/Core/Conversion/Concerns/ArrayOf.php @@ -32,10 +32,11 @@ public function coerce(mixed $value, CoerceState $state): mixed if (!is_array($value)) { return $value; } + ++$state->yes; $acc = []; foreach ($value as $k => $v) { - if ($this->nullable && null === $v) { + if ($this->nullable && is_null($v)) { ++$state->yes; $acc[$k] = null; } else { @@ -51,15 +52,27 @@ public function dump(mixed $value, DumpState $state): mixed if (!is_array($value)) { return Conversion::dump_unknown($value, state: $state); } + ++$state->yes; if (empty($value)) { return $this->empty(); } - return array_map(fn ($v) => Conversion::dump($this->type, value: $v, state: $state), array: $value); + $acc = []; + foreach ($value as $k => $v) { + if ($this->nullable && is_null($v)) { + ++$state->yes; + $acc[$k] = null; + } else { + $acc[$k] = Conversion::dump($this->type, value: $v, state: $state); + } + } + + return $acc; } - private function empty(): array|object // @phpstan-ignore-line + // @phpstan-ignore-next-line missingType.iterableValue + private function empty(): array|object { return (object) []; } diff --git a/src/Core/Conversion/DumpState.php b/src/Core/Conversion/DumpState.php index fbc8c1d..86435ab 100644 --- a/src/Core/Conversion/DumpState.php +++ b/src/Core/Conversion/DumpState.php @@ -10,6 +10,11 @@ final class DumpState { public function __construct( + public bool $translateNames = true, + public int $yes = 0, + public int $no = 0, + public int $maybe = 0, + public int $branched = 0, public bool $canRetry = true ) {} } diff --git a/src/Core/Conversion/EnumOf.php b/src/Core/Conversion/EnumOf.php index aaed8da..c1ae0aa 100644 --- a/src/Core/Conversion/EnumOf.php +++ b/src/Core/Conversion/EnumOf.php @@ -28,19 +28,26 @@ public function __construct(private readonly array $members) public function coerce(mixed $value, CoerceState $state): mixed { - if (in_array($value, haystack: $this->members, strict: true)) { - ++$state->yes; - } elseif ($this->type === gettype($value)) { - ++$state->maybe; - } else { - ++$state->no; - } + $this->tally($value, state: $state); return $value; } public function dump(mixed $value, DumpState $state): mixed { + $this->tally($value, state: $state); + return Conversion::dump_unknown($value, state: $state); } + + private function tally(mixed $value, CoerceState|DumpState $state): void + { + if (in_array($value, haystack: $this->members, strict: true)) { + ++$state->yes; + } elseif ($this->type === gettype($value)) { + ++$state->maybe; + } else { + ++$state->no; + } + } } diff --git a/src/Core/Conversion/ListOf.php b/src/Core/Conversion/ListOf.php index 8af6837..229d124 100644 --- a/src/Core/Conversion/ListOf.php +++ b/src/Core/Conversion/ListOf.php @@ -14,7 +14,8 @@ final class ListOf implements Converter { use ArrayOf; - private function empty(): array|object // @phpstan-ignore-line + // @phpstan-ignore-next-line missingType.iterableValue + private function empty(): array|object { return []; } diff --git a/src/Core/Conversion/ModelOf.php b/src/Core/Conversion/ModelOf.php index 0dbf406..36669be 100644 --- a/src/Core/Conversion/ModelOf.php +++ b/src/Core/Conversion/ModelOf.php @@ -4,7 +4,8 @@ namespace CasParser\Core\Conversion; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; +use CasParser\Core\Attributes\Required; use CasParser\Core\Contracts\BaseModel; use CasParser\Core\Conversion; use CasParser\Core\Conversion\Contracts\Converter; @@ -27,7 +28,9 @@ public function __construct(public readonly \ReflectionClass $class) $properties = []; foreach ($this->class->getProperties() as $property) { - if (!empty($property->getAttributes(Api::class))) { + $attributes = [...$property->getAttributes(Required::class), ...$property->getAttributes(Optional::class)]; + + if (!empty($attributes)) { $name = $property->getName(); $properties[$name] = new PropertyInfo($property); } @@ -88,31 +91,23 @@ public function coerce(mixed $value, CoerceState $state): mixed $acc[$name] = $item; } - return $this->from($acc); // @phpstan-ignore-line - } - - /** - * @param array $data - */ - public function from(array $data): BaseModel - { - $instance = $this->class->newInstanceWithoutConstructor(); - $instance->__unserialize($data); // @phpstan-ignore-line - - return $instance; + // @phpstan-ignore-next-line return.type + return $this->from($acc); } public function dump(mixed $value, DumpState $state): mixed { if ($value instanceof BaseModel) { - $value = $value->toArray(); + $value = $value->toProperties(); } if (is_array($value)) { + ++$state->yes; $acc = []; foreach ($value as $name => $item) { if (array_key_exists($name, array: $this->properties)) { + ++$state->yes; $info = $this->properties[$name]; $acc[$info->apiName] = Conversion::dump($info->type, value: $item, state: $state); } else { @@ -120,9 +115,23 @@ public function dump(mixed $value, DumpState $state): mixed } } - return empty($acc) ? ((object) []) : $acc; + return empty($acc) ? ((object) $acc) : $acc; } + ++$state->no; + return Conversion::dump_unknown($value, state: $state); } + + /** + * @param array $data + */ + public function from(array $data): BaseModel + { + $instance = $this->class->newInstanceWithoutConstructor(); + // @phpstan-ignore-next-line + $instance->__unserialize($data); + + return $instance; + } } diff --git a/src/Core/Conversion/PropertyInfo.php b/src/Core/Conversion/PropertyInfo.php index 385627b..aea255b 100644 --- a/src/Core/Conversion/PropertyInfo.php +++ b/src/Core/Conversion/PropertyInfo.php @@ -4,7 +4,8 @@ namespace CasParser\Core\Conversion; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; +use CasParser\Core\Attributes\Required; use CasParser\Core\Conversion\Contracts\Converter; use CasParser\Core\Conversion\Contracts\ConverterSource; @@ -28,9 +29,10 @@ public function __construct(public readonly \ReflectionProperty $property) $apiName = $property->getName(); $type = $property->getType(); $optional = false; + $attributes = [...$property->getAttributes(Required::class), ...$property->getAttributes(Optional::class)]; - foreach ($property->getAttributes(Api::class) as $attr) { - /** @var Api $attribute */ + foreach ($attributes as $attr) { + /** @var Required $attribute */ $attribute = $attr->newInstance(); $apiName = $attribute->apiName ?? $apiName; @@ -55,11 +57,12 @@ private static function parse(array|Converter|ConverterSource|\ReflectionType|st } if (is_array($type)) { - return new UnionOf($type); // @phpstan-ignore-line + // @phpstan-ignore-next-line return.type + return new UnionOf($type); } if ($type instanceof \ReflectionUnionType) { - // @phpstan-ignore-next-line + // @phpstan-ignore-next-line argument.type return new UnionOf(array_map(static fn ($t) => self::parse($t), array: $type->getTypes())); } diff --git a/src/Core/Conversion/UnionOf.php b/src/Core/Conversion/UnionOf.php index 0145ca1..d8852d4 100644 --- a/src/Core/Conversion/UnionOf.php +++ b/src/Core/Conversion/UnionOf.php @@ -65,17 +65,46 @@ public function coerce(mixed $value, CoerceState $state): mixed public function dump(mixed $value, DumpState $state): mixed { - if (null !== ($target = $this->resolveVariant(value: $value))) { + if (!is_null($target = $this->resolveVariant(value: $value))) { return Conversion::dump($target, value: $value, state: $state); } - foreach ($this->variants as $variant) { + $alternatives = []; + foreach ($this->variants as $_ => $variant) { + ++$state->branched; if ($value instanceof $variant) { return Conversion::dump($variant, value: $value, state: $state); } + + $newState = new DumpState; + $dumped = Conversion::dump($variant, value: $value, state: $newState); + if (($newState->no + $newState->maybe) === 0) { + $state->yes += $newState->yes; + + return $dumped; + } + if ($newState->maybe > 0) { + $alternatives[] = [[-$newState->yes, -$newState->maybe, $newState->no], $newState, $dumped]; + } } - return Conversion::dump_unknown($value, state: $state); + usort( + $alternatives, + static fn (array $a, array $b): int => $a[0][0] <=> $b[0][0] ?: $a[0][1] <=> $b[0][1] ?: $a[0][2] <=> $b[0][2] + ); + + if (empty($alternatives)) { + ++$state->no; + + return Conversion::dump_unknown($value, state: $state); + } + + [[,$newState, $best]] = $alternatives; + $state->yes += $newState->yes; + $state->maybe += $newState->maybe; + $state->no += $newState->no; + + return $best; } private function resolveVariant( diff --git a/src/Core/Exceptions/APITimeoutException.php b/src/Core/Exceptions/APITimeoutException.php index 5e9e4d3..999d529 100644 --- a/src/Core/Exceptions/APITimeoutException.php +++ b/src/Core/Exceptions/APITimeoutException.php @@ -10,7 +10,7 @@ class APITimeoutException extends APIConnectionException protected const DESC = 'CasParser API Timeout Exception'; public function __construct( - public RequestInterface $request, + RequestInterface $request, ?\Throwable $previous = null, string $message = 'Request timed out.', ) { diff --git a/src/Core/Implementation/HasRawResponse.php b/src/Core/Implementation/HasRawResponse.php deleted file mode 100644 index d3ffd67..0000000 --- a/src/Core/Implementation/HasRawResponse.php +++ /dev/null @@ -1,10 +0,0 @@ - + */ +class RawResponse implements BaseResponse +{ + use ResponseProxy; + + private mixed $decodedBody; + + /** @var R */ + private mixed $coercedResponse; + + private bool $decoded = false; + private bool $coerced = false; + + /** + * @param NormalizedRequest $requestInfo + * @param list|string|int|null $unwrap + */ + public function __construct( + private BaseClient $client, + private RequestOptions $options, + private RequestInterface $request, + private ResponseInterface $response, + private array $requestInfo, + private array|string|int|null $unwrap, + private Converter|ConverterSource|string $convert, + private ?string $page, + private ?string $stream, + ) {} + + public function getRequest(): RequestInterface + { + return $this->request; + } + + public function parse(): mixed + { + if (!$this->coerced) { + if (!is_null($this->stream)) { + // @phpstan-ignore-next-line assign.propertyType + $this->coercedResponse = new $this->stream( + convert: $this->convert, + request: $this->request, + response: $this->response, + parsedBody: $this->getDecoded(), + ); + } elseif (!is_null($this->page)) { + // @phpstan-ignore-next-line assign.propertyType + $this->coercedResponse = new $this->page( + convert: $this->convert, + client: $this->client, + requestInfo: $this->requestInfo, + options: $this->options, + response: $this->response, + parsedBody: $this->getDecoded(), + ); + } else { + // @phpstan-ignore-next-line assign.propertyType + $this->coercedResponse = Conversion::coerce( + $this->convert, + value: $this->getDecoded(), + ); + } + + $this->coerced = true; + } + + return $this->coercedResponse; + } + + private function getDecoded(): mixed + { + if (!$this->decoded) { + $decoded = Util::decodeContent($this->response); + if (!is_null($this->unwrap)) { + $decoded = Util::dig($decoded, key: $this->unwrap); + } + $this->decodedBody = $decoded; + $this->decoded = true; + } + + return $this->decodedBody; + } +} diff --git a/src/Core/Util.php b/src/Core/Util.php index 8ff5dd1..a319c64 100644 --- a/src/Core/Util.php +++ b/src/Core/Util.php @@ -25,21 +25,64 @@ final class Util public const JSONL_CONTENT_TYPE = '/^application\/(:?x-(?:n|l)djson)|(:?(?:x-)?jsonl)/'; + public static function getenv(string $key): ?string + { + if (array_key_exists($key, array: $_ENV)) { + if (!is_string($value = $_ENV[$key])) { + throw new \InvalidArgumentException; + } + + return $value; + } + + if (is_string($value = getenv($key))) { + return $value; + } + + return null; + } + /** - * @return array + * @return array */ - public static function get_object_vars(object $object1): array + public static function get_object_vars(object $object): array { - return get_object_vars($object1); + return get_object_vars($object); + } + + public static function machtype(): string + { + $arch = php_uname('m'); + + return match (true) { + str_contains($arch, 'aarch64'), str_contains($arch, 'arm64') => 'arm64', + str_contains($arch, 'x86_64'), str_contains($arch, 'amd64') => 'x64', + str_contains($arch, 'i386'), str_contains($arch, 'i686') => 'x32', + str_contains($arch, 'arm') => 'arm', + default => 'unknown', + }; + } + + public static function ostype(): string + { + return match ($os = strtolower(PHP_OS_FAMILY)) { + 'linux' => 'Linux', + 'darwin' => 'MacOS', + 'windows' => 'Windows', + 'solaris' => 'Solaris', + // @phpstan-ignore-next-line match.alwaysFalse + 'bsd', 'freebsd', 'openbsd' => 'BSD', + default => "Other:{$os}", + }; } /** * @template T * - * @param array $array - * @param array $map + * @param array $array + * @param array $map * - * @return array + * @return array */ public static function array_transform_keys(array $array, array $map): array { @@ -51,14 +94,41 @@ public static function array_transform_keys(array $array, array $map): array return $acc; } + public static function strVal(mixed $value): string + { + if (is_bool($value)) { + return $value ? 'true' : 'false'; + } + + if (is_object($value) && is_a($value, class: \DateTimeInterface::class)) { + return date_format($value, format: \DateTimeInterface::RFC3339); + } + + // @phpstan-ignore-next-line argument.type + return strval($value); + } + /** - * @param array $arr - * - * @return array + * @param callable $callback */ - public static function array_filter_omit(array $arr): array + public static function mapRecursive(mixed $callback, mixed $value): mixed { - return array_filter($arr, fn ($v, $_) => OMIT !== $v, mode: ARRAY_FILTER_USE_BOTH); + $mapped = match (true) { + is_array($value) => array_map(static fn ($v) => self::mapRecursive($callback, value: $v), $value), + default => $value, + }; + + return $callback($mapped); + } + + public static function removeNulls(mixed $value): mixed + { + $mapped = self::mapRecursive( + static fn ($vs) => is_array($vs) && !array_is_list($vs) ? array_filter($vs, callback: static fn ($v) => !is_null($v)) : $vs, + value: $value + ); + + return $mapped; } /** @@ -101,12 +171,13 @@ public static function parsePath(string|array $path): string } [$template] = $path; + $mapped = array_map(static fn ($s) => rawurlencode(self::strVal($s)), array: array_slice($path, 1)); - return sprintf($template, ...array_map('rawurlencode', array: array_slice($path, 1))); + return sprintf($template, ...$mapped); } /** - * @param array $query + * @param array $query */ public static function joinUri( UriInterface $base, @@ -134,14 +205,20 @@ public static function joinUri( parse_str($base->getQuery(), $q1); parse_str($parsed['query'] ?? '', $q2); - $merged_query = array_merge_recursive($q1, $q2, $query); - $qs = http_build_query($merged_query, encoding_type: PHP_QUERY_RFC3986); + $mergedQuery = array_merge_recursive($q1, $q2, $query); + + /** @var array */ + $normalizedQuery = self::mapRecursive( + static fn ($v) => is_bool($v) || is_numeric($v) ? self::strVal($v) : $v, + value: $mergedQuery + ); + $qs = http_build_query($normalizedQuery, encoding_type: PHP_QUERY_RFC3986); return $base->withQuery($qs); } /** - * @param array|null> $headers + * @param array|null> $headers */ public static function withSetHeaders( RequestInterface $req, @@ -149,13 +226,12 @@ public static function withSetHeaders( ): RequestInterface { foreach ($headers as $name => $value) { if (is_null($value)) { + /** @var RequestInterface */ $req = $req->withoutHeader($name); } else { - $value = is_int($value) - ? (string) $value - : (is_array($value) - ? array_map(static fn ($v) => (string) $v, array: $value) - : $value); + $value = is_array($value) ? array_map(static fn ($v) => self::strVal($v), array: $value) : self::strVal($value); + + /** @var RequestInterface */ $req = $req->withHeader($name, $value); } } @@ -182,8 +258,7 @@ public static function streamIterator(StreamInterface $stream): \Iterator } /** - * @param bool|int|float|string|resource|\Traversable|array|null $body + * @param bool|int|float|string|resource|\Traversable|array|null $body */ public static function withSetBody( StreamFactoryInterface $factory, @@ -191,6 +266,7 @@ public static function withSetBody( mixed $body ): RequestInterface { if ($body instanceof StreamInterface) { + /** @var RequestInterface */ return $req->withBody($body); } @@ -200,6 +276,7 @@ public static function withSetBody( $encoded = json_encode($body, flags: self::JSON_ENCODE_FLAGS); $stream = $factory->createStream($encoded); + /** @var RequestInterface */ return $req->withBody($stream); } } @@ -209,12 +286,21 @@ public static function withSetBody( $encoded = implode('', iterator_to_array($gen)); $stream = $factory->createStream($encoded); + /** @var RequestInterface */ return $req->withHeader('Content-Type', "{$contentType}; boundary={$boundary}")->withBody($stream); } if (is_resource($body)) { $stream = $factory->createStreamFromResource($body); + /** @var RequestInterface */ + return $req->withBody($stream); + } + + if (is_string($body)) { + $stream = $factory->createStream($body); + + // @var RequestInterface return $req->withBody($stream); } @@ -371,7 +457,7 @@ private static function writeMultipartContent( } elseif (is_string($val) || is_numeric($val) || is_bool($val)) { yield sprintf($contentLine, $contentType ?? 'text/plain'); - yield (string) $val; + yield self::strVal($val); } else { yield sprintf($contentLine, $contentType ?? 'application/json'); @@ -397,7 +483,7 @@ private static function writeMultipartChunk( yield 'Content-Disposition: form-data'; if (!is_null($key)) { - $name = rawurlencode($key); + $name = rawurlencode(self::strVal($key)); yield "; name=\"{$name}\""; } @@ -409,8 +495,7 @@ private static function writeMultipartChunk( } /** - * @param bool|int|float|string|resource|\Traversable|array|null $body + * @param bool|int|float|string|resource|\Traversable|array|null $body * * @return array{string, \Generator} */ 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/Inbox/InboxCheckConnectionStatusParams.php b/src/Inbox/InboxCheckConnectionStatusParams.php new file mode 100644 index 0000000..5fc0317 --- /dev/null +++ b/src/Inbox/InboxCheckConnectionStatusParams.php @@ -0,0 +1,71 @@ + */ + use SdkModel; + use SdkParams; + + #[Required] + public string $xInboxToken; + + /** + * `new InboxCheckConnectionStatusParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * InboxCheckConnectionStatusParams::with(xInboxToken: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new InboxCheckConnectionStatusParams)->withXInboxToken(...) + * ``` + */ + 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 $xInboxToken): self + { + $self = new self; + + $self['xInboxToken'] = $xInboxToken; + + return $self; + } + + public function withXInboxToken(string $xInboxToken): self + { + $self = clone $this; + $self['xInboxToken'] = $xInboxToken; + + return $self; + } +} diff --git a/src/Inbox/InboxCheckConnectionStatusResponse.php b/src/Inbox/InboxCheckConnectionStatusResponse.php new file mode 100644 index 0000000..c26587a --- /dev/null +++ b/src/Inbox/InboxCheckConnectionStatusResponse.php @@ -0,0 +1,105 @@ + */ + use SdkModel; + + /** + * Whether the token is valid and usable. + */ + #[Optional] + public ?bool $connected; + + /** + * Email address of the connected account. + */ + #[Optional] + public ?string $email; + + #[Optional] + public ?string $provider; + + #[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( + ?bool $connected = null, + ?string $email = null, + ?string $provider = null, + ?string $status = null, + ): self { + $self = new self; + + null !== $connected && $self['connected'] = $connected; + null !== $email && $self['email'] = $email; + null !== $provider && $self['provider'] = $provider; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * Whether the token is valid and usable. + */ + public function withConnected(bool $connected): self + { + $self = clone $this; + $self['connected'] = $connected; + + return $self; + } + + /** + * Email address of the connected account. + */ + public function withEmail(string $email): self + { + $self = clone $this; + $self['email'] = $email; + + return $self; + } + + public function withProvider(string $provider): self + { + $self = clone $this; + $self['provider'] = $provider; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/Inbox/InboxConnectEmailParams.php b/src/Inbox/InboxConnectEmailParams.php new file mode 100644 index 0000000..c871809 --- /dev/null +++ b/src/Inbox/InboxConnectEmailParams.php @@ -0,0 +1,110 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Your callback URL to receive the inbox_token (must be http or https). + */ + #[Required('redirect_uri')] + public string $redirectUri; + + /** + * State parameter for CSRF protection (returned in redirect). + */ + #[Optional] + public ?string $state; + + /** + * `new InboxConnectEmailParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * InboxConnectEmailParams::with(redirectUri: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new InboxConnectEmailParams)->withRedirectUri(...) + * ``` + */ + 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 $redirectUri, ?string $state = null): self + { + $self = new self; + + $self['redirectUri'] = $redirectUri; + + null !== $state && $self['state'] = $state; + + return $self; + } + + /** + * Your callback URL to receive the inbox_token (must be http or https). + */ + public function withRedirectUri(string $redirectUri): self + { + $self = clone $this; + $self['redirectUri'] = $redirectUri; + + return $self; + } + + /** + * State parameter for CSRF protection (returned in redirect). + */ + public function withState(string $state): self + { + $self = clone $this; + $self['state'] = $state; + + return $self; + } +} diff --git a/src/Inbox/InboxConnectEmailResponse.php b/src/Inbox/InboxConnectEmailResponse.php new file mode 100644 index 0000000..1316715 --- /dev/null +++ b/src/Inbox/InboxConnectEmailResponse.php @@ -0,0 +1,89 @@ + */ + use SdkModel; + + /** + * Seconds until the OAuth URL expires (typically 10 minutes). + */ + #[Optional('expires_in')] + public ?int $expiresIn; + + /** + * Redirect user to this URL to start OAuth flow. + */ + #[Optional('oauth_url')] + public ?string $oauthURL; + + #[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( + ?int $expiresIn = null, + ?string $oauthURL = null, + ?string $status = null + ): self { + $self = new self; + + null !== $expiresIn && $self['expiresIn'] = $expiresIn; + null !== $oauthURL && $self['oauthURL'] = $oauthURL; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * Seconds until the OAuth URL expires (typically 10 minutes). + */ + public function withExpiresIn(int $expiresIn): self + { + $self = clone $this; + $self['expiresIn'] = $expiresIn; + + return $self; + } + + /** + * Redirect user to this URL to start OAuth flow. + */ + public function withOAuthURL(string $oauthURL): self + { + $self = clone $this; + $self['oauthURL'] = $oauthURL; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/Inbox/InboxDisconnectEmailParams.php b/src/Inbox/InboxDisconnectEmailParams.php new file mode 100644 index 0000000..fbc07fb --- /dev/null +++ b/src/Inbox/InboxDisconnectEmailParams.php @@ -0,0 +1,73 @@ + */ + use SdkModel; + use SdkParams; + + #[Required] + public string $xInboxToken; + + /** + * `new InboxDisconnectEmailParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * InboxDisconnectEmailParams::with(xInboxToken: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new InboxDisconnectEmailParams)->withXInboxToken(...) + * ``` + */ + 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 $xInboxToken): self + { + $self = new self; + + $self['xInboxToken'] = $xInboxToken; + + return $self; + } + + public function withXInboxToken(string $xInboxToken): self + { + $self = clone $this; + $self['xInboxToken'] = $xInboxToken; + + return $self; + } +} diff --git a/src/Inbox/InboxDisconnectEmailResponse.php b/src/Inbox/InboxDisconnectEmailResponse.php new file mode 100644 index 0000000..8941c39 --- /dev/null +++ b/src/Inbox/InboxDisconnectEmailResponse.php @@ -0,0 +1,62 @@ + */ + 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/Inbox/InboxListCasFilesParams.php b/src/Inbox/InboxListCasFilesParams.php new file mode 100644 index 0000000..8b7c872 --- /dev/null +++ b/src/Inbox/InboxListCasFilesParams.php @@ -0,0 +1,155 @@ +>|null, + * endDate?: string|null, + * startDate?: string|null, + * } + */ +final class InboxListCasFilesParams implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + use SdkParams; + + #[Required] + public string $xInboxToken; + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @var list>|null $casTypes + */ + #[Optional('cas_types', list: CasType::class)] + public ?array $casTypes; + + /** + * End date in ISO format (YYYY-MM-DD). Defaults to today. + */ + #[Optional('end_date')] + public ?string $endDate; + + /** + * Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + */ + #[Optional('start_date')] + public ?string $startDate; + + /** + * `new InboxListCasFilesParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * InboxListCasFilesParams::with(xInboxToken: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new InboxListCasFilesParams)->withXInboxToken(...) + * ``` + */ + 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 $casTypes + */ + public static function with( + string $xInboxToken, + ?array $casTypes = null, + ?string $endDate = null, + ?string $startDate = null, + ): self { + $self = new self; + + $self['xInboxToken'] = $xInboxToken; + + null !== $casTypes && $self['casTypes'] = $casTypes; + null !== $endDate && $self['endDate'] = $endDate; + null !== $startDate && $self['startDate'] = $startDate; + + return $self; + } + + public function withXInboxToken(string $xInboxToken): self + { + $self = clone $this; + $self['xInboxToken'] = $xInboxToken; + + return $self; + } + + /** + * Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * + * @param list> $casTypes + */ + public function withCasTypes(array $casTypes): self + { + $self = clone $this; + $self['casTypes'] = $casTypes; + + return $self; + } + + /** + * End date in ISO format (YYYY-MM-DD). Defaults to today. + */ + public function withEndDate(string $endDate): self + { + $self = clone $this; + $self['endDate'] = $endDate; + + return $self; + } + + /** + * Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + */ + public function withStartDate(string $startDate): self + { + $self = clone $this; + $self['startDate'] = $startDate; + + return $self; + } +} diff --git a/src/Inbox/InboxListCasFilesParams/CasType.php b/src/Inbox/InboxListCasFilesParams/CasType.php new file mode 100644 index 0000000..15341a7 --- /dev/null +++ b/src/Inbox/InboxListCasFilesParams/CasType.php @@ -0,0 +1,16 @@ +|null, status?: string|null + * } + */ +final class InboxListCasFilesResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Number of CAS files found. + */ + #[Optional] + public ?int $count; + + /** @var list|null $files */ + #[Optional(list: File::class)] + public ?array $files; + + #[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 $files + */ + public static function with( + ?int $count = null, + ?array $files = null, + ?string $status = null + ): self { + $self = new self; + + null !== $count && $self['count'] = $count; + null !== $files && $self['files'] = $files; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * Number of CAS files found. + */ + public function withCount(int $count): self + { + $self = clone $this; + $self['count'] = $count; + + return $self; + } + + /** + * @param list $files + */ + public function withFiles(array $files): self + { + $self = clone $this; + $self['files'] = $files; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/Inbox/InboxListCasFilesResponse/File.php b/src/Inbox/InboxListCasFilesResponse/File.php new file mode 100644 index 0000000..4228539 --- /dev/null +++ b/src/Inbox/InboxListCasFilesResponse/File.php @@ -0,0 +1,206 @@ +, + * expiresIn?: int|null, + * filename?: string|null, + * messageDate?: string|null, + * messageID?: string|null, + * originalFilename?: string|null, + * size?: int|null, + * url?: string|null, + * } + */ +final class File implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Detected CAS provider based on sender email. + * + * @var value-of|null $casType + */ + #[Optional('cas_type', enum: CasType::class)] + public ?string $casType; + + /** + * URL expiration time in seconds (default 86400 = 24 hours). + */ + #[Optional('expires_in')] + public ?int $expiresIn; + + /** + * Standardized filename (provider_YYYYMMDD_uniqueid.pdf). + */ + #[Optional] + public ?string $filename; + + /** + * Date the email was received. + */ + #[Optional('message_date')] + public ?string $messageDate; + + /** + * Unique identifier for the email message (use for subsequent API calls). + */ + #[Optional('message_id')] + public ?string $messageID; + + /** + * Original attachment filename from the email. + */ + #[Optional('original_filename')] + public ?string $originalFilename; + + /** + * File size in bytes. + */ + #[Optional] + public ?int $size; + + /** + * Direct download URL (presigned, expires based on expires_in). + */ + #[Optional] + public ?string $url; + + 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 CasType|value-of|null $casType + */ + public static function with( + CasType|string|null $casType = null, + ?int $expiresIn = null, + ?string $filename = null, + ?string $messageDate = null, + ?string $messageID = null, + ?string $originalFilename = null, + ?int $size = null, + ?string $url = null, + ): self { + $self = new self; + + null !== $casType && $self['casType'] = $casType; + null !== $expiresIn && $self['expiresIn'] = $expiresIn; + null !== $filename && $self['filename'] = $filename; + null !== $messageDate && $self['messageDate'] = $messageDate; + null !== $messageID && $self['messageID'] = $messageID; + null !== $originalFilename && $self['originalFilename'] = $originalFilename; + null !== $size && $self['size'] = $size; + null !== $url && $self['url'] = $url; + + return $self; + } + + /** + * Detected CAS provider based on sender email. + * + * @param CasType|value-of $casType + */ + public function withCasType(CasType|string $casType): self + { + $self = clone $this; + $self['casType'] = $casType; + + return $self; + } + + /** + * URL expiration time in seconds (default 86400 = 24 hours). + */ + public function withExpiresIn(int $expiresIn): self + { + $self = clone $this; + $self['expiresIn'] = $expiresIn; + + return $self; + } + + /** + * Standardized filename (provider_YYYYMMDD_uniqueid.pdf). + */ + public function withFilename(string $filename): self + { + $self = clone $this; + $self['filename'] = $filename; + + return $self; + } + + /** + * Date the email was received. + */ + public function withMessageDate(string $messageDate): self + { + $self = clone $this; + $self['messageDate'] = $messageDate; + + return $self; + } + + /** + * Unique identifier for the email message (use for subsequent API calls). + */ + public function withMessageID(string $messageID): self + { + $self = clone $this; + $self['messageID'] = $messageID; + + return $self; + } + + /** + * Original attachment filename from the email. + */ + public function withOriginalFilename(string $originalFilename): self + { + $self = clone $this; + $self['originalFilename'] = $originalFilename; + + return $self; + } + + /** + * File size in bytes. + */ + public function withSize(int $size): self + { + $self = clone $this; + $self['size'] = $size; + + return $self; + } + + /** + * Direct download URL (presigned, expires based on expires_in). + */ + public function withURL(string $url): self + { + $self = clone $this; + $self['url'] = $url; + + return $self; + } +} diff --git a/src/Inbox/InboxListCasFilesResponse/File/CasType.php b/src/Inbox/InboxListCasFilesResponse/File/CasType.php new file mode 100644 index 0000000..efd748d --- /dev/null +++ b/src/Inbox/InboxListCasFilesResponse/File/CasType.php @@ -0,0 +1,19 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Email address to receive the CAS document. + */ + #[Required] + public string $email; + + /** + * Start date (YYYY-MM-DD). + */ + #[Required('from_date')] + public string $fromDate; + + /** + * Password for the PDF. + */ + #[Required] + public string $password; + + /** + * End date (YYYY-MM-DD). + */ + #[Required('to_date')] + public string $toDate; + + /** + * PAN number (optional). + */ + #[Optional('pan_no')] + public ?string $panNo; + + /** + * `new KfintechGenerateCasParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * KfintechGenerateCasParams::with( + * email: ..., fromDate: ..., password: ..., toDate: ... + * ) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new KfintechGenerateCasParams) + * ->withEmail(...) + * ->withFromDate(...) + * ->withPassword(...) + * ->withToDate(...) + * ``` + */ + 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 $email, + string $fromDate, + string $password, + string $toDate, + ?string $panNo = null, + ): self { + $self = new self; + + $self['email'] = $email; + $self['fromDate'] = $fromDate; + $self['password'] = $password; + $self['toDate'] = $toDate; + + null !== $panNo && $self['panNo'] = $panNo; + + return $self; + } + + /** + * Email address to receive the CAS document. + */ + public function withEmail(string $email): self + { + $self = clone $this; + $self['email'] = $email; + + return $self; + } + + /** + * Start date (YYYY-MM-DD). + */ + public function withFromDate(string $fromDate): self + { + $self = clone $this; + $self['fromDate'] = $fromDate; + + return $self; + } + + /** + * Password for the PDF. + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * End date (YYYY-MM-DD). + */ + public function withToDate(string $toDate): self + { + $self = clone $this; + $self['toDate'] = $toDate; + + return $self; + } + + /** + * PAN number (optional). + */ + public function withPanNo(string $panNo): self + { + $self = clone $this; + $self['panNo'] = $panNo; + + return $self; + } +} diff --git a/src/Kfintech/KfintechGenerateCasResponse.php b/src/Kfintech/KfintechGenerateCasResponse.php new file mode 100644 index 0000000..2933b4b --- /dev/null +++ b/src/Kfintech/KfintechGenerateCasResponse.php @@ -0,0 +1,62 @@ + */ + 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/Logs/LogCreateParams.php b/src/Logs/LogCreateParams.php new file mode 100644 index 0000000..e1e5df7 --- /dev/null +++ b/src/Logs/LogCreateParams.php @@ -0,0 +1,106 @@ + */ + 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..6448a9d --- /dev/null +++ b/src/Logs/LogGetSummaryParams.php @@ -0,0 +1,84 @@ + */ + 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/Nsdl/NsdlParseParams.php b/src/Nsdl/NsdlParseParams.php new file mode 100644 index 0000000..3bba755 --- /dev/null +++ b/src/Nsdl/NsdlParseParams.php @@ -0,0 +1,102 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Password for the PDF file (if required). + */ + #[Optional] + public ?string $password; + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + #[Optional('pdf_file')] + public ?string $pdfFile; + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + #[Optional('pdf_url')] + public ?string $pdfURL; + + 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 $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null + ): self { + $self = new self; + + null !== $password && $self['password'] = $password; + null !== $pdfFile && $self['pdfFile'] = $pdfFile; + null !== $pdfURL && $self['pdfURL'] = $pdfURL; + + return $self; + } + + /** + * Password for the PDF file (if required). + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + public function withPdfFile(string $pdfFile): self + { + $self = clone $this; + $self['pdfFile'] = $pdfFile; + + return $self; + } + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + public function withPdfURL(string $pdfURL): self + { + $self = clone $this; + $self['pdfURL'] = $pdfURL; + + return $self; + } +} diff --git a/src/RequestOptions.php b/src/RequestOptions.php index 03ece1a..7ae6885 100644 --- a/src/RequestOptions.php +++ b/src/RequestOptions.php @@ -4,36 +4,34 @@ namespace CasParser; -use CasParser\Core\Attributes\Api as Property; +use CasParser\Core\Attributes\Optional; +use CasParser\Core\Attributes\Required as Property; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; -use CasParser\Core\Implementation\Omit; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Message\UriFactoryInterface; -use const CasParser\Core\OMIT as omit; - /** - * @phpstan-type request_options = array{ + * @phpstan-type RequestOptionShape = array{ * timeout?: float|null, * maxRetries?: int|null, * initialRetryDelay?: float|null, * maxRetryDelay?: float|null, - * extraHeaders?: array>|null, - * extraQueryParams?: array|null, + * extraHeaders?: array>|null, + * extraQueryParams?: array|null, * extraBodyParams?: mixed, * transporter?: ClientInterface|null, * uriFactory?: UriFactoryInterface|null, * streamFactory?: StreamFactoryInterface|null, * requestFactory?: RequestFactoryInterface|null, * } - * @phpstan-type request_opts = null|RequestOptions|request_options + * @phpstan-type RequestOpts = null|RequestOptions|RequestOptionShape */ final class RequestOptions implements BaseModel { - /** @use SdkModel */ + /** @use SdkModel */ use SdkModel; #[Property] @@ -48,27 +46,27 @@ final class RequestOptions implements BaseModel #[Property] public float $maxRetryDelay = 8.0; - /** @var array|null>|null $extraHeaders */ - #[Property(optional: true)] + /** @var array|null>|null $extraHeaders */ + #[Optional] public ?array $extraHeaders; - /** @var array|null $extraQueryParams */ - #[Property(optional: true)] + /** @var array|null $extraQueryParams */ + #[Optional] public ?array $extraQueryParams; - #[Property(optional: true)] + #[Optional] public mixed $extraBodyParams; - #[Property(optional: true)] + #[Optional] public ?ClientInterface $transporter; - #[Property(optional: true)] + #[Optional] public ?UriFactoryInterface $uriFactory; - #[Property(optional: true)] + #[Optional] public ?StreamFactoryInterface $streamFactory; - #[Property(optional: true)] + #[Optional] public ?RequestFactoryInterface $requestFactory; public function __construct() @@ -77,19 +75,19 @@ public function __construct() } /** - * @param request_opts|null $options + * @param RequestOpts|null $options */ public static function parse(RequestOptions|array|null ...$options): self { - $parsed = array_map(static fn ($o) => $o instanceof self ? $o->toArray() : $o ?? [], array: $options); + $parsed = array_map(static fn ($o) => $o instanceof self ? $o->toProperties() : $o ?? [], array: $options); - return self::with(...array_merge(...$parsed)); // @phpstan-ignore-line + // @phpstan-ignore-next-line argument.type + return self::with(...array_merge(...$parsed)); } /** - * @param array|null>|null $extraHeaders - * @param array|null $extraQueryParams - * @param mixed|Omit $extraBodyParams + * @param array|null>|null $extraHeaders + * @param array|null $extraQueryParams */ public static function with( ?float $timeout = null, @@ -98,122 +96,124 @@ public static function with( ?float $maxRetryDelay = null, ?array $extraHeaders = null, ?array $extraQueryParams = null, - mixed $extraBodyParams = omit, + mixed $extraBodyParams = null, ?ClientInterface $transporter = null, ?UriFactoryInterface $uriFactory = null, ?StreamFactoryInterface $streamFactory = null, ?RequestFactoryInterface $requestFactory = null, ): self { - $obj = new self; - - null !== $timeout && $obj->timeout = $timeout; - null !== $maxRetries && $obj->maxRetries = $maxRetries; - null !== $initialRetryDelay && $obj->initialRetryDelay = $initialRetryDelay; - null !== $maxRetryDelay && $obj->maxRetryDelay = $maxRetryDelay; - null !== $extraHeaders && $obj->extraHeaders = $extraHeaders; - null !== $extraQueryParams && $obj->extraQueryParams = $extraQueryParams; - omit !== $extraBodyParams && $obj->extraBodyParams = $extraBodyParams; - null !== $transporter && $obj->transporter = $transporter; - null !== $uriFactory && $obj->uriFactory = $uriFactory; - null !== $streamFactory && $obj->streamFactory = $streamFactory; - null !== $requestFactory && $obj->requestFactory = $requestFactory; - - return $obj; + $self = new self; + + null !== $timeout && $self->timeout = $timeout; + null !== $maxRetries && $self->maxRetries = $maxRetries; + null !== $initialRetryDelay && $self + ->initialRetryDelay = $initialRetryDelay + ; + null !== $maxRetryDelay && $self->maxRetryDelay = $maxRetryDelay; + null !== $extraHeaders && $self->extraHeaders = $extraHeaders; + null !== $extraQueryParams && $self->extraQueryParams = $extraQueryParams; + null !== $extraBodyParams && $self->extraBodyParams = $extraBodyParams; + null !== $transporter && $self->transporter = $transporter; + null !== $uriFactory && $self->uriFactory = $uriFactory; + null !== $streamFactory && $self->streamFactory = $streamFactory; + null !== $requestFactory && $self->requestFactory = $requestFactory; + + return $self; } public function withTimeout(float $timeout): self { - $obj = clone $this; - $obj->timeout = $timeout; + $self = clone $this; + $self->timeout = $timeout; - return $obj; + return $self; } public function withMaxRetries(int $maxRetries): self { - $obj = clone $this; - $obj->maxRetries = $maxRetries; + $self = clone $this; + $self->maxRetries = $maxRetries; - return $obj; + return $self; } public function withInitialRetryDelay(float $initialRetryDelay): self { - $obj = clone $this; - $obj->initialRetryDelay = $initialRetryDelay; + $self = clone $this; + $self->initialRetryDelay = $initialRetryDelay; - return $obj; + return $self; } public function withMaxRetryDelay(float $maxRetryDelay): self { - $obj = clone $this; - $obj->maxRetryDelay = $maxRetryDelay; + $self = clone $this; + $self->maxRetryDelay = $maxRetryDelay; - return $obj; + return $self; } /** - * @param array|null> $extraHeaders + * @param array|null> $extraHeaders */ public function withExtraHeaders(array $extraHeaders): self { - $obj = clone $this; - $obj->extraHeaders = $extraHeaders; + $self = clone $this; + $self->extraHeaders = $extraHeaders; - return $obj; + return $self; } /** - * @param array $extraQueryParams + * @param array $extraQueryParams */ public function withExtraQueryParams(array $extraQueryParams): self { - $obj = clone $this; - $obj->extraQueryParams = $extraQueryParams; + $self = clone $this; + $self->extraQueryParams = $extraQueryParams; - return $obj; + return $self; } public function withExtraBodyParams(mixed $extraBodyParams): self { - $obj = clone $this; - $obj->extraBodyParams = $extraBodyParams; + $self = clone $this; + $self->extraBodyParams = $extraBodyParams; - return $obj; + return $self; } public function withTransporter(ClientInterface $transporter): self { - $obj = clone $this; - $obj->transporter = $transporter; + $self = clone $this; + $self->transporter = $transporter; - return $obj; + return $self; } public function withUriFactory(UriFactoryInterface $uriFactory): self { - $obj = clone $this; - $obj->uriFactory = $uriFactory; + $self = clone $this; + $self->uriFactory = $uriFactory; - return $obj; + return $self; } public function withStreamFactory( StreamFactoryInterface $streamFactory ): self { - $obj = clone $this; - $obj->streamFactory = $streamFactory; + $self = clone $this; + $self->streamFactory = $streamFactory; - return $obj; + return $self; } public function withRequestFactory( RequestFactoryInterface $requestFactory ): self { - $obj = clone $this; - $obj->requestFactory = $requestFactory; + $self = clone $this; + $self->requestFactory = $requestFactory; - return $obj; + return $self; } } diff --git a/src/ServiceContracts/AccessTokenContract.php b/src/ServiceContracts/AccessTokenContract.php new file mode 100644 index 0000000..c5a0c9e --- /dev/null +++ b/src/ServiceContracts/AccessTokenContract.php @@ -0,0 +1,28 @@ +|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/CamsKfintechContract.php b/src/ServiceContracts/CamsKfintechContract.php new file mode 100644 index 0000000..85d2f70 --- /dev/null +++ b/src/ServiceContracts/CamsKfintechContract.php @@ -0,0 +1,32 @@ +|CamsKfintechParseParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parse( + array|CamsKfintechParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/CasGeneratorContract.php b/src/ServiceContracts/CasGeneratorContract.php deleted file mode 100644 index 240aad8..0000000 --- a/src/ServiceContracts/CasGeneratorContract.php +++ /dev/null @@ -1,54 +0,0 @@ - $casAuthority CAS authority to generate the document from (currently only kfintech is supported) - * @param string $panNo PAN number (optional for some CAS authorities) - * - * @return CasGeneratorGenerateCasResponse - * - * @throws APIException - */ - public function generateCas( - $email, - $fromDate, - $password, - $toDate, - $casAuthority = omit, - $panNo = omit, - ?RequestOptions $requestOptions = null, - ): CasGeneratorGenerateCasResponse; - - /** - * @api - * - * @param array $params - * - * @return CasGeneratorGenerateCasResponse - * - * @throws APIException - */ - public function generateCasRaw( - array $params, - ?RequestOptions $requestOptions = null - ): CasGeneratorGenerateCasResponse; -} diff --git a/src/ServiceContracts/CasParserContract.php b/src/ServiceContracts/CasParserContract.php deleted file mode 100644 index c21836f..0000000 --- a/src/ServiceContracts/CasParserContract.php +++ /dev/null @@ -1,143 +0,0 @@ - - * - * @throws APIException - */ - public function camsKfintech( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse; - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function camsKfintechRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse; - - /** - * @api - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function cdsl( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse; - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function cdslRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse; - - /** - * @api - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function nsdl( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse; - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function nsdlRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse; - - /** - * @api - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function smartParse( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse; - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function smartParseRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse; -} diff --git a/src/ServiceContracts/Cdsl/FetchContract.php b/src/ServiceContracts/Cdsl/FetchContract.php new file mode 100644 index 0000000..bcfb42f --- /dev/null +++ b/src/ServiceContracts/Cdsl/FetchContract.php @@ -0,0 +1,50 @@ +|FetchRequestOtpParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function requestOtp( + array|FetchRequestOtpParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param string $sessionID Session ID from Step 1 + * @param array|FetchVerifyOtpParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function verifyOtp( + string $sessionID, + array|FetchVerifyOtpParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/CdslContract.php b/src/ServiceContracts/CdslContract.php new file mode 100644 index 0000000..83e5352 --- /dev/null +++ b/src/ServiceContracts/CdslContract.php @@ -0,0 +1,32 @@ +|CdslParsePdfParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parsePdf( + array|CdslParsePdfParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/ContractNoteContract.php b/src/ServiceContracts/ContractNoteContract.php new file mode 100644 index 0000000..b6124fd --- /dev/null +++ b/src/ServiceContracts/ContractNoteContract.php @@ -0,0 +1,35 @@ + $brokerType Optional broker type override. If not provided, system will auto-detect. + * @param string $password Password for the PDF file (usually PAN number for Zerodha) + * @param string $pdfFile Base64 encoded contract note PDF file + * @param string $pdfURL URL to the contract note PDF file + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parse( + BrokerType|string|null $brokerType = null, + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): ContractNoteParseResponse; +} diff --git a/src/ServiceContracts/ContractNoteRawContract.php b/src/ServiceContracts/ContractNoteRawContract.php new file mode 100644 index 0000000..4377337 --- /dev/null +++ b/src/ServiceContracts/ContractNoteRawContract.php @@ -0,0 +1,32 @@ +|ContractNoteParseParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parse( + array|ContractNoteParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/CreditsContract.php b/src/ServiceContracts/CreditsContract.php new file mode 100644 index 0000000..1bb58a2 --- /dev/null +++ b/src/ServiceContracts/CreditsContract.php @@ -0,0 +1,26 @@ + + * + * @throws APIException + */ + public function check( + RequestOptions|array|null $requestOptions = null + ): BaseResponse; +} diff --git a/src/ServiceContracts/InboxContract.php b/src/ServiceContracts/InboxContract.php new file mode 100644 index 0000000..a3210ec --- /dev/null +++ b/src/ServiceContracts/InboxContract.php @@ -0,0 +1,83 @@ +> $casTypes Body param: Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * @param string $endDate Body param: End date in ISO format (YYYY-MM-DD). Defaults to today. + * @param string $startDate Body param: Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function listCasFiles( + string $xInboxToken, + ?array $casTypes = null, + ?string $endDate = null, + ?string $startDate = null, + RequestOptions|array|null $requestOptions = null, + ): InboxListCasFilesResponse; +} diff --git a/src/ServiceContracts/InboxRawContract.php b/src/ServiceContracts/InboxRawContract.php new file mode 100644 index 0000000..f0ecab6 --- /dev/null +++ b/src/ServiceContracts/InboxRawContract.php @@ -0,0 +1,83 @@ +|InboxCheckConnectionStatusParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function checkConnectionStatus( + array|InboxCheckConnectionStatusParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param array|InboxConnectEmailParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function connectEmail( + array|InboxConnectEmailParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param array|InboxDisconnectEmailParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function disconnectEmail( + array|InboxDisconnectEmailParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param array|InboxListCasFilesParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function listCasFiles( + array|InboxListCasFilesParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/KfintechContract.php b/src/ServiceContracts/KfintechContract.php new file mode 100644 index 0000000..cb380d7 --- /dev/null +++ b/src/ServiceContracts/KfintechContract.php @@ -0,0 +1,36 @@ +|KfintechGenerateCasParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function generateCas( + array|KfintechGenerateCasParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/LogsContract.php b/src/ServiceContracts/LogsContract.php new file mode 100644 index 0000000..d7b2de0 --- /dev/null +++ b/src/ServiceContracts/LogsContract.php @@ -0,0 +1,48 @@ +|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/NsdlContract.php b/src/ServiceContracts/NsdlContract.php new file mode 100644 index 0000000..97ec1d3 --- /dev/null +++ b/src/ServiceContracts/NsdlContract.php @@ -0,0 +1,32 @@ +|NsdlParseParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parse( + array|NsdlParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/SmartContract.php b/src/ServiceContracts/SmartContract.php new file mode 100644 index 0000000..06c97ba --- /dev/null +++ b/src/ServiceContracts/SmartContract.php @@ -0,0 +1,32 @@ +|SmartParseCasPdfParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parseCasPdf( + array|SmartParseCasPdfParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/VerifyTokenContract.php b/src/ServiceContracts/VerifyTokenContract.php new file mode 100644 index 0000000..d9073a8 --- /dev/null +++ b/src/ServiceContracts/VerifyTokenContract.php @@ -0,0 +1,26 @@ + + * + * @throws APIException + */ + public function verify( + RequestOptions|array|null $requestOptions = null + ): BaseResponse; +} diff --git a/src/Services/AccessTokenRawService.php b/src/Services/AccessTokenRawService.php new file mode 100644 index 0000000..a2a3bb0 --- /dev/null +++ b/src/Services/AccessTokenRawService.php @@ -0,0 +1,64 @@ + + * + * @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 new file mode 100644 index 0000000..fe0aade --- /dev/null +++ b/src/Services/AccessTokenService.php @@ -0,0 +1,61 @@ +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/CamsKfintechRawService.php b/src/Services/CamsKfintechRawService.php new file mode 100644 index 0000000..3d8ffac --- /dev/null +++ b/src/Services/CamsKfintechRawService.php @@ -0,0 +1,59 @@ + + * + * @throws APIException + */ + public function parse( + array|CamsKfintechParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = CamsKfintechParseParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/cams_kfintech/parse', + body: (object) $parsed, + options: $options, + convert: UnifiedResponse::class, + ); + } +} diff --git a/src/Services/CamsKfintechService.php b/src/Services/CamsKfintechService.php new file mode 100644 index 0000000..32f2863 --- /dev/null +++ b/src/Services/CamsKfintechService.php @@ -0,0 +1,60 @@ +raw = new CamsKfintechRawService($client); + } + + /** + * @api + * + * This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF files and returns data in a unified format. + * Use this endpoint when you know the PDF is from CAMS or KFintech. + * + * @param string $password Password for the PDF file (if required) + * @param string $pdfFile Base64 encoded CAS PDF file (required if pdf_url not provided) + * @param string $pdfURL URL to the CAS PDF file (required if pdf_file not provided) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parse( + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): UnifiedResponse { + $params = Util::removeNulls( + ['password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->parse(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/CasGeneratorService.php b/src/Services/CasGeneratorService.php deleted file mode 100644 index c7d2e8e..0000000 --- a/src/Services/CasGeneratorService.php +++ /dev/null @@ -1,90 +0,0 @@ - $casAuthority CAS authority to generate the document from (currently only kfintech is supported) - * @param string $panNo PAN number (optional for some CAS authorities) - * - * @return CasGeneratorGenerateCasResponse - * - * @throws APIException - */ - public function generateCas( - $email, - $fromDate, - $password, - $toDate, - $casAuthority = omit, - $panNo = omit, - ?RequestOptions $requestOptions = null, - ): CasGeneratorGenerateCasResponse { - $params = [ - 'email' => $email, - 'fromDate' => $fromDate, - 'password' => $password, - 'toDate' => $toDate, - 'casAuthority' => $casAuthority, - 'panNo' => $panNo, - ]; - - return $this->generateCasRaw($params, $requestOptions); - } - - /** - * @api - * - * @param array $params - * - * @return CasGeneratorGenerateCasResponse - * - * @throws APIException - */ - public function generateCasRaw( - array $params, - ?RequestOptions $requestOptions = null - ): CasGeneratorGenerateCasResponse { - [$parsed, $options] = CasGeneratorGenerateCasParams::parseRequest( - $params, - $requestOptions - ); - - // @phpstan-ignore-next-line; - return $this->client->request( - method: 'post', - path: 'v4/generate', - body: (object) $parsed, - options: $options, - convert: CasGeneratorGenerateCasResponse::class, - ); - } -} diff --git a/src/Services/CasParserService.php b/src/Services/CasParserService.php deleted file mode 100644 index 8c2adff..0000000 --- a/src/Services/CasParserService.php +++ /dev/null @@ -1,246 +0,0 @@ - - * - * @throws APIException - */ - public function camsKfintech( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse { - $params = [ - 'password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL, - ]; - - return $this->camsKfintechRaw($params, $requestOptions); - } - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function camsKfintechRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse { - [$parsed, $options] = CasParserCamsKfintechParams::parseRequest( - $params, - $requestOptions - ); - - // @phpstan-ignore-next-line; - return $this->client->request( - method: 'post', - path: 'v4/cams_kfintech/parse', - body: (object) $parsed, - options: $options, - convert: UnifiedResponse::class, - ); - } - - /** - * @api - * - * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. - * Use this endpoint when you know the PDF is from CDSL. - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function cdsl( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse { - $params = [ - 'password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL, - ]; - - return $this->cdslRaw($params, $requestOptions); - } - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function cdslRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse { - [$parsed, $options] = CasParserCdslParams::parseRequest( - $params, - $requestOptions - ); - - // @phpstan-ignore-next-line; - return $this->client->request( - method: 'post', - path: 'v4/cdsl/parse', - body: (object) $parsed, - options: $options, - convert: UnifiedResponse::class, - ); - } - - /** - * @api - * - * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. - * Use this endpoint when you know the PDF is from NSDL. - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function nsdl( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse { - $params = [ - 'password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL, - ]; - - return $this->nsdlRaw($params, $requestOptions); - } - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function nsdlRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse { - [$parsed, $options] = CasParserNsdlParams::parseRequest( - $params, - $requestOptions - ); - - // @phpstan-ignore-next-line; - return $this->client->request( - method: 'post', - path: 'v4/nsdl/parse', - body: (object) $parsed, - options: $options, - convert: UnifiedResponse::class, - ); - } - - /** - * @api - * - * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or CAMS/KFintech and returns data in a unified format. - * It auto-detects the CAS type and transforms the data into a consistent structure regardless of the source. - * - * @param string $password Password for the PDF file (if required) - * @param string $pdfFile Base64 encoded CAS PDF file - * @param string $pdfURL URL to the CAS PDF file - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function smartParse( - $password = omit, - $pdfFile = omit, - $pdfURL = omit, - ?RequestOptions $requestOptions = null, - ): UnifiedResponse { - $params = [ - 'password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL, - ]; - - return $this->smartParseRaw($params, $requestOptions); - } - - /** - * @api - * - * @param array $params - * - * @return UnifiedResponse - * - * @throws APIException - */ - public function smartParseRaw( - array $params, - ?RequestOptions $requestOptions = null - ): UnifiedResponse { - [$parsed, $options] = CasParserSmartParseParams::parseRequest( - $params, - $requestOptions - ); - - // @phpstan-ignore-next-line; - return $this->client->request( - method: 'post', - path: 'v4/smart/parse', - body: (object) $parsed, - options: $options, - convert: UnifiedResponse::class, - ); - } -} diff --git a/src/Services/Cdsl/FetchRawService.php b/src/Services/Cdsl/FetchRawService.php new file mode 100644 index 0000000..2bfe8d6 --- /dev/null +++ b/src/Services/Cdsl/FetchRawService.php @@ -0,0 +1,103 @@ + + * + * @throws APIException + */ + public function requestOtp( + array|FetchRequestOtpParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = FetchRequestOtpParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/cdsl/fetch', + body: (object) $parsed, + options: $options, + convert: FetchRequestOtpResponse::class, + ); + } + + /** + * @api + * + * **Step 2 of 2**: Verify OTP and retrieve CDSL CAS files. + * + * After successful verification, CAS PDFs are fetched from CDSL portal, + * uploaded to cloud storage, and returned as direct download URLs. + * + * @param string $sessionID Session ID from Step 1 + * @param array{otp: string, numPeriods?: int}|FetchVerifyOtpParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function verifyOtp( + string $sessionID, + array|FetchVerifyOtpParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = FetchVerifyOtpParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: ['v4/cdsl/fetch/%1$s/verify', $sessionID], + body: (object) $parsed, + options: $options, + convert: FetchVerifyOtpResponse::class, + ); + } +} diff --git a/src/Services/Cdsl/FetchService.php b/src/Services/Cdsl/FetchService.php new file mode 100644 index 0000000..8902a56 --- /dev/null +++ b/src/Services/Cdsl/FetchService.php @@ -0,0 +1,96 @@ +raw = new FetchRawService($client); + } + + /** + * @api + * + * **Step 1 of 2**: Request OTP for CDSL CAS fetch. + * + * This endpoint: + * 1. Solves reCAPTCHA automatically (~15-20 seconds) + * 2. Submits login credentials to CDSL portal + * 3. Triggers OTP to user's registered mobile number + * + * After user receives OTP, call `/v4/cdsl/fetch/{session_id}/verify` to complete. + * + * @param string $boID CDSL BO ID (16 digits) + * @param string $dob Date of birth (YYYY-MM-DD) + * @param string $pan PAN number + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function requestOtp( + string $boID, + string $dob, + string $pan, + RequestOptions|array|null $requestOptions = null, + ): FetchRequestOtpResponse { + $params = Util::removeNulls( + ['boID' => $boID, 'dob' => $dob, 'pan' => $pan] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->requestOtp(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * **Step 2 of 2**: Verify OTP and retrieve CDSL CAS files. + * + * After successful verification, CAS PDFs are fetched from CDSL portal, + * uploaded to cloud storage, and returned as direct download URLs. + * + * @param string $sessionID Session ID from Step 1 + * @param string $otp OTP received on mobile + * @param int $numPeriods Number of monthly statements to fetch (default 6) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function verifyOtp( + string $sessionID, + string $otp, + int $numPeriods = 6, + RequestOptions|array|null $requestOptions = null, + ): FetchVerifyOtpResponse { + $params = Util::removeNulls(['otp' => $otp, 'numPeriods' => $numPeriods]); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->verifyOtp($sessionID, params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/CdslRawService.php b/src/Services/CdslRawService.php new file mode 100644 index 0000000..ba008f4 --- /dev/null +++ b/src/Services/CdslRawService.php @@ -0,0 +1,59 @@ + + * + * @throws APIException + */ + public function parsePdf( + array|CdslParsePdfParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = CdslParsePdfParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/cdsl/parse', + body: (object) $parsed, + options: $options, + convert: UnifiedResponse::class, + ); + } +} diff --git a/src/Services/CdslService.php b/src/Services/CdslService.php new file mode 100644 index 0000000..140e22c --- /dev/null +++ b/src/Services/CdslService.php @@ -0,0 +1,67 @@ +raw = new CdslRawService($client); + $this->fetch = new FetchService($client); + } + + /** + * @api + * + * This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. + * Use this endpoint when you know the PDF is from CDSL. + * + * @param string $password Password for the PDF file (if required) + * @param string $pdfFile Base64 encoded CAS PDF file (required if pdf_url not provided) + * @param string $pdfURL URL to the CAS PDF file (required if pdf_file not provided) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parsePdf( + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): UnifiedResponse { + $params = Util::removeNulls( + ['password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->parsePdf(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/ContractNoteRawService.php b/src/Services/ContractNoteRawService.php new file mode 100644 index 0000000..fcf863b --- /dev/null +++ b/src/Services/ContractNoteRawService.php @@ -0,0 +1,84 @@ +, + * password?: string, + * pdfFile?: string, + * pdfURL?: string, + * }|ContractNoteParseParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function parse( + array|ContractNoteParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = ContractNoteParseParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/contract_note/parse', + body: (object) $parsed, + options: $options, + convert: ContractNoteParseResponse::class, + ); + } +} diff --git a/src/Services/ContractNoteService.php b/src/Services/ContractNoteService.php new file mode 100644 index 0000000..fd8756f --- /dev/null +++ b/src/Services/ContractNoteService.php @@ -0,0 +1,89 @@ +raw = new ContractNoteRawService($client); + } + + /** + * @api + * + * This endpoint parses Contract Note PDF files from various brokers including Zerodha, Groww, Upstox, ICICI Securities, and others. + * + * **What is a Contract Note?** + * A contract note is a legal document that provides details of all trades executed by an investor. It includes: + * - Trade details with timestamps, quantities, and prices + * - Brokerage and charges breakdown + * - Settlement information + * - Regulatory compliance details + * + * **Supported Brokers:** + * - Zerodha Broking Limited + * - Groww Invest Tech Private Limited + * - Upstox (RKSV Securities) + * - ICICI Securities Limited + * - Auto-detection for unknown brokers + * + * **Key Features:** + * - **Auto-detection**: Automatically identifies broker type from PDF content + * - **Comprehensive parsing**: Extracts equity transactions, derivatives transactions, detailed trades, and charges + * - **Flexible input**: Accepts both file upload and URL-based PDF input + * - **Password protection**: Supports password-protected PDFs + * + * The API returns structured data including contract note information, client details, transaction summaries, and detailed trade-by-trade breakdowns. + * + * @param BrokerType|value-of $brokerType Optional broker type override. If not provided, system will auto-detect. + * @param string $password Password for the PDF file (usually PAN number for Zerodha) + * @param string $pdfFile Base64 encoded contract note PDF file + * @param string $pdfURL URL to the contract note PDF file + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parse( + BrokerType|string|null $brokerType = null, + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): ContractNoteParseResponse { + $params = Util::removeNulls( + [ + 'brokerType' => $brokerType, + 'password' => $password, + 'pdfFile' => $pdfFile, + 'pdfURL' => $pdfURL, + ], + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->parse(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/CreditsRawService.php b/src/Services/CreditsRawService.php new file mode 100644 index 0000000..a3432b2 --- /dev/null +++ b/src/Services/CreditsRawService.php @@ -0,0 +1,54 @@ + + * + * @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 new file mode 100644 index 0000000..4bde97a --- /dev/null +++ b/src/Services/CreditsService.php @@ -0,0 +1,55 @@ +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/InboxRawService.php b/src/Services/InboxRawService.php new file mode 100644 index 0000000..f4ff99a --- /dev/null +++ b/src/Services/InboxRawService.php @@ -0,0 +1,207 @@ + + * + * @throws APIException + */ + public function checkConnectionStatus( + array|InboxCheckConnectionStatusParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboxCheckConnectionStatusParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/inbox/status', + headers: Util::array_transform_keys( + $parsed, + ['xInboxToken' => 'x-inbox-token'] + ), + options: $options, + convert: InboxCheckConnectionStatusResponse::class, + ); + } + + /** + * @api + * + * Initiate OAuth flow to connect user's email inbox. + * + * Returns an `oauth_url` that you should redirect the user to. After authorization, + * they are redirected back to your `redirect_uri` with the following query parameters: + * + * **On success:** + * - `inbox_token` - Encrypted token to store client-side + * - `email` - Email address of the connected account + * - `state` - Your original state parameter (for CSRF verification) + * + * **On error:** + * - `error` - Error code (e.g., `access_denied`, `token_exchange_failed`) + * - `state` - Your original state parameter + * + * **Store the `inbox_token` client-side** and use it for all subsequent inbox API calls. + * + * @param array{ + * redirectUri: string, state?: string + * }|InboxConnectEmailParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function connectEmail( + array|InboxConnectEmailParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboxConnectEmailParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/inbox/connect', + body: (object) $parsed, + options: $options, + convert: InboxConnectEmailResponse::class, + ); + } + + /** + * @api + * + * Revoke email access and invalidate the token. + * + * This calls the provider's token revocation API (e.g., Google's revoke endpoint) + * to ensure the user's consent is properly removed. + * + * After calling this, the `inbox_token` becomes unusable. + * + * @param array{xInboxToken: string}|InboxDisconnectEmailParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function disconnectEmail( + array|InboxDisconnectEmailParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboxDisconnectEmailParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/inbox/disconnect', + headers: Util::array_transform_keys( + $parsed, + ['xInboxToken' => 'x-inbox-token'] + ), + options: $options, + convert: InboxDisconnectEmailResponse::class, + ); + } + + /** + * @api + * + * Search the user's email inbox for CAS files from known senders + * (CAMS, KFintech, CDSL, NSDL). + * + * Files are uploaded to temporary cloud storage. **URLs expire in 24 hours.** + * + * Optionally filter by CAS provider and date range. + * + * **Billing:** 0.2 credits per request (charged regardless of success or number of files found). + * + * @param array{ + * xInboxToken: string, + * casTypes?: list>, + * endDate?: string, + * startDate?: string, + * }|InboxListCasFilesParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function listCasFiles( + array|InboxListCasFilesParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboxListCasFilesParams::parseRequest( + $params, + $requestOptions, + ); + $header_params = ['xInboxToken' => 'x-inbox-token']; + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/inbox/cas', + headers: Util::array_transform_keys( + array_intersect_key($parsed, array_flip(array_keys($header_params))), + $header_params, + ), + body: (object) array_diff_key( + $parsed, + array_flip(array_keys($header_params)) + ), + options: $options, + convert: InboxListCasFilesResponse::class, + ); + } +} diff --git a/src/Services/InboxService.php b/src/Services/InboxService.php new file mode 100644 index 0000000..f213f62 --- /dev/null +++ b/src/Services/InboxService.php @@ -0,0 +1,173 @@ +raw = new InboxRawService($client); + } + + /** + * @api + * + * Verify if an `inbox_token` is still valid and check connection status. + * + * Use this to check if the user needs to re-authenticate (e.g., if they + * revoked access in their email provider settings). + * + * @param string $xInboxToken The encrypted inbox token + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function checkConnectionStatus( + string $xInboxToken, + RequestOptions|array|null $requestOptions = null + ): InboxCheckConnectionStatusResponse { + $params = Util::removeNulls(['xInboxToken' => $xInboxToken]); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->checkConnectionStatus(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Initiate OAuth flow to connect user's email inbox. + * + * Returns an `oauth_url` that you should redirect the user to. After authorization, + * they are redirected back to your `redirect_uri` with the following query parameters: + * + * **On success:** + * - `inbox_token` - Encrypted token to store client-side + * - `email` - Email address of the connected account + * - `state` - Your original state parameter (for CSRF verification) + * + * **On error:** + * - `error` - Error code (e.g., `access_denied`, `token_exchange_failed`) + * - `state` - Your original state parameter + * + * **Store the `inbox_token` client-side** and use it for all subsequent inbox API calls. + * + * @param string $redirectUri Your callback URL to receive the inbox_token (must be http or https) + * @param string $state State parameter for CSRF protection (returned in redirect) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function connectEmail( + string $redirectUri, + ?string $state = null, + RequestOptions|array|null $requestOptions = null, + ): InboxConnectEmailResponse { + $params = Util::removeNulls( + ['redirectUri' => $redirectUri, 'state' => $state] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->connectEmail(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Revoke email access and invalidate the token. + * + * This calls the provider's token revocation API (e.g., Google's revoke endpoint) + * to ensure the user's consent is properly removed. + * + * After calling this, the `inbox_token` becomes unusable. + * + * @param string $xInboxToken The encrypted inbox token to revoke + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function disconnectEmail( + string $xInboxToken, + RequestOptions|array|null $requestOptions = null + ): InboxDisconnectEmailResponse { + $params = Util::removeNulls(['xInboxToken' => $xInboxToken]); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->disconnectEmail(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Search the user's email inbox for CAS files from known senders + * (CAMS, KFintech, CDSL, NSDL). + * + * Files are uploaded to temporary cloud storage. **URLs expire in 24 hours.** + * + * Optionally filter by CAS provider and date range. + * + * **Billing:** 0.2 credits per request (charged regardless of success or number of files found). + * + * @param string $xInboxToken Header param: The encrypted inbox token + * @param list> $casTypes Body param: Filter by CAS provider(s): + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * @param string $endDate Body param: End date in ISO format (YYYY-MM-DD). Defaults to today. + * @param string $startDate Body param: Start date in ISO format (YYYY-MM-DD). Defaults to 30 days ago. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function listCasFiles( + string $xInboxToken, + ?array $casTypes = null, + ?string $endDate = null, + ?string $startDate = null, + RequestOptions|array|null $requestOptions = null, + ): InboxListCasFilesResponse { + $params = Util::removeNulls( + [ + 'xInboxToken' => $xInboxToken, + 'casTypes' => $casTypes, + 'endDate' => $endDate, + 'startDate' => $startDate, + ], + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->listCasFiles(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/KfintechRawService.php b/src/Services/KfintechRawService.php new file mode 100644 index 0000000..e60f0a5 --- /dev/null +++ b/src/Services/KfintechRawService.php @@ -0,0 +1,65 @@ + + * + * @throws APIException + */ + public function generateCas( + array|KfintechGenerateCasParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = KfintechGenerateCasParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/kfintech/generate', + body: (object) $parsed, + options: $options, + convert: KfintechGenerateCasResponse::class, + ); + } +} diff --git a/src/Services/KfintechService.php b/src/Services/KfintechService.php new file mode 100644 index 0000000..61e3f13 --- /dev/null +++ b/src/Services/KfintechService.php @@ -0,0 +1,72 @@ +raw = new KfintechRawService($client); + } + + /** + * @api + * + * Generate CAS via KFintech mailback. The CAS PDF will be sent to the investor's email. + * + * This is an async operation - the investor receives the CAS via email within a few minutes. + * For instant CAS retrieval, use CDSL Fetch (`/v4/cdsl/fetch`). + * + * @param string $email Email address to receive the CAS document + * @param string $fromDate Start date (YYYY-MM-DD) + * @param string $password Password for the PDF + * @param string $toDate End date (YYYY-MM-DD) + * @param string $panNo PAN number (optional) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function generateCas( + string $email, + string $fromDate, + string $password, + string $toDate, + ?string $panNo = null, + RequestOptions|array|null $requestOptions = null, + ): KfintechGenerateCasResponse { + $params = Util::removeNulls( + [ + 'email' => $email, + 'fromDate' => $fromDate, + 'password' => $password, + 'toDate' => $toDate, + 'panNo' => $panNo, + ], + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->generateCas(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/LogsRawService.php b/src/Services/LogsRawService.php new file mode 100644 index 0000000..4048e37 --- /dev/null +++ b/src/Services/LogsRawService.php @@ -0,0 +1,98 @@ + + * + * @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 new file mode 100644 index 0000000..03336f0 --- /dev/null +++ b/src/Services/LogsService.php @@ -0,0 +1,91 @@ +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/NsdlRawService.php b/src/Services/NsdlRawService.php new file mode 100644 index 0000000..12919b7 --- /dev/null +++ b/src/Services/NsdlRawService.php @@ -0,0 +1,59 @@ + + * + * @throws APIException + */ + public function parse( + array|NsdlParseParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = NsdlParseParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/nsdl/parse', + body: (object) $parsed, + options: $options, + convert: UnifiedResponse::class, + ); + } +} diff --git a/src/Services/NsdlService.php b/src/Services/NsdlService.php new file mode 100644 index 0000000..d5cf01c --- /dev/null +++ b/src/Services/NsdlService.php @@ -0,0 +1,60 @@ +raw = new NsdlRawService($client); + } + + /** + * @api + * + * This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns data in a unified format. + * Use this endpoint when you know the PDF is from NSDL. + * + * @param string $password Password for the PDF file (if required) + * @param string $pdfFile Base64 encoded CAS PDF file (required if pdf_url not provided) + * @param string $pdfURL URL to the CAS PDF file (required if pdf_file not provided) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parse( + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): UnifiedResponse { + $params = Util::removeNulls( + ['password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->parse(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/SmartRawService.php b/src/Services/SmartRawService.php new file mode 100644 index 0000000..508068c --- /dev/null +++ b/src/Services/SmartRawService.php @@ -0,0 +1,59 @@ + + * + * @throws APIException + */ + public function parseCasPdf( + array|SmartParseCasPdfParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = SmartParseCasPdfParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/smart/parse', + body: (object) $parsed, + options: $options, + convert: UnifiedResponse::class, + ); + } +} diff --git a/src/Services/SmartService.php b/src/Services/SmartService.php new file mode 100644 index 0000000..76026dd --- /dev/null +++ b/src/Services/SmartService.php @@ -0,0 +1,60 @@ +raw = new SmartRawService($client); + } + + /** + * @api + * + * This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or CAMS/KFintech and returns data in a unified format. + * It auto-detects the CAS type and transforms the data into a consistent structure regardless of the source. + * + * @param string $password Password for the PDF file (if required) + * @param string $pdfFile Base64 encoded CAS PDF file (required if pdf_url not provided) + * @param string $pdfURL URL to the CAS PDF file (required if pdf_file not provided) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function parseCasPdf( + ?string $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null, + RequestOptions|array|null $requestOptions = null, + ): UnifiedResponse { + $params = Util::removeNulls( + ['password' => $password, 'pdfFile' => $pdfFile, 'pdfURL' => $pdfURL] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->parseCasPdf(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/VerifyTokenRawService.php b/src/Services/VerifyTokenRawService.php new file mode 100644 index 0000000..f7504bb --- /dev/null +++ b/src/Services/VerifyTokenRawService.php @@ -0,0 +1,48 @@ + + * + * @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 new file mode 100644 index 0000000..9c1094d --- /dev/null +++ b/src/Services/VerifyTokenService.php @@ -0,0 +1,49 @@ +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/Smart/SmartParseCasPdfParams.php b/src/Smart/SmartParseCasPdfParams.php new file mode 100644 index 0000000..4ee219d --- /dev/null +++ b/src/Smart/SmartParseCasPdfParams.php @@ -0,0 +1,102 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Password for the PDF file (if required). + */ + #[Optional] + public ?string $password; + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + #[Optional('pdf_file')] + public ?string $pdfFile; + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + #[Optional('pdf_url')] + public ?string $pdfURL; + + 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 $password = null, + ?string $pdfFile = null, + ?string $pdfURL = null + ): self { + $self = new self; + + null !== $password && $self['password'] = $password; + null !== $pdfFile && $self['pdfFile'] = $pdfFile; + null !== $pdfURL && $self['pdfURL'] = $pdfURL; + + return $self; + } + + /** + * Password for the PDF file (if required). + */ + public function withPassword(string $password): self + { + $self = clone $this; + $self['password'] = $password; + + return $self; + } + + /** + * Base64 encoded CAS PDF file (required if pdf_url not provided). + */ + public function withPdfFile(string $pdfFile): self + { + $self = clone $this; + $self['pdfFile'] = $pdfFile; + + return $self; + } + + /** + * URL to the CAS PDF file (required if pdf_file not provided). + */ + public function withPdfURL(string $pdfURL): self + { + $self = clone $this; + $self['pdfURL'] = $pdfURL; + + return $self; + } +} 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/src/Version.php b/src/Version.php new file mode 100644 index 0000000..e05c34e --- /dev/null +++ b/src/Version.php @@ -0,0 +1,9 @@ +createResponse() + ->withStatus(200) + ->withHeader('Content-Type', 'application/json') + ->withBody(Psr17FactoryDiscovery::findStreamFactory()->createStream(json_encode([], flags: Util::JSON_ENCODE_FLAGS) ?: '')) + ; + + $transporter->setDefaultResponse($mockRsp); + + $client = new \CasParser\Client( + baseUrl: 'http://localhost', + apiKey: 'My API Key', + requestOptions: ['transporter' => $transporter], + ); + + $client->credits->check(); + + $this->assertNotFalse($requested = $transporter->getRequests()[0] ?? false); + + foreach (['accept', 'content-type'] as $header) { + $sent = $requested->getHeaderLine($header); + $this->assertNotEmpty($sent); + } + } +} diff --git a/tests/Core/TestModel.php b/tests/Core/ModelTest.php similarity index 68% rename from tests/Core/TestModel.php rename to tests/Core/ModelTest.php index 4d24c06..033b9d1 100644 --- a/tests/Core/TestModel.php +++ b/tests/Core/ModelTest.php @@ -2,29 +2,30 @@ namespace Tests\Core; -use CasParser\Core\Attributes\Api; +use CasParser\Core\Attributes\Optional; +use CasParser\Core\Attributes\Required; use CasParser\Core\Concerns\SdkModel; use CasParser\Core\Contracts\BaseModel; use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; -class TestModel implements BaseModel +class Dog implements BaseModel { /** @use SdkModel> */ use SdkModel; - #[Api] + #[Required] public string $name; - #[Api('age_years')] + #[Required('age_years')] public int $ageYears; /** @var list|null */ - #[Api(optional: true)] + #[Optional] public ?array $friends; - #[Api] + #[Required] public ?string $owner; /** @@ -42,7 +43,7 @@ public function __construct( $this->ageYears = $ageYears; $this->owner = $owner; - null != $friends && $this->friends = $friends; + null !== $friends && $this['friends'] = $friends; } } @@ -52,16 +53,12 @@ public function __construct( * @coversNothing */ #[CoversNothing] -class TestModelTest extends TestCase +class ModelTest extends TestCase { #[Test] public function testBasicGetAndSet(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $this->assertEquals(12, $model->ageYears); ++$model->ageYears; @@ -71,11 +68,7 @@ public function testBasicGetAndSet(): void #[Test] public function testNullAccess(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $this->assertNull($model->owner); $this->assertNull($model->friends); } @@ -83,11 +76,7 @@ public function testNullAccess(): void #[Test] public function testArrayGetAndSet(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $model->friends ??= []; $this->assertEquals([], $model->friends); $model->friends[] = 'Alice'; @@ -97,16 +86,8 @@ public function testArrayGetAndSet(): void #[Test] public function testDiscernsBetweenNullAndUnset(): void { - $modelUnsetFriends = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); - $modelNullFriends = new TestModel( - name: 'bob', - ageYears: 12, - owner: null, - ); + $modelUnsetFriends = new Dog(name: 'Bob', ageYears: 12, owner: null); + $modelNullFriends = new Dog(name: 'bob', ageYears: 12, owner: null); $modelNullFriends->friends = null; $this->assertEquals(12, $modelUnsetFriends->ageYears); @@ -125,11 +106,7 @@ public function testDiscernsBetweenNullAndUnset(): void #[Test] public function testIssetOnOmittedProperties(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $this->assertFalse(isset($model->owner)); $this->assertFalse(isset($model->friends)); } @@ -137,12 +114,7 @@ public function testIssetOnOmittedProperties(): void #[Test] public function testSerializeBasicModel(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: 'Eve', - friends: ['Alice', 'Charlie'], - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: 'Eve', friends: ['Alice', 'Charlie']); $this->assertEquals( '{"name":"Bob","age_years":12,"friends":["Alice","Charlie"],"owner":"Eve"}', json_encode($model) @@ -152,11 +124,7 @@ public function testSerializeBasicModel(): void #[Test] public function testSerializeModelWithOmittedProperties(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $this->assertEquals( '{"name":"Bob","age_years":12,"owner":null}', json_encode($model) @@ -166,11 +134,7 @@ public function testSerializeModelWithOmittedProperties(): void #[Test] public function testSerializeModelWithExplicitNull(): void { - $model = new TestModel( - name: 'Bob', - ageYears: 12, - owner: null, - ); + $model = new Dog(name: 'Bob', ageYears: 12, owner: null); $model->friends = null; $this->assertEquals( '{"name":"Bob","age_years":12,"friends":null,"owner":null}', diff --git a/tests/Core/UtilTest.php b/tests/Core/UtilTest.php new file mode 100644 index 0000000..2134876 --- /dev/null +++ b/tests/Core/UtilTest.php @@ -0,0 +1,90 @@ + $v, + ], + [ + ['a' => null, 'b' => [null, null], 'c' => ['d' => null, 'e' => 0], 'f' => ['g' => null]], + ['b' => [null, null], 'c' => ['e' => 0], 'f' => []], + static fn ($vs) => is_array($vs) && !array_is_list($vs) ? array_filter($vs, callback: static fn ($v) => !is_null($v)) : $vs, + ], + [ + ['a' => null, 'b' => 2, 'c' => true, 'd' => [1, 2]], + ['a' => null, 'b' => '2', 'c' => true, 'd' => ['1', '2']], + static fn ($v) => is_bool($v) || is_numeric($v) ? Util::strVal($v) : $v, + ], + ]; + + foreach ($cases as [$input, $expected, $xform]) { + $actual = Util::mapRecursive($xform, value: $input); + $this->assertEquals($expected, $actual); + } + } + + #[Test] + public function testJoinUri(): void + { + $factory = Psr17FactoryDiscovery::findUriFactory(); + $base = $factory->createUri('http://localhost'); + $cases = [ + [ + '', + [], + 'http://localhost', + ], + [ + 'dog', + [], + 'http://localhost/dog', + ], + [ + '', + ['dog' => 'dog'], + 'http://localhost?dog=dog', + ], + [ + '', + ['dog' => ['dog']], + 'http://localhost?dog[0]=dog', + ], + [ + '', + ['dog' => [true, false]], + 'http://localhost?dog[0]=true&dog[1]=false', + ], + [ + '', + ['dog' => ['dog' => ['dog']]], + 'http://localhost?dog[dog][0]=dog', + ], + ]; + + foreach ($cases as [$path, $query, $output]) { + $expected = $factory->createUri($output); + $actual = Util::joinUri($base, path: $path, query: $query); + $this->assertEquals($expected, $actual); + } + } +} diff --git a/tests/Services/AccessTokenTest.php b/tests/Services/AccessTokenTest.php new file mode 100644 index 0000000..d46346f --- /dev/null +++ b/tests/Services/AccessTokenTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->accessToken->create(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(AccessTokenNewResponse::class, $result); + } +} diff --git a/tests/Services/CamsKfintechTest.php b/tests/Services/CamsKfintechTest.php new file mode 100644 index 0000000..bd5095b --- /dev/null +++ b/tests/Services/CamsKfintechTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testParse(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->camsKfintech->parse(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(UnifiedResponse::class, $result); + } +} diff --git a/tests/Services/CasParserTest.php b/tests/Services/CasParserTest.php deleted file mode 100644 index 17f3bb6..0000000 --- a/tests/Services/CasParserTest.php +++ /dev/null @@ -1,76 +0,0 @@ -client = $client; - } - - #[Test] - public function testCamsKfintech(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); - } - - $result = $this->client->casParser->camsKfintech(); - - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType - } - - #[Test] - public function testCdsl(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); - } - - $result = $this->client->casParser->cdsl(); - - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType - } - - #[Test] - public function testNsdl(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); - } - - $result = $this->client->casParser->nsdl(); - - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType - } - - #[Test] - public function testSmartParse(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); - } - - $result = $this->client->casParser->smartParse(); - - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType - } -} diff --git a/tests/Services/Cdsl/FetchTest.php b/tests/Services/Cdsl/FetchTest.php new file mode 100644 index 0000000..64a2678 --- /dev/null +++ b/tests/Services/Cdsl/FetchTest.php @@ -0,0 +1,98 @@ +client = $client; + } + + #[Test] + public function testRequestOtp(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->cdsl->fetch->requestOtp( + boID: '1234567890123456', + dob: '1990-01-15', + pan: 'ABCDE1234F' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(FetchRequestOtpResponse::class, $result); + } + + #[Test] + public function testRequestOtpWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->cdsl->fetch->requestOtp( + boID: '1234567890123456', + dob: '1990-01-15', + pan: 'ABCDE1234F' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(FetchRequestOtpResponse::class, $result); + } + + #[Test] + public function testVerifyOtp(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->cdsl->fetch->verifyOtp( + 'session_id', + otp: '123456' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(FetchVerifyOtpResponse::class, $result); + } + + #[Test] + public function testVerifyOtpWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->cdsl->fetch->verifyOtp( + 'session_id', + otp: '123456', + numPeriods: 6 + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(FetchVerifyOtpResponse::class, $result); + } +} diff --git a/tests/Services/CdslTest.php b/tests/Services/CdslTest.php new file mode 100644 index 0000000..ba35fd5 --- /dev/null +++ b/tests/Services/CdslTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testParsePdf(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->cdsl->parsePdf(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(UnifiedResponse::class, $result); + } +} diff --git a/tests/Services/ContractNoteTest.php b/tests/Services/ContractNoteTest.php new file mode 100644 index 0000000..57f171b --- /dev/null +++ b/tests/Services/ContractNoteTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testParse(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->contractNote->parse(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(ContractNoteParseResponse::class, $result); + } +} diff --git a/tests/Services/CreditsTest.php b/tests/Services/CreditsTest.php new file mode 100644 index 0000000..c658279 --- /dev/null +++ b/tests/Services/CreditsTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testCheck(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->credits->check(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(CreditCheckResponse::class, $result); + } +} diff --git a/tests/Services/InboxTest.php b/tests/Services/InboxTest.php new file mode 100644 index 0000000..236a1aa --- /dev/null +++ b/tests/Services/InboxTest.php @@ -0,0 +1,155 @@ +client = $client; + } + + #[Test] + public function testCheckConnectionStatus(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->checkConnectionStatus( + xInboxToken: 'x-inbox-token' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxCheckConnectionStatusResponse::class, $result); + } + + #[Test] + public function testCheckConnectionStatusWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->checkConnectionStatus( + xInboxToken: 'x-inbox-token' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxCheckConnectionStatusResponse::class, $result); + } + + #[Test] + public function testConnectEmail(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->connectEmail( + redirectUri: 'https://yourapp.com/oauth-callback' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxConnectEmailResponse::class, $result); + } + + #[Test] + public function testConnectEmailWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->connectEmail( + redirectUri: 'https://yourapp.com/oauth-callback', + state: 'abc123' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxConnectEmailResponse::class, $result); + } + + #[Test] + public function testDisconnectEmail(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->disconnectEmail( + xInboxToken: 'x-inbox-token' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxDisconnectEmailResponse::class, $result); + } + + #[Test] + public function testDisconnectEmailWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->disconnectEmail( + xInboxToken: 'x-inbox-token' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxDisconnectEmailResponse::class, $result); + } + + #[Test] + public function testListCasFiles(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->listCasFiles(xInboxToken: 'x-inbox-token'); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxListCasFilesResponse::class, $result); + } + + #[Test] + public function testListCasFilesWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->inbox->listCasFiles( + xInboxToken: 'x-inbox-token', + casTypes: ['cdsl', 'nsdl'], + endDate: '2025-12-31', + startDate: '2025-12-01', + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboxListCasFilesResponse::class, $result); + } +} diff --git a/tests/Services/CasGeneratorTest.php b/tests/Services/KfintechTest.php similarity index 65% rename from tests/Services/CasGeneratorTest.php rename to tests/Services/KfintechTest.php index ac566d8..d181b1d 100644 --- a/tests/Services/CasGeneratorTest.php +++ b/tests/Services/KfintechTest.php @@ -3,6 +3,8 @@ namespace Tests\Services; use CasParser\Client; +use CasParser\Core\Util; +use CasParser\Kfintech\KfintechGenerateCasResponse; use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; @@ -12,7 +14,7 @@ * @internal */ #[CoversNothing] -final class CasGeneratorTest extends TestCase +final class KfintechTest extends TestCase { protected Client $client; @@ -20,7 +22,7 @@ protected function setUp(): void { parent::setUp(); - $testUrl = getenv('TEST_API_BASE_URL') ?: 'http://127.0.0.1:4010'; + $testUrl = Util::getenv('TEST_API_BASE_URL') ?: 'http://127.0.0.1:4010'; $client = new Client(apiKey: 'My API Key', baseUrl: $testUrl); $this->client = $client; @@ -33,14 +35,15 @@ public function testGenerateCas(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this->client->casGenerator->generateCas( + $result = $this->client->kfintech->generateCas( email: 'user@example.com', fromDate: '2023-01-01', password: 'Abcdefghi12$', toDate: '2023-12-31', ); - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(KfintechGenerateCasResponse::class, $result); } #[Test] @@ -50,13 +53,15 @@ public function testGenerateCasWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this->client->casGenerator->generateCas( + $result = $this->client->kfintech->generateCas( email: 'user@example.com', fromDate: '2023-01-01', password: 'Abcdefghi12$', toDate: '2023-12-31', + panNo: 'ABCDE1234F', ); - $this->assertTrue(true); // @phpstan-ignore method.alreadyNarrowedType + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(KfintechGenerateCasResponse::class, $result); } } diff --git a/tests/Services/LogsTest.php b/tests/Services/LogsTest.php new file mode 100644 index 0000000..fefa01f --- /dev/null +++ b/tests/Services/LogsTest.php @@ -0,0 +1,57 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism 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('Prism tests are disabled'); + } + + $result = $this->client->logs->getSummary(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(LogGetSummaryResponse::class, $result); + } +} diff --git a/tests/Services/NsdlTest.php b/tests/Services/NsdlTest.php new file mode 100644 index 0000000..ba72197 --- /dev/null +++ b/tests/Services/NsdlTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testParse(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->nsdl->parse(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(UnifiedResponse::class, $result); + } +} diff --git a/tests/Services/SmartTest.php b/tests/Services/SmartTest.php new file mode 100644 index 0000000..95305b4 --- /dev/null +++ b/tests/Services/SmartTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testParseCasPdf(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->smart->parseCasPdf(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(UnifiedResponse::class, $result); + } +} diff --git a/tests/Services/VerifyTokenTest.php b/tests/Services/VerifyTokenTest.php new file mode 100644 index 0000000..16b7649 --- /dev/null +++ b/tests/Services/VerifyTokenTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testVerify(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Prism tests are disabled'); + } + + $result = $this->client->verifyToken->verify(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(VerifyTokenVerifyResponse::class, $result); + } +}