From 2a2aebedacb48bcf3e1b7d9fd2477f03d48a5bb9 Mon Sep 17 00:00:00 2001 From: EgorMajj <91486022+EgorMajj@users.noreply.github.com> Date: Thu, 1 Oct 2026 20:00:44 +0300 Subject: [PATCH] Add an OpenAPI generator beside the supported client sync.sh downloads the current API description and generate.sh rebuilds generated/ from it. The library people install is unchanged. --- .gitattributes | 4 + .github/workflows/ci.yml | 12 + CHANGELOG.md | 6 + README.md | 8 + config.json | 9 + generate.sh | 69 + generated/.openapi-generator-ignore | 8 + generated/.openapi-generator/FILES | 26 + generated/.openapi-generator/VERSION | 1 + generated/.php-cs-fixer.dist.php | 29 + generated/composer.json | 39 + generated/lib/Api/HealthApi.php | 552 ++++ generated/lib/Api/HistoryAPIApi.php | 674 +++++ generated/lib/Api/ManagementAPIApi.php | 1082 ++++++++ generated/lib/ApiException.php | 120 + generated/lib/Configuration.php | 593 ++++ generated/lib/FormDataProcessor.php | 247 ++ generated/lib/HeaderSelector.php | 274 ++ generated/lib/Model/DetectionFlags.php | 1080 ++++++++ generated/lib/Model/DomainProfile.php | 617 +++++ generated/lib/Model/ErrorBody.php | 414 +++ generated/lib/Model/HealthStatus.php | 446 +++ generated/lib/Model/HistoryPage.php | 460 +++ generated/lib/Model/HistoryRow.php | 2317 ++++++++++++++++ .../lib/Model/IdentificationScoredData.php | 1068 +++++++ .../lib/Model/IdentificationScoredEvent.php | 575 ++++ generated/lib/Model/IpInfo.php | 460 +++ generated/lib/Model/LegacySnapshot.php | 1052 +++++++ generated/lib/Model/ModelInterface.php | 112 + generated/lib/Model/ScoreDetail.php | 451 +++ generated/lib/Model/Signal.php | 460 +++ generated/lib/Model/TrafficSource.php | 710 +++++ generated/lib/Model/WebhookPingEvent.php | 538 ++++ generated/lib/ObjectSerializer.php | 604 ++++ generated/phpunit.xml.dist | 18 + resources/shieldlabs-api.yaml | 2462 +++++++++++++++++ sync.sh | 15 + 37 files changed, 17612 insertions(+) create mode 100644 config.json create mode 100755 generate.sh create mode 100644 generated/.openapi-generator-ignore create mode 100644 generated/.openapi-generator/FILES create mode 100644 generated/.openapi-generator/VERSION create mode 100644 generated/.php-cs-fixer.dist.php create mode 100644 generated/composer.json create mode 100644 generated/lib/Api/HealthApi.php create mode 100644 generated/lib/Api/HistoryAPIApi.php create mode 100644 generated/lib/Api/ManagementAPIApi.php create mode 100644 generated/lib/ApiException.php create mode 100644 generated/lib/Configuration.php create mode 100644 generated/lib/FormDataProcessor.php create mode 100644 generated/lib/HeaderSelector.php create mode 100644 generated/lib/Model/DetectionFlags.php create mode 100644 generated/lib/Model/DomainProfile.php create mode 100644 generated/lib/Model/ErrorBody.php create mode 100644 generated/lib/Model/HealthStatus.php create mode 100644 generated/lib/Model/HistoryPage.php create mode 100644 generated/lib/Model/HistoryRow.php create mode 100644 generated/lib/Model/IdentificationScoredData.php create mode 100644 generated/lib/Model/IdentificationScoredEvent.php create mode 100644 generated/lib/Model/IpInfo.php create mode 100644 generated/lib/Model/LegacySnapshot.php create mode 100644 generated/lib/Model/ModelInterface.php create mode 100644 generated/lib/Model/ScoreDetail.php create mode 100644 generated/lib/Model/Signal.php create mode 100644 generated/lib/Model/TrafficSource.php create mode 100644 generated/lib/Model/WebhookPingEvent.php create mode 100644 generated/lib/ObjectSerializer.php create mode 100644 generated/phpunit.xml.dist create mode 100644 resources/shieldlabs-api.yaml create mode 100755 sync.sh diff --git a/.gitattributes b/.gitattributes index ef70083..30fbf30 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,3 +14,7 @@ /phpstan.neon.dist export-ignore /phpunit.xml.dist export-ignore /CONTRIBUTING.md export-ignore +generated/** linguist-generated +resources/shieldlabs-api.yaml linguist-generated +sync.sh text eol=lf +generate.sh text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2837a78..759d6f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,3 +62,15 @@ jobs: run: vendor/bin/php-cs-fixer check --diff - name: Coverage run: vendor/bin/phpunit --coverage-text --only-summary-for-coverage-text + + generated: + name: Generated API types + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 + with: + persist-credentials: false + - name: Rebuild generated files + run: ./generate.sh + - name: Fail if generated files drifted + run: git diff --exit-code diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5ac2e..3d01630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this package are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the package follows [Semantic Versioning](https://semver.org/). +## [Unreleased] + +### Added + +- `sync.sh` downloads the OpenAPI description and `generate.sh` rebuilds `generated/` from it. The supported client is unchanged. + ## [1.0.0] - 2026-09-30 First stable release, published as `shieldlabs/shieldlabs-php`. It replaces the diff --git a/README.md b/README.md index 5b529ea..ac3c58b 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,14 @@ Enums: `LookupType`, `RiskBand` (`Trusted`, `Suspicious`, `Dangerous`, `RateLimi ## Development +Refresh the generated client when the API description changes. This does not replace the supported library in this repository. + +```bash +./sync.sh # download the current OpenAPI description into resources/ +./generate.sh # rebuild generated/ from that file +``` + + ```bash composer install composer test # PHPUnit: unit, shared fixture and integration tests diff --git a/config.json b/config.json new file mode 100644 index 0000000..8f5cda9 --- /dev/null +++ b/config.json @@ -0,0 +1,9 @@ +{ + "invokerPackage": "ShieldLabs\\Generated", + "packageName": "ShieldLabsGenerated", + "composerPackageName": "shieldlabs/shieldlabs-php-generated", + "gitUserId": "ShieldLabs-ai", + "gitRepoId": "shieldlabs-php", + "developerOrganization": "ShieldLabs Inc.", + "hideGenerationTimestamp": true +} diff --git a/generate.sh b/generate.sh new file mode 100755 index 0000000..f76c440 --- /dev/null +++ b/generate.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")" + +if ! docker info >/dev/null 2>&1; then + echo "Docker is not running. Start Docker and run this script again." >&2 + exit 1 +fi + +generator="php" +image="openapitools/openapi-generator-cli:v7.23.0" +workdir="$(mktemp -d)" +trap 'rm -rf "$workdir"' EXIT + +python3 - "$PWD/resources/shieldlabs-api.yaml" "$workdir/spec.yaml" << 'PY' +import sys +from pathlib import Path + +source, dest = sys.argv[1:] +lines = Path(source).read_text().splitlines(keepends=True) +out = [] +i = 0 +while i < len(lines): + if lines[i].startswith(" description:"): + out.append(" description: Identification results and risk scoring for your backend.\n") + i += 1 + while i < len(lines) and not (lines[i].startswith(" ") and not lines[i].startswith(" ")): + i += 1 + continue + out.append(lines[i]) + i += 1 +Path(dest).write_text("".join(out)) +PY + +rm -rf generated +mkdir -p generated +cat > generated/.openapi-generator-ignore << 'IGN' +README.md +git_push.sh +.travis.yml +.gitignore +docs/ +test/ +api/openapi.yaml +.github/ +IGN + +docker run --rm -u "$(id -u):$(id -g)" \ + -v "$PWD":/local -v "$workdir":/work -w /local \ + "$image" generate \ + -i /work/spec.yaml \ + -g "$generator" \ + -o /local/generated \ + -c /local/config.json \ + --global-property apis,models,supportingFiles,modelTests=false,apiTests=false,modelDocs=false,apiDocs=false + +find generated \( -name README.md -o -name '*README.md' -o -name git_push.sh -o -name .travis.yml -o -name appveyor.yml -o -name .gitignore -o -name build.sbt -o -name '*.sln' \) -delete +rm -rf generated/docs generated/test generated/.github +find generated -type d -empty -delete + +if [ "$generator" = "go" ]; then + docker run --rm -u "$(id -u):$(id -g)" -v "$PWD/generated":/src -w /src golang:1.24-bookworm gofmt -w . + cat > generated/go.mod << 'MOD' +module github.com/ShieldLabs-ai/shieldlabs-go/generated + +go 1.23 +MOD +fi diff --git a/generated/.openapi-generator-ignore b/generated/.openapi-generator-ignore new file mode 100644 index 0000000..432ff52 --- /dev/null +++ b/generated/.openapi-generator-ignore @@ -0,0 +1,8 @@ +README.md +git_push.sh +.travis.yml +.gitignore +docs/ +test/ +api/openapi.yaml +.github/ diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES new file mode 100644 index 0000000..7042961 --- /dev/null +++ b/generated/.openapi-generator/FILES @@ -0,0 +1,26 @@ +.php-cs-fixer.dist.php +composer.json +lib/Api/HealthApi.php +lib/Api/HistoryAPIApi.php +lib/Api/ManagementAPIApi.php +lib/ApiException.php +lib/Configuration.php +lib/FormDataProcessor.php +lib/HeaderSelector.php +lib/Model/DetectionFlags.php +lib/Model/DomainProfile.php +lib/Model/ErrorBody.php +lib/Model/HealthStatus.php +lib/Model/HistoryPage.php +lib/Model/HistoryRow.php +lib/Model/IdentificationScoredData.php +lib/Model/IdentificationScoredEvent.php +lib/Model/IpInfo.php +lib/Model/LegacySnapshot.php +lib/Model/ModelInterface.php +lib/Model/ScoreDetail.php +lib/Model/Signal.php +lib/Model/TrafficSource.php +lib/Model/WebhookPingEvent.php +lib/ObjectSerializer.php +phpunit.xml.dist diff --git a/generated/.openapi-generator/VERSION b/generated/.openapi-generator/VERSION new file mode 100644 index 0000000..14d6b5d --- /dev/null +++ b/generated/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.23.0 diff --git a/generated/.php-cs-fixer.dist.php b/generated/.php-cs-fixer.dist.php new file mode 100644 index 0000000..af9cf39 --- /dev/null +++ b/generated/.php-cs-fixer.dist.php @@ -0,0 +1,29 @@ +in(__DIR__) + ->exclude('vendor') + ->exclude('test') + ->exclude('tests') +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + '@PSR12' => true, + 'phpdoc_order' => true, + 'array_syntax' => [ 'syntax' => 'short' ], + 'strict_comparison' => true, + 'strict_param' => true, + 'no_trailing_whitespace' => false, + 'no_trailing_whitespace_in_comment' => false, + 'braces' => false, + 'single_blank_line_at_eof' => false, + 'blank_line_after_namespace' => false, + 'no_leading_import_slash' => false, + ]) + ->setFinder($finder) +; diff --git a/generated/composer.json b/generated/composer.json new file mode 100644 index 0000000..a244907 --- /dev/null +++ b/generated/composer.json @@ -0,0 +1,39 @@ +{ + "name": "shieldlabs/shieldlabs-php-generated", + "description": "Identification results and risk scoring for your backend.", + "keywords": [ + "openapitools", + "openapi-generator", + "openapi", + "php", + "sdk", + "rest", + "api" + ], + "homepage": "https://openapi-generator.tech", + "license": "unlicense", + "authors": [ + { + "name": "ShieldLabs Inc.", + "homepage": "https://openapi-generator.tech" + } + ], + "require": { + "php": "^8.1", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^7.3", + "guzzlehttp/psr7": "^1.7 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0 || ^9.0", + "friendsofphp/php-cs-fixer": "^3.5" + }, + "autoload": { + "psr-4": { "ShieldLabs\\Generated\\" : "lib/" } + }, + "autoload-dev": { + "psr-4": { "ShieldLabs\\Generated\\Test\\" : "test/" } + } +} diff --git a/generated/lib/Api/HealthApi.php b/generated/lib/Api/HealthApi.php new file mode 100644 index 0000000..d403371 --- /dev/null +++ b/generated/lib/Api/HealthApi.php @@ -0,0 +1,552 @@ + [ + 'application/json', + ], + ]; + + /** + * @param ClientInterface $client + * @param Configuration $config + * @param HeaderSelector $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation getHealth + * + * Check service health + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * URL: https://api.shieldlabs.ai + * + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getHealth'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \ShieldLabs\Generated\Model\HealthStatus|string|string|string + */ + public function getHealth(?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getHealth'][0]) + { + list($response) = $this->getHealthWithHttpInfo($hostIndex, $variables, $contentType); + return $response; + } + + /** + * Operation getHealthWithHttpInfo + * + * Check service health + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * URL: https://api.shieldlabs.ai + * + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getHealth'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \ShieldLabs\Generated\Model\HealthStatus|string|string|string, HTTP status code, HTTP response headers (array of strings) + */ + public function getHealthWithHttpInfo(?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getHealth'][0]) + { + $request = $this->getHealthRequest($hostIndex, $variables, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\HealthStatus', + $request, + $response, + ); + case 404: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 502: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 504: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\HealthStatus', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\HealthStatus', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 404: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 502: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 504: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation getHealthAsync + * + * Check service health + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * URL: https://api.shieldlabs.ai + * + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getHealth'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function getHealthAsync(?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getHealth'][0]) + { + return $this->getHealthAsyncWithHttpInfo($hostIndex, $variables, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation getHealthAsyncWithHttpInfo + * + * Check service health + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * URL: https://api.shieldlabs.ai + * + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getHealth'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function getHealthAsyncWithHttpInfo(?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getHealth'][0]) + { + $returnType = '\ShieldLabs\Generated\Model\HealthStatus'; + $request = $this->getHealthRequest($hostIndex, $variables, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'getHealth' + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * URL: https://api.shieldlabs.ai + * + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getHealth'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function getHealthRequest(?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getHealth'][0]) + { + + + $resourcePath = '/health'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + + + $headers = $this->headerSelector->selectHeaders( + ['application/json', 'text/plain', 'text/html', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + # Preserve the original behavior of server indexing. + if ($hostIndex === null) { + $hostIndex = $this->hostIndex; + } + + $hostSettings = $this->getHostSettingsForgetHealth(); + + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new \InvalidArgumentException("Invalid index {$hostIndex} when selecting the host. Must be less than ".count($hostSettings)); + } + $operationHost = Configuration::getHostString($hostSettings, $hostIndex, $variables); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Returns an array of host settings for Operation getHealth + * + * @return array an array of host settings + */ + protected function getHostSettingsForgetHealth(): array + { + return [ + [ + "url" => "https://account.shieldlabs.ai", + "description" => "History API host", + ], + [ + "url" => "https://api.shieldlabs.ai", + "description" => "Management API host", + ] + ]; + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + if ($this->config->getCertFile()) { + $options[RequestOptions::CERT] = $this->config->getCertFile(); + } + + if ($this->config->getKeyFile()) { + $options[RequestOptions::SSL_KEY] = $this->config->getKeyFile(); + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response + ): array { + if ($dataType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/generated/lib/Api/HistoryAPIApi.php b/generated/lib/Api/HistoryAPIApi.php new file mode 100644 index 0000000..5bfcd1a --- /dev/null +++ b/generated/lib/Api/HistoryAPIApi.php @@ -0,0 +1,674 @@ + [ + 'application/json', + ], + ]; + + /** + * @param ClientInterface $client + * @param Configuration $config + * @param HeaderSelector $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation searchHistory + * + * Search identifications + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * + * @param string $search_type Identifier to search by. Only these seven values are supported: - `request_id`: one identification (read a verdict); - `device_id`: every identification of one device; - `user_hid`: every identification of one account; - `visitor_id`: every identification of one visitor; - `ip`: every identification from one public IPv4 address; - `session_id`: every identification of one visit; - `cookie_id`: every identification with one browser cookie. The server does not reject other values: it ignores them and returns the latest identifications of the whole domain, so restrict the value on your side. (required) + * @param string $value Value of the identifier, validated on your side before sending: - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, the nil UUID included, matching `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it lowercase. - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build this path yourself when yours does. A User HID that contains `/` cannot be searched, and most HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern rejects these values. Hex-encoded hashes need no escaping at all. The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. (required) + * @param int|null $limit Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. (optional, default to 20) + * @param int|null $offset Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`. (optional, default to 0) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistory'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \ShieldLabs\Generated\Model\HistoryPage|string|string|\ShieldLabs\Generated\Model\ErrorBody|\ShieldLabs\Generated\Model\ErrorBody|string|string + */ + public function searchHistory($search_type, $value, $limit = 20, $offset = 0, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistory'][0]) + { + list($response) = $this->searchHistoryWithHttpInfo($search_type, $value, $limit, $offset, $hostIndex, $variables, $contentType); + return $response; + } + + /** + * Operation searchHistoryWithHttpInfo + * + * Search identifications + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * + * @param string $search_type Identifier to search by. Only these seven values are supported: - `request_id`: one identification (read a verdict); - `device_id`: every identification of one device; - `user_hid`: every identification of one account; - `visitor_id`: every identification of one visitor; - `ip`: every identification from one public IPv4 address; - `session_id`: every identification of one visit; - `cookie_id`: every identification with one browser cookie. The server does not reject other values: it ignores them and returns the latest identifications of the whole domain, so restrict the value on your side. (required) + * @param string $value Value of the identifier, validated on your side before sending: - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, the nil UUID included, matching `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it lowercase. - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build this path yourself when yours does. A User HID that contains `/` cannot be searched, and most HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern rejects these values. Hex-encoded hashes need no escaping at all. The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. (required) + * @param int|null $limit Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. (optional, default to 20) + * @param int|null $offset Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`. (optional, default to 0) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistory'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \ShieldLabs\Generated\Model\HistoryPage|string|string|\ShieldLabs\Generated\Model\ErrorBody|\ShieldLabs\Generated\Model\ErrorBody|string|string, HTTP status code, HTTP response headers (array of strings) + */ + public function searchHistoryWithHttpInfo($search_type, $value, $limit = 20, $offset = 0, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistory'][0]) + { + $request = $this->searchHistoryRequest($search_type, $value, $limit, $offset, $hostIndex, $variables, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\HistoryPage', + $request, + $response, + ); + case 401: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 404: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 429: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 500: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 502: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 504: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\HistoryPage', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\HistoryPage', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 401: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 404: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 429: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 500: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 502: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 504: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation searchHistoryAsync + * + * Search identifications + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * + * @param string $search_type Identifier to search by. Only these seven values are supported: - `request_id`: one identification (read a verdict); - `device_id`: every identification of one device; - `user_hid`: every identification of one account; - `visitor_id`: every identification of one visitor; - `ip`: every identification from one public IPv4 address; - `session_id`: every identification of one visit; - `cookie_id`: every identification with one browser cookie. The server does not reject other values: it ignores them and returns the latest identifications of the whole domain, so restrict the value on your side. (required) + * @param string $value Value of the identifier, validated on your side before sending: - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, the nil UUID included, matching `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it lowercase. - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build this path yourself when yours does. A User HID that contains `/` cannot be searched, and most HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern rejects these values. Hex-encoded hashes need no escaping at all. The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. (required) + * @param int|null $limit Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. (optional, default to 20) + * @param int|null $offset Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`. (optional, default to 0) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistory'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function searchHistoryAsync($search_type, $value, $limit = 20, $offset = 0, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistory'][0]) + { + return $this->searchHistoryAsyncWithHttpInfo($search_type, $value, $limit, $offset, $hostIndex, $variables, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation searchHistoryAsyncWithHttpInfo + * + * Search identifications + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * + * @param string $search_type Identifier to search by. Only these seven values are supported: - `request_id`: one identification (read a verdict); - `device_id`: every identification of one device; - `user_hid`: every identification of one account; - `visitor_id`: every identification of one visitor; - `ip`: every identification from one public IPv4 address; - `session_id`: every identification of one visit; - `cookie_id`: every identification with one browser cookie. The server does not reject other values: it ignores them and returns the latest identifications of the whole domain, so restrict the value on your side. (required) + * @param string $value Value of the identifier, validated on your side before sending: - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, the nil UUID included, matching `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it lowercase. - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build this path yourself when yours does. A User HID that contains `/` cannot be searched, and most HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern rejects these values. Hex-encoded hashes need no escaping at all. The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. (required) + * @param int|null $limit Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. (optional, default to 20) + * @param int|null $offset Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`. (optional, default to 0) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistory'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function searchHistoryAsyncWithHttpInfo($search_type, $value, $limit = 20, $offset = 0, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistory'][0]) + { + $returnType = '\ShieldLabs\Generated\Model\HistoryPage'; + $request = $this->searchHistoryRequest($search_type, $value, $limit, $offset, $hostIndex, $variables, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'searchHistory' + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://account.shieldlabs.ai + * + * @param string $search_type Identifier to search by. Only these seven values are supported: - `request_id`: one identification (read a verdict); - `device_id`: every identification of one device; - `user_hid`: every identification of one account; - `visitor_id`: every identification of one visitor; - `ip`: every identification from one public IPv4 address; - `session_id`: every identification of one visit; - `cookie_id`: every identification with one browser cookie. The server does not reject other values: it ignores them and returns the latest identifications of the whole domain, so restrict the value on your side. (required) + * @param string $value Value of the identifier, validated on your side before sending: - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, the nil UUID included, matching `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it lowercase. - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build this path yourself when yours does. A User HID that contains `/` cannot be searched, and most HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern rejects these values. Hex-encoded hashes need no escaping at all. The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. (required) + * @param int|null $limit Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. (optional, default to 20) + * @param int|null $offset Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`. (optional, default to 0) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistory'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function searchHistoryRequest($search_type, $value, $limit = 20, $offset = 0, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistory'][0]) + { + + // verify the required parameter 'search_type' is set + if ($search_type === null || (is_array($search_type) && count($search_type) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $search_type when calling searchHistory' + ); + } + + // verify the required parameter 'value' is set + if ($value === null || (is_array($value) && count($value) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $value when calling searchHistory' + ); + } + if (strlen($value) < 1) { + throw new \InvalidArgumentException('invalid length for "$value" when calling HistoryAPIApi.searchHistory, must be bigger than or equal to 1.'); + } + if (!preg_match("/^(?:[^\/.][^\/]*|\\.[^\/.][^\/]*|\\.\\.[^\/]+)$/", $value)) { + throw new \InvalidArgumentException("invalid value for \"value\" when calling HistoryAPIApi.searchHistory, must conform to the pattern /^(?:[^\/.][^\/]*|\\.[^\/.][^\/]*|\\.\\.[^\/]+)$/."); + } + + if ($limit !== null && $limit > 100) { + throw new \InvalidArgumentException('invalid value for "$limit" when calling HistoryAPIApi.searchHistory, must be smaller than or equal to 100.'); + } + if ($limit !== null && $limit < 1) { + throw new \InvalidArgumentException('invalid value for "$limit" when calling HistoryAPIApi.searchHistory, must be bigger than or equal to 1.'); + } + + if ($offset !== null && $offset < 0) { + throw new \InvalidArgumentException('invalid value for "$offset" when calling HistoryAPIApi.searchHistory, must be bigger than or equal to 0.'); + } + + + $resourcePath = '/api/v1/history/{search_type}/{value}'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $limit, + 'limit', // param base name + 'integer', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $offset, + 'offset', // param base name + 'integer', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + + + // path params + if ($search_type !== null) { + $resourcePath = str_replace( + '{search_type}', + ObjectSerializer::toPathValue($search_type), + $resourcePath + ); + } + // path params + if ($value !== null) { + $resourcePath = str_replace( + '{value}', + ObjectSerializer::toPathValue($value), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + ['application/json', 'text/plain', 'text/html', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (sec_xxxxxxxx-xxxxxxxx-xxxxxxxx) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + # Preserve the original behavior of server indexing. + if ($hostIndex === null) { + $hostIndex = $this->hostIndex; + } + + $hostSettings = $this->getHostSettingsForsearchHistory(); + + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new \InvalidArgumentException("Invalid index {$hostIndex} when selecting the host. Must be less than ".count($hostSettings)); + } + $operationHost = Configuration::getHostString($hostSettings, $hostIndex, $variables); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Returns an array of host settings for Operation searchHistory + * + * @return array an array of host settings + */ + protected function getHostSettingsForsearchHistory(): array + { + return [ + [ + "url" => "https://account.shieldlabs.ai", + "description" => "History API", + ] + ]; + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + if ($this->config->getCertFile()) { + $options[RequestOptions::CERT] = $this->config->getCertFile(); + } + + if ($this->config->getKeyFile()) { + $options[RequestOptions::SSL_KEY] = $this->config->getKeyFile(); + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response + ): array { + if ($dataType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/generated/lib/Api/ManagementAPIApi.php b/generated/lib/Api/ManagementAPIApi.php new file mode 100644 index 0000000..29cf71a --- /dev/null +++ b/generated/lib/Api/ManagementAPIApi.php @@ -0,0 +1,1082 @@ + [ + 'application/json', + ], + 'searchHistoryDeprecated' => [ + 'application/json', + ], + ]; + + /** + * @param ClientInterface $client + * @param Configuration $config + * @param HeaderSelector $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation getDomainProfile + * + * Get the domain profile + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getDomainProfile'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \ShieldLabs\Generated\Model\DomainProfile|string|\ShieldLabs\Generated\Model\ErrorBody|string|\ShieldLabs\Generated\Model\ErrorBody|string + */ + public function getDomainProfile($x_shield_domain, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getDomainProfile'][0]) + { + list($response) = $this->getDomainProfileWithHttpInfo($x_shield_domain, $hostIndex, $variables, $contentType); + return $response; + } + + /** + * Operation getDomainProfileWithHttpInfo + * + * Get the domain profile + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getDomainProfile'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \ShieldLabs\Generated\Model\DomainProfile|string|\ShieldLabs\Generated\Model\ErrorBody|string|\ShieldLabs\Generated\Model\ErrorBody|string, HTTP status code, HTTP response headers (array of strings) + */ + public function getDomainProfileWithHttpInfo($x_shield_domain, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getDomainProfile'][0]) + { + $request = $this->getDomainProfileRequest($x_shield_domain, $hostIndex, $variables, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\DomainProfile', + $request, + $response, + ); + case 404: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 429: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 502: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 503: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 504: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\DomainProfile', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\DomainProfile', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 404: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 429: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 502: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 503: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 504: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation getDomainProfileAsync + * + * Get the domain profile + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getDomainProfile'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function getDomainProfileAsync($x_shield_domain, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getDomainProfile'][0]) + { + return $this->getDomainProfileAsyncWithHttpInfo($x_shield_domain, $hostIndex, $variables, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation getDomainProfileAsyncWithHttpInfo + * + * Get the domain profile + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getDomainProfile'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function getDomainProfileAsyncWithHttpInfo($x_shield_domain, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getDomainProfile'][0]) + { + $returnType = '\ShieldLabs\Generated\Model\DomainProfile'; + $request = $this->getDomainProfileRequest($x_shield_domain, $hostIndex, $variables, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'getDomainProfile' + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['getDomainProfile'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function getDomainProfileRequest($x_shield_domain, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['getDomainProfile'][0]) + { + + // verify the required parameter 'x_shield_domain' is set + if ($x_shield_domain === null || (is_array($x_shield_domain) && count($x_shield_domain) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $x_shield_domain when calling getDomainProfile' + ); + } + if (strlen($x_shield_domain) > 253) { + throw new \InvalidArgumentException('invalid length for "$x_shield_domain" when calling ManagementAPIApi.getDomainProfile, must be smaller than or equal to 253.'); + } + if (strlen($x_shield_domain) < 1) { + throw new \InvalidArgumentException('invalid length for "$x_shield_domain" when calling ManagementAPIApi.getDomainProfile, must be bigger than or equal to 1.'); + } + + + $resourcePath = '/v1/profile'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + // header params + if ($x_shield_domain !== null) { + $headerParams['X-Shield-Domain'] = ObjectSerializer::toHeaderValue($x_shield_domain); + } + + + + $headers = $this->headerSelector->selectHeaders( + ['application/json', 'text/plain', 'text/html', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + # Preserve the original behavior of server indexing. + if ($hostIndex === null) { + $hostIndex = $this->hostIndex; + } + + $hostSettings = $this->getHostSettingsForgetDomainProfile(); + + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new \InvalidArgumentException("Invalid index {$hostIndex} when selecting the host. Must be less than ".count($hostSettings)); + } + $operationHost = Configuration::getHostString($hostSettings, $hostIndex, $variables); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Returns an array of host settings for Operation getDomainProfile + * + * @return array an array of host settings + */ + protected function getHostSettingsForgetDomainProfile(): array + { + return [ + [ + "url" => "https://api.shieldlabs.ai", + "description" => "Management API", + ] + ]; + } + + /** + * Operation searchHistoryDeprecated + * + * Search history by identifier (deprecated) + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param string $type Identifier to search by. Other values get a `404` with a bare JSON string such as `\"auto is not supported\"`. (required) + * @param string $value Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. (required) + * @param int|null $limit Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. (optional, default to 100) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistoryDeprecated'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \ShieldLabs\Generated\Model\LegacySnapshot[]|string|string|\ShieldLabs\Generated\Model\ErrorBody|string|\ShieldLabs\Generated\Model\ErrorBody|string + * @deprecated + */ + public function searchHistoryDeprecated($x_shield_domain, $type, $value, $limit = 100, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistoryDeprecated'][0]) + { + list($response) = $this->searchHistoryDeprecatedWithHttpInfo($x_shield_domain, $type, $value, $limit, $hostIndex, $variables, $contentType); + return $response; + } + + /** + * Operation searchHistoryDeprecatedWithHttpInfo + * + * Search history by identifier (deprecated) + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param string $type Identifier to search by. Other values get a `404` with a bare JSON string such as `\"auto is not supported\"`. (required) + * @param string $value Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. (required) + * @param int|null $limit Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. (optional, default to 100) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistoryDeprecated'] to see the possible values for this operation + * + * @throws \ShieldLabs\Generated\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \ShieldLabs\Generated\Model\LegacySnapshot[]|string|string|\ShieldLabs\Generated\Model\ErrorBody|string|\ShieldLabs\Generated\Model\ErrorBody|string, HTTP status code, HTTP response headers (array of strings) + * @deprecated + */ + public function searchHistoryDeprecatedWithHttpInfo($x_shield_domain, $type, $value, $limit = 100, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistoryDeprecated'][0]) + { + $request = $this->searchHistoryDeprecatedRequest($x_shield_domain, $type, $value, $limit, $hostIndex, $variables, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\LegacySnapshot[]', + $request, + $response, + ); + case 400: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 404: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 429: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 502: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + case 503: + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\ErrorBody', + $request, + $response, + ); + case 504: + return $this->handleResponseWithDataType( + 'string', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\ShieldLabs\Generated\Model\LegacySnapshot[]', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\LegacySnapshot[]', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 400: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 404: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 429: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 502: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 503: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\ShieldLabs\Generated\Model\ErrorBody', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + case 504: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + 'string', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation searchHistoryDeprecatedAsync + * + * Search history by identifier (deprecated) + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param string $type Identifier to search by. Other values get a `404` with a bare JSON string such as `\"auto is not supported\"`. (required) + * @param string $value Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. (required) + * @param int|null $limit Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. (optional, default to 100) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistoryDeprecated'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + * @deprecated + */ + public function searchHistoryDeprecatedAsync($x_shield_domain, $type, $value, $limit = 100, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistoryDeprecated'][0]) + { + return $this->searchHistoryDeprecatedAsyncWithHttpInfo($x_shield_domain, $type, $value, $limit, $hostIndex, $variables, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation searchHistoryDeprecatedAsyncWithHttpInfo + * + * Search history by identifier (deprecated) + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param string $type Identifier to search by. Other values get a `404` with a bare JSON string such as `\"auto is not supported\"`. (required) + * @param string $value Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. (required) + * @param int|null $limit Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. (optional, default to 100) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistoryDeprecated'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + * @deprecated + */ + public function searchHistoryDeprecatedAsyncWithHttpInfo($x_shield_domain, $type, $value, $limit = 100, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistoryDeprecated'][0]) + { + $returnType = '\ShieldLabs\Generated\Model\LegacySnapshot[]'; + $request = $this->searchHistoryDeprecatedRequest($x_shield_domain, $type, $value, $limit, $hostIndex, $variables, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'searchHistoryDeprecated' + * + * This operation contains host(s) defined in the OpenAPI spec. Use 'hostIndex' to select the host. + * if needed, use the 'variables' parameter to pass variables to the host. + * URL: https://api.shieldlabs.ai + * + * @param string $x_shield_domain Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body. (required) + * @param string $type Identifier to search by. Other values get a `404` with a bare JSON string such as `\"auto is not supported\"`. (required) + * @param string $value Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. (required) + * @param int|null $limit Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. (optional, default to 100) + * @param null|int $hostIndex Host index. Defaults to null. If null, then the library will use $this->hostIndex instead + * @param array $variables Associative array of variables to pass to the host. Defaults to empty array. + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['searchHistoryDeprecated'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + * @deprecated + */ + public function searchHistoryDeprecatedRequest($x_shield_domain, $type, $value, $limit = 100, ?int $hostIndex = null, array $variables = [], string $contentType = self::contentTypes['searchHistoryDeprecated'][0]) + { + + // verify the required parameter 'x_shield_domain' is set + if ($x_shield_domain === null || (is_array($x_shield_domain) && count($x_shield_domain) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $x_shield_domain when calling searchHistoryDeprecated' + ); + } + if (strlen($x_shield_domain) > 253) { + throw new \InvalidArgumentException('invalid length for "$x_shield_domain" when calling ManagementAPIApi.searchHistoryDeprecated, must be smaller than or equal to 253.'); + } + if (strlen($x_shield_domain) < 1) { + throw new \InvalidArgumentException('invalid length for "$x_shield_domain" when calling ManagementAPIApi.searchHistoryDeprecated, must be bigger than or equal to 1.'); + } + + // verify the required parameter 'type' is set + if ($type === null || (is_array($type) && count($type) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $type when calling searchHistoryDeprecated' + ); + } + + // verify the required parameter 'value' is set + if ($value === null || (is_array($value) && count($value) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $value when calling searchHistoryDeprecated' + ); + } + if (strlen($value) < 1) { + throw new \InvalidArgumentException('invalid length for "$value" when calling ManagementAPIApi.searchHistoryDeprecated, must be bigger than or equal to 1.'); + } + + if ($limit !== null && $limit > 100) { + throw new \InvalidArgumentException('invalid value for "$limit" when calling ManagementAPIApi.searchHistoryDeprecated, must be smaller than or equal to 100.'); + } + if ($limit !== null && $limit < 1) { + throw new \InvalidArgumentException('invalid value for "$limit" when calling ManagementAPIApi.searchHistoryDeprecated, must be bigger than or equal to 1.'); + } + + + $resourcePath = '/v1/history/{type}/{value}'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $limit, + 'limit', // param base name + 'integer', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + + // header params + if ($x_shield_domain !== null) { + $headerParams['X-Shield-Domain'] = ObjectSerializer::toHeaderValue($x_shield_domain); + } + + // path params + if ($type !== null) { + $resourcePath = str_replace( + '{type}', + ObjectSerializer::toPathValue($type), + $resourcePath + ); + } + // path params + if ($value !== null) { + $resourcePath = str_replace( + '{value}', + ObjectSerializer::toPathValue($value), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + ['application/json', 'text/plain', 'text/html', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + # Preserve the original behavior of server indexing. + if ($hostIndex === null) { + $hostIndex = $this->hostIndex; + } + + $hostSettings = $this->getHostSettingsForsearchHistoryDeprecated(); + + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new \InvalidArgumentException("Invalid index {$hostIndex} when selecting the host. Must be less than ".count($hostSettings)); + } + $operationHost = Configuration::getHostString($hostSettings, $hostIndex, $variables); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Returns an array of host settings for Operation searchHistoryDeprecated + * + * @return array an array of host settings + */ + protected function getHostSettingsForsearchHistoryDeprecated(): array + { + return [ + [ + "url" => "https://api.shieldlabs.ai", + "description" => "Management API", + ] + ]; + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + if ($this->config->getCertFile()) { + $options[RequestOptions::CERT] = $this->config->getCertFile(); + } + + if ($this->config->getKeyFile()) { + $options[RequestOptions::SSL_KEY] = $this->config->getKeyFile(); + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response + ): array { + if ($dataType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/generated/lib/ApiException.php b/generated/lib/ApiException.php new file mode 100644 index 0000000..1186ef3 --- /dev/null +++ b/generated/lib/ApiException.php @@ -0,0 +1,120 @@ +responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; + } + + /** + * Gets the HTTP response header + * + * @return string[][]|null HTTP response header + */ + public function getResponseHeaders() + { + return $this->responseHeaders; + } + + /** + * Gets the HTTP body of the server response either as Json or string + * + * @return \stdClass|string|null HTTP body of the server response either as \stdClass or string + */ + public function getResponseBody() + { + return $this->responseBody; + } + + /** + * Sets the deserialized response object (during deserialization) + * + * @param mixed $obj Deserialized response object + * + * @return void + */ + public function setResponseObject($obj) + { + $this->responseObject = $obj; + } + + /** + * Gets the deserialized response object (during deserialization) + * + * @return mixed the deserialized response object + */ + public function getResponseObject() + { + return $this->responseObject; + } +} diff --git a/generated/lib/Configuration.php b/generated/lib/Configuration.php new file mode 100644 index 0000000..95fd86b --- /dev/null +++ b/generated/lib/Configuration.php @@ -0,0 +1,593 @@ +tempFolderPath = sys_get_temp_dir(); + } + + /** + * Sets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $key API key or token + * + * @return $this + */ + public function setApiKey($apiKeyIdentifier, $key) + { + $this->apiKeys[$apiKeyIdentifier] = $key; + return $this; + } + + /** + * Gets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string API key or token + */ + public function getApiKey($apiKeyIdentifier) + { + return isset($this->apiKeys[$apiKeyIdentifier]) ? $this->apiKeys[$apiKeyIdentifier] : null; + } + + /** + * Sets the prefix for API key (e.g. Bearer) + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $prefix API key prefix, e.g. Bearer + * + * @return $this + */ + public function setApiKeyPrefix($apiKeyIdentifier, $prefix) + { + $this->apiKeyPrefixes[$apiKeyIdentifier] = $prefix; + return $this; + } + + /** + * Gets API key prefix + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string + */ + public function getApiKeyPrefix($apiKeyIdentifier) + { + return isset($this->apiKeyPrefixes[$apiKeyIdentifier]) ? $this->apiKeyPrefixes[$apiKeyIdentifier] : null; + } + + /** + * Sets the access token for OAuth + * + * @param string $accessToken Token for OAuth + * + * @return $this + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + return $this; + } + + /** + * Gets the access token for OAuth + * + * @return string Access token for OAuth + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Sets boolean format for query string. + * + * @param string $booleanFormat Boolean format for query string + * + * @return $this + */ + public function setBooleanFormatForQueryString(string $booleanFormat) + { + $this->booleanFormatForQueryString = $booleanFormat; + + return $this; + } + + /** + * Gets boolean format for query string. + * + * @return string Boolean format for query string + */ + public function getBooleanFormatForQueryString(): string + { + return $this->booleanFormatForQueryString; + } + + /** + * Sets the username for HTTP basic authentication + * + * @param string $username Username for HTTP basic authentication + * + * @return $this + */ + public function setUsername($username) + { + $this->username = $username; + return $this; + } + + /** + * Gets the username for HTTP basic authentication + * + * @return string Username for HTTP basic authentication + */ + public function getUsername() + { + return $this->username; + } + + /** + * Sets the password for HTTP basic authentication + * + * @param string $password Password for HTTP basic authentication + * + * @return $this + */ + public function setPassword($password) + { + $this->password = $password; + return $this; + } + + /** + * Gets the password for HTTP basic authentication + * + * @return string Password for HTTP basic authentication + */ + public function getPassword() + { + return $this->password; + } + + /** + * Sets the host + * + * @param string $host Host + * + * @return $this + */ + public function setHost($host) + { + $this->host = $host; + return $this; + } + + /** + * Gets the host + * + * @return string Host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * + * @throws \InvalidArgumentException + * @return $this + */ + public function setUserAgent($userAgent) + { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * Gets the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() + { + return $this->userAgent; + } + + /** + * Sets debug flag + * + * @param bool $debug Debug flag + * + * @return $this + */ + public function setDebug($debug) + { + $this->debug = $debug; + return $this; + } + + /** + * Gets the debug flag + * + * @return bool + */ + public function getDebug() + { + return $this->debug; + } + + /** + * Sets the debug file + * + * @param string $debugFile Debug file + * + * @return $this + */ + public function setDebugFile($debugFile) + { + $this->debugFile = $debugFile; + return $this; + } + + /** + * Gets the debug file + * + * @return string + */ + public function getDebugFile() + { + return $this->debugFile; + } + + /** + * Sets the temp folder path + * + * @param string $tempFolderPath Temp folder path + * + * @return $this + */ + public function setTempFolderPath($tempFolderPath) + { + $this->tempFolderPath = $tempFolderPath; + return $this; + } + + /** + * Gets the temp folder path + * + * @return string Temp folder path + */ + public function getTempFolderPath() + { + return $this->tempFolderPath; + } + + /** + * Sets the certificate file path, for mTLS + * + * @return $this + */ + public function setCertFile($certFile) + { + $this->certFile = $certFile; + return $this; + } + + /** + * Gets the certificate file path, for mTLS + * + * @return string Certificate file path + */ + public function getCertFile() + { + return $this->certFile; + } + + /** + * Sets the certificate key path, for mTLS + * + * @return $this + */ + public function setKeyFile($keyFile) + { + $this->keyFile = $keyFile; + return $this; + } + + /** + * Gets the certificate key path, for mTLS + * + * @return string Certificate key path + */ + public function getKeyFile() + { + return $this->keyFile; + } + + + /** + * Gets the default configuration instance + * + * @return Configuration + */ + public static function getDefaultConfiguration() + { + if (self::$defaultConfiguration === null) { + self::$defaultConfiguration = new Configuration(); + } + + return self::$defaultConfiguration; + } + + /** + * Sets the default configuration instance + * + * @param Configuration $config An instance of the Configuration Object + * + * @return void + */ + public static function setDefaultConfiguration(Configuration $config) + { + self::$defaultConfiguration = $config; + } + + /** + * Gets the essential information for debugging + * + * @return string The report for debugging + */ + public static function toDebugReport() + { + $report = 'PHP SDK (ShieldLabs\Generated) Debug Report:' . PHP_EOL; + $report .= ' OS: ' . php_uname() . PHP_EOL; + $report .= ' PHP Version: ' . PHP_VERSION . PHP_EOL; + $report .= ' The version of the OpenAPI document: 1.0.1' . PHP_EOL; + $report .= ' Temp Folder Path: ' . self::getDefaultConfiguration()->getTempFolderPath() . PHP_EOL; + + return $report; + } + + /** + * Get API key (with prefix if set) + * + * @param string $apiKeyIdentifier name of apikey + * + * @return null|string API key with the prefix + */ + public function getApiKeyWithPrefix($apiKeyIdentifier) + { + $prefix = $this->getApiKeyPrefix($apiKeyIdentifier); + $apiKey = $this->getApiKey($apiKeyIdentifier); + + if ($apiKey === null) { + return null; + } + + if ($prefix === null) { + $keyWithPrefix = $apiKey; + } else { + $keyWithPrefix = $prefix . ' ' . $apiKey; + } + + return $keyWithPrefix; + } + + /** + * Returns an array of host settings + * + * @return array an array of host settings + */ + public function getHostSettings() + { + return [ + [ + "url" => "https://account.shieldlabs.ai", + "description" => "History API (every operation also declares its own server)", + ], + [ + "url" => "https://api.shieldlabs.ai", + "description" => "Management API (every operation also declares its own server)", + ] + ]; + } + + /** + * Returns URL based on host settings, index and variables + * + * @param array $hostSettings array of host settings, generated from getHostSettings() or equivalent from the API clients + * @param int $hostIndex index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public static function getHostString(array $hostSettings, $hostIndex, ?array $variables = null) + { + if (null === $variables) { + $variables = []; + } + + // check array index out of bound + if ($hostIndex < 0 || $hostIndex >= count($hostSettings)) { + throw new \InvalidArgumentException("Invalid index $hostIndex when selecting the host. Must be less than ".count($hostSettings)); + } + + $host = $hostSettings[$hostIndex]; + $url = $host["url"]; + + // go through variable and assign a value + foreach ($host["variables"] ?? [] as $name => $variable) { + if (array_key_exists($name, $variables)) { // check to see if it's in the variables provided by the user + if (!isset($variable['enum_values']) || in_array($variables[$name], $variable["enum_values"], true)) { // check to see if the value is in the enum + $url = str_replace("{".$name."}", $variables[$name], $url); + } else { + throw new \InvalidArgumentException("The variable `$name` in the host URL has invalid value ".$variables[$name].". Must be ".join(',', $variable["enum_values"])."."); + } + } else { + // use default value + $url = str_replace("{".$name."}", $variable["default_value"], $url); + } + } + + return $url; + } + + /** + * Returns URL based on the index and variables + * + * @param int $index index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public function getHostFromSettings($index, $variables = null) + { + return self::getHostString($this->getHostSettings(), $index, $variables); + } +} diff --git a/generated/lib/FormDataProcessor.php b/generated/lib/FormDataProcessor.php new file mode 100644 index 0000000..6b7e98f --- /dev/null +++ b/generated/lib/FormDataProcessor.php @@ -0,0 +1,247 @@ + $values the value of the form parameter + * + * @return array [key => value] of formdata + */ + public function prepare(array $values): array + { + $this->has_file = false; + $result = []; + + foreach ($values as $k => $v) { + if ($v === null) { + continue; + } + + $result[$k] = $this->makeFormSafe($v); + } + + return $result; + } + + /** + * Flattens a multi-level array of data and generates a single-level array + * compatible with formdata - a single-level array where the keys use bracket + * notation to signify nested data. + * + * credit: https://github.com/FranBar1966/FlatPHP + */ + public static function flatten(array $source, string $start = ''): array + { + $opt = [ + 'prefix' => '[', + 'suffix' => ']', + 'suffix-end' => true, + 'prefix-list' => '[', + 'suffix-list' => ']', + 'suffix-list-end' => true, + ]; + + if ($start === '') { + $currentPrefix = ''; + $currentSuffix = ''; + $currentSuffixEnd = false; + } elseif (array_is_list($source)) { + $currentPrefix = $opt['prefix-list']; + $currentSuffix = $opt['suffix-list']; + $currentSuffixEnd = $opt['suffix-list-end']; + } else { + $currentPrefix = $opt['prefix']; + $currentSuffix = $opt['suffix']; + $currentSuffixEnd = $opt['suffix-end']; + } + + $currentName = $start; + $result = []; + + foreach ($source as $key => $val) { + $currentName .= $currentPrefix.$key; + + if (is_array($val) && !empty($val)) { + $currentName .= $currentSuffix; + $result += self::flatten($val, $currentName); + } else { + if ($currentSuffixEnd) { + $currentName .= $currentSuffix; + } + + if (is_resource($val)) { + $result[$currentName] = $val; + } else { + $result[$currentName] = ObjectSerializer::toString($val); + } + } + + $currentName = $start; + } + + return $result; + } + + /** + * formdata must be limited to scalars or arrays of scalar values, + * or a resource for a file upload. Here we iterate through all available + * data and identify how to handle each scenario + */ + protected function makeFormSafe($value) + { + if ($value instanceof SplFileObject) { + return $this->processFiles([$value])[0]; + } + + if (is_resource($value)) { + $this->has_file = true; + + return $value; + } + + if ($value instanceof ModelInterface) { + return $this->processModel($value); + } + + if (is_array($value) || (is_object($value) && !$value instanceof \DateTimeInterface)) { + $data = []; + + foreach ($value as $k => $v) { + $data[$k] = $this->makeFormSafe($v); + } + + return $data; + } + + return ObjectSerializer::toString($value); + } + + /** + * We are able to handle nested ModelInterface. We do not simply call + * json_decode(json_encode()) because any given model may have binary data + * or other data that cannot be serialized to a JSON string + */ + protected function processModel(ModelInterface $model): array + { + $result = []; + + foreach ($model::openAPITypes() as $name => $type) { + $value = $model->offsetGet($name); + + if ($value === null) { + continue; + } + + if (strpos($type, '\SplFileObject') !== false) { + $file = is_array($value) ? $value : [$value]; + $result[$name] = $this->processFiles($file); + + continue; + } + + if ($value instanceof ModelInterface) { + $result[$name] = $this->processModel($value); + + continue; + } + + if (is_array($value) || is_object($value)) { + $result[$name] = $this->makeFormSafe($value); + + continue; + } + + $result[$name] = ObjectSerializer::toString($value); + } + + return $result; + } + + /** + * Handle file data + */ + protected function processFiles(array $files): array + { + $this->has_file = true; + + $result = []; + + foreach ($files as $i => $file) { + if (is_array($file)) { + $result[$i] = $this->processFiles($file); + + continue; + } + + if ($file instanceof StreamInterface) { + $result[$i] = $file; + + continue; + } + + if ($file instanceof SplFileObject) { + $result[$i] = $this->tryFopen($file); + } + } + + return $result; + } + + private function tryFopen(SplFileObject $file) + { + return Utils::tryFopen($file->getRealPath(), 'rb'); + } +} diff --git a/generated/lib/HeaderSelector.php b/generated/lib/HeaderSelector.php new file mode 100644 index 0000000..09accdf --- /dev/null +++ b/generated/lib/HeaderSelector.php @@ -0,0 +1,274 @@ +selectAcceptHeader($accept); + if ($accept !== null) { + $headers['Accept'] = $accept; + } + + if (!$isMultipart) { + if($contentType === '') { + $contentType = 'application/json'; + } + + $headers['Content-Type'] = $contentType; + } + + return $headers; + } + + /** + * Return the header 'Accept' based on an array of Accept provided. + * + * @param string[] $accept Array of header + * + * @return null|string Accept (e.g. application/json) + */ + private function selectAcceptHeader(array $accept): ?string + { + # filter out empty entries + $accept = array_filter($accept); + + if (count($accept) === 0) { + return null; + } + + # If there's only one Accept header, just use it + if (count($accept) === 1) { + return reset($accept); + } + + # If none of the available Accept headers is of type "json", then just use all them + $headersWithJson = $this->selectJsonMimeList($accept); + if (count($headersWithJson) === 0) { + return implode(',', $accept); + } + + # If we got here, then we need add quality values (weight), as described in IETF RFC 9110, Items 12.4.2/12.5.1, + # to give the highest priority to json-like headers - recalculating the existing ones, if needed + return $this->getAcceptHeaderWithAdjustedWeight($accept, $headersWithJson); + } + + /** + * Detects whether a string contains a valid JSON mime type + * + * @param string $searchString + * @return bool + */ + public function isJsonMime(string $searchString): bool + { + return preg_match('~^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)~', $searchString) === 1; + } + + /** + * Select all items from a list containing a JSON mime type + * + * @param array $mimeList + * @return array + */ + private function selectJsonMimeList(array $mimeList): array { + $jsonMimeList = []; + foreach ($mimeList as $mime) { + if($this->isJsonMime($mime)) { + $jsonMimeList[] = $mime; + } + } + return $jsonMimeList; + } + + + /** + * Create an Accept header string from the given "Accept" headers array, recalculating all weights + * + * @param string[] $accept Array of Accept Headers + * @param string[] $headersWithJson Array of Accept Headers of type "json" + * + * @return string "Accept" Header (e.g. "application/json, text/html; q=0.9") + */ + private function getAcceptHeaderWithAdjustedWeight(array $accept, array $headersWithJson): string + { + $processedHeaders = [ + 'withApplicationJson' => [], + 'withJson' => [], + 'withoutJson' => [], + ]; + + foreach ($accept as $header) { + + $headerData = $this->getHeaderAndWeight($header); + + if (stripos($headerData['header'], 'application/json') === 0) { + $processedHeaders['withApplicationJson'][] = $headerData; + } elseif (in_array($header, $headersWithJson, true)) { + $processedHeaders['withJson'][] = $headerData; + } else { + $processedHeaders['withoutJson'][] = $headerData; + } + } + + $acceptHeaders = []; + $currentWeight = 1000; + + $hasMoreThan28Headers = count($accept) > 28; + + foreach($processedHeaders as $headers) { + if (count($headers) > 0) { + $acceptHeaders[] = $this->adjustWeight($headers, $currentWeight, $hasMoreThan28Headers); + } + } + + $acceptHeaders = array_merge(...$acceptHeaders); + + return implode(',', $acceptHeaders); + } + + /** + * Given an Accept header, returns an associative array splitting the header and its weight + * + * @param string $header "Accept" Header + * + * @return array with the header and its weight + */ + private function getHeaderAndWeight(string $header): array + { + # matches headers with weight, splitting the header and the weight in $outputArray + if (preg_match('/(.*);\s*q=(1(?:\.0+)?|0\.\d+)$/', $header, $outputArray) === 1) { + $headerData = [ + 'header' => $outputArray[1], + 'weight' => (int)($outputArray[2] * 1000), + ]; + } else { + $headerData = [ + 'header' => trim($header), + 'weight' => 1000, + ]; + } + + return $headerData; + } + + /** + * @param array[] $headers + * @param float $currentWeight + * @param bool $hasMoreThan28Headers + * @return string[] array of adjusted "Accept" headers + */ + private function adjustWeight(array $headers, float &$currentWeight, bool $hasMoreThan28Headers): array + { + usort($headers, function (array $a, array $b) { + return $b['weight'] - $a['weight']; + }); + + $acceptHeaders = []; + foreach ($headers as $index => $header) { + if($index > 0 && $headers[$index - 1]['weight'] > $header['weight']) + { + $currentWeight = $this->getNextWeight($currentWeight, $hasMoreThan28Headers); + } + + $weight = $currentWeight; + + $acceptHeaders[] = $this->buildAcceptHeader($header['header'], $weight); + } + + $currentWeight = $this->getNextWeight($currentWeight, $hasMoreThan28Headers); + + return $acceptHeaders; + } + + /** + * @param string $header + * @param int $weight + * @return string + */ + private function buildAcceptHeader(string $header, int $weight): string + { + if($weight === 1000) { + return $header; + } + + return trim($header, '; ') . ';q=' . rtrim(sprintf('%0.3f', $weight / 1000), '0'); + } + + /** + * Calculate the next weight, based on the current one. + * + * If there are less than 28 "Accept" headers, the weights will be decreased by 1 on its highest significant digit, using the + * following formula: + * + * next weight = current weight - 10 ^ (floor(log(current weight - 1))) + * + * ( current weight minus ( 10 raised to the power of ( floor of (log to the base 10 of ( current weight minus 1 ) ) ) ) ) + * + * Starting from 1000, this generates the following series: + * + * 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 + * + * The resulting quality codes are closer to the average "normal" usage of them (like "q=0.9", "q=0.8" and so on), but it only works + * if there is a maximum of 28 "Accept" headers. If we have more than that (which is extremely unlikely), then we fall back to a 1-by-1 + * decrement rule, which will result in quality codes like "q=0.999", "q=0.998" etc. + * + * @param int $currentWeight varying from 1 to 1000 (will be divided by 1000 to build the quality value) + * @param bool $hasMoreThan28Headers + * @return int + */ + public function getNextWeight(int $currentWeight, bool $hasMoreThan28Headers): int + { + if ($currentWeight <= 1) { + return 1; + } + + if ($hasMoreThan28Headers) { + return $currentWeight - 1; + } + + return $currentWeight - 10 ** floor( log10($currentWeight - 1) ); + } +} diff --git a/generated/lib/Model/DetectionFlags.php b/generated/lib/Model/DetectionFlags.php new file mode 100644 index 0000000..56f504e --- /dev/null +++ b/generated/lib/Model/DetectionFlags.php @@ -0,0 +1,1080 @@ + + */ +class DetectionFlags implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'DetectionFlags'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'vpn' => 'bool', + 'privacy_relay' => 'bool', + 'browser_vpn_proxy' => 'bool', + 'tor' => 'bool', + 'proxy' => 'bool', + 'datacenter_ip' => 'bool', + 'abuser' => 'bool', + 'os_mismatch' => 'bool', + 'os_not_detected' => 'bool', + 'timezone_mismatch' => 'bool', + 'anti_detect_browser' => 'bool', + 'browser_automation' => 'bool', + 'ip_mismatch' => 'bool', + 'incognito' => 'bool', + 'search_bot' => 'bool', + 'suspicious_paid_click' => 'bool', + 'javascript_disabled' => 'bool', + 'stun_not_checked' => 'bool', + 'check_incomplete' => 'bool' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'vpn' => null, + 'privacy_relay' => null, + 'browser_vpn_proxy' => null, + 'tor' => null, + 'proxy' => null, + 'datacenter_ip' => null, + 'abuser' => null, + 'os_mismatch' => null, + 'os_not_detected' => null, + 'timezone_mismatch' => null, + 'anti_detect_browser' => null, + 'browser_automation' => null, + 'ip_mismatch' => null, + 'incognito' => null, + 'search_bot' => null, + 'suspicious_paid_click' => null, + 'javascript_disabled' => null, + 'stun_not_checked' => null, + 'check_incomplete' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'vpn' => false, + 'privacy_relay' => false, + 'browser_vpn_proxy' => false, + 'tor' => false, + 'proxy' => false, + 'datacenter_ip' => false, + 'abuser' => false, + 'os_mismatch' => false, + 'os_not_detected' => false, + 'timezone_mismatch' => false, + 'anti_detect_browser' => false, + 'browser_automation' => false, + 'ip_mismatch' => false, + 'incognito' => false, + 'search_bot' => false, + 'suspicious_paid_click' => false, + 'javascript_disabled' => false, + 'stun_not_checked' => false, + 'check_incomplete' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'vpn' => 'vpn', + 'privacy_relay' => 'privacy_relay', + 'browser_vpn_proxy' => 'browser_vpn_proxy', + 'tor' => 'tor', + 'proxy' => 'proxy', + 'datacenter_ip' => 'datacenter_ip', + 'abuser' => 'abuser', + 'os_mismatch' => 'os_mismatch', + 'os_not_detected' => 'os_not_detected', + 'timezone_mismatch' => 'timezone_mismatch', + 'anti_detect_browser' => 'anti_detect_browser', + 'browser_automation' => 'browser_automation', + 'ip_mismatch' => 'ip_mismatch', + 'incognito' => 'incognito', + 'search_bot' => 'search_bot', + 'suspicious_paid_click' => 'suspicious_paid_click', + 'javascript_disabled' => 'javascript_disabled', + 'stun_not_checked' => 'stun_not_checked', + 'check_incomplete' => 'check_incomplete' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'vpn' => 'setVpn', + 'privacy_relay' => 'setPrivacyRelay', + 'browser_vpn_proxy' => 'setBrowserVpnProxy', + 'tor' => 'setTor', + 'proxy' => 'setProxy', + 'datacenter_ip' => 'setDatacenterIp', + 'abuser' => 'setAbuser', + 'os_mismatch' => 'setOsMismatch', + 'os_not_detected' => 'setOsNotDetected', + 'timezone_mismatch' => 'setTimezoneMismatch', + 'anti_detect_browser' => 'setAntiDetectBrowser', + 'browser_automation' => 'setBrowserAutomation', + 'ip_mismatch' => 'setIpMismatch', + 'incognito' => 'setIncognito', + 'search_bot' => 'setSearchBot', + 'suspicious_paid_click' => 'setSuspiciousPaidClick', + 'javascript_disabled' => 'setJavascriptDisabled', + 'stun_not_checked' => 'setStunNotChecked', + 'check_incomplete' => 'setCheckIncomplete' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'vpn' => 'getVpn', + 'privacy_relay' => 'getPrivacyRelay', + 'browser_vpn_proxy' => 'getBrowserVpnProxy', + 'tor' => 'getTor', + 'proxy' => 'getProxy', + 'datacenter_ip' => 'getDatacenterIp', + 'abuser' => 'getAbuser', + 'os_mismatch' => 'getOsMismatch', + 'os_not_detected' => 'getOsNotDetected', + 'timezone_mismatch' => 'getTimezoneMismatch', + 'anti_detect_browser' => 'getAntiDetectBrowser', + 'browser_automation' => 'getBrowserAutomation', + 'ip_mismatch' => 'getIpMismatch', + 'incognito' => 'getIncognito', + 'search_bot' => 'getSearchBot', + 'suspicious_paid_click' => 'getSuspiciousPaidClick', + 'javascript_disabled' => 'getJavascriptDisabled', + 'stun_not_checked' => 'getStunNotChecked', + 'check_incomplete' => 'getCheckIncomplete' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('vpn', $data ?? [], null); + $this->setIfExists('privacy_relay', $data ?? [], null); + $this->setIfExists('browser_vpn_proxy', $data ?? [], null); + $this->setIfExists('tor', $data ?? [], null); + $this->setIfExists('proxy', $data ?? [], null); + $this->setIfExists('datacenter_ip', $data ?? [], null); + $this->setIfExists('abuser', $data ?? [], null); + $this->setIfExists('os_mismatch', $data ?? [], null); + $this->setIfExists('os_not_detected', $data ?? [], null); + $this->setIfExists('timezone_mismatch', $data ?? [], null); + $this->setIfExists('anti_detect_browser', $data ?? [], null); + $this->setIfExists('browser_automation', $data ?? [], null); + $this->setIfExists('ip_mismatch', $data ?? [], null); + $this->setIfExists('incognito', $data ?? [], null); + $this->setIfExists('search_bot', $data ?? [], null); + $this->setIfExists('suspicious_paid_click', $data ?? [], null); + $this->setIfExists('javascript_disabled', $data ?? [], null); + $this->setIfExists('stun_not_checked', $data ?? [], null); + $this->setIfExists('check_incomplete', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['vpn'] === null) { + $invalidProperties[] = "'vpn' can't be null"; + } + if ($this->container['privacy_relay'] === null) { + $invalidProperties[] = "'privacy_relay' can't be null"; + } + if ($this->container['browser_vpn_proxy'] === null) { + $invalidProperties[] = "'browser_vpn_proxy' can't be null"; + } + if ($this->container['tor'] === null) { + $invalidProperties[] = "'tor' can't be null"; + } + if ($this->container['proxy'] === null) { + $invalidProperties[] = "'proxy' can't be null"; + } + if ($this->container['datacenter_ip'] === null) { + $invalidProperties[] = "'datacenter_ip' can't be null"; + } + if ($this->container['abuser'] === null) { + $invalidProperties[] = "'abuser' can't be null"; + } + if ($this->container['os_mismatch'] === null) { + $invalidProperties[] = "'os_mismatch' can't be null"; + } + if ($this->container['os_not_detected'] === null) { + $invalidProperties[] = "'os_not_detected' can't be null"; + } + if ($this->container['timezone_mismatch'] === null) { + $invalidProperties[] = "'timezone_mismatch' can't be null"; + } + if ($this->container['anti_detect_browser'] === null) { + $invalidProperties[] = "'anti_detect_browser' can't be null"; + } + if ($this->container['browser_automation'] === null) { + $invalidProperties[] = "'browser_automation' can't be null"; + } + if ($this->container['ip_mismatch'] === null) { + $invalidProperties[] = "'ip_mismatch' can't be null"; + } + if ($this->container['incognito'] === null) { + $invalidProperties[] = "'incognito' can't be null"; + } + if ($this->container['search_bot'] === null) { + $invalidProperties[] = "'search_bot' can't be null"; + } + if ($this->container['suspicious_paid_click'] === null) { + $invalidProperties[] = "'suspicious_paid_click' can't be null"; + } + if ($this->container['javascript_disabled'] === null) { + $invalidProperties[] = "'javascript_disabled' can't be null"; + } + if ($this->container['stun_not_checked'] === null) { + $invalidProperties[] = "'stun_not_checked' can't be null"; + } + if ($this->container['check_incomplete'] === null) { + $invalidProperties[] = "'check_incomplete' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets vpn + * + * @return bool + */ + public function getVpn() + { + return $this->container['vpn']; + } + + /** + * Sets vpn + * + * @param bool $vpn A VPN was detected (scored `vpn` signal). + * + * @return self + */ + public function setVpn($vpn) + { + if (is_null($vpn)) { + throw new \InvalidArgumentException('non-nullable vpn cannot be null'); + } + $this->container['vpn'] = $vpn; + + return $this; + } + + /** + * Gets privacy_relay + * + * @return bool + */ + public function getPrivacyRelay() + { + return $this->container['privacy_relay']; + } + + /** + * Sets privacy_relay + * + * @param bool $privacy_relay A privacy relay such as iCloud Private Relay was detected. + * + * @return self + */ + public function setPrivacyRelay($privacy_relay) + { + if (is_null($privacy_relay)) { + throw new \InvalidArgumentException('non-nullable privacy_relay cannot be null'); + } + $this->container['privacy_relay'] = $privacy_relay; + + return $this; + } + + /** + * Gets browser_vpn_proxy + * + * @return bool + */ + public function getBrowserVpnProxy() + { + return $this->container['browser_vpn_proxy']; + } + + /** + * Sets browser_vpn_proxy + * + * @param bool $browser_vpn_proxy A VPN or proxy built into the browser or one of its extensions. `true` exactly when `connection_type` is `browser_vpn_proxy`. + * + * @return self + */ + public function setBrowserVpnProxy($browser_vpn_proxy) + { + if (is_null($browser_vpn_proxy)) { + throw new \InvalidArgumentException('non-nullable browser_vpn_proxy cannot be null'); + } + $this->container['browser_vpn_proxy'] = $browser_vpn_proxy; + + return $this; + } + + /** + * Gets tor + * + * @return bool + */ + public function getTor() + { + return $this->container['tor']; + } + + /** + * Sets tor + * + * @param bool $tor The request came through the Tor network. + * + * @return self + */ + public function setTor($tor) + { + if (is_null($tor)) { + throw new \InvalidArgumentException('non-nullable tor cannot be null'); + } + $this->container['tor'] = $tor; + + return $this; + } + + /** + * Gets proxy + * + * @return bool + */ + public function getProxy() + { + return $this->container['proxy']; + } + + /** + * Sets proxy + * + * @param bool $proxy A proxy was detected. + * + * @return self + */ + public function setProxy($proxy) + { + if (is_null($proxy)) { + throw new \InvalidArgumentException('non-nullable proxy cannot be null'); + } + $this->container['proxy'] = $proxy; + + return $this; + } + + /** + * Gets datacenter_ip + * + * @return bool + */ + public function getDatacenterIp() + { + return $this->container['datacenter_ip']; + } + + /** + * Sets datacenter_ip + * + * @param bool $datacenter_ip The public IP belongs to a datacenter or hosting range. + * + * @return self + */ + public function setDatacenterIp($datacenter_ip) + { + if (is_null($datacenter_ip)) { + throw new \InvalidArgumentException('non-nullable datacenter_ip cannot be null'); + } + $this->container['datacenter_ip'] = $datacenter_ip; + + return $this; + } + + /** + * Gets abuser + * + * @return bool + */ + public function getAbuser() + { + return $this->container['abuser']; + } + + /** + * Sets abuser + * + * @param bool $abuser The public IP has a record of abuse in IP intelligence. + * + * @return self + */ + public function setAbuser($abuser) + { + if (is_null($abuser)) { + throw new \InvalidArgumentException('non-nullable abuser cannot be null'); + } + $this->container['abuser'] = $abuser; + + return $this; + } + + /** + * Gets os_mismatch + * + * @return bool + */ + public function getOsMismatch() + { + return $this->container['os_mismatch']; + } + + /** + * Sets os_mismatch + * + * @param bool $os_mismatch The operating system seen on the network differs from the one the browser reports. + * + * @return self + */ + public function setOsMismatch($os_mismatch) + { + if (is_null($os_mismatch)) { + throw new \InvalidArgumentException('non-nullable os_mismatch cannot be null'); + } + $this->container['os_mismatch'] = $os_mismatch; + + return $this; + } + + /** + * Gets os_not_detected + * + * @return bool + */ + public function getOsNotDetected() + { + return $this->container['os_not_detected']; + } + + /** + * Sets os_not_detected + * + * @param bool $os_not_detected The operating system could not be determined from the User-Agent or the network. + * + * @return self + */ + public function setOsNotDetected($os_not_detected) + { + if (is_null($os_not_detected)) { + throw new \InvalidArgumentException('non-nullable os_not_detected cannot be null'); + } + $this->container['os_not_detected'] = $os_not_detected; + + return $this; + } + + /** + * Gets timezone_mismatch + * + * @return bool + */ + public function getTimezoneMismatch() + { + return $this->container['timezone_mismatch']; + } + + /** + * Sets timezone_mismatch + * + * @param bool $timezone_mismatch The browser timezone differs from the timezone of the IP location. + * + * @return self + */ + public function setTimezoneMismatch($timezone_mismatch) + { + if (is_null($timezone_mismatch)) { + throw new \InvalidArgumentException('non-nullable timezone_mismatch cannot be null'); + } + $this->container['timezone_mismatch'] = $timezone_mismatch; + + return $this; + } + + /** + * Gets anti_detect_browser + * + * @return bool + */ + public function getAntiDetectBrowser() + { + return $this->container['anti_detect_browser']; + } + + /** + * Sets anti_detect_browser + * + * @param bool $anti_detect_browser An anti-detect browser was detected. + * + * @return self + */ + public function setAntiDetectBrowser($anti_detect_browser) + { + if (is_null($anti_detect_browser)) { + throw new \InvalidArgumentException('non-nullable anti_detect_browser cannot be null'); + } + $this->container['anti_detect_browser'] = $anti_detect_browser; + + return $this; + } + + /** + * Gets browser_automation + * + * @return bool + */ + public function getBrowserAutomation() + { + return $this->container['browser_automation']; + } + + /** + * Sets browser_automation + * + * @param bool $browser_automation Browser automation was detected, for example a WebDriver-controlled browser. + * + * @return self + */ + public function setBrowserAutomation($browser_automation) + { + if (is_null($browser_automation)) { + throw new \InvalidArgumentException('non-nullable browser_automation cannot be null'); + } + $this->container['browser_automation'] = $browser_automation; + + return $this; + } + + /** + * Gets ip_mismatch + * + * @return bool + */ + public function getIpMismatch() + { + return $this->container['ip_mismatch']; + } + + /** + * Sets ip_mismatch + * + * @param bool $ip_mismatch The public IP differs from the local IP found by the browser network check. Informational: it does not add to the score. + * + * @return self + */ + public function setIpMismatch($ip_mismatch) + { + if (is_null($ip_mismatch)) { + throw new \InvalidArgumentException('non-nullable ip_mismatch cannot be null'); + } + $this->container['ip_mismatch'] = $ip_mismatch; + + return $this; + } + + /** + * Gets incognito + * + * @return bool + */ + public function getIncognito() + { + return $this->container['incognito']; + } + + /** + * Sets incognito + * + * @param bool $incognito The browser runs in a private window. + * + * @return self + */ + public function setIncognito($incognito) + { + if (is_null($incognito)) { + throw new \InvalidArgumentException('non-nullable incognito cannot be null'); + } + $this->container['incognito'] = $incognito; + + return $this; + } + + /** + * Gets search_bot + * + * @return bool + */ + public function getSearchBot() + { + return $this->container['search_bot']; + } + + /** + * Sets search_bot + * + * @param bool $search_bot A search-engine crawler. Its Risk Score is always 0. + * + * @return self + */ + public function setSearchBot($search_bot) + { + if (is_null($search_bot)) { + throw new \InvalidArgumentException('non-nullable search_bot cannot be null'); + } + $this->container['search_bot'] = $search_bot; + + return $this; + } + + /** + * Gets suspicious_paid_click + * + * @return bool + */ + public function getSuspiciousPaidClick() + { + return $this->container['suspicious_paid_click']; + } + + /** + * Sets suspicious_paid_click + * + * @param bool $suspicious_paid_click The visit came from a paid ad click (Google Ads, Meta, TikTok, Microsoft Ads, LinkedIn, Pinterest or X) and the Risk Score is 60 or more (the 999 marker included). + * + * @return self + */ + public function setSuspiciousPaidClick($suspicious_paid_click) + { + if (is_null($suspicious_paid_click)) { + throw new \InvalidArgumentException('non-nullable suspicious_paid_click cannot be null'); + } + $this->container['suspicious_paid_click'] = $suspicious_paid_click; + + return $this; + } + + /** + * Gets javascript_disabled + * + * @return bool + */ + public function getJavascriptDisabled() + { + return $this->container['javascript_disabled']; + } + + /** + * Sets javascript_disabled + * + * @param bool $javascript_disabled JavaScript, or the browser APIs the checks need, were unavailable. + * + * @return self + */ + public function setJavascriptDisabled($javascript_disabled) + { + if (is_null($javascript_disabled)) { + throw new \InvalidArgumentException('non-nullable javascript_disabled cannot be null'); + } + $this->container['javascript_disabled'] = $javascript_disabled; + + return $this; + } + + /** + * Gets stun_not_checked + * + * @return bool + */ + public function getStunNotChecked() + { + return $this->container['stun_not_checked']; + } + + /** + * Sets stun_not_checked + * + * @param bool $stun_not_checked The browser network (STUN) check did not complete. Cleared again when a late network result arrives. + * + * @return self + */ + public function setStunNotChecked($stun_not_checked) + { + if (is_null($stun_not_checked)) { + throw new \InvalidArgumentException('non-nullable stun_not_checked cannot be null'); + } + $this->container['stun_not_checked'] = $stun_not_checked; + + return $this; + } + + /** + * Gets check_incomplete + * + * @return bool + */ + public function getCheckIncomplete() + { + return $this->container['check_incomplete']; + } + + /** + * Sets check_incomplete + * + * @param bool $check_incomplete Part of the browser checks timed out, so the verdict rests on partial data. Informational. + * + * @return self + */ + public function setCheckIncomplete($check_incomplete) + { + if (is_null($check_incomplete)) { + throw new \InvalidArgumentException('non-nullable check_incomplete cannot be null'); + } + $this->container['check_incomplete'] = $check_incomplete; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/DomainProfile.php b/generated/lib/Model/DomainProfile.php new file mode 100644 index 0000000..7d7eaca --- /dev/null +++ b/generated/lib/Model/DomainProfile.php @@ -0,0 +1,617 @@ + + */ +class DomainProfile implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'DomainProfile'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'domain' => 'string', + 'weight' => 'int', + 'callback' => 'string', + 'public_key' => 'string', + 'secret' => 'string', + 'created_at' => '\DateTime' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'domain' => null, + 'weight' => null, + 'callback' => null, + 'public_key' => null, + 'secret' => null, + 'created_at' => 'date-time' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'domain' => false, + 'weight' => false, + 'callback' => false, + 'public_key' => false, + 'secret' => false, + 'created_at' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'domain' => 'Domain', + 'weight' => 'Weight', + 'callback' => 'Callback', + 'public_key' => 'PublicKey', + 'secret' => 'Secret', + 'created_at' => 'CreatedAt' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'domain' => 'setDomain', + 'weight' => 'setWeight', + 'callback' => 'setCallback', + 'public_key' => 'setPublicKey', + 'secret' => 'setSecret', + 'created_at' => 'setCreatedAt' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'domain' => 'getDomain', + 'weight' => 'getWeight', + 'callback' => 'getCallback', + 'public_key' => 'getPublicKey', + 'secret' => 'getSecret', + 'created_at' => 'getCreatedAt' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('domain', $data ?? [], null); + $this->setIfExists('weight', $data ?? [], null); + $this->setIfExists('callback', $data ?? [], null); + $this->setIfExists('public_key', $data ?? [], null); + $this->setIfExists('secret', $data ?? [], null); + $this->setIfExists('created_at', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['domain'] === null) { + $invalidProperties[] = "'domain' can't be null"; + } + if ($this->container['weight'] === null) { + $invalidProperties[] = "'weight' can't be null"; + } + if ($this->container['callback'] === null) { + $invalidProperties[] = "'callback' can't be null"; + } + if ($this->container['public_key'] === null) { + $invalidProperties[] = "'public_key' can't be null"; + } + if (!preg_match("/^(\\*+.{4}|.{0,4})$/", $this->container['public_key'])) { + $invalidProperties[] = "invalid value for 'public_key', must be conform to the pattern /^(\\*+.{4}|.{0,4})$/."; + } + + if ($this->container['secret'] === null) { + $invalidProperties[] = "'secret' can't be null"; + } + if (!preg_match("/^(\\*+.{4}|.{0,4})$/", $this->container['secret'])) { + $invalidProperties[] = "invalid value for 'secret', must be conform to the pattern /^(\\*+.{4}|.{0,4})$/."; + } + + if ($this->container['created_at'] === null) { + $invalidProperties[] = "'created_at' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets domain + * + * @return string + */ + public function getDomain() + { + return $this->container['domain']; + } + + /** + * Sets domain + * + * @param string $domain The registered domain, as sent in `X-Shield-Domain`. + * + * @return self + */ + public function setDomain($domain) + { + if (is_null($domain)) { + throw new \InvalidArgumentException('non-nullable domain cannot be null'); + } + $this->container['domain'] = $domain; + + return $this; + } + + /** + * Gets weight + * + * @return int + */ + public function getWeight() + { + return $this->container['weight']; + } + + /** + * Sets weight + * + * @param int $weight Remaining included identifications of the account (shared by its domains). Can be negative when the account is over its included volume. + * + * @return self + */ + public function setWeight($weight) + { + if (is_null($weight)) { + throw new \InvalidArgumentException('non-nullable weight cannot be null'); + } + $this->container['weight'] = $weight; + + return $this; + } + + /** + * Gets callback + * + * @return string + */ + public function getCallback() + { + return $this->container['callback']; + } + + /** + * Sets callback + * + * @param string $callback Legacy field kept for compatibility, normally an empty string. Webhook deliveries do not use it: configure webhook endpoints in the analytics dashboard. + * + * @return self + */ + public function setCallback($callback) + { + if (is_null($callback)) { + throw new \InvalidArgumentException('non-nullable callback cannot be null'); + } + $this->container['callback'] = $callback; + + return $this; + } + + /** + * Gets public_key + * + * @return string + */ + public function getPublicKey() + { + return $this->container['public_key']; + } + + /** + * Sets public_key + * + * @param string $public_key The domain's Public Key, masked. + * + * @return self + */ + public function setPublicKey($public_key) + { + if (is_null($public_key)) { + throw new \InvalidArgumentException('non-nullable public_key cannot be null'); + } + + if ((!preg_match("/^(\\*+.{4}|.{0,4})$/", ObjectSerializer::toString($public_key)))) { + throw new \InvalidArgumentException("invalid value for \$public_key when calling DomainProfile., must conform to the pattern /^(\\*+.{4}|.{0,4})$/."); + } + + $this->container['public_key'] = $public_key; + + return $this; + } + + /** + * Gets secret + * + * @return string + */ + public function getSecret() + { + return $this->container['secret']; + } + + /** + * Sets secret + * + * @param string $secret The domain's Secret Key, masked. + * + * @return self + */ + public function setSecret($secret) + { + if (is_null($secret)) { + throw new \InvalidArgumentException('non-nullable secret cannot be null'); + } + + if ((!preg_match("/^(\\*+.{4}|.{0,4})$/", ObjectSerializer::toString($secret)))) { + throw new \InvalidArgumentException("invalid value for \$secret when calling DomainProfile., must conform to the pattern /^(\\*+.{4}|.{0,4})$/."); + } + + $this->container['secret'] = $secret; + + return $this; + } + + /** + * Gets created_at + * + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->container['created_at']; + } + + /** + * Sets created_at + * + * @param \DateTime $created_at When the domain was registered, RFC 3339 in UTC with second precision. `0001-01-01T00:00:00Z` when unknown. + * + * @return self + */ + public function setCreatedAt($created_at) + { + if (is_null($created_at)) { + throw new \InvalidArgumentException('non-nullable created_at cannot be null'); + } + $this->container['created_at'] = $created_at; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/ErrorBody.php b/generated/lib/Model/ErrorBody.php new file mode 100644 index 0000000..9d4a9c0 --- /dev/null +++ b/generated/lib/Model/ErrorBody.php @@ -0,0 +1,414 @@ + + */ +class ErrorBody implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ErrorBody'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'error' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'error' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'error' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'error' => 'error' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'error' => 'setError' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'error' => 'getError' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('error', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['error'] === null) { + $invalidProperties[] = "'error' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets error + * + * @return string + */ + public function getError() + { + return $this->container['error']; + } + + /** + * Sets error + * + * @param string $error Human-readable error message. Branch on the HTTP status, not on this text. + * + * @return self + */ + public function setError($error) + { + if (is_null($error)) { + throw new \InvalidArgumentException('non-nullable error cannot be null'); + } + $this->container['error'] = $error; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/HealthStatus.php b/generated/lib/Model/HealthStatus.php new file mode 100644 index 0000000..77c7ece --- /dev/null +++ b/generated/lib/Model/HealthStatus.php @@ -0,0 +1,446 @@ + + */ +class HealthStatus implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'HealthStatus'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'status' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'status' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'status' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'status' => 'status' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'status' => 'setStatus' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'status' => 'getStatus' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + public const STATUS_OK = 'ok'; + + /** + * Gets allowable values of the enum + * + * @return string[] + */ + public function getStatusAllowableValues() + { + return [ + self::STATUS_OK, + ]; + } + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('status', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['status'] === null) { + $invalidProperties[] = "'status' can't be null"; + } + $allowedValues = $this->getStatusAllowableValues(); + if (!is_null($this->container['status']) && !in_array($this->container['status'], $allowedValues, true)) { + $invalidProperties[] = sprintf( + "invalid value '%s' for 'status', must be one of '%s'", + $this->container['status'], + implode("', '", $allowedValues) + ); + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets status + * + * @return string + */ + public function getStatus() + { + return $this->container['status']; + } + + /** + * Sets status + * + * @param string $status Always `ok` when the service answers. + * + * @return self + */ + public function setStatus($status) + { + if (is_null($status)) { + throw new \InvalidArgumentException('non-nullable status cannot be null'); + } + $allowedValues = $this->getStatusAllowableValues(); + if (!in_array($status, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf( + "Invalid value '%s' for 'status', must be one of '%s'", + $status, + implode("', '", $allowedValues) + ) + ); + } + $this->container['status'] = $status; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/HistoryPage.php b/generated/lib/Model/HistoryPage.php new file mode 100644 index 0000000..d6a1302 --- /dev/null +++ b/generated/lib/Model/HistoryPage.php @@ -0,0 +1,460 @@ + + */ +class HistoryPage implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'HistoryPage'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'data' => '\ShieldLabs\Generated\Model\HistoryRow[]', + 'total' => 'int' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'data' => null, + 'total' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'data' => false, + 'total' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'data' => 'data', + 'total' => 'total' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'data' => 'setData', + 'total' => 'setTotal' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'data' => 'getData', + 'total' => 'getTotal' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('data', $data ?? [], null); + $this->setIfExists('total', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['data'] === null) { + $invalidProperties[] = "'data' can't be null"; + } + if ($this->container['total'] === null) { + $invalidProperties[] = "'total' can't be null"; + } + if (($this->container['total'] < 0)) { + $invalidProperties[] = "invalid value for 'total', must be bigger than or equal to 0."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets data + * + * @return \ShieldLabs\Generated\Model\HistoryRow[] + */ + public function getData() + { + return $this->container['data']; + } + + /** + * Sets data + * + * @param \ShieldLabs\Generated\Model\HistoryRow[] $data Identifications on this page, ordered by `created_at` descending. Empty when nothing matched. + * + * @return self + */ + public function setData($data) + { + if (is_null($data)) { + throw new \InvalidArgumentException('non-nullable data cannot be null'); + } + $this->container['data'] = $data; + + return $this; + } + + /** + * Gets total + * + * @return int + */ + public function getTotal() + { + return $this->container['total']; + } + + /** + * Sets total + * + * @param int $total Number of identifications that match the search in total, across all pages. Page with `offset` while it is below `total`. + * + * @return self + */ + public function setTotal($total) + { + if (is_null($total)) { + throw new \InvalidArgumentException('non-nullable total cannot be null'); + } + + if (($total < 0)) { + throw new \InvalidArgumentException('invalid value for $total when calling HistoryPage., must be bigger than or equal to 0.'); + } + + $this->container['total'] = $total; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/HistoryRow.php b/generated/lib/Model/HistoryRow.php new file mode 100644 index 0000000..6938273 --- /dev/null +++ b/generated/lib/Model/HistoryRow.php @@ -0,0 +1,2317 @@ + + */ +class HistoryRow implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'HistoryRow'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'request_id' => 'string', + 'session_id' => 'string', + 'cookie_id' => 'string', + 'domain' => 'string', + 'site_domain' => 'string', + 'user_hid' => 'string', + 'device_id' => 'string', + 'visitor_id' => 'string', + 'ip' => 'string', + 'os' => 'string', + 'browser' => 'string', + 'device_type' => 'string', + 'country' => 'string', + 'connection_type' => 'string', + 'score' => 'int', + 'score_details' => 'string', + 'created_at' => 'string', + 'ver' => 'int', + 'web_rtc_ip' => 'string', + 'web_rtc_country' => 'string', + 'web_rtc_connection_type' => 'string', + 'webrtc_leak_ip' => 'string', + 'webrtc_leak_country' => 'string', + 'webrtc_leak_connection_type' => 'string', + 'webrtc_leak_source' => 'string', + 'is_vpn' => 'bool', + 'is_tor' => 'bool', + 'is_proxy' => 'bool', + 'is_datacenter' => 'bool', + 'is_abuser' => 'bool', + 'is_privacy_relay' => 'bool', + 'is_stun_not_checked' => 'bool', + 'check_incomplete' => 'bool', + 'is_antidetect' => 'bool', + 'is_os_mismatch' => 'bool', + 'is_os_not_detected' => 'bool', + 'is_timezone_mismatch' => 'bool', + 'is_js_disabled' => 'bool', + 'is_browser_automation' => 'bool', + 'is_incognito' => 'bool', + 'is_search_bot' => 'bool', + 'is_suspicious_paid_click' => 'bool', + 'entry_url' => 'string', + 'utm_source' => 'string', + 'utm_medium' => 'string', + 'utm_campaign' => 'string', + 'utm_content' => 'string', + 'utm_term' => 'string', + 'traffic_channel' => 'string', + 'traffic_channel_group' => 'string', + 'traffic_reason' => 'string', + 'referrer_domain' => 'string', + 'click_id_type' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'request_id' => 'uuid', + 'session_id' => 'uuid', + 'cookie_id' => 'uuid', + 'domain' => null, + 'site_domain' => null, + 'user_hid' => null, + 'device_id' => 'uuid', + 'visitor_id' => 'uuid', + 'ip' => 'ipv4', + 'os' => null, + 'browser' => null, + 'device_type' => null, + 'country' => null, + 'connection_type' => null, + 'score' => null, + 'score_details' => null, + 'created_at' => null, + 'ver' => 'int64', + 'web_rtc_ip' => 'ipv4', + 'web_rtc_country' => null, + 'web_rtc_connection_type' => null, + 'webrtc_leak_ip' => 'ipv4', + 'webrtc_leak_country' => null, + 'webrtc_leak_connection_type' => null, + 'webrtc_leak_source' => null, + 'is_vpn' => null, + 'is_tor' => null, + 'is_proxy' => null, + 'is_datacenter' => null, + 'is_abuser' => null, + 'is_privacy_relay' => null, + 'is_stun_not_checked' => null, + 'check_incomplete' => null, + 'is_antidetect' => null, + 'is_os_mismatch' => null, + 'is_os_not_detected' => null, + 'is_timezone_mismatch' => null, + 'is_js_disabled' => null, + 'is_browser_automation' => null, + 'is_incognito' => null, + 'is_search_bot' => null, + 'is_suspicious_paid_click' => null, + 'entry_url' => null, + 'utm_source' => null, + 'utm_medium' => null, + 'utm_campaign' => null, + 'utm_content' => null, + 'utm_term' => null, + 'traffic_channel' => null, + 'traffic_channel_group' => null, + 'traffic_reason' => null, + 'referrer_domain' => null, + 'click_id_type' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'request_id' => false, + 'session_id' => false, + 'cookie_id' => false, + 'domain' => false, + 'site_domain' => false, + 'user_hid' => false, + 'device_id' => false, + 'visitor_id' => false, + 'ip' => false, + 'os' => false, + 'browser' => false, + 'device_type' => false, + 'country' => false, + 'connection_type' => false, + 'score' => false, + 'score_details' => false, + 'created_at' => false, + 'ver' => false, + 'web_rtc_ip' => false, + 'web_rtc_country' => false, + 'web_rtc_connection_type' => false, + 'webrtc_leak_ip' => false, + 'webrtc_leak_country' => false, + 'webrtc_leak_connection_type' => false, + 'webrtc_leak_source' => false, + 'is_vpn' => false, + 'is_tor' => false, + 'is_proxy' => false, + 'is_datacenter' => false, + 'is_abuser' => false, + 'is_privacy_relay' => false, + 'is_stun_not_checked' => false, + 'check_incomplete' => false, + 'is_antidetect' => false, + 'is_os_mismatch' => false, + 'is_os_not_detected' => false, + 'is_timezone_mismatch' => false, + 'is_js_disabled' => false, + 'is_browser_automation' => false, + 'is_incognito' => false, + 'is_search_bot' => false, + 'is_suspicious_paid_click' => false, + 'entry_url' => false, + 'utm_source' => false, + 'utm_medium' => false, + 'utm_campaign' => false, + 'utm_content' => false, + 'utm_term' => false, + 'traffic_channel' => false, + 'traffic_channel_group' => false, + 'traffic_reason' => false, + 'referrer_domain' => false, + 'click_id_type' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'request_id' => 'request_id', + 'session_id' => 'session_id', + 'cookie_id' => 'cookie_id', + 'domain' => 'domain', + 'site_domain' => 'site_domain', + 'user_hid' => 'user_hid', + 'device_id' => 'device_id', + 'visitor_id' => 'visitor_id', + 'ip' => 'ip', + 'os' => 'os', + 'browser' => 'browser', + 'device_type' => 'device_type', + 'country' => 'country', + 'connection_type' => 'connection_type', + 'score' => 'score', + 'score_details' => 'score_details', + 'created_at' => 'created_at', + 'ver' => 'ver', + 'web_rtc_ip' => 'web_rtc_ip', + 'web_rtc_country' => 'web_rtc_country', + 'web_rtc_connection_type' => 'web_rtc_connection_type', + 'webrtc_leak_ip' => 'webrtc_leak_ip', + 'webrtc_leak_country' => 'webrtc_leak_country', + 'webrtc_leak_connection_type' => 'webrtc_leak_connection_type', + 'webrtc_leak_source' => 'webrtc_leak_source', + 'is_vpn' => 'is_vpn', + 'is_tor' => 'is_tor', + 'is_proxy' => 'is_proxy', + 'is_datacenter' => 'is_datacenter', + 'is_abuser' => 'is_abuser', + 'is_privacy_relay' => 'is_privacy_relay', + 'is_stun_not_checked' => 'is_stun_not_checked', + 'check_incomplete' => 'check_incomplete', + 'is_antidetect' => 'is_antidetect', + 'is_os_mismatch' => 'is_os_mismatch', + 'is_os_not_detected' => 'is_os_not_detected', + 'is_timezone_mismatch' => 'is_timezone_mismatch', + 'is_js_disabled' => 'is_js_disabled', + 'is_browser_automation' => 'is_browser_automation', + 'is_incognito' => 'is_incognito', + 'is_search_bot' => 'is_search_bot', + 'is_suspicious_paid_click' => 'is_suspicious_paid_click', + 'entry_url' => 'entry_url', + 'utm_source' => 'utm_source', + 'utm_medium' => 'utm_medium', + 'utm_campaign' => 'utm_campaign', + 'utm_content' => 'utm_content', + 'utm_term' => 'utm_term', + 'traffic_channel' => 'traffic_channel', + 'traffic_channel_group' => 'traffic_channel_group', + 'traffic_reason' => 'traffic_reason', + 'referrer_domain' => 'referrer_domain', + 'click_id_type' => 'click_id_type' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'request_id' => 'setRequestId', + 'session_id' => 'setSessionId', + 'cookie_id' => 'setCookieId', + 'domain' => 'setDomain', + 'site_domain' => 'setSiteDomain', + 'user_hid' => 'setUserHid', + 'device_id' => 'setDeviceId', + 'visitor_id' => 'setVisitorId', + 'ip' => 'setIp', + 'os' => 'setOs', + 'browser' => 'setBrowser', + 'device_type' => 'setDeviceType', + 'country' => 'setCountry', + 'connection_type' => 'setConnectionType', + 'score' => 'setScore', + 'score_details' => 'setScoreDetails', + 'created_at' => 'setCreatedAt', + 'ver' => 'setVer', + 'web_rtc_ip' => 'setWebRtcIp', + 'web_rtc_country' => 'setWebRtcCountry', + 'web_rtc_connection_type' => 'setWebRtcConnectionType', + 'webrtc_leak_ip' => 'setWebrtcLeakIp', + 'webrtc_leak_country' => 'setWebrtcLeakCountry', + 'webrtc_leak_connection_type' => 'setWebrtcLeakConnectionType', + 'webrtc_leak_source' => 'setWebrtcLeakSource', + 'is_vpn' => 'setIsVpn', + 'is_tor' => 'setIsTor', + 'is_proxy' => 'setIsProxy', + 'is_datacenter' => 'setIsDatacenter', + 'is_abuser' => 'setIsAbuser', + 'is_privacy_relay' => 'setIsPrivacyRelay', + 'is_stun_not_checked' => 'setIsStunNotChecked', + 'check_incomplete' => 'setCheckIncomplete', + 'is_antidetect' => 'setIsAntidetect', + 'is_os_mismatch' => 'setIsOsMismatch', + 'is_os_not_detected' => 'setIsOsNotDetected', + 'is_timezone_mismatch' => 'setIsTimezoneMismatch', + 'is_js_disabled' => 'setIsJsDisabled', + 'is_browser_automation' => 'setIsBrowserAutomation', + 'is_incognito' => 'setIsIncognito', + 'is_search_bot' => 'setIsSearchBot', + 'is_suspicious_paid_click' => 'setIsSuspiciousPaidClick', + 'entry_url' => 'setEntryUrl', + 'utm_source' => 'setUtmSource', + 'utm_medium' => 'setUtmMedium', + 'utm_campaign' => 'setUtmCampaign', + 'utm_content' => 'setUtmContent', + 'utm_term' => 'setUtmTerm', + 'traffic_channel' => 'setTrafficChannel', + 'traffic_channel_group' => 'setTrafficChannelGroup', + 'traffic_reason' => 'setTrafficReason', + 'referrer_domain' => 'setReferrerDomain', + 'click_id_type' => 'setClickIdType' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'request_id' => 'getRequestId', + 'session_id' => 'getSessionId', + 'cookie_id' => 'getCookieId', + 'domain' => 'getDomain', + 'site_domain' => 'getSiteDomain', + 'user_hid' => 'getUserHid', + 'device_id' => 'getDeviceId', + 'visitor_id' => 'getVisitorId', + 'ip' => 'getIp', + 'os' => 'getOs', + 'browser' => 'getBrowser', + 'device_type' => 'getDeviceType', + 'country' => 'getCountry', + 'connection_type' => 'getConnectionType', + 'score' => 'getScore', + 'score_details' => 'getScoreDetails', + 'created_at' => 'getCreatedAt', + 'ver' => 'getVer', + 'web_rtc_ip' => 'getWebRtcIp', + 'web_rtc_country' => 'getWebRtcCountry', + 'web_rtc_connection_type' => 'getWebRtcConnectionType', + 'webrtc_leak_ip' => 'getWebrtcLeakIp', + 'webrtc_leak_country' => 'getWebrtcLeakCountry', + 'webrtc_leak_connection_type' => 'getWebrtcLeakConnectionType', + 'webrtc_leak_source' => 'getWebrtcLeakSource', + 'is_vpn' => 'getIsVpn', + 'is_tor' => 'getIsTor', + 'is_proxy' => 'getIsProxy', + 'is_datacenter' => 'getIsDatacenter', + 'is_abuser' => 'getIsAbuser', + 'is_privacy_relay' => 'getIsPrivacyRelay', + 'is_stun_not_checked' => 'getIsStunNotChecked', + 'check_incomplete' => 'getCheckIncomplete', + 'is_antidetect' => 'getIsAntidetect', + 'is_os_mismatch' => 'getIsOsMismatch', + 'is_os_not_detected' => 'getIsOsNotDetected', + 'is_timezone_mismatch' => 'getIsTimezoneMismatch', + 'is_js_disabled' => 'getIsJsDisabled', + 'is_browser_automation' => 'getIsBrowserAutomation', + 'is_incognito' => 'getIsIncognito', + 'is_search_bot' => 'getIsSearchBot', + 'is_suspicious_paid_click' => 'getIsSuspiciousPaidClick', + 'entry_url' => 'getEntryUrl', + 'utm_source' => 'getUtmSource', + 'utm_medium' => 'getUtmMedium', + 'utm_campaign' => 'getUtmCampaign', + 'utm_content' => 'getUtmContent', + 'utm_term' => 'getUtmTerm', + 'traffic_channel' => 'getTrafficChannel', + 'traffic_channel_group' => 'getTrafficChannelGroup', + 'traffic_reason' => 'getTrafficReason', + 'referrer_domain' => 'getReferrerDomain', + 'click_id_type' => 'getClickIdType' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('request_id', $data ?? [], null); + $this->setIfExists('session_id', $data ?? [], null); + $this->setIfExists('cookie_id', $data ?? [], null); + $this->setIfExists('domain', $data ?? [], null); + $this->setIfExists('site_domain', $data ?? [], null); + $this->setIfExists('user_hid', $data ?? [], null); + $this->setIfExists('device_id', $data ?? [], null); + $this->setIfExists('visitor_id', $data ?? [], null); + $this->setIfExists('ip', $data ?? [], null); + $this->setIfExists('os', $data ?? [], null); + $this->setIfExists('browser', $data ?? [], null); + $this->setIfExists('device_type', $data ?? [], null); + $this->setIfExists('country', $data ?? [], null); + $this->setIfExists('connection_type', $data ?? [], null); + $this->setIfExists('score', $data ?? [], null); + $this->setIfExists('score_details', $data ?? [], null); + $this->setIfExists('created_at', $data ?? [], null); + $this->setIfExists('ver', $data ?? [], null); + $this->setIfExists('web_rtc_ip', $data ?? [], null); + $this->setIfExists('web_rtc_country', $data ?? [], null); + $this->setIfExists('web_rtc_connection_type', $data ?? [], null); + $this->setIfExists('webrtc_leak_ip', $data ?? [], null); + $this->setIfExists('webrtc_leak_country', $data ?? [], null); + $this->setIfExists('webrtc_leak_connection_type', $data ?? [], null); + $this->setIfExists('webrtc_leak_source', $data ?? [], null); + $this->setIfExists('is_vpn', $data ?? [], null); + $this->setIfExists('is_tor', $data ?? [], null); + $this->setIfExists('is_proxy', $data ?? [], null); + $this->setIfExists('is_datacenter', $data ?? [], null); + $this->setIfExists('is_abuser', $data ?? [], null); + $this->setIfExists('is_privacy_relay', $data ?? [], null); + $this->setIfExists('is_stun_not_checked', $data ?? [], null); + $this->setIfExists('check_incomplete', $data ?? [], null); + $this->setIfExists('is_antidetect', $data ?? [], null); + $this->setIfExists('is_os_mismatch', $data ?? [], null); + $this->setIfExists('is_os_not_detected', $data ?? [], null); + $this->setIfExists('is_timezone_mismatch', $data ?? [], null); + $this->setIfExists('is_js_disabled', $data ?? [], null); + $this->setIfExists('is_browser_automation', $data ?? [], null); + $this->setIfExists('is_incognito', $data ?? [], null); + $this->setIfExists('is_search_bot', $data ?? [], null); + $this->setIfExists('is_suspicious_paid_click', $data ?? [], null); + $this->setIfExists('entry_url', $data ?? [], null); + $this->setIfExists('utm_source', $data ?? [], null); + $this->setIfExists('utm_medium', $data ?? [], null); + $this->setIfExists('utm_campaign', $data ?? [], null); + $this->setIfExists('utm_content', $data ?? [], null); + $this->setIfExists('utm_term', $data ?? [], null); + $this->setIfExists('traffic_channel', $data ?? [], null); + $this->setIfExists('traffic_channel_group', $data ?? [], null); + $this->setIfExists('traffic_reason', $data ?? [], null); + $this->setIfExists('referrer_domain', $data ?? [], null); + $this->setIfExists('click_id_type', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['request_id'] === null) { + $invalidProperties[] = "'request_id' can't be null"; + } + if ($this->container['session_id'] === null) { + $invalidProperties[] = "'session_id' can't be null"; + } + if ($this->container['cookie_id'] === null) { + $invalidProperties[] = "'cookie_id' can't be null"; + } + if ($this->container['domain'] === null) { + $invalidProperties[] = "'domain' can't be null"; + } + if ($this->container['user_hid'] === null) { + $invalidProperties[] = "'user_hid' can't be null"; + } + if ($this->container['device_id'] === null) { + $invalidProperties[] = "'device_id' can't be null"; + } + if ($this->container['visitor_id'] === null) { + $invalidProperties[] = "'visitor_id' can't be null"; + } + if ($this->container['ip'] === null) { + $invalidProperties[] = "'ip' can't be null"; + } + if ($this->container['os'] === null) { + $invalidProperties[] = "'os' can't be null"; + } + if ($this->container['browser'] === null) { + $invalidProperties[] = "'browser' can't be null"; + } + if ($this->container['device_type'] === null) { + $invalidProperties[] = "'device_type' can't be null"; + } + if ($this->container['country'] === null) { + $invalidProperties[] = "'country' can't be null"; + } + if ($this->container['connection_type'] === null) { + $invalidProperties[] = "'connection_type' can't be null"; + } + if ($this->container['score'] === null) { + $invalidProperties[] = "'score' can't be null"; + } + if (($this->container['score'] < 0)) { + $invalidProperties[] = "invalid value for 'score', must be bigger than or equal to 0."; + } + + if ($this->container['score_details'] === null) { + $invalidProperties[] = "'score_details' can't be null"; + } + if ($this->container['created_at'] === null) { + $invalidProperties[] = "'created_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{3})?$/", $this->container['created_at'])) { + $invalidProperties[] = "invalid value for 'created_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{3})?$/."; + } + + if ($this->container['ver'] === null) { + $invalidProperties[] = "'ver' can't be null"; + } + if ($this->container['web_rtc_ip'] === null) { + $invalidProperties[] = "'web_rtc_ip' can't be null"; + } + if ($this->container['web_rtc_country'] === null) { + $invalidProperties[] = "'web_rtc_country' can't be null"; + } + if ($this->container['web_rtc_connection_type'] === null) { + $invalidProperties[] = "'web_rtc_connection_type' can't be null"; + } + if ($this->container['webrtc_leak_ip'] === null) { + $invalidProperties[] = "'webrtc_leak_ip' can't be null"; + } + if ($this->container['webrtc_leak_country'] === null) { + $invalidProperties[] = "'webrtc_leak_country' can't be null"; + } + if ($this->container['webrtc_leak_connection_type'] === null) { + $invalidProperties[] = "'webrtc_leak_connection_type' can't be null"; + } + if ($this->container['webrtc_leak_source'] === null) { + $invalidProperties[] = "'webrtc_leak_source' can't be null"; + } + if ($this->container['is_vpn'] === null) { + $invalidProperties[] = "'is_vpn' can't be null"; + } + if ($this->container['is_tor'] === null) { + $invalidProperties[] = "'is_tor' can't be null"; + } + if ($this->container['is_proxy'] === null) { + $invalidProperties[] = "'is_proxy' can't be null"; + } + if ($this->container['is_datacenter'] === null) { + $invalidProperties[] = "'is_datacenter' can't be null"; + } + if ($this->container['is_abuser'] === null) { + $invalidProperties[] = "'is_abuser' can't be null"; + } + if ($this->container['is_privacy_relay'] === null) { + $invalidProperties[] = "'is_privacy_relay' can't be null"; + } + if ($this->container['is_stun_not_checked'] === null) { + $invalidProperties[] = "'is_stun_not_checked' can't be null"; + } + if ($this->container['check_incomplete'] === null) { + $invalidProperties[] = "'check_incomplete' can't be null"; + } + if ($this->container['is_antidetect'] === null) { + $invalidProperties[] = "'is_antidetect' can't be null"; + } + if ($this->container['is_os_mismatch'] === null) { + $invalidProperties[] = "'is_os_mismatch' can't be null"; + } + if ($this->container['is_os_not_detected'] === null) { + $invalidProperties[] = "'is_os_not_detected' can't be null"; + } + if ($this->container['is_timezone_mismatch'] === null) { + $invalidProperties[] = "'is_timezone_mismatch' can't be null"; + } + if ($this->container['is_js_disabled'] === null) { + $invalidProperties[] = "'is_js_disabled' can't be null"; + } + if ($this->container['is_browser_automation'] === null) { + $invalidProperties[] = "'is_browser_automation' can't be null"; + } + if ($this->container['is_incognito'] === null) { + $invalidProperties[] = "'is_incognito' can't be null"; + } + if ($this->container['is_search_bot'] === null) { + $invalidProperties[] = "'is_search_bot' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets request_id + * + * @return string + */ + public function getRequestId() + { + return $this->container['request_id']; + } + + /** + * Sets request_id + * + * @param string $request_id Identifies one identification. The browser creates it as a UUID v4 and hands it to your page; it is the join key between the browser, the webhook and the History API. The nil UUID appears only on rate-limit marker rows that arrived with a malformed request ID. + * + * @return self + */ + public function setRequestId($request_id) + { + if (is_null($request_id)) { + throw new \InvalidArgumentException('non-nullable request_id cannot be null'); + } + $this->container['request_id'] = $request_id; + + return $this; + } + + /** + * Gets session_id + * + * @return string + */ + public function getSessionId() + { + return $this->container['session_id']; + } + + /** + * Sets session_id + * + * @param string $session_id One visit on one origin (UUID v4 created in the browser), shared by the open tabs of that origin. The next visit after the last tab closes gets a new session ID. The nil UUID appears on rate-limit marker rows. + * + * @return self + */ + public function setSessionId($session_id) + { + if (is_null($session_id)) { + throw new \InvalidArgumentException('non-nullable session_id cannot be null'); + } + $this->container['session_id'] = $session_id; + + return $this; + } + + /** + * Gets cookie_id + * + * @return string + */ + public function getCookieId() + { + return $this->container['cookie_id']; + } + + /** + * Sets cookie_id + * + * @param string $cookie_id First-party browser identifier kept by the ShieldLabs agent (UUID v4). A missing or malformed value is stored as the nil UUID. + * + * @return self + */ + public function setCookieId($cookie_id) + { + if (is_null($cookie_id)) { + throw new \InvalidArgumentException('non-nullable cookie_id cannot be null'); + } + $this->container['cookie_id'] = $cookie_id; + + return $this; + } + + /** + * Gets domain + * + * @return string + */ + public function getDomain() + { + return $this->container['domain']; + } + + /** + * Sets domain + * + * @param string $domain Host the identification came from. Can be a subdomain of your registered domain. + * + * @return self + */ + public function setDomain($domain) + { + if (is_null($domain)) { + throw new \InvalidArgumentException('non-nullable domain cannot be null'); + } + $this->container['domain'] = $domain; + + return $this; + } + + /** + * Gets site_domain + * + * @return string|null + */ + public function getSiteDomain() + { + return $this->container['site_domain']; + } + + /** + * Sets site_domain + * + * @param string|null $site_domain Your registered domain, present when the identification came from a subdomain. Omitted when empty. + * + * @return self + */ + public function setSiteDomain($site_domain) + { + if (is_null($site_domain)) { + throw new \InvalidArgumentException('non-nullable site_domain cannot be null'); + } + $this->container['site_domain'] = $site_domain; + + return $this; + } + + /** + * Gets user_hid + * + * @return string + */ + public function getUserHid() + { + return $this->container['user_hid']; + } + + /** + * Sets user_hid + * + * @param string $user_hid User HID exactly as it was passed to the agent (hashed or pseudonymous account identifier). `anonymous` for anonymous checks; `fail`, `-1` and `unknown` also mean \"no user\". Empty string when no value was stored. Leave the empty string and these values out when you count accounts. + * + * @return self + */ + public function setUserHid($user_hid) + { + if (is_null($user_hid)) { + throw new \InvalidArgumentException('non-nullable user_hid cannot be null'); + } + $this->container['user_hid'] = $user_hid; + + return $this; + } + + /** + * Gets device_id + * + * @return string + */ + public function getDeviceId() + { + return $this->container['device_id']; + } + + /** + * Sets device_id + * + * @param string $device_id Server-side device identifier (UUID v5). It survives cleared cookies and private windows. The nil UUID `00000000-0000-0000-0000-000000000000` means that no usable device signals were collected (for example on rate-limit marker rows): never group identifications by it. + * + * @return self + */ + public function setDeviceId($device_id) + { + if (is_null($device_id)) { + throw new \InvalidArgumentException('non-nullable device_id cannot be null'); + } + $this->container['device_id'] = $device_id; + + return $this; + } + + /** + * Gets visitor_id + * + * @return string + */ + public function getVisitorId() + { + return $this->container['visitor_id']; + } + + /** + * Sets visitor_id + * + * @param string $visitor_id Server-side visitor identifier (UUID v5). It is sticky to the device: a new cookie on a known device keeps the existing visitor ID, so clearing cookies usually does not change it. The nil UUID appears on identifications without usable device data, such as rate-limit marker rows. + * + * @return self + */ + public function setVisitorId($visitor_id) + { + if (is_null($visitor_id)) { + throw new \InvalidArgumentException('non-nullable visitor_id cannot be null'); + } + $this->container['visitor_id'] = $visitor_id; + + return $this; + } + + /** + * Gets ip + * + * @return string + */ + public function getIp() + { + return $this->container['ip']; + } + + /** + * Sets ip + * + * @param string $ip Public IPv4 address of the HTTP request; `0.0.0.0` when none (for example IPv6 visitors). + * + * @return self + */ + public function setIp($ip) + { + if (is_null($ip)) { + throw new \InvalidArgumentException('non-nullable ip cannot be null'); + } + $this->container['ip'] = $ip; + + return $this; + } + + /** + * Gets os + * + * @return string + */ + public function getOs() + { + return $this->container['os']; + } + + /** + * Sets os + * + * @param string $os Operating system name, for example `Windows`, `Mac OS X`, `Linux`, `Android`, `IOS (iPhone)`, `IOS (iPad)`, `ChromeOS` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setOs($os) + { + if (is_null($os)) { + throw new \InvalidArgumentException('non-nullable os cannot be null'); + } + $this->container['os'] = $os; + + return $this; + } + + /** + * Gets browser + * + * @return string + */ + public function getBrowser() + { + return $this->container['browser']; + } + + /** + * Sets browser + * + * @param string $browser Browser name, for example `Chrome`, `Safari`, `Firefox`, `Microsoft Edge`, `Opera`, `Samsung Internet`, `Brave`, `Chrome (iOS)`, `Safari (iOS)` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setBrowser($browser) + { + if (is_null($browser)) { + throw new \InvalidArgumentException('non-nullable browser cannot be null'); + } + $this->container['browser'] = $browser; + + return $this; + } + + /** + * Gets device_type + * + * @return string + */ + public function getDeviceType() + { + return $this->container['device_type']; + } + + /** + * Sets device_type + * + * @param string $device_type Device class from the browser. Known values: `desktop`, `mobile`, `tablet` and `unknown` (the class could not be determined). The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setDeviceType($device_type) + { + if (is_null($device_type)) { + throw new \InvalidArgumentException('non-nullable device_type cannot be null'); + } + $this->container['device_type'] = $device_type; + + return $this; + } + + /** + * Gets country + * + * @return string + */ + public function getCountry() + { + return $this->container['country']; + } + + /** + * Sets country + * + * @param string $country Country of `ip` as an English country name, or an empty string. + * + * @return self + */ + public function setCountry($country) + { + if (is_null($country)) { + throw new \InvalidArgumentException('non-nullable country cannot be null'); + } + $this->container['country'] = $country; + + return $this; + } + + /** + * Gets connection_type + * + * @return string + */ + public function getConnectionType() + { + return $this->container['connection_type']; + } + + /** + * Sets connection_type + * + * @param string $connection_type How the visitor connected. Known values: - `direct`: a regular connection; - `mobile`: a mobile carrier network; - `vpn`: a VPN; - `proxy`: a proxy, datacenter or hosting network (search-engine crawlers are reported here too); - `tor`: the Tor network; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `browser_vpn_proxy`: a VPN or proxy built into the browser or one of its extensions; - `unknown`: not enough data. The value can say `vpn` while `detection_flags.vpn` is `false` (IP intelligence classified the network, but the scored VPN check did not fire). Branch on `detection_flags` for decisions. The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setConnectionType($connection_type) + { + if (is_null($connection_type)) { + throw new \InvalidArgumentException('non-nullable connection_type cannot be null'); + } + $this->container['connection_type'] = $connection_type; + + return $this; + } + + /** + * Gets score + * + * @return int + */ + public function getScore() + { + return $this->container['score']; + } + + /** + * Sets score + * + * @param int $score Risk Score from 0 (no risk found) to 100. Search-engine crawlers always score 0. Risk bands are computed on your side from the score; no band field exists on the wire: - trusted: 0-29 - suspicious: 30-59 - dangerous: 60-100 A value above 100 is not a score. `999` is the rate-limit marker: the visitor's IP went over the ingest rate limit, and the identification carries exactly one signal, `{\"name\":\"rate_limited\",\"weight\":999}`, usually with nil identifiers. Treat every value above 100 as rate limited. One marker is written when the IP goes over the limit; request IDs issued while it stays blocked get no row and no webhook, so they stay unverified. The score usually equals the sum of the signal weights capped at 100, but carried-forward verdicts and corrections make that unreliable: never recompute or validate it yourself. + * + * @return self + */ + public function setScore($score) + { + if (is_null($score)) { + throw new \InvalidArgumentException('non-nullable score cannot be null'); + } + + if (($score < 0)) { + throw new \InvalidArgumentException('invalid value for $score when calling HistoryRow., must be bigger than or equal to 0.'); + } + + $this->container['score'] = $score; + + return $this; + } + + /** + * Gets score_details + * + * @return string + */ + public function getScoreDetails() + { + return $this->container['score_details']; + } + + /** + * Sets score_details + * + * @param string $score_details The entries behind `score` as a JSON-encoded **string** holding an array of `{\"Value\": , \"Description\": }`. Parse it before use. Scored entries come first, followed by informational entries with `Value` 0, which can be long. Empty string when no details were stored. The webhook `signals` are the entries with a non-zero `Value`, in the same order, with each description turned into a signal name (for example `Is proxy` becomes `proxy`). Descriptions are free text for display: never branch on them. + * + * @return self + */ + public function setScoreDetails($score_details) + { + if (is_null($score_details)) { + throw new \InvalidArgumentException('non-nullable score_details cannot be null'); + } + $this->container['score_details'] = $score_details; + + return $this; + } + + /** + * Gets created_at + * + * @return string + */ + public function getCreatedAt() + { + return $this->container['created_at']; + } + + /** + * Sets created_at + * + * @param string $created_at Time of the identification as `YYYY-MM-DD HH:MM:SS.mmm` in UTC, without a zone designator (not RFC 3339). Older rows can lack the milliseconds. + * + * @return self + */ + public function setCreatedAt($created_at) + { + if (is_null($created_at)) { + throw new \InvalidArgumentException('non-nullable created_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{3})?$/", ObjectSerializer::toString($created_at)))) { + throw new \InvalidArgumentException("invalid value for \$created_at when calling HistoryRow., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{3})?$/."); + } + + $this->container['created_at'] = $created_at; + + return $this; + } + + /** + * Gets ver + * + * @return int + */ + public function getVer() + { + return $this->container['ver']; + } + + /** + * Sets ver + * + * @param int $ver Version of the row in Unix milliseconds. It increases every time the row is refined, for example when late network data re-scores it after the webhook was sent. + * + * @return self + */ + public function setVer($ver) + { + if (is_null($ver)) { + throw new \InvalidArgumentException('non-nullable ver cannot be null'); + } + $this->container['ver'] = $ver; + + return $this; + } + + /** + * Gets web_rtc_ip + * + * @return string + */ + public function getWebRtcIp() + { + return $this->container['web_rtc_ip']; + } + + /** + * Sets web_rtc_ip + * + * @param string $web_rtc_ip Local IP address observed by the ShieldLabs network check; `0.0.0.0` when none. + * + * @return self + */ + public function setWebRtcIp($web_rtc_ip) + { + if (is_null($web_rtc_ip)) { + throw new \InvalidArgumentException('non-nullable web_rtc_ip cannot be null'); + } + $this->container['web_rtc_ip'] = $web_rtc_ip; + + return $this; + } + + /** + * Gets web_rtc_country + * + * @return string + */ + public function getWebRtcCountry() + { + return $this->container['web_rtc_country']; + } + + /** + * Sets web_rtc_country + * + * @param string $web_rtc_country Country of `web_rtc_ip`, or an empty string. + * + * @return self + */ + public function setWebRtcCountry($web_rtc_country) + { + if (is_null($web_rtc_country)) { + throw new \InvalidArgumentException('non-nullable web_rtc_country cannot be null'); + } + $this->container['web_rtc_country'] = $web_rtc_country; + + return $this; + } + + /** + * Gets web_rtc_connection_type + * + * @return string + */ + public function getWebRtcConnectionType() + { + return $this->container['web_rtc_connection_type']; + } + + /** + * Sets web_rtc_connection_type + * + * @param string $web_rtc_connection_type Connection class of `web_rtc_ip`, or an empty string. + * + * @return self + */ + public function setWebRtcConnectionType($web_rtc_connection_type) + { + if (is_null($web_rtc_connection_type)) { + throw new \InvalidArgumentException('non-nullable web_rtc_connection_type cannot be null'); + } + $this->container['web_rtc_connection_type'] = $web_rtc_connection_type; + + return $this; + } + + /** + * Gets webrtc_leak_ip + * + * @return string + */ + public function getWebrtcLeakIp() + { + return $this->container['webrtc_leak_ip']; + } + + /** + * Sets webrtc_leak_ip + * + * @param string $webrtc_leak_ip Local network address leaked by the browser; `0.0.0.0` when none. + * + * @return self + */ + public function setWebrtcLeakIp($webrtc_leak_ip) + { + if (is_null($webrtc_leak_ip)) { + throw new \InvalidArgumentException('non-nullable webrtc_leak_ip cannot be null'); + } + $this->container['webrtc_leak_ip'] = $webrtc_leak_ip; + + return $this; + } + + /** + * Gets webrtc_leak_country + * + * @return string + */ + public function getWebrtcLeakCountry() + { + return $this->container['webrtc_leak_country']; + } + + /** + * Sets webrtc_leak_country + * + * @param string $webrtc_leak_country Country of `webrtc_leak_ip`, or an empty string. + * + * @return self + */ + public function setWebrtcLeakCountry($webrtc_leak_country) + { + if (is_null($webrtc_leak_country)) { + throw new \InvalidArgumentException('non-nullable webrtc_leak_country cannot be null'); + } + $this->container['webrtc_leak_country'] = $webrtc_leak_country; + + return $this; + } + + /** + * Gets webrtc_leak_connection_type + * + * @return string + */ + public function getWebrtcLeakConnectionType() + { + return $this->container['webrtc_leak_connection_type']; + } + + /** + * Sets webrtc_leak_connection_type + * + * @param string $webrtc_leak_connection_type Connection class of `webrtc_leak_ip`, or an empty string. + * + * @return self + */ + public function setWebrtcLeakConnectionType($webrtc_leak_connection_type) + { + if (is_null($webrtc_leak_connection_type)) { + throw new \InvalidArgumentException('non-nullable webrtc_leak_connection_type cannot be null'); + } + $this->container['webrtc_leak_connection_type'] = $webrtc_leak_connection_type; + + return $this; + } + + /** + * Gets webrtc_leak_source + * + * @return string + */ + public function getWebrtcLeakSource() + { + return $this->container['webrtc_leak_source']; + } + + /** + * Sets webrtc_leak_source + * + * @param string $webrtc_leak_source Which check found the local network leak. Known values: `scanner`, `shield`, `none` and the empty string. `none` or an empty string when there is no leak; the webhook `local_ip` then uses `web_rtc_ip`. The set is open: keep values added in later versions. + * + * @return self + */ + public function setWebrtcLeakSource($webrtc_leak_source) + { + if (is_null($webrtc_leak_source)) { + throw new \InvalidArgumentException('non-nullable webrtc_leak_source cannot be null'); + } + $this->container['webrtc_leak_source'] = $webrtc_leak_source; + + return $this; + } + + /** + * Gets is_vpn + * + * @return bool + */ + public function getIsVpn() + { + return $this->container['is_vpn']; + } + + /** + * Sets is_vpn + * + * @param bool $is_vpn Same meaning as `detection_flags.vpn`. + * + * @return self + */ + public function setIsVpn($is_vpn) + { + if (is_null($is_vpn)) { + throw new \InvalidArgumentException('non-nullable is_vpn cannot be null'); + } + $this->container['is_vpn'] = $is_vpn; + + return $this; + } + + /** + * Gets is_tor + * + * @return bool + */ + public function getIsTor() + { + return $this->container['is_tor']; + } + + /** + * Sets is_tor + * + * @param bool $is_tor Same meaning as `detection_flags.tor`. + * + * @return self + */ + public function setIsTor($is_tor) + { + if (is_null($is_tor)) { + throw new \InvalidArgumentException('non-nullable is_tor cannot be null'); + } + $this->container['is_tor'] = $is_tor; + + return $this; + } + + /** + * Gets is_proxy + * + * @return bool + */ + public function getIsProxy() + { + return $this->container['is_proxy']; + } + + /** + * Sets is_proxy + * + * @param bool $is_proxy Same meaning as `detection_flags.proxy`. + * + * @return self + */ + public function setIsProxy($is_proxy) + { + if (is_null($is_proxy)) { + throw new \InvalidArgumentException('non-nullable is_proxy cannot be null'); + } + $this->container['is_proxy'] = $is_proxy; + + return $this; + } + + /** + * Gets is_datacenter + * + * @return bool + */ + public function getIsDatacenter() + { + return $this->container['is_datacenter']; + } + + /** + * Sets is_datacenter + * + * @param bool $is_datacenter Same meaning as `detection_flags.datacenter_ip`. + * + * @return self + */ + public function setIsDatacenter($is_datacenter) + { + if (is_null($is_datacenter)) { + throw new \InvalidArgumentException('non-nullable is_datacenter cannot be null'); + } + $this->container['is_datacenter'] = $is_datacenter; + + return $this; + } + + /** + * Gets is_abuser + * + * @return bool + */ + public function getIsAbuser() + { + return $this->container['is_abuser']; + } + + /** + * Sets is_abuser + * + * @param bool $is_abuser Same meaning as `detection_flags.abuser`. + * + * @return self + */ + public function setIsAbuser($is_abuser) + { + if (is_null($is_abuser)) { + throw new \InvalidArgumentException('non-nullable is_abuser cannot be null'); + } + $this->container['is_abuser'] = $is_abuser; + + return $this; + } + + /** + * Gets is_privacy_relay + * + * @return bool + */ + public function getIsPrivacyRelay() + { + return $this->container['is_privacy_relay']; + } + + /** + * Sets is_privacy_relay + * + * @param bool $is_privacy_relay Same meaning as `detection_flags.privacy_relay`. + * + * @return self + */ + public function setIsPrivacyRelay($is_privacy_relay) + { + if (is_null($is_privacy_relay)) { + throw new \InvalidArgumentException('non-nullable is_privacy_relay cannot be null'); + } + $this->container['is_privacy_relay'] = $is_privacy_relay; + + return $this; + } + + /** + * Gets is_stun_not_checked + * + * @return bool + */ + public function getIsStunNotChecked() + { + return $this->container['is_stun_not_checked']; + } + + /** + * Sets is_stun_not_checked + * + * @param bool $is_stun_not_checked Same meaning as `detection_flags.stun_not_checked`. + * + * @return self + */ + public function setIsStunNotChecked($is_stun_not_checked) + { + if (is_null($is_stun_not_checked)) { + throw new \InvalidArgumentException('non-nullable is_stun_not_checked cannot be null'); + } + $this->container['is_stun_not_checked'] = $is_stun_not_checked; + + return $this; + } + + /** + * Gets check_incomplete + * + * @return bool + */ + public function getCheckIncomplete() + { + return $this->container['check_incomplete']; + } + + /** + * Sets check_incomplete + * + * @param bool $check_incomplete Same meaning as `detection_flags.check_incomplete`. Always `false` for search-engine crawlers. + * + * @return self + */ + public function setCheckIncomplete($check_incomplete) + { + if (is_null($check_incomplete)) { + throw new \InvalidArgumentException('non-nullable check_incomplete cannot be null'); + } + $this->container['check_incomplete'] = $check_incomplete; + + return $this; + } + + /** + * Gets is_antidetect + * + * @return bool + */ + public function getIsAntidetect() + { + return $this->container['is_antidetect']; + } + + /** + * Sets is_antidetect + * + * @param bool $is_antidetect Same meaning as `detection_flags.anti_detect_browser`. + * + * @return self + */ + public function setIsAntidetect($is_antidetect) + { + if (is_null($is_antidetect)) { + throw new \InvalidArgumentException('non-nullable is_antidetect cannot be null'); + } + $this->container['is_antidetect'] = $is_antidetect; + + return $this; + } + + /** + * Gets is_os_mismatch + * + * @return bool + */ + public function getIsOsMismatch() + { + return $this->container['is_os_mismatch']; + } + + /** + * Sets is_os_mismatch + * + * @param bool $is_os_mismatch Same meaning as `detection_flags.os_mismatch`. + * + * @return self + */ + public function setIsOsMismatch($is_os_mismatch) + { + if (is_null($is_os_mismatch)) { + throw new \InvalidArgumentException('non-nullable is_os_mismatch cannot be null'); + } + $this->container['is_os_mismatch'] = $is_os_mismatch; + + return $this; + } + + /** + * Gets is_os_not_detected + * + * @return bool + */ + public function getIsOsNotDetected() + { + return $this->container['is_os_not_detected']; + } + + /** + * Sets is_os_not_detected + * + * @param bool $is_os_not_detected Same meaning as `detection_flags.os_not_detected`. + * + * @return self + */ + public function setIsOsNotDetected($is_os_not_detected) + { + if (is_null($is_os_not_detected)) { + throw new \InvalidArgumentException('non-nullable is_os_not_detected cannot be null'); + } + $this->container['is_os_not_detected'] = $is_os_not_detected; + + return $this; + } + + /** + * Gets is_timezone_mismatch + * + * @return bool + */ + public function getIsTimezoneMismatch() + { + return $this->container['is_timezone_mismatch']; + } + + /** + * Sets is_timezone_mismatch + * + * @param bool $is_timezone_mismatch Same meaning as `detection_flags.timezone_mismatch`. + * + * @return self + */ + public function setIsTimezoneMismatch($is_timezone_mismatch) + { + if (is_null($is_timezone_mismatch)) { + throw new \InvalidArgumentException('non-nullable is_timezone_mismatch cannot be null'); + } + $this->container['is_timezone_mismatch'] = $is_timezone_mismatch; + + return $this; + } + + /** + * Gets is_js_disabled + * + * @return bool + */ + public function getIsJsDisabled() + { + return $this->container['is_js_disabled']; + } + + /** + * Sets is_js_disabled + * + * @param bool $is_js_disabled Same meaning as `detection_flags.javascript_disabled`. Always `false` for search-engine crawlers. + * + * @return self + */ + public function setIsJsDisabled($is_js_disabled) + { + if (is_null($is_js_disabled)) { + throw new \InvalidArgumentException('non-nullable is_js_disabled cannot be null'); + } + $this->container['is_js_disabled'] = $is_js_disabled; + + return $this; + } + + /** + * Gets is_browser_automation + * + * @return bool + */ + public function getIsBrowserAutomation() + { + return $this->container['is_browser_automation']; + } + + /** + * Sets is_browser_automation + * + * @param bool $is_browser_automation Same meaning as `detection_flags.browser_automation`. + * + * @return self + */ + public function setIsBrowserAutomation($is_browser_automation) + { + if (is_null($is_browser_automation)) { + throw new \InvalidArgumentException('non-nullable is_browser_automation cannot be null'); + } + $this->container['is_browser_automation'] = $is_browser_automation; + + return $this; + } + + /** + * Gets is_incognito + * + * @return bool + */ + public function getIsIncognito() + { + return $this->container['is_incognito']; + } + + /** + * Sets is_incognito + * + * @param bool $is_incognito Same meaning as `detection_flags.incognito`. Always `false` for search-engine crawlers. + * + * @return self + */ + public function setIsIncognito($is_incognito) + { + if (is_null($is_incognito)) { + throw new \InvalidArgumentException('non-nullable is_incognito cannot be null'); + } + $this->container['is_incognito'] = $is_incognito; + + return $this; + } + + /** + * Gets is_search_bot + * + * @return bool + */ + public function getIsSearchBot() + { + return $this->container['is_search_bot']; + } + + /** + * Sets is_search_bot + * + * @param bool $is_search_bot Same meaning as `detection_flags.search_bot`. + * + * @return self + */ + public function setIsSearchBot($is_search_bot) + { + if (is_null($is_search_bot)) { + throw new \InvalidArgumentException('non-nullable is_search_bot cannot be null'); + } + $this->container['is_search_bot'] = $is_search_bot; + + return $this; + } + + /** + * Gets is_suspicious_paid_click + * + * @return bool|null + */ + public function getIsSuspiciousPaidClick() + { + return $this->container['is_suspicious_paid_click']; + } + + /** + * Sets is_suspicious_paid_click + * + * @param bool|null $is_suspicious_paid_click Same meaning as `detection_flags.suspicious_paid_click`. Omitted when `false`. + * + * @return self + */ + public function setIsSuspiciousPaidClick($is_suspicious_paid_click) + { + if (is_null($is_suspicious_paid_click)) { + throw new \InvalidArgumentException('non-nullable is_suspicious_paid_click cannot be null'); + } + $this->container['is_suspicious_paid_click'] = $is_suspicious_paid_click; + + return $this; + } + + /** + * Gets entry_url + * + * @return string|null + */ + public function getEntryUrl() + { + return $this->container['entry_url']; + } + + /** + * Sets entry_url + * + * @param string|null $entry_url Landing page URL without the `#fragment` (webhook `traffic_source.landing_url`). Omitted when empty. It keeps the query string, which can contain personal data. + * + * @return self + */ + public function setEntryUrl($entry_url) + { + if (is_null($entry_url)) { + throw new \InvalidArgumentException('non-nullable entry_url cannot be null'); + } + $this->container['entry_url'] = $entry_url; + + return $this; + } + + /** + * Gets utm_source + * + * @return string|null + */ + public function getUtmSource() + { + return $this->container['utm_source']; + } + + /** + * Sets utm_source + * + * @param string|null $utm_source `utm_source`, lowercased. Omitted when empty. + * + * @return self + */ + public function setUtmSource($utm_source) + { + if (is_null($utm_source)) { + throw new \InvalidArgumentException('non-nullable utm_source cannot be null'); + } + $this->container['utm_source'] = $utm_source; + + return $this; + } + + /** + * Gets utm_medium + * + * @return string|null + */ + public function getUtmMedium() + { + return $this->container['utm_medium']; + } + + /** + * Sets utm_medium + * + * @param string|null $utm_medium `utm_medium`, lowercased. Omitted when empty. + * + * @return self + */ + public function setUtmMedium($utm_medium) + { + if (is_null($utm_medium)) { + throw new \InvalidArgumentException('non-nullable utm_medium cannot be null'); + } + $this->container['utm_medium'] = $utm_medium; + + return $this; + } + + /** + * Gets utm_campaign + * + * @return string|null + */ + public function getUtmCampaign() + { + return $this->container['utm_campaign']; + } + + /** + * Sets utm_campaign + * + * @param string|null $utm_campaign `utm_campaign` as sent. Omitted when empty. + * + * @return self + */ + public function setUtmCampaign($utm_campaign) + { + if (is_null($utm_campaign)) { + throw new \InvalidArgumentException('non-nullable utm_campaign cannot be null'); + } + $this->container['utm_campaign'] = $utm_campaign; + + return $this; + } + + /** + * Gets utm_content + * + * @return string|null + */ + public function getUtmContent() + { + return $this->container['utm_content']; + } + + /** + * Sets utm_content + * + * @param string|null $utm_content `utm_content` as sent. Omitted when empty. + * + * @return self + */ + public function setUtmContent($utm_content) + { + if (is_null($utm_content)) { + throw new \InvalidArgumentException('non-nullable utm_content cannot be null'); + } + $this->container['utm_content'] = $utm_content; + + return $this; + } + + /** + * Gets utm_term + * + * @return string|null + */ + public function getUtmTerm() + { + return $this->container['utm_term']; + } + + /** + * Sets utm_term + * + * @param string|null $utm_term `utm_term` as sent. Omitted when empty. + * + * @return self + */ + public function setUtmTerm($utm_term) + { + if (is_null($utm_term)) { + throw new \InvalidArgumentException('non-nullable utm_term cannot be null'); + } + $this->container['utm_term'] = $utm_term; + + return $this; + } + + /** + * Gets traffic_channel + * + * @return string|null + */ + public function getTrafficChannel() + { + return $this->container['traffic_channel']; + } + + /** + * Sets traffic_channel + * + * @param string|null $traffic_channel Marketing channel (webhook `traffic_source.channel`). Omitted when empty. + * + * @return self + */ + public function setTrafficChannel($traffic_channel) + { + if (is_null($traffic_channel)) { + throw new \InvalidArgumentException('non-nullable traffic_channel cannot be null'); + } + $this->container['traffic_channel'] = $traffic_channel; + + return $this; + } + + /** + * Gets traffic_channel_group + * + * @return string|null + */ + public function getTrafficChannelGroup() + { + return $this->container['traffic_channel_group']; + } + + /** + * Sets traffic_channel_group + * + * @param string|null $traffic_channel_group Group of the marketing channel. Omitted when empty. + * + * @return self + */ + public function setTrafficChannelGroup($traffic_channel_group) + { + if (is_null($traffic_channel_group)) { + throw new \InvalidArgumentException('non-nullable traffic_channel_group cannot be null'); + } + $this->container['traffic_channel_group'] = $traffic_channel_group; + + return $this; + } + + /** + * Gets traffic_reason + * + * @return string|null + */ + public function getTrafficReason() + { + return $this->container['traffic_reason']; + } + + /** + * Sets traffic_reason + * + * @param string|null $traffic_reason Why the channel was chosen. Omitted when empty. + * + * @return self + */ + public function setTrafficReason($traffic_reason) + { + if (is_null($traffic_reason)) { + throw new \InvalidArgumentException('non-nullable traffic_reason cannot be null'); + } + $this->container['traffic_reason'] = $traffic_reason; + + return $this; + } + + /** + * Gets referrer_domain + * + * @return string|null + */ + public function getReferrerDomain() + { + return $this->container['referrer_domain']; + } + + /** + * Sets referrer_domain + * + * @param string|null $referrer_domain Registrable domain of the referrer without `www.`; the crawler name (for example `GoogleBot`) for search-engine crawlers. Omitted when empty. + * + * @return self + */ + public function setReferrerDomain($referrer_domain) + { + if (is_null($referrer_domain)) { + throw new \InvalidArgumentException('non-nullable referrer_domain cannot be null'); + } + $this->container['referrer_domain'] = $referrer_domain; + + return $this; + } + + /** + * Gets click_id_type + * + * @return string|null + */ + public function getClickIdType() + { + return $this->container['click_id_type']; + } + + /** + * Sets click_id_type + * + * @param string|null $click_id_type Ad click identifier type found in the landing URL. Omitted when empty. + * + * @return self + */ + public function setClickIdType($click_id_type) + { + if (is_null($click_id_type)) { + throw new \InvalidArgumentException('non-nullable click_id_type cannot be null'); + } + $this->container['click_id_type'] = $click_id_type; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/IdentificationScoredData.php b/generated/lib/Model/IdentificationScoredData.php new file mode 100644 index 0000000..ad266c1 --- /dev/null +++ b/generated/lib/Model/IdentificationScoredData.php @@ -0,0 +1,1068 @@ + + */ +class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'IdentificationScoredData'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'request_id' => 'string', + 'visitor_id' => 'string', + 'device_id' => 'string', + 'session_id' => 'string', + 'cookie_id' => 'string', + 'user_hid' => 'string', + 'domain' => 'string', + 'public_ip' => '\ShieldLabs\Generated\Model\IpInfo', + 'local_ip' => '\ShieldLabs\Generated\Model\IpInfo', + 'connection_type' => 'string', + 'os' => 'string', + 'browser' => 'string', + 'device_type' => 'string', + 'traffic_source' => '\ShieldLabs\Generated\Model\TrafficSource', + 'risk_score' => 'int', + 'signals' => '\ShieldLabs\Generated\Model\Signal[]', + 'detection_flags' => '\ShieldLabs\Generated\Model\DetectionFlags', + 'observed_at' => '\DateTime' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'request_id' => 'uuid', + 'visitor_id' => 'uuid', + 'device_id' => 'uuid', + 'session_id' => 'uuid', + 'cookie_id' => 'uuid', + 'user_hid' => null, + 'domain' => null, + 'public_ip' => null, + 'local_ip' => null, + 'connection_type' => null, + 'os' => null, + 'browser' => null, + 'device_type' => null, + 'traffic_source' => null, + 'risk_score' => null, + 'signals' => null, + 'detection_flags' => null, + 'observed_at' => 'date-time' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'request_id' => false, + 'visitor_id' => false, + 'device_id' => false, + 'session_id' => false, + 'cookie_id' => false, + 'user_hid' => true, + 'domain' => false, + 'public_ip' => false, + 'local_ip' => false, + 'connection_type' => false, + 'os' => false, + 'browser' => false, + 'device_type' => false, + 'traffic_source' => false, + 'risk_score' => false, + 'signals' => false, + 'detection_flags' => false, + 'observed_at' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'request_id' => 'request_id', + 'visitor_id' => 'visitor_id', + 'device_id' => 'device_id', + 'session_id' => 'session_id', + 'cookie_id' => 'cookie_id', + 'user_hid' => 'user_hid', + 'domain' => 'domain', + 'public_ip' => 'public_ip', + 'local_ip' => 'local_ip', + 'connection_type' => 'connection_type', + 'os' => 'os', + 'browser' => 'browser', + 'device_type' => 'device_type', + 'traffic_source' => 'traffic_source', + 'risk_score' => 'risk_score', + 'signals' => 'signals', + 'detection_flags' => 'detection_flags', + 'observed_at' => 'observed_at' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'request_id' => 'setRequestId', + 'visitor_id' => 'setVisitorId', + 'device_id' => 'setDeviceId', + 'session_id' => 'setSessionId', + 'cookie_id' => 'setCookieId', + 'user_hid' => 'setUserHid', + 'domain' => 'setDomain', + 'public_ip' => 'setPublicIp', + 'local_ip' => 'setLocalIp', + 'connection_type' => 'setConnectionType', + 'os' => 'setOs', + 'browser' => 'setBrowser', + 'device_type' => 'setDeviceType', + 'traffic_source' => 'setTrafficSource', + 'risk_score' => 'setRiskScore', + 'signals' => 'setSignals', + 'detection_flags' => 'setDetectionFlags', + 'observed_at' => 'setObservedAt' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'request_id' => 'getRequestId', + 'visitor_id' => 'getVisitorId', + 'device_id' => 'getDeviceId', + 'session_id' => 'getSessionId', + 'cookie_id' => 'getCookieId', + 'user_hid' => 'getUserHid', + 'domain' => 'getDomain', + 'public_ip' => 'getPublicIp', + 'local_ip' => 'getLocalIp', + 'connection_type' => 'getConnectionType', + 'os' => 'getOs', + 'browser' => 'getBrowser', + 'device_type' => 'getDeviceType', + 'traffic_source' => 'getTrafficSource', + 'risk_score' => 'getRiskScore', + 'signals' => 'getSignals', + 'detection_flags' => 'getDetectionFlags', + 'observed_at' => 'getObservedAt' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('request_id', $data ?? [], null); + $this->setIfExists('visitor_id', $data ?? [], null); + $this->setIfExists('device_id', $data ?? [], null); + $this->setIfExists('session_id', $data ?? [], null); + $this->setIfExists('cookie_id', $data ?? [], null); + $this->setIfExists('user_hid', $data ?? [], null); + $this->setIfExists('domain', $data ?? [], null); + $this->setIfExists('public_ip', $data ?? [], null); + $this->setIfExists('local_ip', $data ?? [], null); + $this->setIfExists('connection_type', $data ?? [], null); + $this->setIfExists('os', $data ?? [], null); + $this->setIfExists('browser', $data ?? [], null); + $this->setIfExists('device_type', $data ?? [], null); + $this->setIfExists('traffic_source', $data ?? [], null); + $this->setIfExists('risk_score', $data ?? [], null); + $this->setIfExists('signals', $data ?? [], null); + $this->setIfExists('detection_flags', $data ?? [], null); + $this->setIfExists('observed_at', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['request_id'] === null) { + $invalidProperties[] = "'request_id' can't be null"; + } + if ($this->container['visitor_id'] === null) { + $invalidProperties[] = "'visitor_id' can't be null"; + } + if ($this->container['device_id'] === null) { + $invalidProperties[] = "'device_id' can't be null"; + } + if ($this->container['session_id'] === null) { + $invalidProperties[] = "'session_id' can't be null"; + } + if ($this->container['cookie_id'] === null) { + $invalidProperties[] = "'cookie_id' can't be null"; + } + if ($this->container['user_hid'] === null && !$this->isNullableSetToNull('user_hid')) { + $invalidProperties[] = "'user_hid' is required"; + } + if ($this->container['domain'] === null) { + $invalidProperties[] = "'domain' can't be null"; + } + if ($this->container['public_ip'] === null) { + $invalidProperties[] = "'public_ip' can't be null"; + } + if ($this->container['local_ip'] === null) { + $invalidProperties[] = "'local_ip' can't be null"; + } + if ($this->container['connection_type'] === null) { + $invalidProperties[] = "'connection_type' can't be null"; + } + if ($this->container['os'] === null) { + $invalidProperties[] = "'os' can't be null"; + } + if ($this->container['browser'] === null) { + $invalidProperties[] = "'browser' can't be null"; + } + if ($this->container['device_type'] === null) { + $invalidProperties[] = "'device_type' can't be null"; + } + if ($this->container['traffic_source'] === null) { + $invalidProperties[] = "'traffic_source' can't be null"; + } + if ($this->container['risk_score'] === null) { + $invalidProperties[] = "'risk_score' can't be null"; + } + if (($this->container['risk_score'] < 0)) { + $invalidProperties[] = "invalid value for 'risk_score', must be bigger than or equal to 0."; + } + + if ($this->container['signals'] === null) { + $invalidProperties[] = "'signals' can't be null"; + } + if ($this->container['detection_flags'] === null) { + $invalidProperties[] = "'detection_flags' can't be null"; + } + if ($this->container['observed_at'] === null) { + $invalidProperties[] = "'observed_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", $this->container['observed_at'])) { + $invalidProperties[] = "invalid value for 'observed_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets request_id + * + * @return string + */ + public function getRequestId() + { + return $this->container['request_id']; + } + + /** + * Sets request_id + * + * @param string $request_id Identifies one identification. The browser creates it as a UUID v4 and hands it to your page; it is the join key between the browser, the webhook and the History API. The nil UUID appears only on rate-limit marker rows that arrived with a malformed request ID. + * + * @return self + */ + public function setRequestId($request_id) + { + if (is_null($request_id)) { + throw new \InvalidArgumentException('non-nullable request_id cannot be null'); + } + $this->container['request_id'] = $request_id; + + return $this; + } + + /** + * Gets visitor_id + * + * @return string + */ + public function getVisitorId() + { + return $this->container['visitor_id']; + } + + /** + * Sets visitor_id + * + * @param string $visitor_id Server-side visitor identifier (UUID v5). It is sticky to the device: a new cookie on a known device keeps the existing visitor ID, so clearing cookies usually does not change it. The nil UUID appears on identifications without usable device data, such as rate-limit marker rows. + * + * @return self + */ + public function setVisitorId($visitor_id) + { + if (is_null($visitor_id)) { + throw new \InvalidArgumentException('non-nullable visitor_id cannot be null'); + } + $this->container['visitor_id'] = $visitor_id; + + return $this; + } + + /** + * Gets device_id + * + * @return string + */ + public function getDeviceId() + { + return $this->container['device_id']; + } + + /** + * Sets device_id + * + * @param string $device_id Server-side device identifier (UUID v5). It survives cleared cookies and private windows. The nil UUID `00000000-0000-0000-0000-000000000000` means that no usable device signals were collected (for example on rate-limit marker rows): never group identifications by it. + * + * @return self + */ + public function setDeviceId($device_id) + { + if (is_null($device_id)) { + throw new \InvalidArgumentException('non-nullable device_id cannot be null'); + } + $this->container['device_id'] = $device_id; + + return $this; + } + + /** + * Gets session_id + * + * @return string + */ + public function getSessionId() + { + return $this->container['session_id']; + } + + /** + * Sets session_id + * + * @param string $session_id One visit on one origin (UUID v4 created in the browser), shared by the open tabs of that origin. The next visit after the last tab closes gets a new session ID. The nil UUID appears on rate-limit marker rows. + * + * @return self + */ + public function setSessionId($session_id) + { + if (is_null($session_id)) { + throw new \InvalidArgumentException('non-nullable session_id cannot be null'); + } + $this->container['session_id'] = $session_id; + + return $this; + } + + /** + * Gets cookie_id + * + * @return string + */ + public function getCookieId() + { + return $this->container['cookie_id']; + } + + /** + * Sets cookie_id + * + * @param string $cookie_id First-party browser identifier kept by the ShieldLabs agent (UUID v4). A missing or malformed value is stored as the nil UUID. + * + * @return self + */ + public function setCookieId($cookie_id) + { + if (is_null($cookie_id)) { + throw new \InvalidArgumentException('non-nullable cookie_id cannot be null'); + } + $this->container['cookie_id'] = $cookie_id; + + return $this; + } + + /** + * Gets user_hid + * + * @return string|null + */ + public function getUserHid() + { + return $this->container['user_hid']; + } + + /** + * Sets user_hid + * + * @param string|null $user_hid User HID: your hashed or pseudonymous account identifier, exactly as it was passed to the ShieldLabs agent. Pass a hashed value, never a raw email address or database ID. Values that do not identify a user: - `anonymous`: an anonymous check; - `fail`: the agent sent no value; - `-1` and `unknown`: rows created by ShieldLabs itself, such as rate-limit marker rows. `null` only when the stored value is an empty string. Leave `null` and the values above out when you count the accounts of one device, visitor or IP address. + * + * @return self + */ + public function setUserHid($user_hid) + { + if (is_null($user_hid)) { + array_push($this->openAPINullablesSetToNull, 'user_hid'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('user_hid', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['user_hid'] = $user_hid; + + return $this; + } + + /** + * Gets domain + * + * @return string + */ + public function getDomain() + { + return $this->container['domain']; + } + + /** + * Sets domain + * + * @param string $domain Registered domain of your site (the request host when no registered domain matched). + * + * @return self + */ + public function setDomain($domain) + { + if (is_null($domain)) { + throw new \InvalidArgumentException('non-nullable domain cannot be null'); + } + $this->container['domain'] = $domain; + + return $this; + } + + /** + * Gets public_ip + * + * @return \ShieldLabs\Generated\Model\IpInfo + */ + public function getPublicIp() + { + return $this->container['public_ip']; + } + + /** + * Sets public_ip + * + * @param \ShieldLabs\Generated\Model\IpInfo $public_ip Public IPv4 address of the HTTP request and its country. `ip` is empty when the request did not arrive over IPv4. + * + * @return self + */ + public function setPublicIp($public_ip) + { + if (is_null($public_ip)) { + throw new \InvalidArgumentException('non-nullable public_ip cannot be null'); + } + $this->container['public_ip'] = $public_ip; + + return $this; + } + + /** + * Gets local_ip + * + * @return \ShieldLabs\Generated\Model\IpInfo + */ + public function getLocalIp() + { + return $this->container['local_ip']; + } + + /** + * Sets local_ip + * + * @param \ShieldLabs\Generated\Model\IpInfo $local_ip Local IP address found by the browser network check (WebRTC): the leaked address when a local network leak was found, otherwise the address ShieldLabs observed. Both keys are empty when the check found nothing. + * + * @return self + */ + public function setLocalIp($local_ip) + { + if (is_null($local_ip)) { + throw new \InvalidArgumentException('non-nullable local_ip cannot be null'); + } + $this->container['local_ip'] = $local_ip; + + return $this; + } + + /** + * Gets connection_type + * + * @return string + */ + public function getConnectionType() + { + return $this->container['connection_type']; + } + + /** + * Sets connection_type + * + * @param string $connection_type How the visitor connected. Known values: - `direct`: a regular connection; - `mobile`: a mobile carrier network; - `vpn`: a VPN; - `proxy`: a proxy, datacenter or hosting network (search-engine crawlers are reported here too); - `tor`: the Tor network; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `browser_vpn_proxy`: a VPN or proxy built into the browser or one of its extensions; - `unknown`: not enough data. The value can say `vpn` while `detection_flags.vpn` is `false` (IP intelligence classified the network, but the scored VPN check did not fire). Branch on `detection_flags` for decisions. The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setConnectionType($connection_type) + { + if (is_null($connection_type)) { + throw new \InvalidArgumentException('non-nullable connection_type cannot be null'); + } + $this->container['connection_type'] = $connection_type; + + return $this; + } + + /** + * Gets os + * + * @return string + */ + public function getOs() + { + return $this->container['os']; + } + + /** + * Sets os + * + * @param string $os Operating system name, for example `Windows`, `Mac OS X`, `Linux`, `Android`, `IOS (iPhone)`, `IOS (iPad)`, `ChromeOS` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setOs($os) + { + if (is_null($os)) { + throw new \InvalidArgumentException('non-nullable os cannot be null'); + } + $this->container['os'] = $os; + + return $this; + } + + /** + * Gets browser + * + * @return string + */ + public function getBrowser() + { + return $this->container['browser']; + } + + /** + * Sets browser + * + * @param string $browser Browser name, for example `Chrome`, `Safari`, `Firefox`, `Microsoft Edge`, `Opera`, `Samsung Internet`, `Brave`, `Chrome (iOS)`, `Safari (iOS)` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setBrowser($browser) + { + if (is_null($browser)) { + throw new \InvalidArgumentException('non-nullable browser cannot be null'); + } + $this->container['browser'] = $browser; + + return $this; + } + + /** + * Gets device_type + * + * @return string + */ + public function getDeviceType() + { + return $this->container['device_type']; + } + + /** + * Sets device_type + * + * @param string $device_type Device class from the browser. Known values: `desktop`, `mobile`, `tablet` and `unknown` (the class could not be determined). The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setDeviceType($device_type) + { + if (is_null($device_type)) { + throw new \InvalidArgumentException('non-nullable device_type cannot be null'); + } + $this->container['device_type'] = $device_type; + + return $this; + } + + /** + * Gets traffic_source + * + * @return \ShieldLabs\Generated\Model\TrafficSource + */ + public function getTrafficSource() + { + return $this->container['traffic_source']; + } + + /** + * Sets traffic_source + * + * @param \ShieldLabs\Generated\Model\TrafficSource $traffic_source traffic_source + * + * @return self + */ + public function setTrafficSource($traffic_source) + { + if (is_null($traffic_source)) { + throw new \InvalidArgumentException('non-nullable traffic_source cannot be null'); + } + $this->container['traffic_source'] = $traffic_source; + + return $this; + } + + /** + * Gets risk_score + * + * @return int + */ + public function getRiskScore() + { + return $this->container['risk_score']; + } + + /** + * Sets risk_score + * + * @param int $risk_score Risk Score from 0 (no risk found) to 100. Search-engine crawlers always score 0. Risk bands are computed on your side from the score; no band field exists on the wire: - trusted: 0-29 - suspicious: 30-59 - dangerous: 60-100 A value above 100 is not a score. `999` is the rate-limit marker: the visitor's IP went over the ingest rate limit, and the identification carries exactly one signal, `{\"name\":\"rate_limited\",\"weight\":999}`, usually with nil identifiers. Treat every value above 100 as rate limited. One marker is written when the IP goes over the limit; request IDs issued while it stays blocked get no row and no webhook, so they stay unverified. The score usually equals the sum of the signal weights capped at 100, but carried-forward verdicts and corrections make that unreliable: never recompute or validate it yourself. + * + * @return self + */ + public function setRiskScore($risk_score) + { + if (is_null($risk_score)) { + throw new \InvalidArgumentException('non-nullable risk_score cannot be null'); + } + + if (($risk_score < 0)) { + throw new \InvalidArgumentException('invalid value for $risk_score when calling IdentificationScoredData., must be bigger than or equal to 0.'); + } + + $this->container['risk_score'] = $risk_score; + + return $this; + } + + /** + * Gets signals + * + * @return \ShieldLabs\Generated\Model\Signal[] + */ + public function getSignals() + { + return $this->container['signals']; + } + + /** + * Sets signals + * + * @param \ShieldLabs\Generated\Model\Signal[] $signals Weighted risk signals behind `risk_score`, in scoring order. Can be empty. The rate-limit marker carries exactly one entry, `{\"name\":\"rate_limited\",\"weight\":999}`. + * + * @return self + */ + public function setSignals($signals) + { + if (is_null($signals)) { + throw new \InvalidArgumentException('non-nullable signals cannot be null'); + } + $this->container['signals'] = $signals; + + return $this; + } + + /** + * Gets detection_flags + * + * @return \ShieldLabs\Generated\Model\DetectionFlags + */ + public function getDetectionFlags() + { + return $this->container['detection_flags']; + } + + /** + * Sets detection_flags + * + * @param \ShieldLabs\Generated\Model\DetectionFlags $detection_flags detection_flags + * + * @return self + */ + public function setDetectionFlags($detection_flags) + { + if (is_null($detection_flags)) { + throw new \InvalidArgumentException('non-nullable detection_flags cannot be null'); + } + $this->container['detection_flags'] = $detection_flags; + + return $this; + } + + /** + * Gets observed_at + * + * @return \DateTime + */ + public function getObservedAt() + { + return $this->container['observed_at']; + } + + /** + * Sets observed_at + * + * @param \DateTime $observed_at When scoring finished and the event was built (not the page view time); identical to the envelope `created_at`. RFC 3339 in UTC with up to 9 fractional digits. + * + * @return self + */ + public function setObservedAt($observed_at) + { + if (is_null($observed_at)) { + throw new \InvalidArgumentException('non-nullable observed_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", ObjectSerializer::toString($observed_at)))) { + throw new \InvalidArgumentException("invalid value for \$observed_at when calling IdentificationScoredData., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."); + } + + $this->container['observed_at'] = $observed_at; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/IdentificationScoredEvent.php b/generated/lib/Model/IdentificationScoredEvent.php new file mode 100644 index 0000000..9208dde --- /dev/null +++ b/generated/lib/Model/IdentificationScoredEvent.php @@ -0,0 +1,575 @@ + + */ +class IdentificationScoredEvent implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'IdentificationScoredEvent'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'event_type' => 'string', + 'schema_version' => 'string', + 'created_at' => '\DateTime', + 'data' => '\ShieldLabs\Generated\Model\IdentificationScoredData' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'event_type' => null, + 'schema_version' => null, + 'created_at' => 'date-time', + 'data' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'event_type' => false, + 'schema_version' => false, + 'created_at' => false, + 'data' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'event_type' => 'event_type', + 'schema_version' => 'schema_version', + 'created_at' => 'created_at', + 'data' => 'data' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'event_type' => 'setEventType', + 'schema_version' => 'setSchemaVersion', + 'created_at' => 'setCreatedAt', + 'data' => 'setData' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'event_type' => 'getEventType', + 'schema_version' => 'getSchemaVersion', + 'created_at' => 'getCreatedAt', + 'data' => 'getData' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + public const EVENT_TYPE_IDENTIFICATION_SCORED = 'identification.scored'; + + /** + * Gets allowable values of the enum + * + * @return string[] + */ + public function getEventTypeAllowableValues() + { + return [ + self::EVENT_TYPE_IDENTIFICATION_SCORED, + ]; + } + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('event_type', $data ?? [], null); + $this->setIfExists('schema_version', $data ?? [], null); + $this->setIfExists('created_at', $data ?? [], null); + $this->setIfExists('data', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['event_type'] === null) { + $invalidProperties[] = "'event_type' can't be null"; + } + $allowedValues = $this->getEventTypeAllowableValues(); + if (!is_null($this->container['event_type']) && !in_array($this->container['event_type'], $allowedValues, true)) { + $invalidProperties[] = sprintf( + "invalid value '%s' for 'event_type', must be one of '%s'", + $this->container['event_type'], + implode("', '", $allowedValues) + ); + } + + if ($this->container['schema_version'] === null) { + $invalidProperties[] = "'schema_version' can't be null"; + } + if ((mb_strlen($this->container['schema_version']) < 1)) { + $invalidProperties[] = "invalid value for 'schema_version', the character length must be bigger than or equal to 1."; + } + + if ($this->container['created_at'] === null) { + $invalidProperties[] = "'created_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", $this->container['created_at'])) { + $invalidProperties[] = "invalid value for 'created_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."; + } + + if ($this->container['data'] === null) { + $invalidProperties[] = "'data' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets event_type + * + * @return string + */ + public function getEventType() + { + return $this->container['event_type']; + } + + /** + * Sets event_type + * + * @param string $event_type Event type. Ignore events whose type you do not know instead of failing. + * + * @return self + */ + public function setEventType($event_type) + { + if (is_null($event_type)) { + throw new \InvalidArgumentException('non-nullable event_type cannot be null'); + } + $allowedValues = $this->getEventTypeAllowableValues(); + if (!in_array($event_type, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf( + "Invalid value '%s' for 'event_type', must be one of '%s'", + $event_type, + implode("', '", $allowedValues) + ) + ); + } + $this->container['event_type'] = $event_type; + + return $this; + } + + /** + * Gets schema_version + * + * @return string + */ + public function getSchemaVersion() + { + return $this->container['schema_version']; + } + + /** + * Sets schema_version + * + * @param string $schema_version Version of the webhook payload contract. Every event sent today carries `2026-06-01`. Accept other values, so that a future version does not break your handler. + * + * @return self + */ + public function setSchemaVersion($schema_version) + { + if (is_null($schema_version)) { + throw new \InvalidArgumentException('non-nullable schema_version cannot be null'); + } + + if ((mb_strlen($schema_version) < 1)) { + throw new \InvalidArgumentException('invalid length for $schema_version when calling IdentificationScoredEvent., must be bigger than or equal to 1.'); + } + + $this->container['schema_version'] = $schema_version; + + return $this; + } + + /** + * Gets created_at + * + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->container['created_at']; + } + + /** + * Sets created_at + * + * @param \DateTime $created_at When the event was built. Equal to `data.observed_at`. + * + * @return self + */ + public function setCreatedAt($created_at) + { + if (is_null($created_at)) { + throw new \InvalidArgumentException('non-nullable created_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", ObjectSerializer::toString($created_at)))) { + throw new \InvalidArgumentException("invalid value for \$created_at when calling IdentificationScoredEvent., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."); + } + + $this->container['created_at'] = $created_at; + + return $this; + } + + /** + * Gets data + * + * @return \ShieldLabs\Generated\Model\IdentificationScoredData + */ + public function getData() + { + return $this->container['data']; + } + + /** + * Sets data + * + * @param \ShieldLabs\Generated\Model\IdentificationScoredData $data data + * + * @return self + */ + public function setData($data) + { + if (is_null($data)) { + throw new \InvalidArgumentException('non-nullable data cannot be null'); + } + $this->container['data'] = $data; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/IpInfo.php b/generated/lib/Model/IpInfo.php new file mode 100644 index 0000000..0d1120a --- /dev/null +++ b/generated/lib/Model/IpInfo.php @@ -0,0 +1,460 @@ + + */ +class IpInfo implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'IpInfo'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'ip' => 'string', + 'country' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'ip' => null, + 'country' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'ip' => false, + 'country' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'ip' => 'ip', + 'country' => 'country' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'ip' => 'setIp', + 'country' => 'setCountry' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'ip' => 'getIp', + 'country' => 'getCountry' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('ip', $data ?? [], null); + $this->setIfExists('country', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['ip'] === null) { + $invalidProperties[] = "'ip' can't be null"; + } + if (!preg_match("/^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})?$/", $this->container['ip'])) { + $invalidProperties[] = "invalid value for 'ip', must be conform to the pattern /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})?$/."; + } + + if ($this->container['country'] === null) { + $invalidProperties[] = "'country' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets ip + * + * @return string + */ + public function getIp() + { + return $this->container['ip']; + } + + /** + * Sets ip + * + * @param string $ip Dotted IPv4 address, or an empty string when no IPv4 address is known (for example for visitors on IPv6). + * + * @return self + */ + public function setIp($ip) + { + if (is_null($ip)) { + throw new \InvalidArgumentException('non-nullable ip cannot be null'); + } + + if ((!preg_match("/^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})?$/", ObjectSerializer::toString($ip)))) { + throw new \InvalidArgumentException("invalid value for \$ip when calling IpInfo., must conform to the pattern /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})?$/."); + } + + $this->container['ip'] = $ip; + + return $this; + } + + /** + * Gets country + * + * @return string + */ + public function getCountry() + { + return $this->container['country']; + } + + /** + * Sets country + * + * @param string $country English country name from IP intelligence, for example `Germany` or `United States` (not an ISO code). Empty string when the country is unknown. + * + * @return self + */ + public function setCountry($country) + { + if (is_null($country)) { + throw new \InvalidArgumentException('non-nullable country cannot be null'); + } + $this->container['country'] = $country; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/LegacySnapshot.php b/generated/lib/Model/LegacySnapshot.php new file mode 100644 index 0000000..2877642 --- /dev/null +++ b/generated/lib/Model/LegacySnapshot.php @@ -0,0 +1,1052 @@ + + */ +class LegacySnapshot implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'LegacySnapshot'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'request_id' => 'string', + 'session_id' => 'string', + 'cookie_id' => 'string', + 'device_id' => 'string', + 'visitor_id' => 'string', + 'ip' => 'string', + 'connection_type' => 'string', + 'web_rtc_hip' => 'string', + 'web_rtc_country' => 'string', + 'web_rtc_connection_type' => 'string', + 'os' => 'string', + 'browser' => 'string', + 'device_type' => 'string', + 'country' => 'string', + 'user_hid' => 'string', + 'score' => 'int', + 'details' => '\ShieldLabs\Generated\Model\ScoreDetail[]', + 'last_request_time' => '\DateTime' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'request_id' => 'uuid', + 'session_id' => 'uuid', + 'cookie_id' => 'uuid', + 'device_id' => 'uuid', + 'visitor_id' => 'uuid', + 'ip' => 'ipv4', + 'connection_type' => null, + 'web_rtc_hip' => 'ipv4', + 'web_rtc_country' => null, + 'web_rtc_connection_type' => null, + 'os' => null, + 'browser' => null, + 'device_type' => null, + 'country' => null, + 'user_hid' => null, + 'score' => null, + 'details' => null, + 'last_request_time' => 'date-time' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'request_id' => false, + 'session_id' => false, + 'cookie_id' => false, + 'device_id' => false, + 'visitor_id' => false, + 'ip' => false, + 'connection_type' => false, + 'web_rtc_hip' => false, + 'web_rtc_country' => false, + 'web_rtc_connection_type' => false, + 'os' => false, + 'browser' => false, + 'device_type' => false, + 'country' => false, + 'user_hid' => false, + 'score' => false, + 'details' => false, + 'last_request_time' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'request_id' => 'RequestID', + 'session_id' => 'SessionID', + 'cookie_id' => 'CookieID', + 'device_id' => 'DeviceID', + 'visitor_id' => 'VisitorID', + 'ip' => 'IP', + 'connection_type' => 'ConnectionType', + 'web_rtc_hip' => 'WebRtcHIP', + 'web_rtc_country' => 'WebRtcCountry', + 'web_rtc_connection_type' => 'WebRtcConnectionType', + 'os' => 'OS', + 'browser' => 'Browser', + 'device_type' => 'DeviceType', + 'country' => 'Country', + 'user_hid' => 'UserHID', + 'score' => 'Score', + 'details' => 'Details', + 'last_request_time' => 'LastRequestTime' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'request_id' => 'setRequestId', + 'session_id' => 'setSessionId', + 'cookie_id' => 'setCookieId', + 'device_id' => 'setDeviceId', + 'visitor_id' => 'setVisitorId', + 'ip' => 'setIp', + 'connection_type' => 'setConnectionType', + 'web_rtc_hip' => 'setWebRtcHip', + 'web_rtc_country' => 'setWebRtcCountry', + 'web_rtc_connection_type' => 'setWebRtcConnectionType', + 'os' => 'setOs', + 'browser' => 'setBrowser', + 'device_type' => 'setDeviceType', + 'country' => 'setCountry', + 'user_hid' => 'setUserHid', + 'score' => 'setScore', + 'details' => 'setDetails', + 'last_request_time' => 'setLastRequestTime' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'request_id' => 'getRequestId', + 'session_id' => 'getSessionId', + 'cookie_id' => 'getCookieId', + 'device_id' => 'getDeviceId', + 'visitor_id' => 'getVisitorId', + 'ip' => 'getIp', + 'connection_type' => 'getConnectionType', + 'web_rtc_hip' => 'getWebRtcHip', + 'web_rtc_country' => 'getWebRtcCountry', + 'web_rtc_connection_type' => 'getWebRtcConnectionType', + 'os' => 'getOs', + 'browser' => 'getBrowser', + 'device_type' => 'getDeviceType', + 'country' => 'getCountry', + 'user_hid' => 'getUserHid', + 'score' => 'getScore', + 'details' => 'getDetails', + 'last_request_time' => 'getLastRequestTime' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('request_id', $data ?? [], null); + $this->setIfExists('session_id', $data ?? [], null); + $this->setIfExists('cookie_id', $data ?? [], null); + $this->setIfExists('device_id', $data ?? [], null); + $this->setIfExists('visitor_id', $data ?? [], null); + $this->setIfExists('ip', $data ?? [], null); + $this->setIfExists('connection_type', $data ?? [], null); + $this->setIfExists('web_rtc_hip', $data ?? [], null); + $this->setIfExists('web_rtc_country', $data ?? [], null); + $this->setIfExists('web_rtc_connection_type', $data ?? [], null); + $this->setIfExists('os', $data ?? [], null); + $this->setIfExists('browser', $data ?? [], null); + $this->setIfExists('device_type', $data ?? [], null); + $this->setIfExists('country', $data ?? [], null); + $this->setIfExists('user_hid', $data ?? [], null); + $this->setIfExists('score', $data ?? [], null); + $this->setIfExists('details', $data ?? [], null); + $this->setIfExists('last_request_time', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['request_id'] === null) { + $invalidProperties[] = "'request_id' can't be null"; + } + if ($this->container['session_id'] === null) { + $invalidProperties[] = "'session_id' can't be null"; + } + if ($this->container['cookie_id'] === null) { + $invalidProperties[] = "'cookie_id' can't be null"; + } + if ($this->container['device_id'] === null) { + $invalidProperties[] = "'device_id' can't be null"; + } + if ($this->container['visitor_id'] === null) { + $invalidProperties[] = "'visitor_id' can't be null"; + } + if ($this->container['ip'] === null) { + $invalidProperties[] = "'ip' can't be null"; + } + if ($this->container['connection_type'] === null) { + $invalidProperties[] = "'connection_type' can't be null"; + } + if ($this->container['web_rtc_hip'] === null) { + $invalidProperties[] = "'web_rtc_hip' can't be null"; + } + if ($this->container['web_rtc_country'] === null) { + $invalidProperties[] = "'web_rtc_country' can't be null"; + } + if ($this->container['web_rtc_connection_type'] === null) { + $invalidProperties[] = "'web_rtc_connection_type' can't be null"; + } + if ($this->container['os'] === null) { + $invalidProperties[] = "'os' can't be null"; + } + if ($this->container['browser'] === null) { + $invalidProperties[] = "'browser' can't be null"; + } + if ($this->container['device_type'] === null) { + $invalidProperties[] = "'device_type' can't be null"; + } + if ($this->container['country'] === null) { + $invalidProperties[] = "'country' can't be null"; + } + if ($this->container['user_hid'] === null) { + $invalidProperties[] = "'user_hid' can't be null"; + } + if ($this->container['score'] === null) { + $invalidProperties[] = "'score' can't be null"; + } + if (($this->container['score'] < 0)) { + $invalidProperties[] = "invalid value for 'score', must be bigger than or equal to 0."; + } + + if ($this->container['details'] === null) { + $invalidProperties[] = "'details' can't be null"; + } + if ($this->container['last_request_time'] === null) { + $invalidProperties[] = "'last_request_time' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets request_id + * + * @return string + */ + public function getRequestId() + { + return $this->container['request_id']; + } + + /** + * Sets request_id + * + * @param string $request_id Identifies one identification. The browser creates it as a UUID v4 and hands it to your page; it is the join key between the browser, the webhook and the History API. The nil UUID appears only on rate-limit marker rows that arrived with a malformed request ID. + * + * @return self + */ + public function setRequestId($request_id) + { + if (is_null($request_id)) { + throw new \InvalidArgumentException('non-nullable request_id cannot be null'); + } + $this->container['request_id'] = $request_id; + + return $this; + } + + /** + * Gets session_id + * + * @return string + */ + public function getSessionId() + { + return $this->container['session_id']; + } + + /** + * Sets session_id + * + * @param string $session_id One visit on one origin (UUID v4 created in the browser), shared by the open tabs of that origin. The next visit after the last tab closes gets a new session ID. The nil UUID appears on rate-limit marker rows. + * + * @return self + */ + public function setSessionId($session_id) + { + if (is_null($session_id)) { + throw new \InvalidArgumentException('non-nullable session_id cannot be null'); + } + $this->container['session_id'] = $session_id; + + return $this; + } + + /** + * Gets cookie_id + * + * @return string + */ + public function getCookieId() + { + return $this->container['cookie_id']; + } + + /** + * Sets cookie_id + * + * @param string $cookie_id First-party browser identifier kept by the ShieldLabs agent (UUID v4). A missing or malformed value is stored as the nil UUID. + * + * @return self + */ + public function setCookieId($cookie_id) + { + if (is_null($cookie_id)) { + throw new \InvalidArgumentException('non-nullable cookie_id cannot be null'); + } + $this->container['cookie_id'] = $cookie_id; + + return $this; + } + + /** + * Gets device_id + * + * @return string + */ + public function getDeviceId() + { + return $this->container['device_id']; + } + + /** + * Sets device_id + * + * @param string $device_id Server-side device identifier (UUID v5). It survives cleared cookies and private windows. The nil UUID `00000000-0000-0000-0000-000000000000` means that no usable device signals were collected (for example on rate-limit marker rows): never group identifications by it. + * + * @return self + */ + public function setDeviceId($device_id) + { + if (is_null($device_id)) { + throw new \InvalidArgumentException('non-nullable device_id cannot be null'); + } + $this->container['device_id'] = $device_id; + + return $this; + } + + /** + * Gets visitor_id + * + * @return string + */ + public function getVisitorId() + { + return $this->container['visitor_id']; + } + + /** + * Sets visitor_id + * + * @param string $visitor_id Server-side visitor identifier (UUID v5). It is sticky to the device: a new cookie on a known device keeps the existing visitor ID, so clearing cookies usually does not change it. The nil UUID appears on identifications without usable device data, such as rate-limit marker rows. + * + * @return self + */ + public function setVisitorId($visitor_id) + { + if (is_null($visitor_id)) { + throw new \InvalidArgumentException('non-nullable visitor_id cannot be null'); + } + $this->container['visitor_id'] = $visitor_id; + + return $this; + } + + /** + * Gets ip + * + * @return string + */ + public function getIp() + { + return $this->container['ip']; + } + + /** + * Sets ip + * + * @param string $ip Public IPv4 address of the HTTP request. + * + * @return self + */ + public function setIp($ip) + { + if (is_null($ip)) { + throw new \InvalidArgumentException('non-nullable ip cannot be null'); + } + $this->container['ip'] = $ip; + + return $this; + } + + /** + * Gets connection_type + * + * @return string + */ + public function getConnectionType() + { + return $this->container['connection_type']; + } + + /** + * Sets connection_type + * + * @param string $connection_type How the visitor connected. Known values: - `direct`: a regular connection; - `mobile`: a mobile carrier network; - `vpn`: a VPN; - `proxy`: a proxy, datacenter or hosting network (search-engine crawlers are reported here too); - `tor`: the Tor network; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `browser_vpn_proxy`: a VPN or proxy built into the browser or one of its extensions; - `unknown`: not enough data. The value can say `vpn` while `detection_flags.vpn` is `false` (IP intelligence classified the network, but the scored VPN check did not fire). Branch on `detection_flags` for decisions. The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setConnectionType($connection_type) + { + if (is_null($connection_type)) { + throw new \InvalidArgumentException('non-nullable connection_type cannot be null'); + } + $this->container['connection_type'] = $connection_type; + + return $this; + } + + /** + * Gets web_rtc_hip + * + * @return string + */ + public function getWebRtcHip() + { + return $this->container['web_rtc_hip']; + } + + /** + * Sets web_rtc_hip + * + * @param string $web_rtc_hip Local IP address observed by the ShieldLabs network check (not hashed); `0.0.0.0` when none. + * + * @return self + */ + public function setWebRtcHip($web_rtc_hip) + { + if (is_null($web_rtc_hip)) { + throw new \InvalidArgumentException('non-nullable web_rtc_hip cannot be null'); + } + $this->container['web_rtc_hip'] = $web_rtc_hip; + + return $this; + } + + /** + * Gets web_rtc_country + * + * @return string + */ + public function getWebRtcCountry() + { + return $this->container['web_rtc_country']; + } + + /** + * Sets web_rtc_country + * + * @param string $web_rtc_country Country of `WebRtcHIP`, or an empty string. + * + * @return self + */ + public function setWebRtcCountry($web_rtc_country) + { + if (is_null($web_rtc_country)) { + throw new \InvalidArgumentException('non-nullable web_rtc_country cannot be null'); + } + $this->container['web_rtc_country'] = $web_rtc_country; + + return $this; + } + + /** + * Gets web_rtc_connection_type + * + * @return string + */ + public function getWebRtcConnectionType() + { + return $this->container['web_rtc_connection_type']; + } + + /** + * Sets web_rtc_connection_type + * + * @param string $web_rtc_connection_type Connection class of `WebRtcHIP`, or an empty string. + * + * @return self + */ + public function setWebRtcConnectionType($web_rtc_connection_type) + { + if (is_null($web_rtc_connection_type)) { + throw new \InvalidArgumentException('non-nullable web_rtc_connection_type cannot be null'); + } + $this->container['web_rtc_connection_type'] = $web_rtc_connection_type; + + return $this; + } + + /** + * Gets os + * + * @return string + */ + public function getOs() + { + return $this->container['os']; + } + + /** + * Sets os + * + * @param string $os Operating system name, for example `Windows`, `Mac OS X`, `Linux`, `Android`, `IOS (iPhone)`, `IOS (iPad)`, `ChromeOS` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setOs($os) + { + if (is_null($os)) { + throw new \InvalidArgumentException('non-nullable os cannot be null'); + } + $this->container['os'] = $os; + + return $this; + } + + /** + * Gets browser + * + * @return string + */ + public function getBrowser() + { + return $this->container['browser']; + } + + /** + * Sets browser + * + * @param string $browser Browser name, for example `Chrome`, `Safari`, `Firefox`, `Microsoft Edge`, `Opera`, `Samsung Internet`, `Brave`, `Chrome (iOS)`, `Safari (iOS)` or `Unknown`. Open set: display it, do not branch on it. + * + * @return self + */ + public function setBrowser($browser) + { + if (is_null($browser)) { + throw new \InvalidArgumentException('non-nullable browser cannot be null'); + } + $this->container['browser'] = $browser; + + return $this; + } + + /** + * Gets device_type + * + * @return string + */ + public function getDeviceType() + { + return $this->container['device_type']; + } + + /** + * Sets device_type + * + * @param string $device_type Device class from the browser. Known values: `desktop`, `mobile`, `tablet` and `unknown` (the class could not be determined). The set is open: keep values added in later versions and treat them as `unknown`. + * + * @return self + */ + public function setDeviceType($device_type) + { + if (is_null($device_type)) { + throw new \InvalidArgumentException('non-nullable device_type cannot be null'); + } + $this->container['device_type'] = $device_type; + + return $this; + } + + /** + * Gets country + * + * @return string + */ + public function getCountry() + { + return $this->container['country']; + } + + /** + * Sets country + * + * @param string $country Country of `IP` as an English country name, or an empty string. + * + * @return self + */ + public function setCountry($country) + { + if (is_null($country)) { + throw new \InvalidArgumentException('non-nullable country cannot be null'); + } + $this->container['country'] = $country; + + return $this; + } + + /** + * Gets user_hid + * + * @return string + */ + public function getUserHid() + { + return $this->container['user_hid']; + } + + /** + * Sets user_hid + * + * @param string $user_hid User HID as passed to the agent; `anonymous` for anonymous checks. + * + * @return self + */ + public function setUserHid($user_hid) + { + if (is_null($user_hid)) { + throw new \InvalidArgumentException('non-nullable user_hid cannot be null'); + } + $this->container['user_hid'] = $user_hid; + + return $this; + } + + /** + * Gets score + * + * @return int + */ + public function getScore() + { + return $this->container['score']; + } + + /** + * Sets score + * + * @param int $score Risk Score from 0 (no risk found) to 100. Search-engine crawlers always score 0. Risk bands are computed on your side from the score; no band field exists on the wire: - trusted: 0-29 - suspicious: 30-59 - dangerous: 60-100 A value above 100 is not a score. `999` is the rate-limit marker: the visitor's IP went over the ingest rate limit, and the identification carries exactly one signal, `{\"name\":\"rate_limited\",\"weight\":999}`, usually with nil identifiers. Treat every value above 100 as rate limited. One marker is written when the IP goes over the limit; request IDs issued while it stays blocked get no row and no webhook, so they stay unverified. The score usually equals the sum of the signal weights capped at 100, but carried-forward verdicts and corrections make that unreliable: never recompute or validate it yourself. + * + * @return self + */ + public function setScore($score) + { + if (is_null($score)) { + throw new \InvalidArgumentException('non-nullable score cannot be null'); + } + + if (($score < 0)) { + throw new \InvalidArgumentException('invalid value for $score when calling LegacySnapshot., must be bigger than or equal to 0.'); + } + + $this->container['score'] = $score; + + return $this; + } + + /** + * Gets details + * + * @return \ShieldLabs\Generated\Model\ScoreDetail[] + */ + public function getDetails() + { + return $this->container['details']; + } + + /** + * Sets details + * + * @param \ShieldLabs\Generated\Model\ScoreDetail[] $details Every entry behind `Score`, informational entries with `Value` 0 included (unlike the History API, this is a parsed array, not a string). + * + * @return self + */ + public function setDetails($details) + { + if (is_null($details)) { + throw new \InvalidArgumentException('non-nullable details cannot be null'); + } + $this->container['details'] = $details; + + return $this; + } + + /** + * Gets last_request_time + * + * @return \DateTime + */ + public function getLastRequestTime() + { + return $this->container['last_request_time']; + } + + /** + * Sets last_request_time + * + * @param \DateTime $last_request_time Time of the identification, RFC 3339 with fractional seconds. + * + * @return self + */ + public function setLastRequestTime($last_request_time) + { + if (is_null($last_request_time)) { + throw new \InvalidArgumentException('non-nullable last_request_time cannot be null'); + } + $this->container['last_request_time'] = $last_request_time; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/ModelInterface.php b/generated/lib/Model/ModelInterface.php new file mode 100644 index 0000000..71227bb --- /dev/null +++ b/generated/lib/Model/ModelInterface.php @@ -0,0 +1,112 @@ + + */ +class ScoreDetail implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ScoreDetail'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'value' => 'int', + 'description' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'value' => null, + 'description' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'value' => false, + 'description' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'value' => 'Value', + 'description' => 'Description' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'value' => 'setValue', + 'description' => 'setDescription' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'value' => 'getValue', + 'description' => 'getDescription' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('value', $data ?? [], null); + $this->setIfExists('description', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['value'] === null) { + $invalidProperties[] = "'value' can't be null"; + } + if ($this->container['description'] === null) { + $invalidProperties[] = "'description' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets value + * + * @return int + */ + public function getValue() + { + return $this->container['value']; + } + + /** + * Sets value + * + * @param int $value Weight of the entry. Can be negative; 0 for informational entries. + * + * @return self + */ + public function setValue($value) + { + if (is_null($value)) { + throw new \InvalidArgumentException('non-nullable value cannot be null'); + } + $this->container['value'] = $value; + + return $this; + } + + /** + * Gets description + * + * @return string + */ + public function getDescription() + { + return $this->container['description']; + } + + /** + * Sets description + * + * @param string $description Human-readable description, for example `Is proxy` or `Antidetect browser (turn_block)`. + * + * @return self + */ + public function setDescription($description) + { + if (is_null($description)) { + throw new \InvalidArgumentException('non-nullable description cannot be null'); + } + $this->container['description'] = $description; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/Signal.php b/generated/lib/Model/Signal.php new file mode 100644 index 0000000..578921a --- /dev/null +++ b/generated/lib/Model/Signal.php @@ -0,0 +1,460 @@ + + */ +class Signal implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'Signal'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'name' => 'string', + 'weight' => 'int' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'name' => null, + 'weight' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'name' => false, + 'weight' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'name' => 'name', + 'weight' => 'weight' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'name' => 'setName', + 'weight' => 'setWeight' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'name' => 'getName', + 'weight' => 'getWeight' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('name', $data ?? [], null); + $this->setIfExists('weight', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['name'] === null) { + $invalidProperties[] = "'name' can't be null"; + } + if ((mb_strlen($this->container['name']) < 1)) { + $invalidProperties[] = "invalid value for 'name', the character length must be bigger than or equal to 1."; + } + + if ($this->container['weight'] === null) { + $invalidProperties[] = "'weight' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets name + * + * @return string + */ + public function getName() + { + return $this->container['name']; + } + + /** + * Sets name + * + * @param string $name Signal name. The set is open: new names can appear at any time, so keep unknown names and use them for display and logging only. Known names: - `tor`: the request came through Tor; - `vpn`: a VPN was detected; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `proxy`: a proxy was detected; - `datacenter_ip`: the IP belongs to a datacenter or hosting range; - `abuser`: the IP has a record of abuse; - `browser_vpn_proxy`: a VPN or proxy inside the browser; - `antidetect_browser`: an anti-detect browser (the matching flag is `anti_detect_browser`); - `proxy_routed_antidetect`: the network check was routed through a proxy in a way typical for anti-detect browsers; - `port_scan_routed_via_proxy`: `proxy_routed_antidetect` carried forward from an earlier identification of the same device and IP; - `browser_automation`: browser automation, for example a WebDriver-controlled browser; - `javascript_disabled`: JavaScript or the browser APIs the checks need were unavailable; - `os_mismatch`: the operating system seen on the network differs from the one the browser reports; - `os_not_detected`: the operating system could not be determined; - `timezone_mismatch`: the browser timezone differs from the IP location timezone; - `stun_not_checked`: the network (STUN) check did not complete; - `stun_late_correction`: a late network result arrived; negative weight that cancels `stun_not_checked`; - `rate_limited`: the rate-limit marker, weight 999. A verdict carried forward from an earlier identification of the same device and IP (for example `antidetect_browser`) keeps a name derived from the original signal and can carry a partial weight. + * + * @return self + */ + public function setName($name) + { + if (is_null($name)) { + throw new \InvalidArgumentException('non-nullable name cannot be null'); + } + + if ((mb_strlen($name) < 1)) { + throw new \InvalidArgumentException('invalid length for $name when calling Signal., must be bigger than or equal to 1.'); + } + + $this->container['name'] = $name; + + return $this; + } + + /** + * Gets weight + * + * @return int + */ + public function getWeight() + { + return $this->container['weight']; + } + + /** + * Sets weight + * + * @param int $weight Points the signal contributed. Can be negative (`stun_late_correction` is -30) and is 999 for `rate_limited`. Weights can change between releases; never add them up yourself. + * + * @return self + */ + public function setWeight($weight) + { + if (is_null($weight)) { + throw new \InvalidArgumentException('non-nullable weight cannot be null'); + } + $this->container['weight'] = $weight; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/TrafficSource.php b/generated/lib/Model/TrafficSource.php new file mode 100644 index 0000000..0f7e18c --- /dev/null +++ b/generated/lib/Model/TrafficSource.php @@ -0,0 +1,710 @@ + + */ +class TrafficSource implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'TrafficSource'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'channel' => 'string', + 'referrer_domain' => 'string', + 'landing_url' => 'string', + 'click_id_type' => 'string', + 'utm_source' => 'string', + 'utm_medium' => 'string', + 'utm_campaign' => 'string', + 'utm_content' => 'string', + 'utm_term' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'channel' => null, + 'referrer_domain' => null, + 'landing_url' => null, + 'click_id_type' => null, + 'utm_source' => null, + 'utm_medium' => null, + 'utm_campaign' => null, + 'utm_content' => null, + 'utm_term' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'channel' => false, + 'referrer_domain' => false, + 'landing_url' => false, + 'click_id_type' => false, + 'utm_source' => false, + 'utm_medium' => false, + 'utm_campaign' => false, + 'utm_content' => false, + 'utm_term' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'channel' => 'channel', + 'referrer_domain' => 'referrer_domain', + 'landing_url' => 'landing_url', + 'click_id_type' => 'click_id_type', + 'utm_source' => 'utm_source', + 'utm_medium' => 'utm_medium', + 'utm_campaign' => 'utm_campaign', + 'utm_content' => 'utm_content', + 'utm_term' => 'utm_term' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'channel' => 'setChannel', + 'referrer_domain' => 'setReferrerDomain', + 'landing_url' => 'setLandingUrl', + 'click_id_type' => 'setClickIdType', + 'utm_source' => 'setUtmSource', + 'utm_medium' => 'setUtmMedium', + 'utm_campaign' => 'setUtmCampaign', + 'utm_content' => 'setUtmContent', + 'utm_term' => 'setUtmTerm' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'channel' => 'getChannel', + 'referrer_domain' => 'getReferrerDomain', + 'landing_url' => 'getLandingUrl', + 'click_id_type' => 'getClickIdType', + 'utm_source' => 'getUtmSource', + 'utm_medium' => 'getUtmMedium', + 'utm_campaign' => 'getUtmCampaign', + 'utm_content' => 'getUtmContent', + 'utm_term' => 'getUtmTerm' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('channel', $data ?? [], null); + $this->setIfExists('referrer_domain', $data ?? [], null); + $this->setIfExists('landing_url', $data ?? [], null); + $this->setIfExists('click_id_type', $data ?? [], null); + $this->setIfExists('utm_source', $data ?? [], null); + $this->setIfExists('utm_medium', $data ?? [], null); + $this->setIfExists('utm_campaign', $data ?? [], null); + $this->setIfExists('utm_content', $data ?? [], null); + $this->setIfExists('utm_term', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['channel'] === null) { + $invalidProperties[] = "'channel' can't be null"; + } + if ($this->container['referrer_domain'] === null) { + $invalidProperties[] = "'referrer_domain' can't be null"; + } + if ($this->container['landing_url'] === null) { + $invalidProperties[] = "'landing_url' can't be null"; + } + if ($this->container['click_id_type'] === null) { + $invalidProperties[] = "'click_id_type' can't be null"; + } + if ($this->container['utm_source'] === null) { + $invalidProperties[] = "'utm_source' can't be null"; + } + if ($this->container['utm_medium'] === null) { + $invalidProperties[] = "'utm_medium' can't be null"; + } + if ($this->container['utm_campaign'] === null) { + $invalidProperties[] = "'utm_campaign' can't be null"; + } + if ($this->container['utm_content'] === null) { + $invalidProperties[] = "'utm_content' can't be null"; + } + if ($this->container['utm_term'] === null) { + $invalidProperties[] = "'utm_term' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets channel + * + * @return string + */ + public function getChannel() + { + return $this->container['channel']; + } + + /** + * Sets channel + * + * @param string $channel Marketing channel of the visit. Known values: `Google Ads`, `Meta`, `TikTok`, `LinkedIn`, `X`, `Pinterest`, `Microsoft Ads`, `Organic Search`, `Search bot`, `Referral`, `Direct`, `Other` and the empty string. Resolved in this order: a click ID, then UTM parameters, then the referrer (search engines give `Organic Search`, social networks give the platform name, other sites give `Referral`), otherwise `Direct`. Search-engine crawlers get `Search bot`. Empty string on identifications without attribution, such as rate-limit marker rows. The set is open: keep values added in later versions and treat them as `Other`. + * + * @return self + */ + public function setChannel($channel) + { + if (is_null($channel)) { + throw new \InvalidArgumentException('non-nullable channel cannot be null'); + } + $this->container['channel'] = $channel; + + return $this; + } + + /** + * Gets referrer_domain + * + * @return string + */ + public function getReferrerDomain() + { + return $this->container['referrer_domain']; + } + + /** + * Sets referrer_domain + * + * @param string $referrer_domain Registrable domain of the referrer without `www.`. For search-engine crawlers, the crawler name (for example `GoogleBot`). + * + * @return self + */ + public function setReferrerDomain($referrer_domain) + { + if (is_null($referrer_domain)) { + throw new \InvalidArgumentException('non-nullable referrer_domain cannot be null'); + } + $this->container['referrer_domain'] = $referrer_domain; + + return $this; + } + + /** + * Gets landing_url + * + * @return string + */ + public function getLandingUrl() + { + return $this->container['landing_url']; + } + + /** + * Sets landing_url + * + * @param string $landing_url Landing page URL without the `#fragment`. It keeps the query string, which can contain personal data: store it with care. + * + * @return self + */ + public function setLandingUrl($landing_url) + { + if (is_null($landing_url)) { + throw new \InvalidArgumentException('non-nullable landing_url cannot be null'); + } + $this->container['landing_url'] = $landing_url; + + return $this; + } + + /** + * Gets click_id_type + * + * @return string + */ + public function getClickIdType() + { + return $this->container['click_id_type']; + } + + /** + * Sets click_id_type + * + * @param string $click_id_type Ad click identifier found in the landing URL. Known values: `gclid`, `gbraid`, `wbraid`, `msclkid`, `ttclid`, `fbclid` and the empty string when there is none. `fbclid` counts only together with a Meta referrer or a Meta `utm_source`. The set is open: keep values added in later versions. + * + * @return self + */ + public function setClickIdType($click_id_type) + { + if (is_null($click_id_type)) { + throw new \InvalidArgumentException('non-nullable click_id_type cannot be null'); + } + $this->container['click_id_type'] = $click_id_type; + + return $this; + } + + /** + * Gets utm_source + * + * @return string + */ + public function getUtmSource() + { + return $this->container['utm_source']; + } + + /** + * Sets utm_source + * + * @param string $utm_source `utm_source` query parameter, lowercased. + * + * @return self + */ + public function setUtmSource($utm_source) + { + if (is_null($utm_source)) { + throw new \InvalidArgumentException('non-nullable utm_source cannot be null'); + } + $this->container['utm_source'] = $utm_source; + + return $this; + } + + /** + * Gets utm_medium + * + * @return string + */ + public function getUtmMedium() + { + return $this->container['utm_medium']; + } + + /** + * Sets utm_medium + * + * @param string $utm_medium `utm_medium` query parameter, lowercased. + * + * @return self + */ + public function setUtmMedium($utm_medium) + { + if (is_null($utm_medium)) { + throw new \InvalidArgumentException('non-nullable utm_medium cannot be null'); + } + $this->container['utm_medium'] = $utm_medium; + + return $this; + } + + /** + * Gets utm_campaign + * + * @return string + */ + public function getUtmCampaign() + { + return $this->container['utm_campaign']; + } + + /** + * Sets utm_campaign + * + * @param string $utm_campaign `utm_campaign` query parameter as sent. + * + * @return self + */ + public function setUtmCampaign($utm_campaign) + { + if (is_null($utm_campaign)) { + throw new \InvalidArgumentException('non-nullable utm_campaign cannot be null'); + } + $this->container['utm_campaign'] = $utm_campaign; + + return $this; + } + + /** + * Gets utm_content + * + * @return string + */ + public function getUtmContent() + { + return $this->container['utm_content']; + } + + /** + * Sets utm_content + * + * @param string $utm_content `utm_content` query parameter as sent. + * + * @return self + */ + public function setUtmContent($utm_content) + { + if (is_null($utm_content)) { + throw new \InvalidArgumentException('non-nullable utm_content cannot be null'); + } + $this->container['utm_content'] = $utm_content; + + return $this; + } + + /** + * Gets utm_term + * + * @return string + */ + public function getUtmTerm() + { + return $this->container['utm_term']; + } + + /** + * Sets utm_term + * + * @param string $utm_term `utm_term` query parameter as sent. + * + * @return self + */ + public function setUtmTerm($utm_term) + { + if (is_null($utm_term)) { + throw new \InvalidArgumentException('non-nullable utm_term cannot be null'); + } + $this->container['utm_term'] = $utm_term; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/WebhookPingEvent.php b/generated/lib/Model/WebhookPingEvent.php new file mode 100644 index 0000000..6ebb9a6 --- /dev/null +++ b/generated/lib/Model/WebhookPingEvent.php @@ -0,0 +1,538 @@ + + */ +class WebhookPingEvent implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'WebhookPingEvent'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'event_type' => 'string', + 'schema_version' => 'string', + 'created_at' => '\DateTime' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'event_type' => null, + 'schema_version' => null, + 'created_at' => 'date-time' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'event_type' => false, + 'schema_version' => false, + 'created_at' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'event_type' => 'event_type', + 'schema_version' => 'schema_version', + 'created_at' => 'created_at' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'event_type' => 'setEventType', + 'schema_version' => 'setSchemaVersion', + 'created_at' => 'setCreatedAt' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'event_type' => 'getEventType', + 'schema_version' => 'getSchemaVersion', + 'created_at' => 'getCreatedAt' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + public const EVENT_TYPE_WEBHOOK_PING = 'webhook.ping'; + + /** + * Gets allowable values of the enum + * + * @return string[] + */ + public function getEventTypeAllowableValues() + { + return [ + self::EVENT_TYPE_WEBHOOK_PING, + ]; + } + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('event_type', $data ?? [], null); + $this->setIfExists('schema_version', $data ?? [], null); + $this->setIfExists('created_at', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['event_type'] === null) { + $invalidProperties[] = "'event_type' can't be null"; + } + $allowedValues = $this->getEventTypeAllowableValues(); + if (!is_null($this->container['event_type']) && !in_array($this->container['event_type'], $allowedValues, true)) { + $invalidProperties[] = sprintf( + "invalid value '%s' for 'event_type', must be one of '%s'", + $this->container['event_type'], + implode("', '", $allowedValues) + ); + } + + if ($this->container['schema_version'] === null) { + $invalidProperties[] = "'schema_version' can't be null"; + } + if ((mb_strlen($this->container['schema_version']) < 1)) { + $invalidProperties[] = "invalid value for 'schema_version', the character length must be bigger than or equal to 1."; + } + + if ($this->container['created_at'] === null) { + $invalidProperties[] = "'created_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", $this->container['created_at'])) { + $invalidProperties[] = "invalid value for 'created_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets event_type + * + * @return string + */ + public function getEventType() + { + return $this->container['event_type']; + } + + /** + * Sets event_type + * + * @param string $event_type Event type. + * + * @return self + */ + public function setEventType($event_type) + { + if (is_null($event_type)) { + throw new \InvalidArgumentException('non-nullable event_type cannot be null'); + } + $allowedValues = $this->getEventTypeAllowableValues(); + if (!in_array($event_type, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf( + "Invalid value '%s' for 'event_type', must be one of '%s'", + $event_type, + implode("', '", $allowedValues) + ) + ); + } + $this->container['event_type'] = $event_type; + + return $this; + } + + /** + * Gets schema_version + * + * @return string + */ + public function getSchemaVersion() + { + return $this->container['schema_version']; + } + + /** + * Sets schema_version + * + * @param string $schema_version Version of the webhook payload contract. Every event sent today carries `2026-06-01`. Accept other values, so that a future version does not break your handler. + * + * @return self + */ + public function setSchemaVersion($schema_version) + { + if (is_null($schema_version)) { + throw new \InvalidArgumentException('non-nullable schema_version cannot be null'); + } + + if ((mb_strlen($schema_version) < 1)) { + throw new \InvalidArgumentException('invalid length for $schema_version when calling WebhookPingEvent., must be bigger than or equal to 1.'); + } + + $this->container['schema_version'] = $schema_version; + + return $this; + } + + /** + * Gets created_at + * + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->container['created_at']; + } + + /** + * Sets created_at + * + * @param \DateTime $created_at When the ping was sent, with second precision. + * + * @return self + */ + public function setCreatedAt($created_at) + { + if (is_null($created_at)) { + throw new \InvalidArgumentException('non-nullable created_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", ObjectSerializer::toString($created_at)))) { + throw new \InvalidArgumentException("invalid value for \$created_at when calling WebhookPingEvent., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."); + } + + $this->container['created_at'] = $created_at; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/ObjectSerializer.php b/generated/lib/ObjectSerializer.php new file mode 100644 index 0000000..ba222ac --- /dev/null +++ b/generated/lib/ObjectSerializer.php @@ -0,0 +1,604 @@ +format('Y-m-d') : $data->format(self::$dateTimeFormat); + } + + if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = self::sanitizeForSerialization($value); + } + return $data; + } + + if (is_object($data)) { + $values = []; + if ($data instanceof ModelInterface) { + $formats = $data::openAPIFormats(); + foreach ($data::openAPITypes() as $property => $openAPIType) { + $getter = $data::getters()[$property]; + $value = $data->$getter(); + if ($value !== null && !in_array($openAPIType, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + $callable = [$openAPIType, 'getAllowableEnumValues']; + if (is_callable($callable)) { + /** array $callable */ + $allowedEnumTypes = $callable(); + if (!in_array($value, $allowedEnumTypes, true)) { + $imploded = implode("', '", $allowedEnumTypes); + throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'"); + } + } + } + if (($data::isNullable($property) && $data->isNullableSetToNull($property)) || $value !== null) { + $values[$data::attributeMap()[$property]] = self::sanitizeForSerialization($value, $openAPIType, $formats[$property]); + } + } + } else { + foreach ($data as $property => $value) { + $values[$property] = self::sanitizeForSerialization($value); + } + } + return (object) $values; + } else { + return (string)$data; + } + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param string $filename filename to be sanitized + * + * @return string the sanitized filename + */ + public static function sanitizeFilename($filename) + { + if (preg_match("/.*[\/\\\\](.*)$/", $filename, $match)) { + return $match[1]; + } else { + return $filename; + } + } + + /** + * Shorter timestamp microseconds to 6 digits length. + * + * @param string $timestamp Original timestamp + * + * @return string the shorten timestamp + */ + public static function sanitizeTimestamp($timestamp) + { + if (!is_string($timestamp)) { + return $timestamp; + } + + return preg_replace('/(:\d{2}.\d{6})\d*/', '$1', $timestamp); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * + * @param string $value a string which will be part of the path + * + * @return string the serialized object + */ + public static function toPathValue($value) + { + return rawurlencode(self::toString($value)); + } + + /** + * Checks if a value is empty, based on its OpenAPI type. + * + * @param mixed $value + * @param string $openApiType + * + * @return bool true if $value is empty + */ + private static function isEmptyValue($value, string $openApiType): bool + { + // If empty() returns false, it is not empty regardless of its type. + if (!empty($value)) { + return false; + } + + // Null is always empty, as we cannot send a real "null" value in a query parameter. + if ($value === null) { + return true; + } + + switch ($openApiType) { + // For numeric values, false and '' are considered empty. + // This comparison is safe for floating point values, since the previous call to empty() will + // filter out values that don't match 0. + case 'int': + case 'integer': + return $value !== 0; + + case 'number': + case 'float': + return $value !== 0 && $value !== 0.0; + + // For boolean values, '' is considered empty + case 'bool': + case 'boolean': + return !in_array($value, [false, 0], true); + + // For string values, '' is considered empty. + case 'string': + return $value === ''; + + // For all the other types, any value at this point can be considered empty. + default: + return true; + } + } + + /** + * Take query parameter properties and turn it into an array suitable for + * native http_build_query or GuzzleHttp\Psr7\Query::build. + * + * @param mixed $value Parameter value + * @param string $paramName Parameter name + * @param string $openApiType OpenAPIType eg. array or object + * @param string $style Parameter serialization style + * @param bool $explode Parameter explode option + * @param bool $required Whether query param is required or not + * + * @return array + */ + public static function toQueryValue( + $value, + string $paramName, + string $openApiType = 'string', + string $style = 'form', + bool $explode = true, + bool $required = true + ): array { + + // Check if we should omit this parameter from the query. This should only happen when: + // - Parameter is NOT required; AND + // - its value is set to a value that is equivalent to "empty", depending on its OpenAPI type. For + // example, 0 as "int" or "boolean" is NOT an empty value. + if (self::isEmptyValue($value, $openApiType)) { + if ($required) { + return ["{$paramName}" => '']; + } else { + return []; + } + } + + // Handle DateTime objects in query + if ($openApiType === "\\DateTime" && $value instanceof \DateTime) { + return ["{$paramName}" => $value->format(self::$dateTimeFormat)]; + } + + $query = []; + $value = (in_array($openApiType, ['object', 'array'], true)) ? (array)$value : $value; + + // since \GuzzleHttp\Psr7\Query::build fails with nested arrays + // need to flatten array first + $flattenArray = function ($arr, $name, &$result = []) use (&$flattenArray, $style, $explode) { + if (!is_array($arr)) { + return $arr; + } + + foreach ($arr as $k => $v) { + $prop = ($style === 'deepObject') ? "{$name}[{$k}]" : $k; + + if (is_array($v)) { + $flattenArray($v, $prop, $result); + } else { + if ($style !== 'deepObject' && !$explode) { + // push key itself + $result[] = $prop; + } + $result[$prop] = $v; + } + } + return $result; + }; + + $value = $flattenArray($value, $paramName); + + // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values + if ($openApiType === 'array' && $style === 'deepObject' && $explode) { + return $value; + } + + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { + return $value; + } + + if ('boolean' === $openApiType && is_bool($value)) { + $value = self::convertBoolToQueryStringFormat($value); + } + + // handle style in serializeCollection + $query[$paramName] = ($explode) ? $value : self::serializeCollection((array)$value, $style); + + return $query; + } + + /** + * Convert boolean value to format for query string. + * + * @param bool $value Boolean value + * + * @return int|string Boolean value in format + */ + public static function convertBoolToQueryStringFormat(bool $value) + { + if (Configuration::BOOLEAN_FORMAT_STRING == Configuration::getDefaultConfiguration()->getBooleanFormatForQueryString()) { + return $value ? 'true' : 'false'; + } + + return (int) $value; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string $value a string which will be part of the header + * + * @return string the header string + */ + public static function toHeaderValue($value) + { + $callable = [$value, 'toHeaderValue']; + if (is_callable($callable)) { + return $callable(); + } + + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * If it's a boolean, convert it to "true" or "false". + * + * @param float|int|bool|\DateTime $value the value of the parameter + * + * @return string the header string + */ + public static function toString($value) + { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(self::$dateTimeFormat); + } elseif (is_bool($value)) { + return $value ? 'true' : 'false'; + } else { + return (string) $value; + } + } + + /** + * Serialize an array to a string. + * + * @param array $collection collection to serialize to a string + * @param string $style the format use for serialization (csv, + * ssv, tsv, pipes, multi) + * @param bool $allowCollectionFormatMulti allow collection format to be a multidimensional array + * + * @return string + */ + public static function serializeCollection(array $collection, $style, $allowCollectionFormatMulti = false) + { + if ($allowCollectionFormatMulti && ('multi' === $style)) { + // http_build_query() almost does the job for us. We just + // need to fix the result of multidimensional arrays. + return preg_replace('/%5B[0-9]+%5D=/', '=', http_build_query($collection, '', '&')); + } + switch ($style) { + case 'pipeDelimited': + case 'pipes': + return implode('|', $collection); + + case 'tsv': + return implode("\t", $collection); + + case 'spaceDelimited': + case 'ssv': + return implode(' ', $collection); + + case 'simple': + case 'csv': + // Deliberate fall through. CSV is default format. + default: + return implode(',', $collection); + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @param string[]|null $httpHeaders HTTP headers + * + * @return object|array|null a single or an array of $class instances + */ + public static function deserialize($data, $class, $httpHeaders = null) + { + if (null === $data) { + return null; + } + + if (strcasecmp(substr($class, -2), '[]') === 0) { + $data = is_string($data) ? json_decode($data) : $data; + + if (!is_array($data)) { + throw new \InvalidArgumentException("Invalid array '$class'"); + } + + $subClass = substr($class, 0, -2); + $values = []; + foreach ($data as $key => $value) { + $values[] = self::deserialize($value, $subClass, null); + } + return $values; + } + + if (preg_match('/^(array<|map\[)/', $class)) { // for associative array e.g. array + $data = is_string($data) ? json_decode($data) : $data; + settype($data, 'array'); + $inner = substr($class, 4, -1); + $deserialized = []; + if (strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = self::deserialize($value, $subClass, null); + } + } + return $deserialized; + } + + if ($class === 'object') { + settype($data, 'array'); + return $data; + } elseif ($class === 'mixed') { + settype($data, gettype($data)); + return $data; + } + + if ($class === '\DateTime') { + // Some APIs return an invalid, empty string as a + // date-time property. DateTime::__construct() will return + // the current time for empty input which is probably not + // what is meant. The invalid empty string is probably to + // be interpreted as a missing field/value. Let's handle + // this graceful. + if (!empty($data)) { + try { + return new \DateTime($data); + } catch (\Exception $exception) { + // Some APIs return a date-time with too high nanosecond + // precision for php's DateTime to handle. + // With provided regexp 6 digits of microseconds saved + return new \DateTime(self::sanitizeTimestamp($data)); + } + } else { + return null; + } + } + + if ($class === '\SplFileObject') { + $data = Utils::streamFor($data); + + /** @var \Psr\Http\Message\StreamInterface $data */ + + // determine file name + if ( + is_array($httpHeaders) + && array_key_exists('Content-Disposition', $httpHeaders) + && preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeaders['Content-Disposition'], $match) + ) { + $filename = Configuration::getDefaultConfiguration()->getTempFolderPath() . DIRECTORY_SEPARATOR . self::sanitizeFilename($match[1]); + } else { + $filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), ''); + } + + $file = fopen($filename, 'w'); + while ($chunk = $data->read(200)) { + fwrite($file, $chunk); + } + fclose($file); + + return new \SplFileObject($filename, 'r'); + } + + /** @psalm-suppress ParadoxicalCondition */ + if (in_array($class, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + settype($data, $class); + return $data; + } + + + if (method_exists($class, 'getAllowableEnumValues')) { + if (!in_array($data, $class::getAllowableEnumValues(), true)) { + $imploded = implode("', '", $class::getAllowableEnumValues()); + throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); + } + return $data; + } else { + $data = is_string($data) ? json_decode($data) : $data; + + if (is_array($data)) { + $data = (object) $data; + } + + // If a discriminator is defined and points to a valid subclass, use it. + $discriminator = $class::DISCRIMINATOR; + if (!empty($discriminator) && isset($data->{$discriminator}) && is_string($data->{$discriminator})) { + $subclass = '\ShieldLabs\Generated\Model\\' . $data->{$discriminator}; + if (is_subclass_of($subclass, $class)) { + $class = $subclass; + } + } + + /** @var ModelInterface $instance */ + $instance = new $class(); + foreach ($instance::openAPITypes() as $property => $type) { + $propertySetter = $instance::setters()[$property]; + + if (!isset($propertySetter)) { + continue; + } + + if (!isset($data->{$instance::attributeMap()[$property]})) { + if ($instance::isNullable($property)) { + $instance->$propertySetter(null); + } + + continue; + } + + if (isset($data->{$instance::attributeMap()[$property]})) { + $propertyValue = $data->{$instance::attributeMap()[$property]}; + $instance->$propertySetter(self::deserialize($propertyValue, $type, null)); + } + } + return $instance; + } + } + + /** + * Build a query string from an array of key value pairs. + * + * This function can use the return value of `parse()` to build a query + * string. This function does not modify the provided keys when an array is + * encountered (like `http_build_query()` would). + * + * The function is copied from https://github.com/guzzle/psr7/blob/a243f80a1ca7fe8ceed4deee17f12c1930efe662/src/Query.php#L59-L112 + * with a modification which is described in https://github.com/guzzle/psr7/pull/603 + * + * @param array $params Query string parameters. + * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 + * to encode using RFC3986, or PHP_QUERY_RFC1738 + * to encode using RFC1738. + */ + public static function buildQuery(array $params, $encoding = PHP_QUERY_RFC3986): string + { + if (!$params) { + return ''; + } + + if ($encoding === false) { + $encoder = function (string $str): string { + return $str; + }; + } elseif ($encoding === PHP_QUERY_RFC3986) { + $encoder = 'rawurlencode'; + } elseif ($encoding === PHP_QUERY_RFC1738) { + $encoder = 'urlencode'; + } else { + throw new \InvalidArgumentException('Invalid type'); + } + + $castBool = Configuration::BOOLEAN_FORMAT_INT == Configuration::getDefaultConfiguration()->getBooleanFormatForQueryString() + ? function ($v) { return (int) $v; } + : function ($v) { return $v ? 'true' : 'false'; }; + + $qs = ''; + foreach ($params as $k => $v) { + $k = $encoder((string) $k); + if (!is_array($v)) { + $qs .= $k; + $v = is_bool($v) ? $castBool($v) : $v; + if ($v !== null) { + $qs .= '='.$encoder((string) $v); + } + $qs .= '&'; + } else { + foreach ($v as $vv) { + $qs .= $k; + $vv = is_bool($vv) ? $castBool($vv) : $vv; + if ($vv !== null) { + $qs .= '='.$encoder((string) $vv); + } + $qs .= '&'; + } + } + } + + return $qs ? substr($qs, 0, -1) : ''; + } +} diff --git a/generated/phpunit.xml.dist b/generated/phpunit.xml.dist new file mode 100644 index 0000000..485899a --- /dev/null +++ b/generated/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + ./lib/Api + ./lib/Model + + + + + ./test/Api + ./test/Model + + + + + + diff --git a/resources/shieldlabs-api.yaml b/resources/shieldlabs-api.yaml new file mode 100644 index 0000000..2838959 --- /dev/null +++ b/resources/shieldlabs-api.yaml @@ -0,0 +1,2462 @@ +openapi: 3.1.0 +info: + title: ShieldLabs API + version: 1.0.1 + summary: Identification results and risk scoring for your backend. + description: |- + The ShieldLabs API gives your backend the result of every identification the ShieldLabs agent + runs in a browser: the Risk Score, the risk signals behind it, the detection flags and the + identifiers (request, visitor, device, session, cookie and User HID) it belongs to. + + ## How it fits + + 1. **Browser.** The ShieldLabs agent, loaded from `cdn.shieldlabs.ai`, runs an identification + and hands your page a request ID. The browser never receives a Risk Score, a visitor ID or + a device ID. + 2. **Your backend.** Your page sends the request ID along with the protected action (signup, + login, checkout). Your backend reads the verdict for it from the **History API**, or + receives it in a signed `identification.scored` **webhook**. + 3. **Decision.** Your backend acts on `risk_score`, the three risk bands, `detection_flags` + and the identifiers, for example by counting how many accounts one `device_id` has used + (skipping the `user_hid` values that do not identify a user, listed under Identifiers). + + Scoring is asynchronous. The webhook usually arrives about 300 ms after the browser check; when + follow-up network checks run, it is sent when they finish, at most about 10 seconds later. The + History row appears about 1-3 seconds after the browser call and can be refined for up to about + 10 seconds as follow-up checks finish. Start the identification when the user begins the + protected action (for example when the signup form opens), then either poll the History API by + `request_id` with a short backoff or wait for the webhook. Let one identification authorize one + protected action: reject request IDs you have already used and identifications older than your + freshness window. + + ## Hosts and credentials + + | API | Host | Paths | Credentials | + |---|---|---|---| + | History API | `https://account.shieldlabs.ai` | `/api/v1/...` | `Authorization: Bearer ` (`sec_...`, one per domain) | + | Management API | `https://api.shieldlabs.ai` | `/v1/...` | `X-Shield-Domain: ` and `Authorization: Bearer ` | + | Health | both hosts | `/health` | none | + + Every operation declares its own server, so generated clients send each call to the right + host. The History API serves its paths from the host root: the full URL is + `https://account.shieldlabs.ai/api/v1/history/{search_type}/{value}`, and a base URL that + already ends in `/api` produces `/api/api/v1/...` and a `404`. + + The two credentials are not interchangeable. Keep the Private API Key and the Secret Key on your + server; only the Public Key belongs in the browser. All keys are in the analytics dashboard at + https://app.shieldlabs.ai. + + ## Rate limits + + - **History API:** about 15 requests per second per domain, shared by every caller of that + domain. Requests over the limit get `429`; there is no ban, so retry after about a second. + - **Management API:** 15 requests per minute per client IP. The request that goes over the + limit starts a 10-minute block, during which every request gets `429`. Never retry a `429` + from this API; cache the profile instead. + - **Health:** not rate limited. + + API calls and webhook deliveries are free: only identifications made by the browser agent use + your included volume. + + ## Errors + + Error bodies are not uniform. Branch on the HTTP status first, then try to parse the body as + JSON whatever its content type. + + | API | Status | Body | + |---|---|---| + | History API | 401 | JSON text `{"error":"..."}`, sent as `text/plain` | + | History API | 429 | `{"error":"too many requests"}` | + | History API | 500 | `{"error":"..."}`. A malformed UUID or IPv4 value always ends here: validate before sending and do not retry it | + | Management API | 401 | empty | + | Management API | 400 | a bare JSON string or `null` (deprecated history endpoint) | + | Management API | 429, 503 | `{"error":"..."}` | + | Both | 404 | `404 page not found` as `text/plain` when no route matches | + | Both | 502, 504 | an HTML page from the edge proxy | + + Retry `429` (History API only), `5xx` and network errors with backoff. Do not retry `400`, + `401` or `404`, nor a History API `500` caused by a malformed value. + + ## Identifiers + + - `request_id`: one identification, created in the browser (UUID v4). It joins the browser + call, the webhook and the History row. + - `session_id`: one visit on one origin (UUID v4). + - `cookie_id`: first-party browser identifier kept by the agent (UUID v4). + - `device_id`: server-side device identifier (UUID v5). It survives cleared cookies and private + windows. The nil UUID `00000000-0000-0000-0000-000000000000` means no usable device signals. + - `visitor_id`: server-side visitor identifier (UUID v5), sticky to the device: a new cookie on + a known device keeps the visitor ID. + - `user_hid`: your hashed or pseudonymous account identifier, as passed to the agent. + `anonymous` marks anonymous checks; `fail`, `-1` and `unknown` also mean "no user". Leave + these values, `null` and the empty string out when you count accounts. Hex-encoded hashes + are the easiest values to search: see the `value` parameter of `searchHistory` for how to + encode other characters. + + Validate UUIDs with any version accepted, the nil UUID included. + + ## Risk Score, risk bands and the 999 marker + + The Risk Score (`risk_score` on webhooks, `score` in the History API) is an integer from 0 to + 100. Search-engine crawlers always score 0. The three risk bands are computed on your side; no + band field exists on the wire: + + | Band | Score | + |---|---| + | trusted | 0-29 | + | suspicious | 30-59 | + | dangerous | 60-100 | + + A value above 100 is not a score. **999** is the rate-limit marker: the visitor's IP went over + the ingest rate limit, and the identification carries exactly one signal, + `{"name":"rate_limited","weight":999}`, usually with nil identifiers. Treat every value above + 100 as rate limited. One marker is written when the IP goes over the limit; request IDs issued + while it stays blocked get no row and no webhook, so they stay unverified. + + Branch on `detection_flags` and the Risk Score. Signal names are for display and logging; + weights can be negative or change between releases, so never add them up yourself. A missing + identification means "unverified", never "clean". + + ## Countries, IP addresses and timestamps + + - `country` values are English country names from IP intelligence, such as `Germany` or + `United States`, or an empty string when unknown. + - IP fields hold IPv4 addresses. Without an IPv4 address the webhook sends `""` and the History + API sends `0.0.0.0`; such identifications cannot be searched by IP. + - Webhook timestamps (`created_at`, `observed_at`) are RFC 3339 in UTC with up to 9 fractional + digits. + - The History API `created_at` is `YYYY-MM-DD HH:MM:SS.mmm` in UTC without a zone designator; + older rows can lack the milliseconds. + - The Management API `CreatedAt` is RFC 3339 with second precision. + + ## Webhooks + + ShieldLabs sends one signed `POST` for each identification to every enabled endpoint of the + domain. A delivery has a 1-second timeout and is not retried today; a later release adds + retries that resend identical bytes. Answer 2xx within a second, process the event + asynchronously, make the handler idempotent on `data.request_id`, and use the History API for + guaranteed reads. A History row can be refined after its webhook was sent (its `ver` + increases); the webhook is not sent again. See the `identification.scored` and `webhook.ping` + entries for the signature algorithm. + + ## Compatibility + + Ignore fields you do not know, keep unknown values of string fields (such as new signal names + or channels) instead of failing, and accept webhook `schema_version` values other than + `2026-06-01`. + + Start free at https://app.shieldlabs.ai. Guides: https://docs.shieldlabs.ai. + contact: + name: ShieldLabs + url: https://docs.shieldlabs.ai + email: contact@shieldlabs.ai + license: + name: MIT + identifier: MIT +servers: + - url: https://account.shieldlabs.ai + description: History API (every operation also declares its own server) + - url: https://api.shieldlabs.ai + description: Management API (every operation also declares its own server) +tags: + - name: History API + description: 'Read identifications by one identifier on `https://account.shieldlabs.ai` with the Private API Key. The canonical way to read a verdict: by `request_id` right after a protected action, or by `device_id`, `user_hid`, `visitor_id` or `ip` for account-level checks.' + - name: Management API + description: Domain profile on `https://api.shieldlabs.ai`, authenticated with the Secret Key and the `X-Shield-Domain` header. Also serves the deprecated history endpoint until 1 January 2027. + - name: Health + description: Unauthenticated liveness checks on both API hosts. + - name: Webhooks + description: 'Signed events ShieldLabs sends to your webhook endpoints: `identification.scored` for every identification and `webhook.ping` when you verify an endpoint.' +externalDocs: + description: ShieldLabs documentation + url: https://docs.shieldlabs.ai +paths: + /api/v1/history/{search_type}/{value}: + servers: + - url: https://account.shieldlabs.ai + description: History API + get: + operationId: searchHistory + tags: + - History API + summary: Search identifications + description: |- + Returns the identifications of your domain that match one identifier, newest first, together + with the total number of matches. The Private API Key selects the domain; identifications from + its subdomains are included (`domain` holds the host, `site_domain` the registered domain). + + **Read one verdict.** After a protected action, search by `request_id` with `limit=1`. The row + appears about 1-3 seconds after the browser call and can be refined for up to about 10 seconds + as follow-up network checks finish, so start the identification when the user begins the + action (for example when the signup form opens), not when the form is submitted. An empty + `data` array means "not scored yet", never "clean". Poll with backoff (first try at once, then + wait 250 ms, 500 ms, 1 s, then steps of about 1.5 s) and treat a `429` inside that loop as + "wait longer". The official server SDKs do this for you. + + **Account-level checks.** Search by `device_id`, `user_hid`, `visitor_id` or `ip` to see how + many accounts share a device, how many devices one account uses, or what else came from one + IP address. When you count accounts, skip rows whose `user_hid` is empty or one of the values + that do not identify a user: `anonymous`, `fail`, `-1` and `unknown`. + + **Validate before sending.** The server does not validate the path: an unknown `search_type` + returns the latest identifications of the whole domain unfiltered, a malformed UUID or IPv4 + value returns `500`, and a `limit` outside 1-100 silently becomes 20. + + **Paging.** Page with `offset` while it is below `total`. Rows are ordered by `created_at` + only, so paging while new identifications arrive can repeat or skip rows: deduplicate on + `request_id`. + + **Latest state.** A row can be refined after the webhook was sent, for example when late + network data re-scores it; its `ver` then increases. The History API always returns the latest + version, which makes it the guaranteed read path. + + Reads are free: they do not use your included identifications. + security: + - historyApiKey: [] + parameters: + - $ref: '#/components/parameters/HistorySearchType' + - $ref: '#/components/parameters/HistoryValue' + - $ref: '#/components/parameters/HistoryLimit' + - $ref: '#/components/parameters/HistoryOffset' + responses: + '200': + description: Matching identifications, newest first. `data` is empty when nothing matched. + content: + application/json: + schema: + $ref: '#/components/schemas/HistoryPage' + examples: + page: + $ref: '#/components/examples/HistoryPage' + empty: + $ref: '#/components/examples/HistoryPageEmpty' + '401': + $ref: '#/components/responses/HistoryUnauthorized' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/HistoryTooManyRequests' + '500': + $ref: '#/components/responses/HistoryServerError' + '502': + $ref: '#/components/responses/BadGateway' + '504': + $ref: '#/components/responses/GatewayTimeout' + x-codeSamples: + - lang: Shell + label: curl + source: | + curl "https://account.shieldlabs.ai/api/v1/history/request_id/a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d?limit=1" \ + -H "Authorization: Bearer $SHIELDLABS_API_KEY" + /v1/profile: + servers: + - url: https://api.shieldlabs.ai + description: Management API + get: + operationId: getDomainProfile + tags: + - Management API + summary: Get the domain profile + description: |- + Returns the registered domain, the remaining included identifications of the account and the + masked keys. + + **Credentials.** Send the Secret Key as a Bearer token and the registered domain in + `X-Shield-Domain`. The domain is matched exactly: send it lowercase, without scheme, path, + trailing slash or a leading `www.`. + + **Rate limit.** 15 requests per minute per client IP. The request that goes over the limit + starts a 10-minute block during which every request to the Management API gets `429`. Call + this endpoint sparingly, cache the profile, and never retry a `429`. + + `Weight` can be negative when the account is over its included volume. The call is free. + security: + - managementSecretKey: [] + parameters: + - $ref: '#/components/parameters/ShieldDomain' + responses: + '200': + description: The domain profile. + content: + application/json: + schema: + $ref: '#/components/schemas/DomainProfile' + examples: + profile: + $ref: '#/components/examples/DomainProfile' + '401': + $ref: '#/components/responses/ManagementUnauthorized' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/ManagementTooManyRequests' + '502': + $ref: '#/components/responses/BadGateway' + '503': + $ref: '#/components/responses/ManagementServerBusy' + '504': + $ref: '#/components/responses/GatewayTimeout' + x-codeSamples: + - lang: Shell + label: curl + source: | + curl "https://api.shieldlabs.ai/v1/profile" \ + -H "X-Shield-Domain: $SHIELDLABS_DOMAIN" \ + -H "Authorization: Bearer $SHIELDLABS_SECRET_KEY" + /v1/history/{type}/{value}: + servers: + - url: https://api.shieldlabs.ai + description: Management API + get: + operationId: searchHistoryDeprecated + tags: + - Management API + summary: Search history by identifier (deprecated) + deprecated: true + x-sunset: '2027-01-01' + description: |- + **Deprecated.** This endpoint stops working after Sat, 01 Jan 2027 00:00:00 GMT. Use + `searchHistory` on the History API instead: `https://account.shieldlabs.ai/api/v1/history`. + Every answer of this route except `429` and `503` carries `Deprecation: true`, a `Sunset` + header and a `Link` header with `rel="successor-version"` pointing there. The plain-text `404` + for a path that matches no route and the edge proxy errors do not carry them. + + Differences from the History API: the answer is a bare array of PascalCase objects; only rows + whose request host equals `X-Shield-Domain` are returned (no subdomain traffic); `limit` + defaults to 100 and there is no `offset`. It uses the Management API credentials and rate limit + (15 requests per minute per client IP, then a 10-minute block). The call is free. + security: + - managementSecretKey: [] + parameters: + - $ref: '#/components/parameters/ShieldDomain' + - $ref: '#/components/parameters/DeprecatedHistoryType' + - $ref: '#/components/parameters/DeprecatedHistoryValue' + - $ref: '#/components/parameters/DeprecatedHistoryLimit' + responses: + '200': + description: Matching identifications, newest first. + headers: + Deprecation: + $ref: '#/components/headers/Deprecation' + Sunset: + $ref: '#/components/headers/Sunset' + Link: + $ref: '#/components/headers/Link' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/LegacySnapshot' + examples: + list: + $ref: '#/components/examples/LegacySnapshotList' + empty: + $ref: '#/components/examples/LegacySnapshotListEmpty' + '400': + description: The value failed validation (a bare JSON string) or the query failed (the JSON literal `null`, for example for an IPv6 `ip` value). Do not retry. + headers: + Deprecation: + $ref: '#/components/headers/Deprecation' + Sunset: + $ref: '#/components/headers/Sunset' + Link: + $ref: '#/components/headers/Link' + content: + application/json: + schema: + $ref: '#/components/schemas/LegacyErrorMessage' + examples: + invalidUuid: + $ref: '#/components/examples/ManagementBadRequestUuid' + invalidIp: + $ref: '#/components/examples/ManagementBadRequestIp' + emptyValue: + $ref: '#/components/examples/ManagementBadRequestEmpty' + queryFailed: + $ref: '#/components/examples/ManagementBadRequestNull' + '401': + description: Empty body, no `Content-Type`. Missing or malformed headers, unknown or disabled domain, or a wrong Secret Key. Do not retry. + headers: + Deprecation: + $ref: '#/components/headers/Deprecation' + Sunset: + $ref: '#/components/headers/Sunset' + Link: + $ref: '#/components/headers/Link' + '404': + description: '`application/json`: the `type` is not supported (a bare JSON string); this answer carries the deprecation headers. `text/plain`: no route matches the path, for example because the value is empty or contains `/`; this answer comes from the router and carries no deprecation headers. Do not retry.' + headers: + Deprecation: + $ref: '#/components/headers/Deprecation' + Sunset: + $ref: '#/components/headers/Sunset' + Link: + $ref: '#/components/headers/Link' + content: + application/json: + schema: + $ref: '#/components/schemas/LegacyErrorMessage' + examples: + unsupportedType: + $ref: '#/components/examples/ManagementUnsupportedType' + text/plain: + schema: + $ref: '#/components/schemas/PlainText' + examples: + notFound: + $ref: '#/components/examples/NotFoundText' + '429': + $ref: '#/components/responses/ManagementTooManyRequests' + '502': + $ref: '#/components/responses/BadGateway' + '503': + $ref: '#/components/responses/ManagementServerBusy' + '504': + $ref: '#/components/responses/GatewayTimeout' + /health: + servers: + - url: https://account.shieldlabs.ai + description: History API host + - url: https://api.shieldlabs.ai + description: Management API host + get: + operationId: getHealth + tags: + - Health + summary: Check service health + description: |- + Liveness check. Returns `{"status":"ok"}` while the service answers. Available on both API + hosts: `https://account.shieldlabs.ai/health` for the History API and + `https://api.shieldlabs.ai/health` for the Management API. No authentication, not rate + limited, not billed. + security: [] + responses: + '200': + description: The service is up. + content: + application/json: + schema: + $ref: '#/components/schemas/HealthStatus' + examples: + ok: + $ref: '#/components/examples/HealthOk' + '404': + description: No route matches the path. The health check lives at the host root, so `/api/health` gets this answer. Plain text body. + content: + text/plain: + schema: + $ref: '#/components/schemas/PlainText' + examples: + notFound: + $ref: '#/components/examples/NotFoundText' + '502': + $ref: '#/components/responses/BadGateway' + '504': + $ref: '#/components/responses/GatewayTimeout' + x-codeSamples: + - lang: Shell + label: curl + source: | + curl "https://account.shieldlabs.ai/health" +webhooks: + identification.scored: + post: + operationId: identificationScored + tags: + - Webhooks + summary: Identification scored + description: |- + Sent to every enabled webhook endpoint of your domain once for each identification, when its + scoring is final: usually about 300 ms after the browser check, and at most about 10 seconds + later when follow-up network checks run. + + **Verify, then parse.** Compute HMAC-SHA256 over the raw request body and compare it with + `X-Shield-Signature` before you parse the JSON: + - key: the endpoint's signing secret as UTF-8 bytes, including the `whsec_` prefix (not hex- + or base64-decoded, not stripped); + - message: the exact bytes received; re-serializing parsed JSON changes them (for example, `&` + arrives escaped as `\u0026`); + - expected header: `sha256=` followed by the lowercase hex digest, compared in constant time. + + There is no timestamp, delivery ID or event-type header. Rotating a secret replaces it at + once, so accept both the old and the new secret until your deployment has switched. + + **Respond fast.** Answer any 2xx status within 1 second and process the event asynchronously; + do not redirect. Today each identification is delivered once per endpoint, with no retries. A + later release adds retries that resend identical bytes, so make your handler idempotent on + `data.request_id`. + + **Latest state.** The event is a snapshot taken when scoring finished. The History row can + still be refined afterwards (its `ver` increases) and no second event is sent. Use the History + API for guaranteed reads and for the latest state. + + **Test deliveries.** The Test button in the analytics dashboard sends a fixed sample with keys + sorted alphabetically, second-precision timestamps and two-letter country values. Its + `detection_flags` lack `browser_automation` and `search_bot`: parse missing flags as `false`. + + Deliveries are free and do not use your included identifications. + security: [] + parameters: + - $ref: '#/components/parameters/ShieldSignature' + requestBody: + required: true + description: The event as compact JSON. Verify the signature over these exact bytes. + content: + application/json: + schema: + $ref: '#/components/schemas/IdentificationScoredEvent' + examples: + scored: + $ref: '#/components/examples/IdentificationScored' + rateLimited: + $ref: '#/components/examples/IdentificationScoredRateLimited' + testDelivery: + $ref: '#/components/examples/IdentificationScoredTestDelivery' + responses: + 2XX: + description: Delivery accepted. The response body is ignored. + 4XX: + description: Delivery rejected, for example with `401` when the signature does not verify. Any status other than 2xx, and a timeout after 1 second, counts as a failed delivery; failed deliveries are not retried today. + webhook.ping: + post: + operationId: webhookPing + tags: + - Webhooks + summary: Endpoint verification + description: |- + Sent when you verify an endpoint in the analytics dashboard. It carries no `data`. A 2xx + answer within 5 seconds marks the endpoint as verified; anything else marks the verification + as failed. + + The body is signed exactly like `identification.scored`. Its keys are sorted alphabetically + and `created_at` has second precision. Worked example with the test secret + `whsec_00112233445566778899aabbccddeeff`: the body + + ```json + {"created_at":"2026-09-30T12:34:56Z","event_type":"webhook.ping","schema_version":"2026-06-01"} + ``` + + arrives with `X-Shield-Signature: sha256=ea2685733d254f7028fb031c4214583b0650de01e6c8c93131236024edd9fdd8`. + security: [] + parameters: + - $ref: '#/components/parameters/ShieldSignature' + requestBody: + required: true + description: The ping as compact JSON with sorted keys. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookPingEvent' + examples: + ping: + $ref: '#/components/examples/WebhookPing' + responses: + 2XX: + description: Endpoint verified. The response body is ignored. + 4XX: + description: Verification failed. Any status other than 2xx, and a timeout after 5 seconds, fails it. +components: + securitySchemes: + historyApiKey: + type: http + scheme: bearer + bearerFormat: sec_xxxxxxxx-xxxxxxxx-xxxxxxxx + description: 'Private API Key of one domain, sent as `Authorization: Bearer `. Keys look like `sec_` followed by three groups of eight lowercase letters or digits separated by `-`. Create and rotate it in the analytics dashboard. It reads the History API of that domain only; keep it on your server.' + managementSecretKey: + type: http + scheme: bearer + description: 'Secret Key of the domain, sent as `Authorization: Bearer ` together with the registered domain in the `X-Shield-Domain` header. Treat the key as opaque. Find it in the analytics dashboard; keep it on your server.' + parameters: + HistorySearchType: + name: search_type + in: path + required: true + description: |- + Identifier to search by. Only these seven values are supported: + - `request_id`: one identification (read a verdict); + - `device_id`: every identification of one device; + - `user_hid`: every identification of one account; + - `visitor_id`: every identification of one visitor; + - `ip`: every identification from one public IPv4 address; + - `session_id`: every identification of one visit; + - `cookie_id`: every identification with one browser cookie. + + The server does not reject other values: it ignores them and returns the latest identifications + of the whole domain, so restrict the value on your side. + schema: + type: string + enum: + - request_id + - device_id + - user_hid + - visitor_id + - ip + - session_id + - cookie_id + examples: + requestId: + summary: Read one verdict + value: request_id + deviceId: + summary: All identifications of one device + value: device_id + HistoryValue: + name: value + in: path + required: true + description: |- + Value of the identifier, validated on your side before sending: + - `request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`: a UUID of any version, + the nil UUID included, matching + `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`. Send it + lowercase. + - `ip`: a dotted IPv4 address. IPv6 addresses cannot be searched. + - `user_hid`: the exact, case-sensitive User HID as one path segment, encoded the way the + server reads it: send the characters `A-Z a-z 0-9 - . _ ~ $ & + , : ; = @` unescaped and + percent-encode every other byte of the UTF-8 value as uppercase `%XX`, including + `! ' ( ) *`, spaces and `%` itself. The server compares any other encoding literally, so + `%40` instead of `@`, or lowercase hex digits, return an empty page instead of the matching + rows. Many HTTP clients and generated clients escape `$ & + , : ; = @` in path values: build + this path yourself when yours does. A User HID that contains `/` cannot be searched, and most + HTTP clients cannot send `.` or `..` because they remove them as dot segments; the pattern + rejects these values. Hex-encoded hashes need no escaping at all. + + The server does not validate the value: a malformed UUID or IPv4 address gets a `500`. + schema: + type: string + minLength: 1 + pattern: ^(?:[^/.][^/]*|\.[^/.][^/]*|\.\.[^/]+)$ + examples: + requestId: + summary: A request ID + value: a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + ip: + summary: A public IPv4 address + value: 203.0.113.24 + userHid: + summary: A User HID + value: 9f86d081884c7d659a2feaa0c55ad015 + HistoryLimit: + name: limit + in: query + required: false + description: Maximum number of identifications to return, from 1 to 100. The server replaces any other value (and a non-numeric one) with 20 instead of clamping it, so validate it on your side. + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + examples: + one: + summary: Read one verdict + value: 1 + page: + summary: A full page + value: 100 + HistoryOffset: + name: offset + in: query + required: false + description: 'Number of identifications to skip, for paging. The server treats negative or non-numeric values as 0. Rows are ordered by `created_at` only, so paging while new identifications arrive can repeat or skip rows: deduplicate on `request_id`.' + schema: + type: integer + minimum: 0 + default: 0 + examples: + first: + summary: First page + value: 0 + second: + summary: Second page of 100 + value: 100 + ShieldDomain: + name: X-Shield-Domain + in: header + required: true + description: 'Your registered domain. The server matches it exactly against the domain registered in the analytics dashboard, so send it normalized: lowercase, without scheme, path, trailing slash or a leading `www.` (`https://www.Example.com/` becomes `example.com`). A missing or wrong value gets a `401` with an empty body.' + schema: + type: string + minLength: 1 + maxLength: 253 + examples: + domain: + summary: A registered domain + value: example.com + DeprecatedHistoryType: + name: type + in: path + required: true + description: Identifier to search by. Other values get a `404` with a bare JSON string such as `"auto is not supported"`. + schema: + type: string + enum: + - request_id + - device_id + - user_hid + - visitor_id + - ip + - session_id + - cookie_id + examples: + requestId: + summary: Search by request ID + value: request_id + DeprecatedHistoryValue: + name: value + in: path + required: true + description: Value of the identifier. UUID types accept a UUID of any version; `ip` must be an IP address (an IPv6 address passes validation but then fails with `400` and a `null` body); `user_hid` is free text. + schema: + type: string + minLength: 1 + examples: + requestId: + summary: A request ID + value: a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + DeprecatedHistoryLimit: + name: limit + in: query + required: false + description: Maximum number of identifications, from 1 to 100. Any other value becomes 100. There is no `offset`. + schema: + type: integer + minimum: 1 + maximum: 100 + default: 100 + examples: + ten: + summary: Ten rows + value: 10 + ShieldSignature: + name: X-Shield-Signature + in: header + required: true + description: |- + `sha256=` followed by the lowercase hex HMAC-SHA256 of the raw request body: + - key: your endpoint's signing secret as UTF-8 bytes, the `whsec_` prefix included (not hex- or + base64-decoded, not stripped); + - message: the exact bytes of the body as received. + + Compare it with your own digest in constant time, before parsing the JSON. The example values + are the signatures of the example bodies (in their compact form as sent) with the test secret + `whsec_00112233445566778899aabbccddeeff`. + schema: + type: string + pattern: ^sha256=[0-9a-f]{64}$ + examples: + identificationScored: + summary: Signature of the identification.scored example + value: sha256=397ff9bd26888e9e86addc2d920a8c5b2037251a3a1181f3b4810ca6c5f78062 + webhookPing: + summary: Signature of the webhook.ping example + value: sha256=ea2685733d254f7028fb031c4214583b0650de01e6c8c93131236024edd9fdd8 + schemas: + RequestId: + type: string + format: uuid + description: Identifies one identification. The browser creates it as a UUID v4 and hands it to your page; it is the join key between the browser, the webhook and the History API. The nil UUID appears only on rate-limit marker rows that arrived with a malformed request ID. + examples: + - a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + SessionId: + type: string + format: uuid + description: One visit on one origin (UUID v4 created in the browser), shared by the open tabs of that origin. The next visit after the last tab closes gets a new session ID. The nil UUID appears on rate-limit marker rows. + examples: + - b6c8d0e2-f4a6-4b8c-8d0e-2f4a6b8c0d2e + CookieId: + type: string + format: uuid + description: First-party browser identifier kept by the ShieldLabs agent (UUID v4). A missing or malformed value is stored as the nil UUID. + examples: + - c7d9e1f3-a5b7-4c9d-ae1f-3a5b7c9d1e3f + DeviceId: + type: string + format: uuid + description: 'Server-side device identifier (UUID v5). It survives cleared cookies and private windows. The nil UUID `00000000-0000-0000-0000-000000000000` means that no usable device signals were collected (for example on rate-limit marker rows): never group identifications by it.' + examples: + - d8e0f2a4-b6c8-4d0e-bf2a-4b6c8d0e2f4a + - 00000000-0000-0000-0000-000000000000 + VisitorId: + type: string + format: uuid + description: 'Server-side visitor identifier (UUID v5). It is sticky to the device: a new cookie on a known device keeps the existing visitor ID, so clearing cookies usually does not change it. The nil UUID appears on identifications without usable device data, such as rate-limit marker rows.' + examples: + - e9f1a3b5-c7d9-4e1f-8a3b-5c7d9e1f3a5b + Ipv4: + type: string + format: ipv4 + description: Dotted IPv4 address. `0.0.0.0` when no IPv4 address is known (for example for visitors on IPv6); such identifications cannot be searched by IP. + examples: + - 203.0.113.24 + - 0.0.0.0 + OperatingSystem: + type: string + description: 'Operating system name, for example `Windows`, `Mac OS X`, `Linux`, `Android`, `IOS (iPhone)`, `IOS (iPad)`, `ChromeOS` or `Unknown`. Open set: display it, do not branch on it.' + examples: + - Windows + - Mac OS X + - Android + Browser: + type: string + description: 'Browser name, for example `Chrome`, `Safari`, `Firefox`, `Microsoft Edge`, `Opera`, `Samsung Internet`, `Brave`, `Chrome (iOS)`, `Safari (iOS)` or `Unknown`. Open set: display it, do not branch on it.' + examples: + - Chrome + - Safari + DeviceType: + type: string + description: 'Device class from the browser. Known values: `desktop`, `mobile`, `tablet` and `unknown` (the class could not be determined). The set is open: keep values added in later versions and treat them as `unknown`.' + x-extensible-enum: + - desktop + - mobile + - tablet + - unknown + examples: + - desktop + Country: + type: string + description: English country name from IP intelligence, for example `Germany` or `United States` (not an ISO code). Empty string when the country is unknown. + examples: + - Netherlands + - United States + - '' + ConnectionType: + type: string + description: |- + How the visitor connected. Known values: + - `direct`: a regular connection; + - `mobile`: a mobile carrier network; + - `vpn`: a VPN; + - `proxy`: a proxy, datacenter or hosting network (search-engine crawlers are reported here too); + - `tor`: the Tor network; + - `privacy_relay`: a privacy relay such as iCloud Private Relay; + - `browser_vpn_proxy`: a VPN or proxy built into the browser or one of its extensions; + - `unknown`: not enough data. + + The value can say `vpn` while `detection_flags.vpn` is `false` (IP intelligence classified the + network, but the scored VPN check did not fire). Branch on `detection_flags` for decisions. + The set is open: keep values added in later versions and treat them as `unknown`. + x-extensible-enum: + - direct + - mobile + - vpn + - proxy + - tor + - privacy_relay + - browser_vpn_proxy + - unknown + examples: + - direct + RiskScore: + type: integer + minimum: 0 + description: |- + Risk Score from 0 (no risk found) to 100. Search-engine crawlers always score 0. + + Risk bands are computed on your side from the score; no band field exists on the wire: + - trusted: 0-29 + - suspicious: 30-59 + - dangerous: 60-100 + + A value above 100 is not a score. `999` is the rate-limit marker: the visitor's IP went over the + ingest rate limit, and the identification carries exactly one signal, + `{"name":"rate_limited","weight":999}`, usually with nil identifiers. Treat every value above + 100 as rate limited. One marker is written when the IP goes over the limit; request IDs issued + while it stays blocked get no row and no webhook, so they stay unverified. + + The score usually equals the sum of the signal weights capped at 100, but carried-forward + verdicts and corrections make that unreliable: never recompute or validate it yourself. + examples: + - 0 + - 35 + - 80 + - 999 + ScoreDetail: + type: object + description: One entry behind the score, in the PascalCase shape the server stores. `Value` is the weight (0 for informational entries); `Description` is free text for display, never branch on it. + required: + - Value + - Description + properties: + Value: + type: integer + description: Weight of the entry. Can be negative; 0 for informational entries. + examples: + - 10 + Description: + type: string + description: Human-readable description, for example `Is proxy` or `Antidetect browser (turn_block)`. + examples: + - Is proxy + HistoryTimestamp: + type: string + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{3})?$ + description: Time of the identification as `YYYY-MM-DD HH:MM:SS.mmm` in UTC, without a zone designator (not RFC 3339). Older rows can lack the milliseconds. + examples: + - '2026-09-30 12:34:56.123' + - '2026-09-30 13:05:12' + NetworkClass: + type: string + description: 'Connection class of one IP address from IP intelligence. Known values: `direct`, `mobile`, `vpn`, `proxy`, `tor`, `privacy_relay` and the empty string when unknown. The set is open: keep values added in later versions.' + x-extensible-enum: + - direct + - mobile + - vpn + - proxy + - tor + - privacy_relay + - '' + examples: + - direct + TrafficChannel: + type: string + description: 'Marketing channel of the visit. Known values: `Google Ads`, `Meta`, `TikTok`, `LinkedIn`, `X`, `Pinterest`, `Microsoft Ads`, `Organic Search`, `Search bot`, `Referral`, `Direct`, `Other` and the empty string. Resolved in this order: a click ID, then UTM parameters, then the referrer (search engines give `Organic Search`, social networks give the platform name, other sites give `Referral`), otherwise `Direct`. Search-engine crawlers get `Search bot`. Empty string on identifications without attribution, such as rate-limit marker rows. The set is open: keep values added in later versions and treat them as `Other`.' + x-extensible-enum: + - Google Ads + - Meta + - TikTok + - LinkedIn + - X + - Pinterest + - Microsoft Ads + - Organic Search + - Search bot + - Referral + - Direct + - Other + - '' + examples: + - Google Ads + - Direct + TrafficChannelGroup: + type: string + description: 'Group of the marketing channel. Known values: `Paid Search`, `Paid Social`, `Organic`, `Bot`, `Social`, `Referral`, `Direct` and `Other`. History API only; not part of the webhook. The set is open: keep values added in later versions and treat them as `Other`.' + x-extensible-enum: + - Paid Search + - Paid Social + - Organic + - Bot + - Social + - Referral + - Direct + - Other + examples: + - Paid Search + TrafficReason: + type: string + description: 'Why the channel was chosen. Known values: `gclid_present`, `msclkid_present`, `ttclid_present`, `fbclid_present`, `utm_match`, `referrer_search_engine`, `ip_crawler_detected`, `referrer_social`, `external_referrer` and `no_source_detected`. History API only; not part of the webhook. The set is open: keep values added in later versions.' + x-extensible-enum: + - gclid_present + - msclkid_present + - ttclid_present + - fbclid_present + - utm_match + - referrer_search_engine + - ip_crawler_detected + - referrer_social + - external_referrer + - no_source_detected + examples: + - gclid_present + ClickIdType: + type: string + description: 'Ad click identifier found in the landing URL. Known values: `gclid`, `gbraid`, `wbraid`, `msclkid`, `ttclid`, `fbclid` and the empty string when there is none. `fbclid` counts only together with a Meta referrer or a Meta `utm_source`. The set is open: keep values added in later versions.' + x-extensible-enum: + - gclid + - gbraid + - wbraid + - msclkid + - ttclid + - fbclid + - '' + examples: + - gclid + - '' + HistoryRow: + type: object + additionalProperties: true + description: |- + One identification as stored, in its latest version. It describes the same identification as a + webhook `data` object, with different field names: + + | Webhook `data` | History row | + |---|---| + | `risk_score` | `score` | + | `signals` | `score_details` (JSON-encoded string, zero weights included) | + | `detection_flags` | the `is_*` columns and `check_incomplete` (each column names its flag) | + | `detection_flags.browser_vpn_proxy` | derive it: `connection_type == "browser_vpn_proxy"` | + | `domain` | `site_domain` when present, otherwise `domain` | + | `public_ip` | `ip` (`0.0.0.0` instead of `""`) and `country` | + | `local_ip` | `webrtc_leak_ip` and `webrtc_leak_country` when `webrtc_leak_source` is set and not `none`, otherwise `web_rtc_ip` and `web_rtc_country` | + | `traffic_source` | `traffic_channel`, `referrer_domain`, `entry_url`, `click_id_type`, `utm_*` (omitted when empty) | + | `observed_at` (when scoring finished) | `created_at` (when the identification was made) | + + The `ip_mismatch` flag has no column. Rows also carry diagnostic network fields (TCP, MTU and + STUN measurements) that are not part of the stable contract: ignore fields you do not know. + required: + - request_id + - session_id + - cookie_id + - domain + - user_hid + - device_id + - visitor_id + - ip + - os + - browser + - device_type + - country + - connection_type + - score + - score_details + - created_at + - ver + - web_rtc_ip + - web_rtc_country + - web_rtc_connection_type + - webrtc_leak_ip + - webrtc_leak_country + - webrtc_leak_connection_type + - webrtc_leak_source + - is_vpn + - is_tor + - is_proxy + - is_datacenter + - is_abuser + - is_privacy_relay + - is_stun_not_checked + - check_incomplete + - is_antidetect + - is_os_mismatch + - is_os_not_detected + - is_timezone_mismatch + - is_js_disabled + - is_browser_automation + - is_incognito + - is_search_bot + properties: + request_id: + $ref: '#/components/schemas/RequestId' + session_id: + $ref: '#/components/schemas/SessionId' + cookie_id: + $ref: '#/components/schemas/CookieId' + domain: + type: string + description: Host the identification came from. Can be a subdomain of your registered domain. + examples: + - shop.example.com + site_domain: + type: string + description: Your registered domain, present when the identification came from a subdomain. Omitted when empty. + examples: + - example.com + user_hid: + type: string + description: User HID exactly as it was passed to the agent (hashed or pseudonymous account identifier). `anonymous` for anonymous checks; `fail`, `-1` and `unknown` also mean "no user". Empty string when no value was stored. Leave the empty string and these values out when you count accounts. + examples: + - 9f86d081884c7d659a2feaa0c55ad015 + - anonymous + device_id: + $ref: '#/components/schemas/DeviceId' + visitor_id: + $ref: '#/components/schemas/VisitorId' + ip: + $ref: '#/components/schemas/Ipv4' + description: Public IPv4 address of the HTTP request; `0.0.0.0` when none (for example IPv6 visitors). + os: + $ref: '#/components/schemas/OperatingSystem' + browser: + $ref: '#/components/schemas/Browser' + device_type: + $ref: '#/components/schemas/DeviceType' + country: + $ref: '#/components/schemas/Country' + description: Country of `ip` as an English country name, or an empty string. + connection_type: + $ref: '#/components/schemas/ConnectionType' + score: + $ref: '#/components/schemas/RiskScore' + score_details: + type: string + contentMediaType: application/json + contentSchema: + type: array + items: + $ref: '#/components/schemas/ScoreDetail' + description: |- + The entries behind `score` as a JSON-encoded **string** holding an array of + `{"Value": , "Description": }`. Parse it before use. Scored entries come + first, followed by informational entries with `Value` 0, which can be long. Empty string + when no details were stored. + + The webhook `signals` are the entries with a non-zero `Value`, in the same order, with each + description turned into a signal name (for example `Is proxy` becomes `proxy`). Descriptions + are free text for display: never branch on them. + examples: + - '[{"Value":10,"Description":"Is proxy"},{"Value":0,"Description":"Check Incomplete"}]' + - '' + created_at: + $ref: '#/components/schemas/HistoryTimestamp' + ver: + type: integer + format: int64 + description: Version of the row in Unix milliseconds. It increases every time the row is refined, for example when late network data re-scores it after the webhook was sent. + examples: + - 1790771696123 + web_rtc_ip: + $ref: '#/components/schemas/Ipv4' + description: Local IP address observed by the ShieldLabs network check; `0.0.0.0` when none. + web_rtc_country: + $ref: '#/components/schemas/Country' + description: Country of `web_rtc_ip`, or an empty string. + web_rtc_connection_type: + $ref: '#/components/schemas/NetworkClass' + description: Connection class of `web_rtc_ip`, or an empty string. + webrtc_leak_ip: + $ref: '#/components/schemas/Ipv4' + description: Local network address leaked by the browser; `0.0.0.0` when none. + webrtc_leak_country: + $ref: '#/components/schemas/Country' + description: Country of `webrtc_leak_ip`, or an empty string. + webrtc_leak_connection_type: + $ref: '#/components/schemas/NetworkClass' + description: Connection class of `webrtc_leak_ip`, or an empty string. + webrtc_leak_source: + type: string + description: 'Which check found the local network leak. Known values: `scanner`, `shield`, `none` and the empty string. `none` or an empty string when there is no leak; the webhook `local_ip` then uses `web_rtc_ip`. The set is open: keep values added in later versions.' + x-extensible-enum: + - scanner + - shield + - none + - '' + examples: + - none + is_vpn: + type: boolean + description: Same meaning as `detection_flags.vpn`. + is_tor: + type: boolean + description: Same meaning as `detection_flags.tor`. + is_proxy: + type: boolean + description: Same meaning as `detection_flags.proxy`. + is_datacenter: + type: boolean + description: Same meaning as `detection_flags.datacenter_ip`. + is_abuser: + type: boolean + description: Same meaning as `detection_flags.abuser`. + is_privacy_relay: + type: boolean + description: Same meaning as `detection_flags.privacy_relay`. + is_stun_not_checked: + type: boolean + description: Same meaning as `detection_flags.stun_not_checked`. + check_incomplete: + type: boolean + description: Same meaning as `detection_flags.check_incomplete`. Always `false` for search-engine crawlers. + is_antidetect: + type: boolean + description: Same meaning as `detection_flags.anti_detect_browser`. + is_os_mismatch: + type: boolean + description: Same meaning as `detection_flags.os_mismatch`. + is_os_not_detected: + type: boolean + description: Same meaning as `detection_flags.os_not_detected`. + is_timezone_mismatch: + type: boolean + description: Same meaning as `detection_flags.timezone_mismatch`. + is_js_disabled: + type: boolean + description: Same meaning as `detection_flags.javascript_disabled`. Always `false` for search-engine crawlers. + is_browser_automation: + type: boolean + description: Same meaning as `detection_flags.browser_automation`. + is_incognito: + type: boolean + description: Same meaning as `detection_flags.incognito`. Always `false` for search-engine crawlers. + is_search_bot: + type: boolean + description: Same meaning as `detection_flags.search_bot`. + is_suspicious_paid_click: + type: boolean + description: Same meaning as `detection_flags.suspicious_paid_click`. Omitted when `false`. + entry_url: + type: string + description: Landing page URL without the `#fragment` (webhook `traffic_source.landing_url`). Omitted when empty. It keeps the query string, which can contain personal data. + examples: + - https://shop.example.com/signup?utm_source=google&utm_medium=cpc&gclid=abc123 + utm_source: + type: string + description: '`utm_source`, lowercased. Omitted when empty.' + examples: + - google + utm_medium: + type: string + description: '`utm_medium`, lowercased. Omitted when empty.' + examples: + - cpc + utm_campaign: + type: string + description: '`utm_campaign` as sent. Omitted when empty.' + examples: + - spring_launch + utm_content: + type: string + description: '`utm_content` as sent. Omitted when empty.' + examples: + - banner_a + utm_term: + type: string + description: '`utm_term` as sent. Omitted when empty.' + examples: + - device intelligence + traffic_channel: + $ref: '#/components/schemas/TrafficChannel' + description: Marketing channel (webhook `traffic_source.channel`). Omitted when empty. + traffic_channel_group: + $ref: '#/components/schemas/TrafficChannelGroup' + description: Group of the marketing channel. Omitted when empty. + traffic_reason: + $ref: '#/components/schemas/TrafficReason' + description: Why the channel was chosen. Omitted when empty. + referrer_domain: + type: string + description: Registrable domain of the referrer without `www.`; the crawler name (for example `GoogleBot`) for search-engine crawlers. Omitted when empty. + examples: + - news.example.org + click_id_type: + $ref: '#/components/schemas/ClickIdType' + description: Ad click identifier type found in the landing URL. Omitted when empty. + HistoryPage: + type: object + description: One page of identifications, newest first. + required: + - data + - total + properties: + data: + type: array + description: Identifications on this page, ordered by `created_at` descending. Empty when nothing matched. + items: + $ref: '#/components/schemas/HistoryRow' + total: + type: integer + minimum: 0 + description: Number of identifications that match the search in total, across all pages. Page with `offset` while it is below `total`. + examples: + - 37 + ErrorBody: + type: object + description: Error object sent by the History API and by the Management API rate and load limits. + required: + - error + properties: + error: + type: string + description: Human-readable error message. Branch on the HTTP status, not on this text. + examples: + - too many requests + ErrorBodyText: + type: string + contentMediaType: application/json + contentSchema: + $ref: '#/components/schemas/ErrorBody' + description: 'JSON text followed by a newline, sent with `Content-Type: text/plain; charset=utf-8`. Parse it as JSON: it holds `{"error": "..."}`.' + examples: + - | + {"error":"invalid api key"} + PlainText: + type: string + description: Plain text body. + examples: + - 404 page not found + HtmlText: + type: string + description: HTML error page from the edge proxy. Do not parse it; branch on the status. + examples: + -

502 Bad Gateway

+ MaskedKey: + type: string + pattern: ^(\*+.{4}|.{0,4})$ + description: A key with every character except the last four replaced by `*`, keeping the original length. Keys of four characters or fewer are returned as they are. + examples: + - '****************************a3f8' + DomainProfile: + type: object + description: Profile of the registered domain. The keys are PascalCase on the wire. Ignore keys you do not know. + required: + - Domain + - Weight + - Callback + - PublicKey + - Secret + - CreatedAt + properties: + Domain: + type: string + description: The registered domain, as sent in `X-Shield-Domain`. + examples: + - example.com + Weight: + type: integer + description: Remaining included identifications of the account (shared by its domains). Can be negative when the account is over its included volume. + examples: + - 148230 + Callback: + type: string + description: 'Legacy field kept for compatibility, normally an empty string. Webhook deliveries do not use it: configure webhook endpoints in the analytics dashboard.' + examples: + - '' + PublicKey: + $ref: '#/components/schemas/MaskedKey' + description: The domain's Public Key, masked. + Secret: + $ref: '#/components/schemas/MaskedKey' + description: The domain's Secret Key, masked. + CreatedAt: + type: string + format: date-time + description: When the domain was registered, RFC 3339 in UTC with second precision. `0001-01-01T00:00:00Z` when unknown. + examples: + - '2026-01-15T09:00:00Z' + LegacySnapshot: + type: object + additionalProperties: true + description: One identification as returned by the deprecated Management API history endpoint (PascalCase keys). Also carries diagnostic network fields that are not part of the stable contract. Use the History API row instead. + required: + - RequestID + - SessionID + - CookieID + - DeviceID + - VisitorID + - IP + - ConnectionType + - WebRtcHIP + - WebRtcCountry + - WebRtcConnectionType + - OS + - Browser + - DeviceType + - Country + - UserHID + - Score + - Details + - LastRequestTime + properties: + RequestID: + $ref: '#/components/schemas/RequestId' + SessionID: + $ref: '#/components/schemas/SessionId' + CookieID: + $ref: '#/components/schemas/CookieId' + DeviceID: + $ref: '#/components/schemas/DeviceId' + VisitorID: + $ref: '#/components/schemas/VisitorId' + IP: + $ref: '#/components/schemas/Ipv4' + description: Public IPv4 address of the HTTP request. + ConnectionType: + $ref: '#/components/schemas/ConnectionType' + WebRtcHIP: + $ref: '#/components/schemas/Ipv4' + description: Local IP address observed by the ShieldLabs network check (not hashed); `0.0.0.0` when none. + WebRtcCountry: + $ref: '#/components/schemas/Country' + description: Country of `WebRtcHIP`, or an empty string. + WebRtcConnectionType: + $ref: '#/components/schemas/NetworkClass' + description: Connection class of `WebRtcHIP`, or an empty string. + OS: + $ref: '#/components/schemas/OperatingSystem' + Browser: + $ref: '#/components/schemas/Browser' + DeviceType: + $ref: '#/components/schemas/DeviceType' + Country: + $ref: '#/components/schemas/Country' + description: Country of `IP` as an English country name, or an empty string. + UserHID: + type: string + description: User HID as passed to the agent; `anonymous` for anonymous checks. + examples: + - 9f86d081884c7d659a2feaa0c55ad015 + Score: + $ref: '#/components/schemas/RiskScore' + Details: + type: array + description: Every entry behind `Score`, informational entries with `Value` 0 included (unlike the History API, this is a parsed array, not a string). + items: + $ref: '#/components/schemas/ScoreDetail' + LastRequestTime: + type: string + format: date-time + description: Time of the identification, RFC 3339 with fractional seconds. + examples: + - '2026-09-30T12:34:56.123Z' + LegacyErrorMessage: + type: + - string + - 'null' + description: A bare JSON string with the error message, or the JSON literal `null` (an unexpected database error, for example for an IPv6 value). + examples: + - fail parse uuid + - null + HealthStatus: + type: object + description: Liveness status. + required: + - status + properties: + status: + type: string + const: ok + description: Always `ok` when the service answers. + SchemaVersion: + type: string + minLength: 1 + description: Version of the webhook payload contract. Every event sent today carries `2026-06-01`. Accept other values, so that a future version does not break your handler. + examples: + - '2026-06-01' + Rfc3339Timestamp: + type: string + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?Z$ + description: RFC 3339 timestamp in UTC with up to 9 fractional digits (trailing zeros trimmed), for example `2026-09-30T12:34:57.482913041Z`. Parse it with a parser that accepts nanoseconds. + examples: + - '2026-09-30T12:34:57.482913041Z' + - '2026-09-30T12:34:56Z' + UserHid: + type: + - string + - 'null' + description: |- + User HID: your hashed or pseudonymous account identifier, exactly as it was passed to the + ShieldLabs agent. Pass a hashed value, never a raw email address or database ID. + + Values that do not identify a user: + - `anonymous`: an anonymous check; + - `fail`: the agent sent no value; + - `-1` and `unknown`: rows created by ShieldLabs itself, such as rate-limit marker rows. + + `null` only when the stored value is an empty string. Leave `null` and the values above out + when you count the accounts of one device, visitor or IP address. + examples: + - 9f86d081884c7d659a2feaa0c55ad015 + - anonymous + - null + Ipv4OrEmpty: + type: string + pattern: ^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})?$ + description: Dotted IPv4 address, or an empty string when no IPv4 address is known (for example for visitors on IPv6). + examples: + - 203.0.113.24 + - '' + IpInfo: + type: object + description: An IPv4 address and its country. Both keys are always present and can be empty strings. + required: + - ip + - country + properties: + ip: + $ref: '#/components/schemas/Ipv4OrEmpty' + country: + $ref: '#/components/schemas/Country' + TrafficSource: + type: object + description: Where the visit came from. All nine keys are always present; values can be empty strings. + required: + - channel + - referrer_domain + - landing_url + - click_id_type + - utm_source + - utm_medium + - utm_campaign + - utm_content + - utm_term + properties: + channel: + $ref: '#/components/schemas/TrafficChannel' + referrer_domain: + type: string + description: Registrable domain of the referrer without `www.`. For search-engine crawlers, the crawler name (for example `GoogleBot`). + examples: + - google.com + landing_url: + type: string + description: 'Landing page URL without the `#fragment`. It keeps the query string, which can contain personal data: store it with care.' + examples: + - https://shop.example.com/signup?utm_source=google&utm_medium=cpc&gclid=abc123 + click_id_type: + $ref: '#/components/schemas/ClickIdType' + utm_source: + type: string + description: '`utm_source` query parameter, lowercased.' + examples: + - google + utm_medium: + type: string + description: '`utm_medium` query parameter, lowercased.' + examples: + - cpc + utm_campaign: + type: string + description: '`utm_campaign` query parameter as sent.' + examples: + - spring_launch + utm_content: + type: string + description: '`utm_content` query parameter as sent.' + examples: + - '' + utm_term: + type: string + description: '`utm_term` query parameter as sent.' + examples: + - '' + Signal: + type: object + description: One weighted risk signal behind the Risk Score. Only signals with a non-zero weight are listed, in scoring order. The same name can appear twice, and weights can be negative. + required: + - name + - weight + properties: + name: + type: string + minLength: 1 + description: |- + Signal name. The set is open: new names can appear at any time, so keep unknown names and + use them for display and logging only. Known names: + - `tor`: the request came through Tor; + - `vpn`: a VPN was detected; + - `privacy_relay`: a privacy relay such as iCloud Private Relay; + - `proxy`: a proxy was detected; + - `datacenter_ip`: the IP belongs to a datacenter or hosting range; + - `abuser`: the IP has a record of abuse; + - `browser_vpn_proxy`: a VPN or proxy inside the browser; + - `antidetect_browser`: an anti-detect browser (the matching flag is `anti_detect_browser`); + - `proxy_routed_antidetect`: the network check was routed through a proxy in a way typical + for anti-detect browsers; + - `port_scan_routed_via_proxy`: `proxy_routed_antidetect` carried forward from an earlier + identification of the same device and IP; + - `browser_automation`: browser automation, for example a WebDriver-controlled browser; + - `javascript_disabled`: JavaScript or the browser APIs the checks need were unavailable; + - `os_mismatch`: the operating system seen on the network differs from the one the browser + reports; + - `os_not_detected`: the operating system could not be determined; + - `timezone_mismatch`: the browser timezone differs from the IP location timezone; + - `stun_not_checked`: the network (STUN) check did not complete; + - `stun_late_correction`: a late network result arrived; negative weight that cancels + `stun_not_checked`; + - `rate_limited`: the rate-limit marker, weight 999. + + A verdict carried forward from an earlier identification of the same device and IP (for + example `antidetect_browser`) keeps a name derived from the original signal and can carry a + partial weight. + examples: + - proxy + - antidetect_browser + weight: + type: integer + description: Points the signal contributed. Can be negative (`stun_late_correction` is -30) and is 999 for `rate_limited`. Weights can change between releases; never add them up yourself. + examples: + - 10 + - -30 + DetectionFlags: + type: object + description: |- + Stable yes/no verdicts for the identification. Always all 19 keys. Branch on these flags and on + the Risk Score; signal names are for display and logging. + + When `search_bot` is `true`, `incognito`, `check_incomplete`, `ip_mismatch` and + `javascript_disabled` are always `false`. + required: + - vpn + - privacy_relay + - browser_vpn_proxy + - tor + - proxy + - datacenter_ip + - abuser + - os_mismatch + - os_not_detected + - timezone_mismatch + - anti_detect_browser + - browser_automation + - ip_mismatch + - incognito + - search_bot + - suspicious_paid_click + - javascript_disabled + - stun_not_checked + - check_incomplete + properties: + vpn: + type: boolean + description: A VPN was detected (scored `vpn` signal). + privacy_relay: + type: boolean + description: A privacy relay such as iCloud Private Relay was detected. + browser_vpn_proxy: + type: boolean + description: A VPN or proxy built into the browser or one of its extensions. `true` exactly when `connection_type` is `browser_vpn_proxy`. + tor: + type: boolean + description: The request came through the Tor network. + proxy: + type: boolean + description: A proxy was detected. + datacenter_ip: + type: boolean + description: The public IP belongs to a datacenter or hosting range. + abuser: + type: boolean + description: The public IP has a record of abuse in IP intelligence. + os_mismatch: + type: boolean + description: The operating system seen on the network differs from the one the browser reports. + os_not_detected: + type: boolean + description: The operating system could not be determined from the User-Agent or the network. + timezone_mismatch: + type: boolean + description: The browser timezone differs from the timezone of the IP location. + anti_detect_browser: + type: boolean + description: An anti-detect browser was detected. + browser_automation: + type: boolean + description: Browser automation was detected, for example a WebDriver-controlled browser. + ip_mismatch: + type: boolean + description: 'The public IP differs from the local IP found by the browser network check. Informational: it does not add to the score.' + incognito: + type: boolean + description: The browser runs in a private window. + search_bot: + type: boolean + description: A search-engine crawler. Its Risk Score is always 0. + suspicious_paid_click: + type: boolean + description: The visit came from a paid ad click (Google Ads, Meta, TikTok, Microsoft Ads, LinkedIn, Pinterest or X) and the Risk Score is 60 or more (the 999 marker included). + javascript_disabled: + type: boolean + description: JavaScript, or the browser APIs the checks need, were unavailable. + stun_not_checked: + type: boolean + description: The browser network (STUN) check did not complete. Cleared again when a late network result arrives. + check_incomplete: + type: boolean + description: Part of the browser checks timed out, so the verdict rests on partial data. Informational. + IdentificationScoredData: + type: object + description: The scored identification. Every key is always present (no key is ever omitted); only `user_hid` can be `null`. + required: + - request_id + - visitor_id + - device_id + - session_id + - cookie_id + - user_hid + - domain + - public_ip + - local_ip + - connection_type + - os + - browser + - device_type + - traffic_source + - risk_score + - signals + - detection_flags + - observed_at + properties: + request_id: + $ref: '#/components/schemas/RequestId' + visitor_id: + $ref: '#/components/schemas/VisitorId' + device_id: + $ref: '#/components/schemas/DeviceId' + session_id: + $ref: '#/components/schemas/SessionId' + cookie_id: + $ref: '#/components/schemas/CookieId' + user_hid: + $ref: '#/components/schemas/UserHid' + domain: + type: string + description: Registered domain of your site (the request host when no registered domain matched). + examples: + - example.com + public_ip: + $ref: '#/components/schemas/IpInfo' + description: Public IPv4 address of the HTTP request and its country. `ip` is empty when the request did not arrive over IPv4. + local_ip: + $ref: '#/components/schemas/IpInfo' + description: 'Local IP address found by the browser network check (WebRTC): the leaked address when a local network leak was found, otherwise the address ShieldLabs observed. Both keys are empty when the check found nothing.' + connection_type: + $ref: '#/components/schemas/ConnectionType' + os: + $ref: '#/components/schemas/OperatingSystem' + browser: + $ref: '#/components/schemas/Browser' + device_type: + $ref: '#/components/schemas/DeviceType' + traffic_source: + $ref: '#/components/schemas/TrafficSource' + risk_score: + $ref: '#/components/schemas/RiskScore' + signals: + type: array + description: Weighted risk signals behind `risk_score`, in scoring order. Can be empty. The rate-limit marker carries exactly one entry, `{"name":"rate_limited","weight":999}`. + items: + $ref: '#/components/schemas/Signal' + detection_flags: + $ref: '#/components/schemas/DetectionFlags' + observed_at: + $ref: '#/components/schemas/Rfc3339Timestamp' + description: When scoring finished and the event was built (not the page view time); identical to the envelope `created_at`. RFC 3339 in UTC with up to 9 fractional digits. + IdentificationScoredEvent: + type: object + description: 'Body of an `identification.scored` delivery. The signature is not part of the body: it arrives in the `X-Shield-Signature` header.' + required: + - event_type + - schema_version + - created_at + - data + properties: + event_type: + type: string + const: identification.scored + description: Event type. Ignore events whose type you do not know instead of failing. + schema_version: + $ref: '#/components/schemas/SchemaVersion' + created_at: + $ref: '#/components/schemas/Rfc3339Timestamp' + description: When the event was built. Equal to `data.observed_at`. + data: + $ref: '#/components/schemas/IdentificationScoredData' + WebhookPingEvent: + type: object + description: Body of a `webhook.ping` delivery, sent when you verify an endpoint. It has no `data`. The keys arrive sorted alphabetically and `created_at` has second precision. + required: + - event_type + - schema_version + - created_at + properties: + event_type: + type: string + const: webhook.ping + description: Event type. + schema_version: + $ref: '#/components/schemas/SchemaVersion' + created_at: + $ref: '#/components/schemas/Rfc3339Timestamp' + description: When the ping was sent, with second precision. + examples: + HistoryPage: + summary: Five identifications + description: 'One page of five identifications out of 37 matches: a dangerous paid click through a proxy with an anti-detect browser, a trusted anonymous visit, a VPN visit with a local network leak and a late network correction, a rate-limit marker (999) and a search-engine crawler.' + value: + data: + - request_id: a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + session_id: b6c8d0e2-f4a6-4b8c-8d0e-2f4a6b8c0d2e + cookie_id: c7d9e1f3-a5b7-4c9d-ae1f-3a5b7c9d1e3f + domain: shop.example.com + site_domain: example.com + user_hid: 9f86d081884c7d659a2feaa0c55ad015 + device_id: d8e0f2a4-b6c8-4d0e-bf2a-4b6c8d0e2f4a + visitor_id: e9f1a3b5-c7d9-4e1f-8a3b-5c7d9e1f3a5b + ip: 203.0.113.24 + os: Windows + browser: Chrome + device_type: desktop + country: Netherlands + connection_type: proxy + score: 80 + score_details: '[{"Value":10,"Description":"Is proxy"},{"Value":10,"Description":"Is datacenter"},{"Value":60,"Description":"Antidetect browser (turn_block)"},{"Value":0,"Description":"Check Incomplete"}]' + created_at: '2026-09-30 12:34:56.123' + ver: 1790771696123 + web_rtc_ip: 198.51.100.23 + web_rtc_country: Germany + web_rtc_connection_type: direct + scanner_web_rtc_ip: 0.0.0.0 + scanner_web_rtc_country: '' + scanner_web_rtc_connection_type: '' + webrtc_leak_ip: 0.0.0.0 + webrtc_leak_country: '' + webrtc_leak_connection_type: '' + webrtc_leak_source: none + tcp_mss: 1460 + mtu_value: 1500 + mtu_hint: direct + is_vpn: false + is_tor: false + is_proxy: true + is_datacenter: true + is_abuser: false + is_privacy_relay: false + is_stun_not_checked: false + check_incomplete: false + is_antidetect: true + is_os_mismatch: false + is_os_not_detected: false + is_timezone_mismatch: false + is_js_disabled: false + is_browser_automation: false + is_incognito: false + is_search_bot: false + stun_request_seen: true + is_scanner_stun_passed: false + stun_flow_status: ok + entry_url: https://shop.example.com/signup?utm_source=google&utm_medium=cpc&gclid=abc123 + utm_source: google + utm_medium: cpc + traffic_channel: Google Ads + traffic_channel_group: Paid Search + traffic_reason: gclid_present + click_id_type: gclid + is_suspicious_paid_click: true + - request_id: 7c1e2f4a-3b6d-4e8f-9a0b-1c2d3e4f5a6b + session_id: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d + cookie_id: f0e1d2c3-b4a5-4968-8776-655443322110 + domain: example.com + user_hid: anonymous + device_id: 5d9a1f3e-7b2c-5e4d-8f6a-9b0c1d2e3f4a + visitor_id: 3c4d5e6f-7a8b-5c9d-8e0f-1a2b3c4d5e6f + ip: 192.0.2.44 + os: Mac OS X + browser: Safari + device_type: desktop + country: United States + connection_type: direct + score: 10 + score_details: '[{"Value":10,"Description":"Browser timezone ≠ IP-timezone"}]' + created_at: '2026-09-30 12:40:01.007' + ver: 1790772001007 + web_rtc_ip: 192.0.2.44 + web_rtc_country: United States + web_rtc_connection_type: direct + scanner_web_rtc_ip: 0.0.0.0 + scanner_web_rtc_country: '' + scanner_web_rtc_connection_type: '' + webrtc_leak_ip: 0.0.0.0 + webrtc_leak_country: '' + webrtc_leak_connection_type: '' + webrtc_leak_source: '' + tcp_mss: 1460 + mtu_value: 1500 + mtu_hint: direct + is_vpn: false + is_tor: false + is_proxy: false + is_datacenter: false + is_abuser: false + is_privacy_relay: false + is_stun_not_checked: false + check_incomplete: false + is_antidetect: false + is_os_mismatch: false + is_os_not_detected: false + is_timezone_mismatch: true + is_js_disabled: false + is_browser_automation: false + is_incognito: true + is_search_bot: false + stun_request_seen: true + is_scanner_stun_passed: false + stun_flow_status: ok + - request_id: 9e8d7c6b-5a49-4382-9716-05f4e3d2c1b0 + session_id: b0c1d2e3-f4a5-4b6c-9d7e-8f9a0b1c2d3e + cookie_id: c3d4e5f6-a7b8-4c9d-8e0f-a1b2c3d4e5f6 + domain: example.com + user_hid: '' + device_id: e1f2a3b4-c5d6-5e7f-8a9b-0c1d2e3f4a5b + visitor_id: d2e3f4a5-b6c7-5d8e-9f0a-1b2c3d4e5f6a + ip: 198.51.100.7 + os: Android + browser: Chrome + device_type: mobile + country: France + connection_type: vpn + score: 45 + score_details: '[{"Value":15,"Description":"Is VPN"},{"Value":30,"Description":"Stun is not checked"},{"Value":-30,"Description":"Stun passed (late arrival, corrected)"},{"Value":30,"Description":"Sticky verdict: Stun is not checked (request 11111111-2222-4333-8444-555555555555)"},{"Value":0,"Description":"IP ≠ leakIP (198.51.100.7 ≠ 203.0.113.9, source=scanner)"}]' + created_at: '2026-09-30 13:05:12' + ver: 1790773512000 + web_rtc_ip: 0.0.0.0 + web_rtc_country: '' + web_rtc_connection_type: '' + scanner_web_rtc_ip: 203.0.113.9 + scanner_web_rtc_country: Spain + scanner_web_rtc_connection_type: direct + webrtc_leak_ip: 203.0.113.9 + webrtc_leak_country: Spain + webrtc_leak_connection_type: direct + webrtc_leak_source: scanner + tcp_mss: 1380 + mtu_value: 1420 + mtu_hint: vpn_likely + is_vpn: true + is_tor: false + is_proxy: false + is_datacenter: false + is_abuser: false + is_privacy_relay: false + is_stun_not_checked: true + check_incomplete: true + is_antidetect: false + is_os_mismatch: false + is_os_not_detected: false + is_timezone_mismatch: false + is_js_disabled: false + is_browser_automation: false + is_incognito: false + is_search_bot: false + stun_request_seen: false + is_scanner_stun_passed: true + stun_flow_status: reply_without_request + entry_url: https://example.com/pricing + referrer_domain: news.example.org + traffic_channel: Referral + traffic_channel_group: Referral + traffic_reason: external_referrer + - request_id: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d + session_id: 00000000-0000-0000-0000-000000000000 + cookie_id: 00000000-0000-0000-0000-000000000000 + domain: example.com + user_hid: '-1' + device_id: 00000000-0000-0000-0000-000000000000 + visitor_id: 00000000-0000-0000-0000-000000000000 + ip: 203.0.113.200 + os: Unknown + browser: Unknown + device_type: desktop + country: '' + connection_type: unknown + score: 999 + score_details: '[{"Value":999,"Description":"User has been banned 1H, to many requests"}]' + created_at: '2026-09-30 13:10:00.500' + ver: 1790773800500 + web_rtc_ip: 0.0.0.0 + web_rtc_country: '' + web_rtc_connection_type: '' + scanner_web_rtc_ip: 0.0.0.0 + scanner_web_rtc_country: '' + scanner_web_rtc_connection_type: '' + webrtc_leak_ip: 0.0.0.0 + webrtc_leak_country: '' + webrtc_leak_connection_type: '' + webrtc_leak_source: '' + tcp_mss: 0 + mtu_value: 0 + mtu_hint: '' + is_vpn: false + is_tor: false + is_proxy: false + is_datacenter: false + is_abuser: false + is_privacy_relay: false + is_stun_not_checked: false + check_incomplete: false + is_antidetect: false + is_os_mismatch: false + is_os_not_detected: false + is_timezone_mismatch: false + is_js_disabled: false + is_browser_automation: false + is_incognito: false + is_search_bot: false + stun_request_seen: false + is_scanner_stun_passed: false + stun_flow_status: '' + - request_id: 4f5e6d7c-8b9a-4c1d-9e2f-3a4b5c6d7e8f + session_id: 5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d + cookie_id: 6b7c8d9e-0f1a-4b2c-9d3e-4f5a6b7c8d9e + domain: example.com + user_hid: anonymous + device_id: 7c8d9e0f-1a2b-5c3d-8e4f-5a6b7c8d9e0f + visitor_id: 8d9e0f1a-2b3c-5d4e-9f5a-6b7c8d9e0f1a + ip: 198.51.100.66 + os: Linux + browser: Chrome + device_type: desktop + country: United States + connection_type: proxy + score: 0 + score_details: '' + created_at: '2026-09-30 13:20:30.250' + ver: 1790774430250 + web_rtc_ip: 203.0.113.77 + web_rtc_country: United States + web_rtc_connection_type: direct + scanner_web_rtc_ip: 0.0.0.0 + scanner_web_rtc_country: '' + scanner_web_rtc_connection_type: '' + webrtc_leak_ip: 0.0.0.0 + webrtc_leak_country: '' + webrtc_leak_connection_type: '' + webrtc_leak_source: none + tcp_mss: 1460 + mtu_value: 1500 + mtu_hint: direct + is_vpn: false + is_tor: false + is_proxy: false + is_datacenter: false + is_abuser: false + is_privacy_relay: false + is_stun_not_checked: false + check_incomplete: false + is_antidetect: false + is_os_mismatch: false + is_os_not_detected: false + is_timezone_mismatch: false + is_js_disabled: false + is_browser_automation: false + is_incognito: false + is_search_bot: true + stun_request_seen: false + is_scanner_stun_passed: false + stun_flow_status: '' + referrer_domain: GoogleBot + traffic_channel: Search bot + traffic_channel_group: Bot + traffic_reason: ip_crawler_detected + total: 37 + HistoryPageEmpty: + summary: Nothing matched + description: No identification matched. When searching by `request_id` right after a protected action, this means "not scored yet" (or an invalid request ID), never "clean". + value: + data: [] + total: 0 + HistoryUnauthorizedMissingHeader: + summary: Missing or malformed Authorization header + description: JSON text sent as `text/plain`, followed by a newline. + value: | + {"error":"missing or invalid authorization header"} + HistoryUnauthorizedInvalidKey: + summary: Unknown, deleted or disabled key + description: JSON text sent as `text/plain`, followed by a newline. + value: | + {"error":"invalid api key"} + NotFoundText: + summary: No route matched + description: Plain text body of an unrouted path. + value: 404 page not found + HistoryTooManyRequests: + summary: Soft rate limit reached + description: More than about 15 requests in the current second for this domain. Retry after about a second. + value: + error: too many requests + HistoryInvalidValue: + summary: Malformed UUID value + description: 'The raw database error for a value that is not a UUID. It repeats for the same request: validate the value instead of retrying.' + value: + error: 'code: 53, message: Cannot convert string ''abc'' to type UUID' + HistoryKeyLookupFailed: + summary: Key lookup failed + description: A transient error while checking the key, sent as JSON text. Retry with backoff. + value: | + {"error":"internal error"} + BadGatewayHtml: + summary: Bad gateway + description: HTML page from the edge proxy. + value:

502 Bad Gateway

+ GatewayTimeoutHtml: + summary: Gateway timeout + description: HTML page from the edge proxy. + value:

504 Gateway Time-out

+ DomainProfile: + summary: Profile of example.com + description: A domain with 148,230 remaining included identifications and masked keys. + value: + Domain: example.com + Weight: 148230 + Callback: '' + PublicKey: '****************************a3f8' + Secret: '****************************9c2d' + CreatedAt: '2026-01-15T09:00:00Z' + ManagementTooManyRequests: + summary: Rate limit reached or block active + description: 'Do not retry: every request gets this answer until the 10-minute block ends.' + value: + error: too many requests + ManagementServerBusy: + summary: Too many requests in flight + description: Retry with backoff. + value: + error: server is busy + LegacySnapshotList: + summary: One identification (deprecated shape) + description: The PascalCase array returned by the deprecated endpoint, for the same identification as the first History API example row. + value: + - RequestID: a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + SessionID: b6c8d0e2-f4a6-4b8c-8d0e-2f4a6b8c0d2e + CookieID: c7d9e1f3-a5b7-4c9d-ae1f-3a5b7c9d1e3f + DeviceID: d8e0f2a4-b6c8-4d0e-bf2a-4b6c8d0e2f4a + VisitorID: e9f1a3b5-c7d9-4e1f-8a3b-5c7d9e1f3a5b + IP: 203.0.113.24 + ConnectionType: proxy + TcpMss: 1460 + MtuValue: 1500 + MtuHint: direct + WebRtcHIP: 198.51.100.23 + WebRtcCountry: Germany + WebRtcConnectionType: direct + OS: Windows + Browser: Chrome + DeviceType: desktop + Country: Netherlands + UserHID: 9f86d081884c7d659a2feaa0c55ad015 + Score: 80 + Details: + - Value: 10 + Description: Is proxy + - Value: 10 + Description: Is datacenter + - Value: 60 + Description: Antidetect browser (turn_block) + LastRequestTime: '2026-09-30T12:34:56.123Z' + LegacySnapshotListEmpty: + summary: Nothing matched + description: An empty array. + value: [] + ManagementBadRequestUuid: + summary: Value is not a UUID + description: A bare JSON string. + value: fail parse uuid + ManagementBadRequestIp: + summary: Value is not an IP address + description: A bare JSON string. + value: invalid IP address + ManagementBadRequestEmpty: + summary: Empty value + description: A bare JSON string. + value: value cannot be empty + ManagementBadRequestNull: + summary: Database error + description: The JSON literal `null`, for example for an IPv6 `ip` value. + value: null + ManagementUnsupportedType: + summary: Unsupported identifier type + description: A bare JSON string naming the type that was sent. + value: auto is not supported + HealthOk: + summary: Service is up + description: The only successful answer. + value: + status: ok + IdentificationScored: + summary: Dangerous identification from a paid click + description: Risk Score 80 from a proxy, a datacenter IP and an anti-detect browser, on a visit from a Google Ads click. + value: + event_type: identification.scored + schema_version: '2026-06-01' + created_at: '2026-09-30T12:34:57.482913041Z' + data: + request_id: a5b7c9d1-e3f5-4a7b-9c1d-3e5f7a9b1c3d + visitor_id: e9f1a3b5-c7d9-4e1f-8a3b-5c7d9e1f3a5b + device_id: d8e0f2a4-b6c8-4d0e-bf2a-4b6c8d0e2f4a + session_id: b6c8d0e2-f4a6-4b8c-8d0e-2f4a6b8c0d2e + cookie_id: c7d9e1f3-a5b7-4c9d-ae1f-3a5b7c9d1e3f + user_hid: 9f86d081884c7d659a2feaa0c55ad015 + domain: example.com + public_ip: + ip: 203.0.113.24 + country: Netherlands + local_ip: + ip: 198.51.100.23 + country: Germany + connection_type: proxy + os: Windows + browser: Chrome + device_type: desktop + traffic_source: + channel: Google Ads + referrer_domain: google.com + landing_url: https://shop.example.com/signup?utm_source=google&utm_medium=cpc&gclid=abc123 + click_id_type: gclid + utm_source: google + utm_medium: cpc + utm_campaign: '' + utm_content: '' + utm_term: '' + risk_score: 80 + signals: + - name: proxy + weight: 10 + - name: datacenter_ip + weight: 10 + - name: antidetect_browser + weight: 60 + detection_flags: + vpn: false + privacy_relay: false + browser_vpn_proxy: false + tor: false + proxy: true + datacenter_ip: true + abuser: false + os_mismatch: false + os_not_detected: false + timezone_mismatch: false + anti_detect_browser: true + browser_automation: false + ip_mismatch: true + incognito: false + search_bot: false + suspicious_paid_click: true + javascript_disabled: false + stun_not_checked: false + check_incomplete: false + observed_at: '2026-09-30T12:34:57.482913041Z' + IdentificationScoredRateLimited: + summary: Rate-limit marker (999) + description: 'The 999 rate-limit marker: one `rate_limited` signal, nil identifiers and no attribution. It is not a Risk Score.' + value: + event_type: identification.scored + schema_version: '2026-06-01' + created_at: '2026-09-30T13:10:00.5Z' + data: + request_id: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d + visitor_id: 00000000-0000-0000-0000-000000000000 + device_id: 00000000-0000-0000-0000-000000000000 + session_id: 00000000-0000-0000-0000-000000000000 + cookie_id: 00000000-0000-0000-0000-000000000000 + user_hid: '-1' + domain: example.com + public_ip: + ip: 203.0.113.200 + country: '' + local_ip: + ip: '' + country: '' + connection_type: unknown + os: Unknown + browser: Unknown + device_type: desktop + traffic_source: + channel: '' + referrer_domain: '' + landing_url: '' + click_id_type: '' + utm_source: '' + utm_medium: '' + utm_campaign: '' + utm_content: '' + utm_term: '' + risk_score: 999 + signals: + - name: rate_limited + weight: 999 + detection_flags: + vpn: false + privacy_relay: false + browser_vpn_proxy: false + tor: false + proxy: false + datacenter_ip: false + abuser: false + os_mismatch: false + os_not_detected: false + timezone_mismatch: false + anti_detect_browser: false + browser_automation: false + ip_mismatch: false + incognito: false + search_bot: false + suspicious_paid_click: false + javascript_disabled: false + stun_not_checked: false + check_incomplete: false + observed_at: '2026-09-30T13:10:00.5Z' + IdentificationScoredTestDelivery: + summary: Test delivery from the analytics dashboard + description: 'The fixed sample sent by the Test button: keys sorted alphabetically, second-precision timestamps, two-letter country values and only 17 detection flags (`browser_automation` and `search_bot` are missing). It differs from the schema in exactly those two flags: parse missing flags as `false`.' + value: + created_at: '2026-09-30T12:34:56Z' + data: + browser: Chrome + connection_type: proxy + cookie_id: 2c9d1e8f-4b7a-4c3e-9d2f-1a8b7c6d5e4f + detection_flags: + abuser: true + anti_detect_browser: false + browser_vpn_proxy: false + check_incomplete: false + datacenter_ip: true + incognito: false + ip_mismatch: false + javascript_disabled: false + os_mismatch: false + os_not_detected: false + privacy_relay: false + proxy: true + stun_not_checked: false + suspicious_paid_click: false + timezone_mismatch: false + tor: false + vpn: false + device_id: 6f1e2d3c-4b5a-5968-8776-655443322110 + device_type: desktop + domain: example.com + local_ip: + country: BY + ip: 198.51.100.10 + observed_at: '2026-09-30T12:34:56Z' + os: Windows + public_ip: + country: BY + ip: 203.0.113.10 + request_id: 13f84f05-7c2a-4e9b-9f1d-2a6b8c0e4d11 + risk_score: 30 + session_id: 3a2b1c0d-9e8f-4a7b-8c6d-5e4f3a2b1c0d + signals: + - name: proxy + weight: 10 + - name: datacenter_ip + weight: 10 + - name: abuser + weight: 10 + traffic_source: + channel: Direct + click_id_type: '' + landing_url: https://example.com/ + referrer_domain: '' + utm_campaign: '' + utm_content: '' + utm_medium: '' + utm_source: '' + utm_term: '' + user_hid: null + visitor_id: 7a6b5c4d-3e2f-5a1b-9c8d-7e6f5a4b3c2d + event_type: identification.scored + schema_version: '2026-06-01' + WebhookPing: + summary: Endpoint verification + description: The ping sent when you verify an endpoint. It has no `data`. + value: + created_at: '2026-09-30T12:34:56Z' + event_type: webhook.ping + schema_version: '2026-06-01' + responses: + HistoryUnauthorized: + description: 'The `Authorization` header is missing or is not a Bearer token, or the Private API Key is unknown, deleted or belongs to a disabled domain. The body is JSON text sent with `Content-Type: text/plain; charset=utf-8`: parse it as JSON anyway. Do not retry.' + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorBodyText' + examples: + missingHeader: + $ref: '#/components/examples/HistoryUnauthorizedMissingHeader' + invalidKey: + $ref: '#/components/examples/HistoryUnauthorizedInvalidKey' + NotFound: + description: No route matches the method and path, for example because the base URL repeats part of the path or a path value is empty or contains `/`. Plain text body. Check the URL; do not retry. + content: + text/plain: + schema: + $ref: '#/components/schemas/PlainText' + examples: + notFound: + $ref: '#/components/examples/NotFoundText' + HistoryTooManyRequests: + description: 'More than about 15 requests in the current second for this domain (all callers of the domain share the limit). There is no ban: retry after about a second, with backoff.' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + examples: + tooManyRequests: + $ref: '#/components/examples/HistoryTooManyRequests' + HistoryServerError: + description: |- + Server error. + - `application/json`: the query failed. A malformed UUID or IPv4 value always ends here with the + raw database message, so validate the path before sending and do not retry such a request. + Other failures are transient. + - `text/plain` (JSON text): the key lookup failed. Transient: retry with backoff. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + examples: + invalidValue: + $ref: '#/components/examples/HistoryInvalidValue' + text/plain: + schema: + $ref: '#/components/schemas/ErrorBodyText' + examples: + keyLookupFailed: + $ref: '#/components/examples/HistoryKeyLookupFailed' + BadGateway: + description: The edge proxy could not reach the service. HTML body. Retry with backoff. + content: + text/html: + schema: + $ref: '#/components/schemas/HtmlText' + examples: + badGateway: + $ref: '#/components/examples/BadGatewayHtml' + GatewayTimeout: + description: The service did not answer the edge proxy in time. HTML body. Retry with backoff. + content: + text/html: + schema: + $ref: '#/components/schemas/HtmlText' + examples: + gatewayTimeout: + $ref: '#/components/examples/GatewayTimeoutHtml' + ManagementUnauthorized: + description: Empty body, no `Content-Type`. `X-Shield-Domain` or `Authorization` is missing or malformed, the domain is unknown or disabled, or the Secret Key is wrong. Do not retry. + ManagementTooManyRequests: + description: 'More than 15 requests in the current minute from your IP, or a 10-minute block is active. The request that exceeds the limit starts the block, and every request during it gets this answer. Do not retry: wait for the block to end and cache results to stay under the limit.' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + examples: + tooManyRequests: + $ref: '#/components/examples/ManagementTooManyRequests' + ManagementServerBusy: + description: Too many requests are in flight on the server. Retry with backoff. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + examples: + serverBusy: + $ref: '#/components/examples/ManagementServerBusy' + headers: + Deprecation: + description: Marks the endpoint as deprecated. The value is the literal `true`. + schema: + type: string + const: 'true' + examples: + deprecated: + summary: Deprecated endpoint + value: 'true' + Sunset: + description: HTTP date after which the endpoint stops working. + schema: + type: string + const: Sat, 01 Jan 2027 00:00:00 GMT + examples: + sunset: + summary: Sunset date + value: Sat, 01 Jan 2027 00:00:00 GMT + Link: + description: Points to the replacement endpoint with `rel="successor-version"`. + schema: + type: string + const: ; rel="successor-version" + examples: + successor: + summary: Successor endpoint + value: ; rel="successor-version" diff --git a/sync.sh b/sync.sh new file mode 100755 index 0000000..624350a --- /dev/null +++ b/sync.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")" + +schemaUrl="${1:-https://raw.githubusercontent.com/ShieldLabs-ai/shieldlabs-openapi/main/dist/shieldlabs-api.yaml}" +schemaDestination="./resources/shieldlabs-api.yaml" + +mkdir -p "$(dirname "$schemaDestination")" + +echo "Downloading $schemaUrl to $schemaDestination" +curl -fSL --retry 3 --proto-redir '=https' --connect-timeout 10 --max-time 120 \ + -o "$schemaDestination" "$schemaUrl" + +echo "OpenAPI schema download complete. Run ./generate.sh to refresh generated/."