diff --git a/.editorconfig b/.editorconfig
index 1bf78ed..4f106fa 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -44,6 +44,13 @@ dotnet_naming_style.end_in_async.capitalization = pascal_case
generated_code = true
dotnet_analyzer_diagnostic.severity = none
+[src/GoAffPro.Client.Generated/Generated/**/*.cs]
+generated_code = true
+dotnet_analyzer_diagnostic.severity = none
+dotnet_diagnostic.CS1591.severity = none
+dotnet_diagnostic.CA1707.severity = none
+dotnet_diagnostic.CA1716.severity = none
+
[*.json]
indent_size = 2
diff --git a/.gitignore b/.gitignore
index cd89e01..73a1c84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,12 +19,6 @@ packages/
openapi/goaffpro.openapi.json
openapi/goaffpro-user.openapi.json
openapi/goaffpro-public.openapi.json
-openapi/swagger-ui-init.js
-obj/GoAffPro.Client.Generator.hash
-
-# Generated code (tracked, but can be regenerated)
-# Uncomment to gitignore if you prefer not to commit generated code:
-# src/GoAffPro.Client/Generated/*.g.cs
# Test results
TestResults/
@@ -36,8 +30,10 @@ Thumbs.db
# Local development overrides
examples/GoAffPro.Client.Example/appsettings.development.json
+tests/GoAffPro.Client.IntegrationTests/appsettings.Test.local.json
# Local LLM/notes docs (not published to GitHub)
AGENTS.md
ARCHITECTURE.md
docs/
+.tools/
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 5204ebd..245c18a 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -10,13 +10,15 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/GoAffPro.Client.slnx b/GoAffPro.Client.slnx
index cafc98d..d95be48 100644
--- a/GoAffPro.Client.slnx
+++ b/GoAffPro.Client.slnx
@@ -7,8 +7,8 @@
+
-
diff --git a/README.md b/README.md
index ff200c0..0683666 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# GoAffPro.Client
-Async-first .NET client for the GoAffPro API with build-time NSwag generation and polling/event-based change detection.
+Async-first .NET client for the GoAffPro API with build-time Kiota generation and polling/event-based change detection.
## Targets
@@ -30,54 +30,34 @@ await using var loggedInClient = await GoAffProClient.CreateLoggedInAsync(
password: "password123");
```
-### Wrapper Methods (DX Layer)
+### Wrapper Surface
-The wrapper methods are built on top of generated clients:
+`GoAffProClient` intentionally keeps a minimal wrapper surface:
-```csharp
-// Fetch orders with optional time filtering
-var orders = await client.GetOrdersAsync(from: DateTimeOffset.UtcNow.AddDays(-1), limit: 50);
-
-// Fetch affiliates with time range
-var affiliates = await client.GetAffiliatesAsync(from: startDate, toDate: endDate, limit: 50);
-
-// Fetch payouts and products
-var payouts = await client.GetPayoutsAsync(limit: 50);
-var products = await client.GetProductsAsync(limit: 50);
-```
-
-Wrapper methods return typed models:
-
-- `GoAffProOrder` (includes Subtotal, AffiliateId, Status)
-- `GoAffProAffiliate` (includes FirstName, LastName, Phone, Country, GroupId)
-- `GoAffProReward` (includes AffiliateId, Type, Metadata, Level, Status) - currently disabled
-- `GoAffProPayout`
-- `GoAffProProduct`
-
-Each model includes strongly typed fields and `RawPayload` (`JsonElement`) for advanced scenarios.
-
-`GetRewardsAsync` is currently disabled because `/user/feed/rewards` is returning `404` (observed on 2026-02-18). The method is marked `[Obsolete]` and returns an empty collection.
+- auth helpers: `LoginAsync`, `SetBearerToken`
+- generated client access: `User` and `PublicApi`
+- polling detector: `GoAffProEventDetector`
### Access Generated Clients Directly
```csharp
-var loginResponse = await client.User.UserLoginAsync(new GoAffPro.Client.Generated.User.Body
+var loginResponse = await client.User.User.Login.PostAsync(new GoAffPro.Client.Generated.User.User.Login.LoginPostRequestBody
{
Email = "affiliate@example.com",
Password = "password123",
});
-var publicSites = await client.PublicApi.PublicSitesAsync(
- site_ids: null,
- currency: null,
- keyword: null,
- limit: 20,
- offset: 0);
+var publicSites = await client.PublicApi.Public.Sites.GetAsync(config =>
+{
+ config.QueryParameters.Limit = 20;
+ config.QueryParameters.Offset = 0;
+});
```
## Event Detection
`GoAffProEventDetector` supports both async streams and classic `.NET` events. It uses time-based filtering to fetch only new items since the last poll.
+Detected payloads are propagated as generated Kiota feed item types.
### Async Streams
@@ -135,18 +115,15 @@ dotnet run --project examples/GoAffPro.Client.Example
## Build-Time Generation
-On build, `GoAffPro.Client.Generator`:
+On build, `GoAffPro.Client.Generated`:
-1. Fetches `https://api.goaffpro.com/docs/admin/swagger-ui-init.js`
- (or uses `openapi/swagger-ui-init.js` only if you provide a local override file)
-2. Extracts OpenAPI JSON
-3. Filters to `/user/*` and `/public/*`
-4. Normalizes schema gaps for generation
-5. Generates:
- - `src/GoAffPro.Client/Generated/GoAffProUserClient.g.cs`
- - `src/GoAffPro.Client/Generated/GoAffProPublicClient.g.cs`
+1. Loads the local canonical spec `openapi/goaffpro-canonical.yaml`
+2. Runs Kiota generation for `/user/*` and `/public/*`
+3. Writes generated files under:
+ - `src/GoAffPro.Client.Generated/Generated/User`
+ - `src/GoAffPro.Client.Generated/Generated/Public`
-Do not edit `*.g.cs` manually.
+Generated output is implementation detail for the wrapper package. Do not manually edit files under `Generated/`.
## Testing
diff --git a/dotnet-tools.json b/dotnet-tools.json
new file mode 100644
index 0000000..5b4d81b
--- /dev/null
+++ b/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "microsoft.openapi.kiota": {
+ "version": "1.30.0",
+ "commands": [
+ "kiota"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/GoAffPro.Client.Example/ExampleOptions.cs b/examples/GoAffPro.Client.Example/ExampleOptions.cs
deleted file mode 100644
index 7389a8a..0000000
--- a/examples/GoAffPro.Client.Example/ExampleOptions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace GoAffPro.Client.Example;
-
-[System.Diagnostics.CodeAnalysis.SuppressMessage(
- "Performance",
- "CA1812:Avoid uninstantiated internal classes",
- Justification = "Instantiated via options binding.")]
-internal sealed class ExampleOptions
-{
- public string? Email { get; set; }
-
- public string? Password { get; set; }
-
- public int PollingIntervalSeconds { get; set; } = 30;
-
- public int PageSize { get; set; } = 50;
-}
diff --git a/examples/GoAffPro.Client.Example/GoAffPro.Client.Example.csproj b/examples/GoAffPro.Client.Example/GoAffPro.Client.Example.csproj
index 495a47d..fb9a828 100644
--- a/examples/GoAffPro.Client.Example/GoAffPro.Client.Example.csproj
+++ b/examples/GoAffPro.Client.Example/GoAffPro.Client.Example.csproj
@@ -19,8 +19,7 @@
-
-
+
diff --git a/examples/GoAffPro.Client.Example/Program.cs b/examples/GoAffPro.Client.Example/Program.cs
index 1441324..ac5499d 100644
--- a/examples/GoAffPro.Client.Example/Program.cs
+++ b/examples/GoAffPro.Client.Example/Program.cs
@@ -1,22 +1,873 @@
+using System.Diagnostics;
+using System.Globalization;
+using System.Text.Json;
using GoAffPro.Client;
-using GoAffPro.Client.Example;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
+using GoAffPro.Client.Exceptions;
+using Microsoft.Kiota.Abstractions;
+using Spectre.Console;
+using AggregateField = GoAffPro.Client.Generated.User.Stats.Aggregate.GetFieldsQueryParameterType;
+using SiteField = GoAffPro.Client.Generated.User.Sites.GetFieldsQueryParameterType;
+using SiteStatus = GoAffPro.Client.Generated.User.Sites.GetStatusQueryParameterType;
-HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
+ExampleSettings settings = LoadSettings();
+var options = CommandLineOptions.Parse(args);
-builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
+using var client = new GoAffProClient(new GoAffProClientOptions
+{
+ BaseUrl = settings.BaseUrl,
+ BearerToken = settings.BearerToken,
+ Timeout = settings.Timeout,
+});
-builder.Logging.ClearProviders();
-builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
-builder.Logging.AddConsole();
+if (options.RunTests)
+{
+ int code = await RunCliSweepAsync(client, settings, options).ConfigureAwait(false);
+ Environment.ExitCode = code;
+ return;
+}
-builder.Services.Configure(builder.Configuration.GetSection("GoAffPro"));
-builder.Services.Configure(builder.Configuration.GetSection("Example"));
-builder.Services.AddGoAffProClient();
-builder.Services.AddHostedService();
+await RunInteractiveAsync(client).ConfigureAwait(false);
-using IHost host = builder.Build();
-await host.RunAsync().ConfigureAwait(false);
+static async Task RunCliSweepAsync(GoAffProClient client, ExampleSettings settings, CommandLineOptions options)
+{
+ string? token = ResolveToken(options.AccessToken) ?? client.BearerToken;
+ if (string.IsNullOrWhiteSpace(token) &&
+ !string.IsNullOrWhiteSpace(options.Email) &&
+ !string.IsNullOrWhiteSpace(options.Password))
+ {
+ token = await client.LoginAsync(options.Email, options.Password, CancellationToken.None).ConfigureAwait(false);
+ }
+
+ if (string.IsNullOrWhiteSpace(token))
+ {
+ await Console.Error.WriteLineAsync("No access token is available. Use --access_token=... or --email/--password.").ConfigureAwait(false);
+ return 2;
+ }
+
+ client.SetBearerToken(token);
+ string outputPath = string.IsNullOrWhiteSpace(options.OutputPath)
+ ? Path.Combine(Environment.CurrentDirectory, $"api-sweep-{DateTimeOffset.UtcNow:yyyyMMdd-HHmmss}.json")
+ : options.OutputPath;
+
+ TimeSpan productTimeout = options.ProductsTimeoutSeconds > 0
+ ? TimeSpan.FromSeconds(options.ProductsTimeoutSeconds)
+ : TimeSpan.FromSeconds(90);
+
+ ApiSweepReport report = await ApiSweepRunner.RunAllAsync(client, settings, productTimeout, CancellationToken.None).ConfigureAwait(false);
+ string reportJson = JsonSerializer.Serialize(report, JsonOptions.Value);
+ await File.WriteAllTextAsync(outputPath, reportJson, CancellationToken.None).ConfigureAwait(false);
+
+ int failures = report.Results.Count(static x => !x.Success);
+ await Console.Out.WriteLineAsync($"Sweep completed. Total: {report.Results.Count}, failed: {failures}").ConfigureAwait(false);
+ await Console.Out.WriteLineAsync($"Report: {outputPath}").ConfigureAwait(false);
+ return failures == 0 ? 0 : 1;
+}
+
+static async Task RunInteractiveAsync(GoAffProClient client)
+{
+ var observer = new ObserverController(client);
+ try
+ {
+ AnsiConsole.MarkupLine("[bold green]GoAffPro Interactive Playground[/]");
+ if (!string.IsNullOrWhiteSpace(client.BearerToken))
+ {
+ AnsiConsole.MarkupLine("[green]Bearer token loaded from appsettings.[/]");
+ }
+
+ bool exitRequested = false;
+ while (!exitRequested)
+ {
+ AnsiConsole.WriteLine();
+ AnsiConsole.MarkupLine($"Auth: {(string.IsNullOrWhiteSpace(client.BearerToken) ? "[yellow]not authenticated[/]" : "[green]authenticated[/]")}");
+ AnsiConsole.MarkupLine($"Observer: {(observer.IsRunning ? "[green]running[/]" : "[grey]stopped[/]")}");
+
+ string action = AnsiConsole.Prompt(
+ new SelectionPrompt()
+ .Title("Select an action")
+ .AddChoices(
+ [
+ "Set bearer token",
+ "Login with email/password",
+ "Call endpoint",
+ "Run full endpoint sweep",
+ "Start observer",
+ "Stop observer",
+ "Exit"
+ ]));
+
+ try
+ {
+ switch (action)
+ {
+ case "Set bearer token":
+ SetBearerToken(client);
+ break;
+ case "Login with email/password":
+ await LoginAsync(client).ConfigureAwait(false);
+ break;
+ case "Call endpoint":
+ await CallEndpointAsync(client).ConfigureAwait(false);
+ break;
+ case "Run full endpoint sweep":
+ await RunSweepFromInteractiveAsync(client).ConfigureAwait(false);
+ break;
+ case "Start observer":
+ await observer.StartAsync().ConfigureAwait(false);
+ break;
+ case "Stop observer":
+ await observer.StopAsync().ConfigureAwait(false);
+ break;
+ case "Exit":
+ exitRequested = true;
+ break;
+ }
+ }
+ catch (GoAffProApiException ex)
+ {
+ AnsiConsole.MarkupLine($"[red]API error:[/] {Markup.Escape(ex.Message)}");
+ }
+ catch (ApiException ex)
+ {
+ AnsiConsole.MarkupLine($"[red]Request failed:[/] {Markup.Escape(ex.Message)}");
+ }
+ catch (HttpRequestException ex)
+ {
+ AnsiConsole.MarkupLine($"[red]HTTP error:[/] {Markup.Escape(ex.Message)}");
+ }
+ catch (TaskCanceledException ex)
+ {
+ AnsiConsole.MarkupLine($"[red]Timeout/cancelled:[/] {Markup.Escape(ex.Message)}");
+ }
+ catch (InvalidOperationException ex)
+ {
+ AnsiConsole.MarkupLine($"[red]Invalid operation:[/] {Markup.Escape(ex.Message)}");
+ }
+ }
+ }
+ finally
+ {
+ await observer.DisposeAsync().ConfigureAwait(false);
+ }
+}
+
+static async Task RunSweepFromInteractiveAsync(GoAffProClient client)
+{
+ if (string.IsNullOrWhiteSpace(client.BearerToken))
+ {
+ AnsiConsole.MarkupLine("[yellow]Set a bearer token or login first.[/]");
+ return;
+ }
+
+ string defaultPath = Path.Combine(Environment.CurrentDirectory, $"api-sweep-{DateTimeOffset.UtcNow:yyyyMMdd-HHmmss}.json");
+ string outputPath = AnsiConsole.Prompt(new TextPrompt("Output path").DefaultValue(defaultPath));
+
+ int timeoutSeconds = AnsiConsole.Prompt(new TextPrompt("Product endpoint timeout (seconds)").DefaultValue(90));
+ var productTimeout = TimeSpan.FromSeconds(Math.Max(1, timeoutSeconds));
+
+ ApiSweepReport report = await ApiSweepRunner.RunAllAsync(
+ client,
+ ExampleSettings.Default,
+ productTimeout,
+ CancellationToken.None).ConfigureAwait(false);
+ string reportJson = JsonSerializer.Serialize(report, JsonOptions.Value);
+ await File.WriteAllTextAsync(outputPath, reportJson, CancellationToken.None).ConfigureAwait(false);
+
+ int failures = report.Results.Count(static x => !x.Success);
+ AnsiConsole.MarkupLine($"[green]Sweep complete.[/] total={report.Results.Count}, failed={failures}");
+ AnsiConsole.MarkupLine($"Saved: [grey]{Markup.Escape(outputPath)}[/]");
+}
+
+static void SetBearerToken(GoAffProClient client)
+{
+ string token = AnsiConsole.Prompt(new TextPrompt("Bearer token").Secret());
+ client.SetBearerToken(token);
+ AnsiConsole.MarkupLine("[green]Bearer token updated.[/]");
+}
+
+static async Task LoginAsync(GoAffProClient client)
+{
+ string email = AnsiConsole.Ask("Email");
+ string password = AnsiConsole.Prompt(new TextPrompt("Password").Secret());
+
+ string token = await client.LoginAsync(email, password).ConfigureAwait(false);
+ AnsiConsole.MarkupLine($"[green]Login successful.[/] Token: [grey]{Markup.Escape(ShortToken(token))}[/]");
+}
+
+static async Task CallEndpointAsync(GoAffProClient client)
+{
+ string endpoint = AnsiConsole.Prompt(
+ new SelectionPrompt()
+ .Title("Select endpoint")
+ .AddChoices(
+ [
+ "GET /user",
+ "POST /user",
+ "GET /user/sites",
+ "GET /user/stats/aggregate",
+ "GET /user/feed/orders",
+ "GET /user/feed/traffic",
+ "GET /user/feed/payouts",
+ "GET /user/feed/products",
+ "GET /user/feed/rewards",
+ "GET /user/feed/transactions",
+ "GET /user/commissions",
+ "GET /user/payouts/pending",
+ "GET /public/sites",
+ "GET /public/products",
+ "Back"
+ ]));
+
+ if (endpoint == "Back")
+ {
+ return;
+ }
+
+ int limit = AskInt("Limit", 10);
+ int offset = AskInt("Offset", 0);
+ string? siteIds = AskOptional("site_ids (optional)");
+ string startTime = DateTimeOffset.UtcNow.AddDays(-1).ToString("o", CultureInfo.InvariantCulture);
+ string endTime = DateTimeOffset.UtcNow.ToString("o", CultureInfo.InvariantCulture);
+
+ object? result = endpoint switch
+ {
+ "GET /user" => await client.Api.User.GetAsync().ConfigureAwait(false),
+ "POST /user" => await client.Api.User.PostAsync().ConfigureAwait(false),
+ "GET /user/sites" => await client.Api.User.Sites.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.StatusAsGetStatusQueryParameterType = AskSiteStatus();
+ config.QueryParameters.FieldsAsGetFieldsQueryParameterType = [SiteField.Id, SiteField.Name, SiteField.Logo];
+ }).ConfigureAwait(false),
+ "GET /user/stats/aggregate" => await client.Api.User.Stats.Aggregate.GetAsync(config =>
+ {
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.StartTime = AskOptional("start_time (ISO8601, optional)") ?? startTime;
+ config.QueryParameters.EndTime = AskOptional("end_time (ISO8601, optional)") ?? endTime;
+ config.QueryParameters.FieldsAsGetFieldsQueryParameterType =
+ [
+ AggregateField.Total_sales,
+ AggregateField.Other_commission_earned,
+ AggregateField.Revenue_generated,
+ AggregateField.Sale_commission_earned,
+ AggregateField.Commission_paid,
+ ];
+ }).ConfigureAwait(false),
+ "GET /user/feed/orders" => await client.Api.User.Feed.Orders.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.CreatedAtMin = AskOptional("created_at_min (ISO8601, optional)") ?? startTime;
+ config.QueryParameters.CreatedAtMax = AskOptional("created_at_max (ISO8601, optional)") ?? endTime;
+ }).ConfigureAwait(false),
+ "GET /user/feed/traffic" => await client.Api.User.Feed.Traffic.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.StartTime = AskOptional("start_time (ISO8601, optional)") ?? startTime;
+ config.QueryParameters.EndTime = AskOptional("end_time (ISO8601, optional)") ?? endTime;
+ }).ConfigureAwait(false),
+ "GET /user/feed/payouts" => await client.Api.User.Feed.Payouts.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.StartTime = AskOptional("start_time (ISO8601, optional)") ?? startTime;
+ config.QueryParameters.EndTime = AskOptional("end_time (ISO8601, optional)") ?? endTime;
+ }).ConfigureAwait(false),
+ "GET /user/feed/products" => await client.Api.User.Feed.Products.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ }).ConfigureAwait(false),
+ "GET /user/feed/rewards" => await client.Api.User.Feed.Rewards.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.StartTime = AskOptional("start_time (ISO8601, optional)") ?? startTime;
+ config.QueryParameters.EndTime = AskOptional("end_time (ISO8601, optional)") ?? endTime;
+ }).ConfigureAwait(false),
+ "GET /user/feed/transactions" => await client.Api.User.Feed.Transactions.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ }).ConfigureAwait(false),
+ "GET /user/commissions" => await client.Api.User.Commissions.GetAsync(config =>
+ {
+ config.QueryParameters.SiteIds = siteIds;
+ }).ConfigureAwait(false),
+ "GET /user/payouts/pending" => await client.Api.User.Payouts.Pending.GetAsync().ConfigureAwait(false),
+ "GET /public/sites" => await client.Api.Public.Sites.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ config.QueryParameters.Currency = AskOptional("currency (optional)");
+ config.QueryParameters.Keyword = AskOptional("keyword (optional)");
+ }).ConfigureAwait(false),
+ "GET /public/products" => await client.Api.Public.Products.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = limit;
+ config.QueryParameters.Offset = offset;
+ config.QueryParameters.SiteIds = siteIds;
+ }).ConfigureAwait(false),
+ _ => null,
+ };
+
+ RenderJson(endpoint, result);
+}
+
+static SiteStatus? AskSiteStatus()
+{
+ string status = AnsiConsole.Prompt(
+ new SelectionPrompt()
+ .Title("status")
+ .AddChoices(["(none)", "approved", "pending", "blocked"]));
+
+ return status switch
+ {
+ "approved" => SiteStatus.Approved,
+ "pending" => SiteStatus.Pending,
+ "blocked" => SiteStatus.Blocked,
+ _ => null,
+ };
+}
+
+static int AskInt(string label, int defaultValue)
+{
+ return AnsiConsole.Prompt(new TextPrompt(label).DefaultValue(defaultValue));
+}
+
+static string? AskOptional(string label)
+{
+ string value = AnsiConsole.Prompt(new TextPrompt(label).AllowEmpty());
+ return string.IsNullOrWhiteSpace(value) ? null : value;
+}
+
+static void RenderJson(string title, object? value)
+{
+ string json = Serialize(value);
+
+ var panel = new Panel(new Markup(Markup.Escape(json)))
+ {
+ Header = new PanelHeader(title),
+ Expand = true,
+ };
+
+ AnsiConsole.Write(panel);
+}
+
+static string Serialize(object? value)
+{
+ if (value is null)
+ {
+ return "null";
+ }
+
+ try
+ {
+ return JsonSerializer.Serialize(value, JsonOptions.Value);
+ }
+ catch (JsonException)
+ {
+ return value.ToString() ?? "";
+ }
+ catch (NotSupportedException)
+ {
+ return value.ToString() ?? "";
+ }
+}
+
+static string ShortToken(string token)
+{
+ return token.Length <= 10 ? token : $"{token[..6]}...{token[^4..]}";
+}
+
+static string? ResolveToken(string? value)
+{
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ return null;
+ }
+
+ const string envPrefix = "env:";
+ if (value.StartsWith(envPrefix, StringComparison.OrdinalIgnoreCase))
+ {
+ string envName = value[envPrefix.Length..];
+ return Environment.GetEnvironmentVariable(envName);
+ }
+
+ return value;
+}
+
+static ExampleSettings LoadSettings()
+{
+ string path = Path.Combine(AppContext.BaseDirectory, "appsettings.json");
+ if (!File.Exists(path))
+ {
+ return ExampleSettings.Default;
+ }
+
+ try
+ {
+ string json = File.ReadAllText(path);
+ using var document = JsonDocument.Parse(json);
+
+ if (!document.RootElement.TryGetProperty("GoAffPro", out JsonElement goAffPro))
+ {
+ return ExampleSettings.Default;
+ }
+
+ string baseUrlText = goAffPro.TryGetProperty("BaseUrl", out JsonElement baseUrlElement)
+ ? baseUrlElement.GetString() ?? ExampleSettings.Default.BaseUrl.ToString()
+ : ExampleSettings.Default.BaseUrl.ToString();
+
+ string? bearerToken = goAffPro.TryGetProperty("BearerToken", out JsonElement tokenElement)
+ ? tokenElement.GetString()
+ : null;
+
+ string timeoutText = goAffPro.TryGetProperty("Timeout", out JsonElement timeoutElement)
+ ? timeoutElement.GetString() ?? "00:00:30"
+ : "00:00:30";
+
+ Uri baseUrl = Uri.TryCreate(baseUrlText, UriKind.Absolute, out Uri? parsedBaseUrl)
+ ? parsedBaseUrl
+ : ExampleSettings.Default.BaseUrl;
+
+ TimeSpan timeout = TimeSpan.TryParse(timeoutText, out TimeSpan parsedTimeout)
+ ? parsedTimeout
+ : ExampleSettings.Default.Timeout;
+
+ return new ExampleSettings(baseUrl, bearerToken, timeout);
+ }
+ catch (IOException)
+ {
+ return ExampleSettings.Default;
+ }
+ catch (JsonException)
+ {
+ return ExampleSettings.Default;
+ }
+}
+
+internal sealed class ObserverController(IGoAffProClient client) : IAsyncDisposable
+{
+ private readonly Lock _consoleLock = new();
+ private CancellationTokenSource? _cts;
+ private Task? _task;
+
+ public bool IsRunning => _task is { IsCompleted: false };
+
+ public Task StartAsync()
+ {
+ if (IsRunning)
+ {
+ AnsiConsole.MarkupLine("[yellow]Observer already running.[/]");
+ return Task.CompletedTask;
+ }
+
+ int pollingSeconds = AnsiConsole.Prompt(new TextPrompt("Polling interval (seconds)").DefaultValue(30));
+ int pageSize = AnsiConsole.Prompt(new TextPrompt("Page size").DefaultValue(50));
+
+ client.OrderDetected += (_, args) =>
+ WriteLiveEvent("order", args.Order.Id?.String ?? args.Order.OrderId?.String ?? "");
+ client.AffiliateDetected += (_, args) =>
+ WriteLiveEvent("affiliate", args.Affiliate.AffiliateId?.String ?? args.Affiliate.Id?.String ?? args.Affiliate.CustomerId?.String ?? "");
+ client.PayoutDetected += (_, args) =>
+ WriteLiveEvent("payout", args.Payout.Id?.String ?? args.Payout.PayoutId?.String ?? "");
+ client.ProductDetected += (_, args) =>
+ WriteLiveEvent("product", args.Product.ProductId?.String ?? args.Product.Id?.String ?? "");
+ client.TransactionDetected += (_, args) =>
+ WriteLiveEvent("transaction", args.Transaction.TxId?.ToString(CultureInfo.InvariantCulture) ?? args.Transaction.Id ?? "");
+
+ _cts = new CancellationTokenSource();
+ _task = Task.Run(async () =>
+ {
+ try
+ {
+ await client.StartEventObserverAsync(
+ pollingInterval: TimeSpan.FromSeconds(Math.Max(1, pollingSeconds)),
+ pageSize: Math.Max(1, pageSize),
+ cancellationToken: _cts.Token).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
+ {
+ // Expected when stop is requested.
+ }
+ catch (GoAffProApiException ex)
+ {
+ WriteObserverError(ex.Message);
+ }
+ catch (ApiException ex)
+ {
+ WriteObserverError(ex.Message);
+ }
+ catch (HttpRequestException ex)
+ {
+ WriteObserverError(ex.Message);
+ }
+ catch (InvalidOperationException ex)
+ {
+ WriteObserverError(ex.Message);
+ }
+ });
+
+ AnsiConsole.MarkupLine("[green]Observer started.[/]");
+ return Task.CompletedTask;
+ }
+
+ public async Task StopAsync()
+ {
+ if (_cts is null)
+ {
+ return;
+ }
+
+ await _cts.CancelAsync().ConfigureAwait(false);
+
+ if (_task is not null)
+ {
+ await _task.ConfigureAwait(false);
+ }
+
+ _cts.Dispose();
+ _cts = null;
+ _task = null;
+
+ AnsiConsole.MarkupLine("[grey]Observer stopped.[/]");
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ await StopAsync().ConfigureAwait(false);
+ }
+
+ private void WriteLiveEvent(string type, string id)
+ {
+ lock (_consoleLock)
+ {
+ string timestamp = DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture);
+ AnsiConsole.MarkupLine($"[blue]{Markup.Escape(timestamp)}[/] [green]{Markup.Escape(type)}[/] -> {Markup.Escape(id)}");
+ }
+ }
+
+ private void WriteObserverError(string message)
+ {
+ lock (_consoleLock)
+ {
+ AnsiConsole.MarkupLine($"[red]Observer failed:[/] {Markup.Escape(message)}");
+ }
+ }
+}
+
+internal static class ApiSweepRunner
+{
+ public static async Task RunAllAsync(
+ GoAffProClient client,
+ ExampleSettings settings,
+ TimeSpan productTimeout,
+ CancellationToken cancellationToken)
+ {
+ string startTime = DateTimeOffset.UtcNow.AddDays(-1).ToString("o", CultureInfo.InvariantCulture);
+ string endTime = DateTimeOffset.UtcNow.ToString("o", CultureInfo.InvariantCulture);
+ var results = new List();
+
+ await RunEndpointAsync(results, "GET /user", () => client.Api.User.GetAsync(cancellationToken: cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "POST /user", () => client.Api.User.PostAsync(cancellationToken: cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/sites", () => client.Api.User.Sites.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ config.QueryParameters.StatusAsGetStatusQueryParameterType = SiteStatus.Approved;
+ config.QueryParameters.FieldsAsGetFieldsQueryParameterType = [SiteField.Id, SiteField.Name, SiteField.Logo];
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/stats/aggregate", () => client.Api.User.Stats.Aggregate.GetAsync(config =>
+ {
+ config.QueryParameters.StartTime = startTime;
+ config.QueryParameters.EndTime = endTime;
+ config.QueryParameters.FieldsAsGetFieldsQueryParameterType =
+ [
+ AggregateField.Total_sales,
+ AggregateField.Other_commission_earned,
+ AggregateField.Revenue_generated,
+ AggregateField.Sale_commission_earned,
+ AggregateField.Commission_paid,
+ ];
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/feed/orders", () => client.Api.User.Feed.Orders.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ config.QueryParameters.CreatedAtMin = startTime;
+ config.QueryParameters.CreatedAtMax = endTime;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/feed/traffic", () => client.Api.User.Feed.Traffic.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ config.QueryParameters.StartTime = startTime;
+ config.QueryParameters.EndTime = endTime;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/feed/payouts", () => client.Api.User.Feed.Payouts.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ config.QueryParameters.StartTime = startTime;
+ config.QueryParameters.EndTime = endTime;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(
+ results,
+ "GET /user/feed/products",
+ () => ExecuteProductsCallAsync(client, settings, productTimeout, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/feed/rewards", () => client.Api.User.Feed.Rewards.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ config.QueryParameters.StartTime = startTime;
+ config.QueryParameters.EndTime = endTime;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/feed/transactions", () => client.Api.User.Feed.Transactions.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/commissions", () => client.Api.User.Commissions.GetAsync(cancellationToken: cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /user/payouts/pending", () => client.Api.User.Payouts.Pending.GetAsync(cancellationToken: cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /public/sites", () => client.Api.Public.Sites.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ }, cancellationToken)).ConfigureAwait(false);
+ await RunEndpointAsync(results, "GET /public/products", () => client.Api.Public.Products.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ }, cancellationToken)).ConfigureAwait(false);
+
+ return new ApiSweepReport(
+ TimestampUtc: DateTimeOffset.UtcNow,
+ BaseUrl: settings.BaseUrl.ToString(),
+ Total: results.Count,
+ Failed: results.Count(static r => !r.Success),
+ Results: results);
+ }
+
+ private static async Task RunEndpointAsync(
+ List sink,
+ string endpoint,
+ Func> call)
+ {
+ var sw = Stopwatch.StartNew();
+ try
+ {
+ TResponse? result = await call().ConfigureAwait(false);
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: true,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: null,
+ ErrorType: null,
+ ErrorMessage: null,
+ ResponseJson: SerializeResponse(result)));
+ }
+ catch (ApiException ex)
+ {
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: false,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: ex.ResponseStatusCode,
+ ErrorType: ex.GetType().FullName,
+ ErrorMessage: ex.Message,
+ ResponseJson: null));
+ }
+ catch (HttpRequestException ex)
+ {
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: false,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: null,
+ ErrorType: ex.GetType().FullName,
+ ErrorMessage: ex.Message,
+ ResponseJson: null));
+ }
+ catch (TaskCanceledException ex)
+ {
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: false,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: null,
+ ErrorType: ex.GetType().FullName,
+ ErrorMessage: ex.Message,
+ ResponseJson: null));
+ }
+ catch (InvalidOperationException ex)
+ {
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: false,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: null,
+ ErrorType: ex.GetType().FullName,
+ ErrorMessage: ex.Message,
+ ResponseJson: null));
+ }
+ catch (GoAffProApiException ex)
+ {
+ sw.Stop();
+ sink.Add(new ApiEndpointResult(
+ Endpoint: endpoint,
+ Success: false,
+ DurationMs: sw.ElapsedMilliseconds,
+ StatusCode: (int)ex.StatusCode,
+ ErrorType: ex.GetType().FullName,
+ ErrorMessage: ex.Message,
+ ResponseJson: null));
+ }
+ }
+
+ private static string SerializeResponse(TResponse? value)
+ {
+ if (value is null)
+ {
+ return "null";
+ }
+
+ try
+ {
+ return JsonSerializer.Serialize(value, JsonOptions.Value);
+ }
+ catch (JsonException)
+ {
+ return value.ToString() ?? "";
+ }
+ catch (NotSupportedException)
+ {
+ return value.ToString() ?? "";
+ }
+ }
+
+ private static async Task ExecuteProductsCallAsync(
+ GoAffProClient client,
+ ExampleSettings settings,
+ TimeSpan productTimeout,
+ CancellationToken cancellationToken)
+ {
+ if (productTimeout <= TimeSpan.Zero || productTimeout == settings.Timeout)
+ {
+ return await client.Api.User.Feed.Products.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ }, cancellationToken).ConfigureAwait(false);
+ }
+
+ using var timeoutClient = new GoAffProClient(new GoAffProClientOptions
+ {
+ BaseUrl = settings.BaseUrl,
+ BearerToken = client.BearerToken,
+ Timeout = productTimeout
+ });
+
+ return await timeoutClient.Api.User.Feed.Products.GetAsync(config =>
+ {
+ config.QueryParameters.Limit = 1;
+ config.QueryParameters.Offset = 0;
+ }, cancellationToken).ConfigureAwait(false);
+ }
+}
+
+internal sealed record CommandLineOptions
+{
+ public bool RunTests { get; init; }
+ public string? AccessToken { get; init; }
+ public string? OutputPath { get; init; }
+ public string? Email { get; init; }
+ public string? Password { get; init; }
+ public int ProductsTimeoutSeconds { get; init; }
+
+ public static CommandLineOptions Parse(string[] args)
+ {
+ var options = new CommandLineOptions();
+ foreach (string arg in args)
+ {
+ if (arg.Equals("--run-tests", StringComparison.OrdinalIgnoreCase))
+ {
+ options = options with { RunTests = true };
+ continue;
+ }
+
+ if (arg.StartsWith("--access_token=", StringComparison.OrdinalIgnoreCase))
+ {
+ options = options with { AccessToken = arg["--access_token=".Length..] };
+ continue;
+ }
+
+ if (arg.StartsWith("--output=", StringComparison.OrdinalIgnoreCase))
+ {
+ options = options with { OutputPath = arg["--output=".Length..] };
+ continue;
+ }
+
+ if (arg.StartsWith("--email=", StringComparison.OrdinalIgnoreCase))
+ {
+ options = options with { Email = arg["--email=".Length..] };
+ continue;
+ }
+
+ if (arg.StartsWith("--password=", StringComparison.OrdinalIgnoreCase))
+ {
+ options = options with { Password = arg["--password=".Length..] };
+ continue;
+ }
+
+ if (arg.StartsWith("--products-timeout-seconds=", StringComparison.OrdinalIgnoreCase) &&
+ int.TryParse(arg["--products-timeout-seconds=".Length..], NumberStyles.Integer, CultureInfo.InvariantCulture, out int timeoutSeconds))
+ {
+ options = options with { ProductsTimeoutSeconds = timeoutSeconds };
+ }
+ }
+
+ return options;
+ }
+}
+
+internal sealed record ExampleSettings(Uri BaseUrl, string? BearerToken, TimeSpan Timeout)
+{
+ public static ExampleSettings Default { get; } =
+ new(new Uri("https://api.goaffpro.com/v1/", UriKind.Absolute), null, TimeSpan.FromSeconds(30));
+}
+
+internal sealed record ApiSweepReport(
+ DateTimeOffset TimestampUtc,
+ string BaseUrl,
+ int Total,
+ int Failed,
+ IReadOnlyList Results);
+
+internal sealed record ApiEndpointResult(
+ string Endpoint,
+ bool Success,
+ long DurationMs,
+ int? StatusCode,
+ string? ErrorType,
+ string? ErrorMessage,
+ string? ResponseJson);
+
+file static class JsonOptions
+{
+ public static JsonSerializerOptions Value { get; } = new()
+ {
+ WriteIndented = true,
+ };
+}
diff --git a/examples/GoAffPro.Client.Example/Worker.cs b/examples/GoAffPro.Client.Example/Worker.cs
deleted file mode 100644
index fff449b..0000000
--- a/examples/GoAffPro.Client.Example/Worker.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using GoAffPro.Client.Events;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace GoAffPro.Client.Example;
-
-[System.Diagnostics.CodeAnalysis.SuppressMessage(
- "Performance",
- "CA1812:Avoid uninstantiated internal classes",
- Justification = "Instantiated by host via AddHostedService().")]
-internal sealed partial class Worker(
- ILogger logger,
- IGoAffProClient client,
- IOptions exampleOptions,
- IHostApplicationLifetime lifetime) : BackgroundService
-{
- private readonly ExampleOptions _options = exampleOptions.Value;
-
- protected override async Task ExecuteAsync(CancellationToken stoppingToken)
- {
- try
- {
- if (string.IsNullOrWhiteSpace(client.BearerToken))
- {
- if (string.IsNullOrWhiteSpace(_options.Email) || string.IsNullOrWhiteSpace(_options.Password))
- {
- LogMissingCredentials(logger);
- lifetime.StopApplication();
- return;
- }
-
- _ = await client.LoginAsync(_options.Email, _options.Password, stoppingToken).ConfigureAwait(false);
- LogAuthenticated(logger);
- }
-
- IReadOnlyList orders = await client
- .GetOrdersAsync(limit: _options.PageSize, offset: 0, cancellationToken: stoppingToken)
- .ConfigureAwait(false);
-
- LogFetchedOrders(logger, orders.Count);
-
- var detector = new GoAffProEventDetector(
- client,
- pollingInterval: TimeSpan.FromSeconds(Math.Max(1, _options.PollingIntervalSeconds)),
- pageSize: Math.Max(1, _options.PageSize));
-
- detector.OrderDetected += (_, args) =>
- LogOrderDetected(logger, args.Order.Id);
- detector.AffiliateDetected += (_, args) =>
- LogAffiliateDetected(logger, args.Affiliate.Id);
-
- LogStartingDetector(logger);
- await detector.StartAsync(stoppingToken).ConfigureAwait(false);
- }
- catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
- {
- LogStopping(logger);
- }
- }
-
- [LoggerMessage(
- EventId = 1,
- Level = LogLevel.Warning,
- Message = "No bearer token is configured. Set GoAffPro:BearerToken or Example:Email/Example:Password in appsettings.json.")]
- private static partial void LogMissingCredentials(ILogger logger);
-
- [LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "Authenticated with login flow.")]
- private static partial void LogAuthenticated(ILogger logger);
-
- [LoggerMessage(EventId = 3, Level = LogLevel.Information, Message = "Fetched {Count} order(s) from GoAffPro feed.")]
- private static partial void LogFetchedOrders(ILogger logger, int count);
-
- [LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "Order detected: {Id}")]
- private static partial void LogOrderDetected(ILogger logger, string id);
-
- [LoggerMessage(EventId = 5, Level = LogLevel.Information, Message = "Affiliate detected: {Id}")]
- private static partial void LogAffiliateDetected(ILogger logger, string id);
-
- [LoggerMessage(EventId = 7, Level = LogLevel.Information, Message = "Starting detector loop. Press Ctrl+C to stop.")]
- private static partial void LogStartingDetector(ILogger logger);
-
- [LoggerMessage(EventId = 8, Level = LogLevel.Information, Message = "Example is stopping.")]
- private static partial void LogStopping(ILogger logger);
-}
diff --git a/openapi/goaffpro-canonical.yaml b/openapi/goaffpro-canonical.yaml
new file mode 100644
index 0000000..c449ee3
--- /dev/null
+++ b/openapi/goaffpro-canonical.yaml
@@ -0,0 +1,1031 @@
+openapi: 3.0.3
+info:
+ title: GOAFFPRO Canonical API (User/Public)
+ version: 2026.2.25
+ description: >
+ Maintained canonical contract for GoAffPro user/public endpoints.
+ This spec intentionally corrects known response-shape drift from upstream docs.
+servers:
+ - url: https://api.goaffpro.com/v1/
+
+paths:
+ /user/login:
+ post:
+ summary: Log in to get the access token
+ requestBody:
+ required: true
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: object
+ required:
+ - email
+ - password
+ properties:
+ email:
+ type: string
+ password:
+ type: string
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/LoginResponse'
+
+ /user/sites:
+ get:
+ summary: List of stores the user is enrolled in
+ parameters:
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ - $ref: '#/components/parameters/UserStatusQuery'
+ - in: query
+ name: fields
+ required: true
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ enum: [id, name, logo, website, status, currency, affiliate_portal, ref_code, referral_link, coupon]
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserSiteListResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user:
+ get:
+ summary: Get information about logged in user profile
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserProfileEnvelope'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+ post:
+ summary: Update your profile
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserProfileUpdateResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/stats/aggregate:
+ get:
+ summary: Aggregates of user stats
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/StartTimeQuery'
+ - $ref: '#/components/parameters/EndTimeQuery'
+ - in: query
+ name: fields
+ required: true
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ enum: [total_sales, other_commission_earned, revenue_generated, sale_commission_earned, commission_paid]
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserStatsAggregateResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/orders:
+ get:
+ summary: Feed of user orders
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/SinceIdStringQuery'
+ - $ref: '#/components/parameters/MaxIdQuery'
+ - $ref: '#/components/parameters/CreatedAtMaxQuery'
+ - $ref: '#/components/parameters/CreatedAtMinQuery'
+ - in: query
+ name: fields
+ required: true
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ enum: [id, number, total, subtotal, line_items, commission, created_at, currency, site_id, sub_id, conversion_details]
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserOrderFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/payouts:
+ get:
+ summary: Feed of user payouts
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/StartTimeQuery'
+ - $ref: '#/components/parameters/EndTimeQuery'
+ - $ref: '#/components/parameters/SinceIdIntegerQuery'
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserPayoutFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/products:
+ # Known runtime issue (observed on 2026-02-25):
+ # endpoint can hang/timeout for valid authenticated requests.
+ # Keep error mappings broad and preserve this note until behavior stabilizes.
+ get:
+ summary: Feed of products available for promotion
+ parameters:
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserProductFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+ '502':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/rewards:
+ # Known runtime issue (observed on 2026-02-25):
+ # endpoint responds as not found / non-JSON error payload for authenticated requests.
+ # Leave modeled but treat as unstable until upstream fixes behavior.
+ get:
+ summary: Feed of user rewards
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/StartTimeQuery'
+ - $ref: '#/components/parameters/EndTimeQuery'
+ - $ref: '#/components/parameters/SinceIdIntegerQuery'
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserRewardFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '404':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/traffic:
+ get:
+ summary: Feed of user traffic
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/StartTimeQuery'
+ - $ref: '#/components/parameters/EndTimeQuery'
+ - $ref: '#/components/parameters/SinceIdIntegerQuery'
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserTrafficFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/feed/transactions:
+ # Known runtime issue (observed on 2026-02-25):
+ # endpoint can return HTTP 500 with HTML/plain-text error payloads.
+ # Error content may not match structured JSON schema.
+ get:
+ summary: Feed of user transactions
+ parameters:
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserTransactionFeedResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/commissions:
+ get:
+ summary: Get commission structure
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserCommissionsResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /user/payouts/pending:
+ # Undocumented/parity endpoint:
+ # observed to exist on /user while also exposed under /sdk/user paths.
+ # Keep tracked here even if upstream /user docs omit or mis-document it.
+ get:
+ summary: Get pending payout amount (and its breakdown)
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserPendingPayoutsResponse'
+ '401':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '403':
+ $ref: '#/components/responses/AuthErrorResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /public/sites:
+ get:
+ summary: Public marketplace sites
+ parameters:
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ - $ref: '#/components/parameters/PublicCurrencyQuery'
+ - $ref: '#/components/parameters/PublicKeywordQuery'
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PublicSitesResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+ '502':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+ /public/products:
+ get:
+ summary: Public marketplace products
+ parameters:
+ - $ref: '#/components/parameters/LimitQuery'
+ - $ref: '#/components/parameters/OffsetQuery'
+ - $ref: '#/components/parameters/SiteIdsQuery'
+ responses:
+ '200':
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PublicProductsResponse'
+ '500':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+ '502':
+ $ref: '#/components/responses/PlainTextErrorResponse'
+
+components:
+ parameters:
+ LimitQuery:
+ in: query
+ name: limit
+ schema:
+ type: integer
+ OffsetQuery:
+ in: query
+ name: offset
+ schema:
+ type: integer
+ SiteIdsQuery:
+ in: query
+ name: site_ids
+ schema:
+ type: string
+ StartTimeQuery:
+ in: query
+ name: start_time
+ schema:
+ type: string
+ EndTimeQuery:
+ in: query
+ name: end_time
+ schema:
+ type: string
+ SinceIdIntegerQuery:
+ in: query
+ name: since_id
+ schema:
+ type: integer
+ SinceIdStringQuery:
+ in: query
+ name: since_id
+ schema:
+ type: string
+ MaxIdQuery:
+ in: query
+ name: max_id
+ schema:
+ type: string
+ CreatedAtMaxQuery:
+ in: query
+ name: created_at_max
+ schema:
+ type: string
+ CreatedAtMinQuery:
+ in: query
+ name: created_at_min
+ schema:
+ type: string
+ PublicCurrencyQuery:
+ in: query
+ name: currency
+ schema:
+ type: string
+ PublicKeywordQuery:
+ in: query
+ name: keyword
+ schema:
+ type: string
+ UserStatusQuery:
+ in: query
+ name: status
+ schema:
+ type: string
+ enum: [approved, pending, blocked]
+ responses:
+ AuthErrorResponse:
+ description: Authentication or authorization failure.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ text/plain:
+ schema:
+ type: string
+ PlainTextErrorResponse:
+ description: Upstream service error response in plain text.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ text/plain:
+ schema:
+ type: string
+ schemas:
+ LoginResponse:
+ type: object
+ required: [access_token]
+ properties:
+ access_token:
+ type: string
+
+ UserProfileEnvelope:
+ type: object
+ required: [user]
+ properties:
+ user:
+ type: object
+ additionalProperties: true
+ additionalProperties: true
+
+ UserProfileUpdateResponse:
+ type: object
+ required: [success]
+ properties:
+ success:
+ type: integer
+ additionalProperties: true
+
+ UserSiteListResponse:
+ type: object
+ required: [sites, count]
+ properties:
+ sites:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserSite'
+ count:
+ type: integer
+ additionalProperties: true
+
+ UserSite:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ logo:
+ type: string
+ website:
+ type: string
+ status:
+ type: string
+ currency:
+ type: string
+ affiliate_portal:
+ type: string
+ ref_code:
+ type: string
+ referral_link:
+ type: string
+ coupon:
+ type: object
+ additionalProperties: true
+ additionalProperties: true
+
+ UserStatsAggregateResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserStatsAggregateItem'
+ additionalProperties: true
+
+ UserStatsAggregateItem:
+ type: object
+ properties:
+ site_id:
+ type: integer
+ total_sales:
+ type: number
+ currency:
+ type: string
+ sale_commission_earned:
+ type: number
+ revenue_generated:
+ type: number
+ commission_paid:
+ type: number
+ additionalProperties: true
+
+ CountLimitOffsetEnvelope:
+ type: object
+ required: [count, limit, offset]
+ properties:
+ count:
+ type: integer
+ limit:
+ type: integer
+ offset:
+ type: integer
+ additionalProperties: true
+
+ CountLimitOffsetEnvelopeFlexibleOffset:
+ type: object
+ required: [count, limit, offset]
+ properties:
+ count:
+ type: integer
+ limit:
+ type: integer
+ offset:
+ oneOf:
+ - type: integer
+ - type: string
+ additionalProperties: true
+
+ SinceIdEcho:
+ type: object
+ properties:
+ since_id:
+ oneOf:
+ - type: integer
+ - type: string
+ additionalProperties: true
+
+ UserOrderFeedResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelope'
+ - type: object
+ required: [orders]
+ properties:
+ orders:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserOrderFeedItem'
+ additionalProperties: true
+
+ UserOrderFeedItem:
+ type: object
+ properties:
+ id:
+ oneOf:
+ - type: string
+ - type: integer
+ order_id:
+ oneOf:
+ - type: string
+ - type: integer
+ number:
+ type: string
+ total:
+ type: number
+ subtotal:
+ type: number
+ line_items:
+ type: array
+ items:
+ type: object
+ additionalProperties: true
+ commission:
+ oneOf:
+ - type: number
+ - type: string
+ created_at:
+ type: string
+ created:
+ oneOf:
+ - type: string
+ - type: integer
+ currency:
+ type: string
+ site_id:
+ oneOf:
+ - type: string
+ - type: integer
+ sub_id:
+ type: string
+ status:
+ type: string
+ affiliate_id:
+ oneOf:
+ - type: string
+ - type: integer
+ conversion_details:
+ type: object
+ additionalProperties: true
+ additionalProperties: true
+
+ UserPayoutFeedResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelope'
+ - $ref: '#/components/schemas/SinceIdEcho'
+ - type: object
+ required: [payouts]
+ properties:
+ payouts:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserPayoutFeedItem'
+ additionalProperties: true
+
+ UserPayoutFeedItem:
+ type: object
+ properties:
+ id:
+ oneOf:
+ - type: string
+ - type: integer
+ payout_id:
+ oneOf:
+ - type: string
+ - type: integer
+ affiliate_id:
+ oneOf:
+ - type: string
+ - type: integer
+ amount:
+ oneOf:
+ - type: number
+ - type: string
+ status:
+ type: string
+ payment_method:
+ type: string
+ transaction_id:
+ type: string
+ currency:
+ type: string
+ created_at:
+ type: string
+ created:
+ oneOf:
+ - type: string
+ - type: integer
+ additionalProperties: true
+
+ UserProductFeedResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelopeFlexibleOffset'
+ - type: object
+ required: [products]
+ properties:
+ products:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserProductFeedItem'
+ additionalProperties: true
+
+ UserProductFeedItem:
+ type: object
+ properties:
+ id:
+ oneOf:
+ - type: string
+ - type: integer
+ product_id:
+ oneOf:
+ - type: string
+ - type: integer
+ name:
+ type: string
+ description:
+ type: string
+ price:
+ oneOf:
+ - type: number
+ - type: string
+ sale_price:
+ oneOf:
+ - type: number
+ - type: string
+ image_url:
+ type: string
+ product_url:
+ type: string
+ category:
+ type: string
+ sku:
+ type: string
+ currency:
+ type: string
+ additionalProperties: true
+
+ UserRewardFeedResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelope'
+ - type: object
+ required: [rewards]
+ properties:
+ rewards:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserRewardFeedItem'
+ additionalProperties: true
+
+ UserRewardFeedItem:
+ type: object
+ properties:
+ id:
+ type: string
+ affiliate_id:
+ type: string
+ type:
+ type: string
+ metadata:
+ type: string
+ order_id:
+ type: string
+ level:
+ type: integer
+ amount:
+ type: number
+ status:
+ type: string
+ created:
+ type: string
+ additionalProperties: true
+
+ UserTrafficFeedResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelope'
+ - $ref: '#/components/schemas/SinceIdEcho'
+ - type: object
+ required: [traffic]
+ properties:
+ traffic:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserTrafficFeedItem'
+ additionalProperties: true
+
+ UserTrafficFeedItem:
+ type: object
+ properties:
+ id:
+ oneOf:
+ - type: string
+ - type: integer
+ affiliate_id:
+ oneOf:
+ - type: string
+ - type: integer
+ customer_id:
+ oneOf:
+ - type: string
+ - type: integer
+ name:
+ type: string
+ first_name:
+ type: string
+ last_name:
+ type: string
+ email:
+ type: string
+ ref_code:
+ type: string
+ phone:
+ type: string
+ country:
+ type: string
+ group_id:
+ oneOf:
+ - type: integer
+ - type: string
+ site_id:
+ oneOf:
+ - type: string
+ - type: integer
+ sub_id:
+ type: string
+ created_at:
+ type: string
+ created:
+ oneOf:
+ - type: string
+ - type: integer
+ additionalProperties: true
+
+ UserCommissionsResponse:
+ type: object
+ properties:
+ standard:
+ type: object
+ additionalProperties: true
+ special:
+ type: array
+ items:
+ type: object
+ additionalProperties: true
+ royalties:
+ type: array
+ items:
+ type: object
+ additionalProperties: true
+ mlm:
+ type: object
+ additionalProperties: true
+ commissions:
+ type: array
+ items:
+ nullable: true
+ additionalProperties: true
+
+ UserTransactionFeedResponse:
+ type: object
+ required: [transactions]
+ properties:
+ transactions:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserTransactionItem'
+ count:
+ type: integer
+ limit:
+ type: integer
+ offset:
+ oneOf:
+ - type: integer
+ - type: string
+ additionalProperties: true
+
+ UserTransactionItem:
+ type: object
+ properties:
+ id:
+ type: string
+ tx_id:
+ type: integer
+ affiliate_id:
+ type: integer
+ amount:
+ type: number
+ currency:
+ type: string
+ startingBalance:
+ type: number
+ endingBalance:
+ type: number
+ created_at:
+ type: string
+ entity_type:
+ type: string
+ enum: [orders, rewards, payouts, ORDERS, REWARDS, PAYOUTS]
+ event_type:
+ type: string
+ enum: [insert, update, delete]
+ entity_id:
+ type: string
+ is_paid:
+ type: boolean
+ metadata:
+ type: object
+ additionalProperties: true
+ additionalProperties: true
+
+ UserPendingPayoutsResponse:
+ type: object
+ required: [pending]
+ properties:
+ pending:
+ oneOf:
+ - type: array
+ items:
+ $ref: '#/components/schemas/PendingPayoutItem'
+ - $ref: '#/components/schemas/PendingPayoutBreakdown'
+ additionalProperties: true
+
+ PendingPayoutItem:
+ type: object
+ properties:
+ affiliate_id:
+ oneOf:
+ - type: integer
+ - type: string
+ amount:
+ oneOf:
+ - type: number
+ - type: string
+ total_earned:
+ oneOf:
+ - type: number
+ - type: string
+ total_paid:
+ oneOf:
+ - type: number
+ - type: string
+ additionalProperties: true
+
+ PendingPayoutBreakdown:
+ type: object
+ properties:
+ sale_earnings:
+ type: number
+ other_earnings:
+ type: number
+ paid_earnings:
+ type: number
+ amount_pending:
+ type: number
+ additionalProperties: true
+
+ PublicSitesResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelopeFlexibleOffset'
+ - type: object
+ required: [stores]
+ properties:
+ stores:
+ type: array
+ items:
+ $ref: '#/components/schemas/PublicStore'
+ currency:
+ type: string
+ keyword:
+ type: string
+ additionalProperties: true
+
+ PublicStore:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ website:
+ type: string
+ logo:
+ type: string
+ currency:
+ type: string
+ affiliatePortal:
+ type: string
+ cookieDuration:
+ type: integer
+ areRegistrationsOpen:
+ type: integer
+ isApprovedAutomatically:
+ type: integer
+ commission:
+ $ref: '#/components/schemas/CommissionLike'
+ additionalProperties: true
+
+ PublicProductsResponse:
+ allOf:
+ - $ref: '#/components/schemas/CountLimitOffsetEnvelopeFlexibleOffset'
+ - type: object
+ required: [products]
+ properties:
+ products:
+ type: array
+ items:
+ type: object
+ additionalProperties: true
+ site_ids:
+ type: string
+ additionalProperties: true
+
+ CommissionLike:
+ type: object
+ properties:
+ type:
+ type: string
+ amount:
+ type: number
+ on:
+ type: string
+ additionalProperties: true
+
+ ErrorResponse:
+ type: object
+ required: [error]
+ properties:
+ error:
+ type: string
+ code:
+ oneOf:
+ - type: integer
+ - type: string
+ additionalProperties: true
diff --git a/scripts/analyze-api.ps1 b/scripts/analyze-api.ps1
new file mode 100644
index 0000000..8e263c0
--- /dev/null
+++ b/scripts/analyze-api.ps1
@@ -0,0 +1,268 @@
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$BearerToken,
+ [string]$OutputPath = "api-analysis-data.json",
+ [int]$MaxDepth = 6
+)
+
+$ErrorActionPreference = "Stop"
+$ProgressPreference = "SilentlyContinue"
+
+function Resolve-Schema {
+ param([hashtable]$Doc, [object]$Schema)
+ if ($null -eq $Schema) { return $null }
+ if ($Schema -is [hashtable] -and $Schema.ContainsKey('$ref')) {
+ $ref = [string]$Schema['$ref']
+ if ($ref.StartsWith("#/components/schemas/")) {
+ $name = $ref.Substring("#/components/schemas/".Length)
+ if ($Doc.components.schemas.ContainsKey($name)) { return $Doc.components.schemas[$name] }
+ }
+ }
+ return $Schema
+}
+
+function Get-SchemaTypeSummary {
+ param([hashtable]$Doc, [object]$Schema, [int]$Depth = 0, [int]$MaxDepth = 6)
+ if ($Depth -ge $MaxDepth) { return @{ type = "max-depth-reached" } }
+ $resolved = Resolve-Schema -Doc $Doc -Schema $Schema
+ if ($null -eq $resolved -or $resolved -isnot [hashtable]) { return @{ type = "unknown" } }
+
+ if ($resolved.ContainsKey("oneOf")) {
+ return @{
+ type = "oneOf"
+ variants = @($resolved.oneOf | ForEach-Object { Get-SchemaTypeSummary -Doc $Doc -Schema $_ -Depth ($Depth + 1) -MaxDepth $MaxDepth })
+ }
+ }
+
+ if ($resolved.ContainsKey("allOf")) {
+ return @{
+ type = "allOf"
+ variants = @($resolved.allOf | ForEach-Object { Get-SchemaTypeSummary -Doc $Doc -Schema $_ -Depth ($Depth + 1) -MaxDepth $MaxDepth })
+ }
+ }
+
+ if ($resolved.ContainsKey("type") -and $resolved["type"] -eq "array") {
+ return @{
+ type = "array"
+ items = Get-SchemaTypeSummary -Doc $Doc -Schema $resolved.items -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ }
+
+ if ($resolved.ContainsKey("properties") -or ($resolved.ContainsKey("type") -and $resolved["type"] -eq "object")) {
+ $properties = @{}
+ if ($resolved.ContainsKey("properties")) {
+ foreach ($k in $resolved.properties.Keys) {
+ $properties[$k] = Get-SchemaTypeSummary -Doc $Doc -Schema $resolved.properties[$k] -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ }
+ return @{
+ type = "object"
+ properties = $properties
+ additionalProperties = if ($resolved.ContainsKey("additionalProperties")) { $resolved.additionalProperties } else { $false }
+ }
+ }
+
+ if ($resolved.ContainsKey("type")) { return @{ type = [string]$resolved.type } }
+ return @{ type = "unknown" }
+}
+
+function Get-JsonShapeSummary {
+ param([object]$Node, [int]$Depth = 0, [int]$MaxDepth = 6)
+ if ($Depth -ge $MaxDepth) { return @{ type = "max-depth-reached" } }
+ if ($null -eq $Node) { return @{ type = "null" } }
+
+ if ($Node -is [System.Collections.IDictionary]) {
+ $props = @{}
+ foreach ($k in $Node.Keys) {
+ $props[[string]$k] = Get-JsonShapeSummary -Node $Node[$k] -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ return @{ type = "object"; properties = $props }
+ }
+
+ if ($Node -is [System.Collections.IEnumerable] -and $Node -isnot [string]) {
+ $items = @($Node)
+ if ($items.Count -eq 0) { return @{ type = "array"; items = @{ type = "unknown-empty" } } }
+ return @{ type = "array"; items = Get-JsonShapeSummary -Node $items[0] -Depth ($Depth + 1) -MaxDepth $MaxDepth }
+ }
+
+ if ($Node -is [bool]) { return @{ type = "boolean" } }
+ if ($Node -is [int] -or $Node -is [long]) { return @{ type = "integer" } }
+ if ($Node -is [double] -or $Node -is [decimal] -or $Node -is [float]) { return @{ type = "number" } }
+ return @{ type = "string" }
+}
+
+function Get-SampleQueryValue {
+ param([hashtable]$Param)
+ $name = [string]$Param.name
+ $schema = if ($Param.ContainsKey("schema")) { $Param.schema } else { $null }
+
+ if ($name -eq "fields") {
+ if ($schema -is [hashtable] -and $schema.ContainsKey("items") -and $schema.items.ContainsKey("enum")) {
+ return (($schema.items.enum | ForEach-Object { [string]$_ }) -join ",")
+ }
+ return "id,name"
+ }
+
+ if ($schema -is [hashtable] -and $schema.ContainsKey("enum") -and $schema.enum.Count -gt 0) {
+ return [string]$schema.enum[0]
+ }
+
+ switch ($name) {
+ "limit" { "1" }
+ "offset" { "0" }
+ "status" { "approved" }
+ "site_ids" { "1" }
+ "currency" { "USD" }
+ "keyword" { "test" }
+ "since_id" { "1" }
+ "max_id" { "1" }
+ "created_at_min" { "2026-01-01T00:00:00Z" }
+ "created_at_max" { "2026-12-31T23:59:59Z" }
+ "start_time" { "2026-01-01T00:00:00Z" }
+ "end_time" { "2026-12-31T23:59:59Z" }
+ default { "sample" }
+ }
+}
+
+function Build-QueryString {
+ param([object[]]$Parameters)
+ $parts = @()
+ foreach ($param in $Parameters) {
+ if ([string]$param.in -ne "query") { continue }
+ $required = [bool]($param.required)
+ $name = [string]$param.name
+ if (-not $required -and $name -notin @("limit", "offset", "fields", "status", "site_ids", "currency", "keyword", "since_id", "max_id", "created_at_min", "created_at_max", "start_time", "end_time")) {
+ continue
+ }
+ $value = Get-SampleQueryValue -Param $param
+ $parts += ([System.Uri]::EscapeDataString($name) + "=" + [System.Uri]::EscapeDataString($value))
+ }
+ if ($parts.Count -eq 0) { return "" }
+ return "?" + ($parts -join "&")
+}
+
+function Build-RequestBody {
+ param([hashtable]$Operation)
+ if (-not $Operation.ContainsKey("requestBody")) { return $null }
+ $content = $Operation.requestBody.content
+ if ($content -and $content.ContainsKey("application/x-www-form-urlencoded")) {
+ $form = @{ email = "invalid@example.com"; password = "invalid-password" }
+ return @{ Body = $form; ContentType = "application/x-www-form-urlencoded" }
+ }
+ return $null
+}
+
+function Invoke-Probe {
+ param(
+ [string]$Method,
+ [string]$Url,
+ [hashtable]$Headers,
+ [hashtable]$RequestBody
+ )
+
+ $statusCode = -1
+ $bodyText = ""
+ $contentType = ""
+ try {
+ if ($null -eq $RequestBody) {
+ $resp = Invoke-WebRequest -UseBasicParsing -Uri $Url -Method $Method -Headers $Headers -TimeoutSec 60 -ErrorAction Stop
+ }
+ else {
+ $resp = Invoke-WebRequest -UseBasicParsing -Uri $Url -Method $Method -Headers $Headers -Body $RequestBody.Body -ContentType $RequestBody.ContentType -TimeoutSec 60 -ErrorAction Stop
+ }
+ $statusCode = [int]$resp.StatusCode
+ $bodyText = [string]$resp.Content
+ $contentType = [string]$resp.Headers["Content-Type"]
+ }
+ catch {
+ if ($_.Exception.Response) {
+ $statusCode = [int]$_.Exception.Response.StatusCode.value__
+ try { $contentType = [string]$_.Exception.Response.Headers["Content-Type"] } catch {}
+ }
+ if ($_.ErrorDetails -and $_.ErrorDetails.Message) {
+ $bodyText = [string]$_.ErrorDetails.Message
+ }
+ elseif ($_.Exception.Message) {
+ $bodyText = [string]$_.Exception.Message
+ }
+ }
+
+ $actualShape = @{ type = "non-json" }
+ $isLogicalError = $false
+ $errorCode = $null
+ if (-not [string]::IsNullOrWhiteSpace($bodyText)) {
+ try {
+ $parsed = $bodyText | ConvertFrom-Json -AsHashtable -Depth 100
+ $actualShape = Get-JsonShapeSummary -Node $parsed -Depth 0 -MaxDepth $MaxDepth
+ if ($parsed -is [System.Collections.IDictionary] -and $parsed.ContainsKey("error")) {
+ $isLogicalError = $true
+ if ($parsed.ContainsKey("code")) { $errorCode = [string]$parsed.code }
+ }
+ }
+ catch {
+ $actualShape = @{ type = "non-json" }
+ }
+ }
+
+ return @{
+ statusCode = $statusCode
+ contentType = $contentType
+ isLogicalError = $isLogicalError
+ errorCode = $errorCode
+ actualShape = $actualShape
+ bodyPreview = if ($bodyText.Length -gt 2500) { $bodyText.Substring(0, 2500) } else { $bodyText }
+ }
+}
+
+$docs = @(
+ @{ Name = "user"; Path = "openapi/goaffpro-user.openapi.json"; Prefix = "/user" },
+ @{ Name = "public"; Path = "openapi/goaffpro-public.openapi.json"; Prefix = "/public" }
+)
+
+$results = @()
+foreach ($docInfo in $docs) {
+ $doc = Get-Content -Raw $docInfo.Path | ConvertFrom-Json -AsHashtable -Depth 120
+ foreach ($path in ($doc.paths.Keys | Sort-Object)) {
+ if (-not $path.StartsWith($docInfo.Prefix)) { continue }
+ $pathItem = $doc.paths[$path]
+ foreach ($method in @("get", "post", "put", "patch", "delete")) {
+ if (-not $pathItem.ContainsKey($method)) { continue }
+ $operation = $pathItem[$method]
+ $parameters = if ($operation.ContainsKey("parameters")) { @($operation.parameters) } else { @() }
+ $query = Build-QueryString -Parameters $parameters
+ $url = "https://api.goaffpro.com/v1$path$query"
+ $specShape = $null
+ if ($operation.responses -and $operation.responses["200"] -and $operation.responses["200"].content -and $operation.responses["200"].content["application/json"]) {
+ $specShape = Get-SchemaTypeSummary -Doc $doc -Schema $operation.responses["200"].content["application/json"].schema -Depth 0 -MaxDepth $MaxDepth
+ }
+ if ($null -eq $specShape) { $specShape = @{ type = "unknown" } }
+ $requestBody = Build-RequestBody -Operation $operation
+
+ $scenarios = @()
+ if ($docInfo.Name -eq "user") {
+ $scenarios += @{ authMode = "auth"; headers = @{ Authorization = "Bearer $BearerToken" } }
+ $scenarios += @{ authMode = "no_auth"; headers = @{} }
+ }
+ else {
+ $scenarios += @{ authMode = "public"; headers = @{} }
+ }
+
+ foreach ($scenario in $scenarios) {
+ $probe = Invoke-Probe -Method $method.ToUpperInvariant() -Url $url -Headers $scenario.headers -RequestBody $requestBody
+ $results += @{
+ domain = $docInfo.Name
+ method = $method.ToUpperInvariant()
+ path = $path
+ summary = if ($operation.ContainsKey("summary")) { [string]$operation.summary } else { "" }
+ authMode = $scenario.authMode
+ requestParameters = $parameters
+ specShape = $specShape
+ probe = ($probe + @{ url = $url })
+ }
+ }
+ }
+ }
+}
+
+$results | ConvertTo-Json -Depth 100 | Set-Content -Encoding UTF8 $OutputPath
+Write-Output "Wrote $OutputPath with $($results.Count) operation scenario records."
diff --git a/scripts/probe-openapi-spec.ps1 b/scripts/probe-openapi-spec.ps1
new file mode 100644
index 0000000..0e3c1d1
--- /dev/null
+++ b/scripts/probe-openapi-spec.ps1
@@ -0,0 +1,446 @@
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$SpecPath,
+ [Parameter(Mandatory = $true)]
+ [string]$OutputPath,
+ [string]$BearerToken,
+ [string[]]$IncludePathPrefixes = @("/user", "/public"),
+ [int]$MaxDepth = 6,
+ [switch]$ProbeNoAuthForUser
+)
+
+$ErrorActionPreference = "Stop"
+$ProgressPreference = "SilentlyContinue"
+
+function Read-OpenApiSpecAsHashtable {
+ param([string]$Path)
+
+ $ext = [System.IO.Path]::GetExtension($Path).ToLowerInvariant()
+ if ($ext -in @(".yaml", ".yml")) {
+ $tmpPath = [System.IO.Path]::GetTempFileName()
+ try {
+ $escapedInput = $Path.Replace("'", "''")
+ $escapedOutput = $tmpPath.Replace("'", "''")
+ $py = "import yaml,json,pathlib; p=pathlib.Path(r'$escapedInput'); data=yaml.safe_load(p.read_text(encoding='utf-8')); pathlib.Path(r'$escapedOutput').write_text(json.dumps(data), encoding='utf-8')"
+ python -c $py | Out-Null
+ return (Get-Content -Raw $tmpPath | ConvertFrom-Json -AsHashtable -Depth 120)
+ }
+ finally {
+ if (Test-Path $tmpPath) { Remove-Item $tmpPath -Force }
+ }
+ }
+
+ return (Get-Content -Raw $Path | ConvertFrom-Json -AsHashtable -Depth 120)
+}
+
+function Resolve-Schema {
+ param(
+ [hashtable]$Spec,
+ [object]$Schema
+ )
+
+ if ($null -eq $Schema) {
+ return $null
+ }
+
+ if ($Schema -is [hashtable] -and $Schema.ContainsKey('$ref')) {
+ $ref = [string]$Schema['$ref']
+ if ($ref.StartsWith("#/components/schemas/")) {
+ $name = $ref.Substring("#/components/schemas/".Length)
+ if ($Spec.components -and $Spec.components.schemas -and $Spec.components.schemas.ContainsKey($name)) {
+ return $Spec.components.schemas[$name]
+ }
+ }
+ }
+
+ return $Schema
+}
+
+function Get-SpecSchemaShape {
+ param(
+ [hashtable]$Spec,
+ [object]$Schema,
+ [int]$Depth = 0,
+ [int]$MaxDepth = 6
+ )
+
+ if ($Depth -ge $MaxDepth) {
+ return @{ type = "max-depth-reached" }
+ }
+
+ $resolved = Resolve-Schema -Spec $Spec -Schema $Schema
+ if ($null -eq $resolved -or $resolved -isnot [hashtable]) {
+ return @{ type = "unknown" }
+ }
+
+ if ($resolved.ContainsKey("oneOf")) {
+ return @{
+ type = "oneOf"
+ variants = @($resolved.oneOf | ForEach-Object {
+ Get-SpecSchemaShape -Spec $Spec -Schema $_ -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ })
+ }
+ }
+
+ if ($resolved.ContainsKey("anyOf")) {
+ return @{
+ type = "anyOf"
+ variants = @($resolved.anyOf | ForEach-Object {
+ Get-SpecSchemaShape -Spec $Spec -Schema $_ -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ })
+ }
+ }
+
+ $schemaType = if ($resolved.ContainsKey("type")) { [string]$resolved.type } else { "" }
+
+ if ($schemaType -eq "array") {
+ return @{
+ type = "array"
+ items = Get-SpecSchemaShape -Spec $Spec -Schema $resolved.items -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ }
+
+ if ($schemaType -eq "object" -or $resolved.ContainsKey("properties")) {
+ $properties = @{}
+ if ($resolved.ContainsKey("properties")) {
+ foreach ($key in $resolved.properties.Keys) {
+ $properties[$key] = Get-SpecSchemaShape -Spec $Spec -Schema $resolved.properties[$key] -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ }
+
+ $additionalProperties = $false
+ if ($resolved.ContainsKey("additionalProperties")) {
+ $additionalProperties = $resolved.additionalProperties
+ }
+
+ return @{
+ type = "object"
+ properties = $properties
+ additionalProperties = $additionalProperties
+ }
+ }
+
+ if (-not [string]::IsNullOrWhiteSpace($schemaType)) {
+ return @{ type = $schemaType }
+ }
+
+ return @{ type = "unknown" }
+}
+
+function Get-JsonShape {
+ param(
+ [object]$Node,
+ [int]$Depth = 0,
+ [int]$MaxDepth = 6
+ )
+
+ if ($Depth -ge $MaxDepth) {
+ return @{ type = "max-depth-reached" }
+ }
+
+ if ($null -eq $Node) {
+ return @{ type = "null" }
+ }
+
+ if ($Node -is [System.Collections.IDictionary]) {
+ $properties = @{}
+ foreach ($key in $Node.Keys) {
+ $properties[[string]$key] = Get-JsonShape -Node $Node[$key] -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+
+ return @{
+ type = "object"
+ properties = $properties
+ }
+ }
+
+ if ($Node -is [System.Collections.IEnumerable] -and $Node -isnot [string]) {
+ $items = @($Node)
+ if ($items.Count -eq 0) {
+ return @{
+ type = "array"
+ items = @{ type = "unknown-empty" }
+ }
+ }
+
+ return @{
+ type = "array"
+ items = Get-JsonShape -Node $items[0] -Depth ($Depth + 1) -MaxDepth $MaxDepth
+ }
+ }
+
+ if ($Node -is [bool]) { return @{ type = "boolean" } }
+ if ($Node -is [int] -or $Node -is [long]) { return @{ type = "integer" } }
+ if ($Node -is [double] -or $Node -is [decimal] -or $Node -is [float]) { return @{ type = "number" } }
+ return @{ type = "string" }
+}
+
+function Get-SampleValueFromSchema {
+ param(
+ [hashtable]$Schema,
+ [string]$Name
+ )
+
+ if ($Schema -and $Schema.ContainsKey("enum") -and $Schema.enum.Count -gt 0) {
+ return [string]$Schema.enum[0]
+ }
+
+ if ($Name -eq "fields") {
+ if ($Schema -and $Schema.ContainsKey("items") -and $Schema.items.ContainsKey("enum")) {
+ return (($Schema.items.enum | ForEach-Object { [string]$_ }) -join ",")
+ }
+ return "id,name"
+ }
+
+ switch ($Name) {
+ "limit" { return "1" }
+ "offset" { return "0" }
+ "status" { return "approved" }
+ "site_ids" { return "1" }
+ "currency" { return "USD" }
+ "keyword" { return "test" }
+ "since_id" { return "1" }
+ "max_id" { return "1" }
+ "created_at_min" { return "2026-01-01T00:00:00Z" }
+ "created_at_max" { return "2026-12-31T23:59:59Z" }
+ "start_time" { return "2026-01-01T00:00:00Z" }
+ "end_time" { return "2026-12-31T23:59:59Z" }
+ "email" { return "invalid@example.com" }
+ "password" { return "invalid-password" }
+ default {
+ if ($Schema -and $Schema.ContainsKey("type")) {
+ switch ([string]$Schema.type) {
+ "integer" { return "1" }
+ "number" { return "1" }
+ "boolean" { return "true" }
+ default { return "sample" }
+ }
+ }
+
+ return "sample"
+ }
+ }
+}
+
+function Build-QueryString {
+ param(
+ [object[]]$Parameters
+ )
+
+ $parts = @()
+ foreach ($parameter in $Parameters) {
+ if (-not $parameter -or [string]$parameter.in -ne "query") {
+ continue
+ }
+
+ $name = [string]$parameter.name
+ $required = [bool]($parameter.required)
+
+ # Include required parameters and known useful optional filters.
+ if (-not $required -and $name -notin @("limit", "offset", "fields", "status", "site_ids", "currency", "keyword", "since_id", "max_id", "created_at_min", "created_at_max", "start_time", "end_time")) {
+ continue
+ }
+
+ $schema = if ($parameter.schema -is [hashtable]) { $parameter.schema } else { @{} }
+ $value = Get-SampleValueFromSchema -Schema $schema -Name $name
+ $parts += ([System.Uri]::EscapeDataString($name) + "=" + [System.Uri]::EscapeDataString([string]$value))
+ }
+
+ if ($parts.Count -eq 0) {
+ return ""
+ }
+
+ return "?" + ($parts -join "&")
+}
+
+function Build-RequestBody {
+ param(
+ [hashtable]$Operation
+ )
+
+ if (-not $Operation.ContainsKey("requestBody")) {
+ return $null
+ }
+
+ $requestBody = $Operation.requestBody
+ if (-not $requestBody -or -not $requestBody.ContainsKey("content")) {
+ return $null
+ }
+
+ $content = $requestBody.content
+ if ($content.ContainsKey("application/x-www-form-urlencoded")) {
+ return @{
+ Body = @{
+ email = "invalid@example.com"
+ password = "invalid-password"
+ }
+ ContentType = "application/x-www-form-urlencoded"
+ }
+ }
+
+ if ($content.ContainsKey("application/json")) {
+ $schema = $content["application/json"].schema
+ if ($schema -and $schema.ContainsKey("properties")) {
+ $obj = @{}
+ foreach ($propName in $schema.properties.Keys) {
+ $propSchema = if ($schema.properties[$propName] -is [hashtable]) { $schema.properties[$propName] } else { @{} }
+ $obj[$propName] = Get-SampleValueFromSchema -Schema $propSchema -Name $propName
+ }
+
+ return @{
+ Body = ($obj | ConvertTo-Json -Depth 20 -Compress)
+ ContentType = "application/json"
+ }
+ }
+ }
+
+ return $null
+}
+
+$spec = Read-OpenApiSpecAsHashtable -Path $SpecPath
+$baseUrl = [string]$spec.servers[0].url
+if (-not $baseUrl.EndsWith("/")) {
+ $baseUrl += "/"
+}
+$baseUrl = $baseUrl.TrimEnd("/")
+
+$records = @()
+
+foreach ($path in ($spec.paths.Keys | Sort-Object)) {
+ $include = $false
+ foreach ($prefix in $IncludePathPrefixes) {
+ if ($path.StartsWith($prefix)) {
+ $include = $true
+ break
+ }
+ }
+
+ if (-not $include) {
+ continue
+ }
+
+ $pathItem = $spec.paths[$path]
+ $pathParameters = @()
+ if ($pathItem.ContainsKey("parameters")) {
+ $pathParameters = @($pathItem.parameters)
+ }
+
+ foreach ($method in @("get", "post", "put", "patch", "delete")) {
+ if (-not $pathItem.ContainsKey($method)) {
+ continue
+ }
+
+ $operation = $pathItem[$method]
+ $operationParameters = @()
+ if ($operation.ContainsKey("parameters")) {
+ $operationParameters = @($operation.parameters)
+ }
+
+ $allParameters = @($pathParameters + $operationParameters)
+ $pathWithValues = $path
+ foreach ($param in $allParameters) {
+ if ([string]$param.in -eq "path") {
+ $token = "{" + [string]$param.name + "}"
+ $pathWithValues = $pathWithValues.Replace($token, "1")
+ }
+ }
+
+ $query = Build-QueryString -Parameters $allParameters
+ $url = "$baseUrl$pathWithValues$query"
+
+ $requestBody = Build-RequestBody -Operation $operation
+
+ $scenarios = @()
+ if ($path.StartsWith("/user")) {
+ if (-not [string]::IsNullOrWhiteSpace($BearerToken)) {
+ $scenarios += @{ authMode = "auth"; headers = @{ Authorization = "Bearer $BearerToken" } }
+ }
+ if ($ProbeNoAuthForUser.IsPresent) {
+ $scenarios += @{ authMode = "no_auth"; headers = @{} }
+ }
+ }
+ else {
+ $scenarios += @{ authMode = "public"; headers = @{} }
+ }
+
+ foreach ($scenario in $scenarios) {
+ $statusCode = -1
+ $responseText = ""
+ $contentType = ""
+ try {
+ if ($null -eq $requestBody) {
+ $response = Invoke-WebRequest -UseBasicParsing -Uri $url -Method $method.ToUpperInvariant() -Headers $scenario.headers -TimeoutSec 60 -ErrorAction Stop
+ }
+ else {
+ $response = Invoke-WebRequest -UseBasicParsing -Uri $url -Method $method.ToUpperInvariant() -Headers $scenario.headers -Body $requestBody.Body -ContentType $requestBody.ContentType -TimeoutSec 60 -ErrorAction Stop
+ }
+
+ $statusCode = [int]$response.StatusCode
+ $responseText = [string]$response.Content
+ $contentType = [string]$response.Headers["Content-Type"]
+ }
+ catch {
+ if ($_.Exception.Response) {
+ $statusCode = [int]$_.Exception.Response.StatusCode.value__
+ try { $contentType = [string]$_.Exception.Response.Headers["Content-Type"] } catch {}
+ }
+
+ if ($_.ErrorDetails -and $_.ErrorDetails.Message) {
+ $responseText = [string]$_.ErrorDetails.Message
+ }
+ elseif ($_.Exception.Message) {
+ $responseText = [string]$_.Exception.Message
+ }
+ }
+
+ $actualShape = @{ type = "non-json" }
+ $isLogicalError = $false
+ $errorCode = $null
+ if (-not [string]::IsNullOrWhiteSpace($responseText)) {
+ try {
+ $parsed = $responseText | ConvertFrom-Json -AsHashtable -Depth 100
+ $actualShape = Get-JsonShape -Node $parsed -Depth 0 -MaxDepth $MaxDepth
+ if ($parsed -is [System.Collections.IDictionary] -and $parsed.ContainsKey("error")) {
+ $isLogicalError = $true
+ if ($parsed.ContainsKey("code")) {
+ $errorCode = [string]$parsed.code
+ }
+ }
+ }
+ catch {
+ $actualShape = @{ type = "non-json" }
+ }
+ }
+
+ $responseSchema = $null
+ if ($operation.ContainsKey("responses") -and $operation.responses.ContainsKey("200")) {
+ $r200 = $operation.responses["200"]
+ if ($r200 -is [hashtable] -and $r200.ContainsKey("content") -and $r200.content.ContainsKey("application/json")) {
+ $media = $r200.content["application/json"]
+ if ($media -is [hashtable] -and $media.ContainsKey("schema")) {
+ $responseSchema = $media.schema
+ }
+ }
+ }
+
+ $records += @{
+ method = $method.ToUpperInvariant()
+ path = $path
+ summary = if ($operation.ContainsKey("summary")) { [string]$operation.summary } else { "" }
+ authMode = $scenario.authMode
+ url = $url
+ statusCode = $statusCode
+ contentType = $contentType
+ isLogicalError = $isLogicalError
+ errorCode = $errorCode
+ requestParameters = $allParameters
+ specResponseShape = Get-SpecSchemaShape -Spec $spec -Schema $responseSchema -Depth 0 -MaxDepth $MaxDepth
+ actualResponseShape = $actualShape
+ responsePreview = if ($responseText.Length -gt 4000) { $responseText.Substring(0, 4000) } else { $responseText }
+ }
+ }
+ }
+}
+
+$records | ConvertTo-Json -Depth 100 | Set-Content -Encoding UTF8 $OutputPath
+Write-Output "Wrote $OutputPath with $($records.Count) records from $SpecPath."
diff --git a/src/GoAffPro.Client.Generated/Generated/.kiota.log b/src/GoAffPro.Client.Generated/Generated/.kiota.log
new file mode 100644
index 0000000..542a0f0
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/.kiota.log
@@ -0,0 +1,2 @@
+Warning: KiotaBuilder Discriminator UserTrafficFeedResponse is not inherited from CountLimitOffsetEnvelope.
+Warning: KiotaBuilder Discriminator UserPayoutFeedResponse is not inherited from CountLimitOffsetEnvelope.
diff --git a/src/GoAffPro.Client.Generated/Generated/GoAffProApiClient.cs b/src/GoAffPro.Client.Generated/Generated/GoAffProApiClient.cs
new file mode 100644
index 0000000..ac00bc1
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/GoAffProApiClient.cs
@@ -0,0 +1,54 @@
+//
+#pragma warning disable CS0618
+using GoAffPro.Client.Generated.Public;
+using GoAffPro.Client.Generated.User;
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions;
+using Microsoft.Kiota.Serialization.Form;
+using Microsoft.Kiota.Serialization.Json;
+using Microsoft.Kiota.Serialization.Multipart;
+using Microsoft.Kiota.Serialization.Text;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using System;
+namespace GoAffPro.Client.Generated
+{
+ ///
+ /// The main entry point of the SDK, exposes the configuration and the fluent API.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class GoAffProApiClient : BaseRequestBuilder
+ {
+ /// The public property
+ public global::GoAffPro.Client.Generated.Public.PublicRequestBuilder Public
+ {
+ get => new global::GoAffPro.Client.Generated.Public.PublicRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The user property
+ public global::GoAffPro.Client.Generated.User.UserRequestBuilder User
+ {
+ get => new global::GoAffPro.Client.Generated.User.UserRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ /// The request adapter to use to execute the requests.
+ public GoAffProApiClient(IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}", new Dictionary())
+ {
+ ApiClientBuilder.RegisterDefaultSerializer();
+ ApiClientBuilder.RegisterDefaultSerializer();
+ ApiClientBuilder.RegisterDefaultSerializer();
+ ApiClientBuilder.RegisterDefaultSerializer();
+ ApiClientBuilder.RegisterDefaultDeserializer();
+ ApiClientBuilder.RegisterDefaultDeserializer();
+ ApiClientBuilder.RegisterDefaultDeserializer();
+ if (string.IsNullOrEmpty(RequestAdapter.BaseUrl))
+ {
+ RequestAdapter.BaseUrl = "https://api.goaffpro.com/v1";
+ }
+ PathParameters.TryAdd("baseurl", RequestAdapter.BaseUrl);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/CommissionLike.cs b/src/GoAffPro.Client.Generated/Generated/Models/CommissionLike.cs
new file mode 100644
index 0000000..6d0e027
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/CommissionLike.cs
@@ -0,0 +1,79 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class CommissionLike : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The amount property
+ public double? Amount { get; set; }
+ /// The on property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? On { get; set; }
+#nullable restore
+#else
+ public string On { get; set; }
+#endif
+ /// The type property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Type { get; set; }
+#nullable restore
+#else
+ public string Type { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public CommissionLike()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.CommissionLike CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.CommissionLike();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "amount", n => { Amount = n.GetDoubleValue(); } },
+ { "on", n => { On = n.GetStringValue(); } },
+ { "type", n => { Type = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteDoubleValue("amount", Amount);
+ writer.WriteStringValue("on", On);
+ writer.WriteStringValue("type", Type);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelope.cs b/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelope.cs
new file mode 100644
index 0000000..de5b739
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelope.cs
@@ -0,0 +1,67 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class CountLimitOffsetEnvelope : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The count property
+ public int? Count { get; set; }
+ /// The limit property
+ public int? Limit { get; set; }
+ /// The offset property
+ public int? Offset { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public CountLimitOffsetEnvelope()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelope CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelope();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "count", n => { Count = n.GetIntValue(); } },
+ { "limit", n => { Limit = n.GetIntValue(); } },
+ { "offset", n => { Offset = n.GetIntValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteIntValue("count", Count);
+ writer.WriteIntValue("limit", Limit);
+ writer.WriteIntValue("offset", Offset);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelopeFlexibleOffset.cs b/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelopeFlexibleOffset.cs
new file mode 100644
index 0000000..05e8f12
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/CountLimitOffsetEnvelopeFlexibleOffset.cs
@@ -0,0 +1,134 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class CountLimitOffsetEnvelopeFlexibleOffset : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The count property
+ public int? Count { get; set; }
+ /// The limit property
+ public int? Limit { get; set; }
+ /// The offset property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset.CountLimitOffsetEnvelopeFlexibleOffset_offset? Offset { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset.CountLimitOffsetEnvelopeFlexibleOffset_offset Offset { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public CountLimitOffsetEnvelopeFlexibleOffset()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "count", n => { Count = n.GetIntValue(); } },
+ { "limit", n => { Limit = n.GetIntValue(); } },
+ { "offset", n => { Offset = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset.CountLimitOffsetEnvelopeFlexibleOffset_offset.CreateFromDiscriminatorValue); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteIntValue("count", Count);
+ writer.WriteIntValue("limit", Limit);
+ writer.WriteObjectValue("offset", Offset);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class CountLimitOffsetEnvelopeFlexibleOffset_offset : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset.CountLimitOffsetEnvelopeFlexibleOffset_offset CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset.CountLimitOffsetEnvelopeFlexibleOffset_offset();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/ErrorResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/ErrorResponse.cs
new file mode 100644
index 0000000..a453ad8
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/ErrorResponse.cs
@@ -0,0 +1,139 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class ErrorResponse : ApiException, IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The code property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.ErrorResponse.ErrorResponse_code? Code { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.ErrorResponse.ErrorResponse_code Code { get; set; }
+#endif
+ /// The error property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Error { get; set; }
+#nullable restore
+#else
+ public string Error { get; set; }
+#endif
+ /// The primary error message.
+ public override string Message { get => base.Message; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public ErrorResponse()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.ErrorResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.ErrorResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "code", n => { Code = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.ErrorResponse.ErrorResponse_code.CreateFromDiscriminatorValue); } },
+ { "error", n => { Error = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteObjectValue("code", Code);
+ writer.WriteStringValue("error", Error);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class ErrorResponse_code : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.ErrorResponse.ErrorResponse_code CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.ErrorResponse.ErrorResponse_code();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/LoginResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/LoginResponse.cs
new file mode 100644
index 0000000..ddbf540
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/LoginResponse.cs
@@ -0,0 +1,65 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class LoginResponse : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// The access_token property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? AccessToken { get; set; }
+#nullable restore
+#else
+ public string AccessToken { get; set; }
+#endif
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public LoginResponse()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.LoginResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.LoginResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "access_token", n => { AccessToken = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteStringValue("access_token", AccessToken);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutBreakdown.cs b/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutBreakdown.cs
new file mode 100644
index 0000000..f82d907
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutBreakdown.cs
@@ -0,0 +1,71 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PendingPayoutBreakdown : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The amount_pending property
+ public double? AmountPending { get; set; }
+ /// The other_earnings property
+ public double? OtherEarnings { get; set; }
+ /// The paid_earnings property
+ public double? PaidEarnings { get; set; }
+ /// The sale_earnings property
+ public double? SaleEarnings { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public PendingPayoutBreakdown()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.PendingPayoutBreakdown CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PendingPayoutBreakdown();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "amount_pending", n => { AmountPending = n.GetDoubleValue(); } },
+ { "other_earnings", n => { OtherEarnings = n.GetDoubleValue(); } },
+ { "paid_earnings", n => { PaidEarnings = n.GetDoubleValue(); } },
+ { "sale_earnings", n => { SaleEarnings = n.GetDoubleValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteDoubleValue("amount_pending", AmountPending);
+ writer.WriteDoubleValue("other_earnings", OtherEarnings);
+ writer.WriteDoubleValue("paid_earnings", PaidEarnings);
+ writer.WriteDoubleValue("sale_earnings", SaleEarnings);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutItem.cs b/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutItem.cs
new file mode 100644
index 0000000..c06630e
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PendingPayoutItem.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PendingPayoutItem : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public PendingPayoutItem()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.PendingPayoutItem CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PendingPayoutItem();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse.cs
new file mode 100644
index 0000000..e63c409
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse.cs
@@ -0,0 +1,66 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PublicProductsResponse : global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset, IParsable
+ #pragma warning restore CS1591
+ {
+ /// The products property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Products { get; set; }
+#nullable restore
+#else
+ public List Products { get; set; }
+#endif
+ /// The site_ids property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? SiteIds { get; set; }
+#nullable restore
+#else
+ public string SiteIds { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static new global::GoAffPro.Client.Generated.Models.PublicProductsResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PublicProductsResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public override IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>(base.GetFieldDeserializers())
+ {
+ { "products", n => { Products = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.PublicProductsResponse_products.CreateFromDiscriminatorValue)?.AsList(); } },
+ { "site_ids", n => { SiteIds = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public override void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ base.Serialize(writer);
+ writer.WriteCollectionOfObjectValues("products", Products);
+ writer.WriteStringValue("site_ids", SiteIds);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse_products.cs b/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse_products.cs
new file mode 100644
index 0000000..397f41c
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PublicProductsResponse_products.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PublicProductsResponse_products : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public PublicProductsResponse_products()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.PublicProductsResponse_products CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PublicProductsResponse_products();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PublicSitesResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/PublicSitesResponse.cs
new file mode 100644
index 0000000..6dbe4c5
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PublicSitesResponse.cs
@@ -0,0 +1,76 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PublicSitesResponse : global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelopeFlexibleOffset, IParsable
+ #pragma warning restore CS1591
+ {
+ /// The currency property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Currency { get; set; }
+#nullable restore
+#else
+ public string Currency { get; set; }
+#endif
+ /// The keyword property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Keyword { get; set; }
+#nullable restore
+#else
+ public string Keyword { get; set; }
+#endif
+ /// The stores property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Stores { get; set; }
+#nullable restore
+#else
+ public List Stores { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static new global::GoAffPro.Client.Generated.Models.PublicSitesResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PublicSitesResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public override IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>(base.GetFieldDeserializers())
+ {
+ { "currency", n => { Currency = n.GetStringValue(); } },
+ { "keyword", n => { Keyword = n.GetStringValue(); } },
+ { "stores", n => { Stores = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.PublicStore.CreateFromDiscriminatorValue)?.AsList(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public override void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ base.Serialize(writer);
+ writer.WriteStringValue("currency", Currency);
+ writer.WriteStringValue("keyword", Keyword);
+ writer.WriteCollectionOfObjectValues("stores", Stores);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/PublicStore.cs b/src/GoAffPro.Client.Generated/Generated/Models/PublicStore.cs
new file mode 100644
index 0000000..d9271cd
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/PublicStore.cs
@@ -0,0 +1,131 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class PublicStore : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The affiliatePortal property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? AffiliatePortal { get; set; }
+#nullable restore
+#else
+ public string AffiliatePortal { get; set; }
+#endif
+ /// The areRegistrationsOpen property
+ public int? AreRegistrationsOpen { get; set; }
+ /// The commission property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.CommissionLike? Commission { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.CommissionLike Commission { get; set; }
+#endif
+ /// The cookieDuration property
+ public int? CookieDuration { get; set; }
+ /// The currency property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Currency { get; set; }
+#nullable restore
+#else
+ public string Currency { get; set; }
+#endif
+ /// The id property
+ public int? Id { get; set; }
+ /// The isApprovedAutomatically property
+ public int? IsApprovedAutomatically { get; set; }
+ /// The logo property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Logo { get; set; }
+#nullable restore
+#else
+ public string Logo { get; set; }
+#endif
+ /// The name property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Name { get; set; }
+#nullable restore
+#else
+ public string Name { get; set; }
+#endif
+ /// The website property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Website { get; set; }
+#nullable restore
+#else
+ public string Website { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public PublicStore()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.PublicStore CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.PublicStore();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "affiliatePortal", n => { AffiliatePortal = n.GetStringValue(); } },
+ { "areRegistrationsOpen", n => { AreRegistrationsOpen = n.GetIntValue(); } },
+ { "commission", n => { Commission = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.CommissionLike.CreateFromDiscriminatorValue); } },
+ { "cookieDuration", n => { CookieDuration = n.GetIntValue(); } },
+ { "currency", n => { Currency = n.GetStringValue(); } },
+ { "id", n => { Id = n.GetIntValue(); } },
+ { "isApprovedAutomatically", n => { IsApprovedAutomatically = n.GetIntValue(); } },
+ { "logo", n => { Logo = n.GetStringValue(); } },
+ { "name", n => { Name = n.GetStringValue(); } },
+ { "website", n => { Website = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteStringValue("affiliatePortal", AffiliatePortal);
+ writer.WriteIntValue("areRegistrationsOpen", AreRegistrationsOpen);
+ writer.WriteObjectValue("commission", Commission);
+ writer.WriteIntValue("cookieDuration", CookieDuration);
+ writer.WriteStringValue("currency", Currency);
+ writer.WriteIntValue("id", Id);
+ writer.WriteIntValue("isApprovedAutomatically", IsApprovedAutomatically);
+ writer.WriteStringValue("logo", Logo);
+ writer.WriteStringValue("name", Name);
+ writer.WriteStringValue("website", Website);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse.cs
new file mode 100644
index 0000000..fb905eb
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse.cs
@@ -0,0 +1,105 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserCommissionsResponse : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The commissions property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Commissions { get; set; }
+#nullable restore
+#else
+ public List Commissions { get; set; }
+#endif
+ /// The mlm property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_mlm? Mlm { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_mlm Mlm { get; set; }
+#endif
+ /// The royalties property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Royalties { get; set; }
+#nullable restore
+#else
+ public List Royalties { get; set; }
+#endif
+ /// The special property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Special { get; set; }
+#nullable restore
+#else
+ public List Special { get; set; }
+#endif
+ /// The standard property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_standard? Standard { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_standard Standard { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserCommissionsResponse()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserCommissionsResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserCommissionsResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "commissions", n => { Commissions = n.GetCollectionOfPrimitiveValues()?.AsList(); } },
+ { "mlm", n => { Mlm = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_mlm.CreateFromDiscriminatorValue); } },
+ { "royalties", n => { Royalties = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_royalties.CreateFromDiscriminatorValue)?.AsList(); } },
+ { "special", n => { Special = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_special.CreateFromDiscriminatorValue)?.AsList(); } },
+ { "standard", n => { Standard = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_standard.CreateFromDiscriminatorValue); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteCollectionOfPrimitiveValues("commissions", Commissions);
+ writer.WriteObjectValue("mlm", Mlm);
+ writer.WriteCollectionOfObjectValues("royalties", Royalties);
+ writer.WriteCollectionOfObjectValues("special", Special);
+ writer.WriteObjectValue("standard", Standard);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_mlm.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_mlm.cs
new file mode 100644
index 0000000..a45b2f9
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_mlm.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserCommissionsResponse_mlm : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserCommissionsResponse_mlm()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_mlm CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_mlm();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_royalties.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_royalties.cs
new file mode 100644
index 0000000..f205aa8
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_royalties.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserCommissionsResponse_royalties : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserCommissionsResponse_royalties()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_royalties CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_royalties();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_special.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_special.cs
new file mode 100644
index 0000000..6d08c62
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_special.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserCommissionsResponse_special : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserCommissionsResponse_special()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_special CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_special();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_standard.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_standard.cs
new file mode 100644
index 0000000..9fb5c78
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserCommissionsResponse_standard.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserCommissionsResponse_standard : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserCommissionsResponse_standard()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_standard CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserCommissionsResponse_standard();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem.cs
new file mode 100644
index 0000000..0be307d
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem.cs
@@ -0,0 +1,559 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserOrderFeedItem : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The affiliate_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_affiliate_id? AffiliateId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_affiliate_id AffiliateId { get; set; }
+#endif
+ /// The commission property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_commission? Commission { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_commission Commission { get; set; }
+#endif
+ /// The conversion_details property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_conversion_details? ConversionDetails { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_conversion_details ConversionDetails { get; set; }
+#endif
+ /// The created property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_created? Created { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_created Created { get; set; }
+#endif
+ /// The created_at property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? CreatedAt { get; set; }
+#nullable restore
+#else
+ public string CreatedAt { get; set; }
+#endif
+ /// The currency property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Currency { get; set; }
+#nullable restore
+#else
+ public string Currency { get; set; }
+#endif
+ /// The id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_id? Id { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_id Id { get; set; }
+#endif
+ /// The line_items property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? LineItems { get; set; }
+#nullable restore
+#else
+ public List LineItems { get; set; }
+#endif
+ /// The number property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Number { get; set; }
+#nullable restore
+#else
+ public string Number { get; set; }
+#endif
+ /// The order_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_order_id? OrderId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_order_id OrderId { get; set; }
+#endif
+ /// The site_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_site_id? SiteId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_site_id SiteId { get; set; }
+#endif
+ /// The status property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Status { get; set; }
+#nullable restore
+#else
+ public string Status { get; set; }
+#endif
+ /// The sub_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? SubId { get; set; }
+#nullable restore
+#else
+ public string SubId { get; set; }
+#endif
+ /// The subtotal property
+ public double? Subtotal { get; set; }
+ /// The total property
+ public double? Total { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserOrderFeedItem()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "affiliate_id", n => { AffiliateId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_affiliate_id.CreateFromDiscriminatorValue); } },
+ { "commission", n => { Commission = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_commission.CreateFromDiscriminatorValue); } },
+ { "conversion_details", n => { ConversionDetails = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_conversion_details.CreateFromDiscriminatorValue); } },
+ { "created", n => { Created = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_created.CreateFromDiscriminatorValue); } },
+ { "created_at", n => { CreatedAt = n.GetStringValue(); } },
+ { "currency", n => { Currency = n.GetStringValue(); } },
+ { "id", n => { Id = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_id.CreateFromDiscriminatorValue); } },
+ { "line_items", n => { LineItems = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_line_items.CreateFromDiscriminatorValue)?.AsList(); } },
+ { "number", n => { Number = n.GetStringValue(); } },
+ { "order_id", n => { OrderId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_order_id.CreateFromDiscriminatorValue); } },
+ { "site_id", n => { SiteId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_site_id.CreateFromDiscriminatorValue); } },
+ { "status", n => { Status = n.GetStringValue(); } },
+ { "sub_id", n => { SubId = n.GetStringValue(); } },
+ { "subtotal", n => { Subtotal = n.GetDoubleValue(); } },
+ { "total", n => { Total = n.GetDoubleValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteObjectValue("affiliate_id", AffiliateId);
+ writer.WriteObjectValue("commission", Commission);
+ writer.WriteObjectValue("conversion_details", ConversionDetails);
+ writer.WriteObjectValue("created", Created);
+ writer.WriteStringValue("created_at", CreatedAt);
+ writer.WriteStringValue("currency", Currency);
+ writer.WriteObjectValue("id", Id);
+ writer.WriteCollectionOfObjectValues("line_items", LineItems);
+ writer.WriteStringValue("number", Number);
+ writer.WriteObjectValue("order_id", OrderId);
+ writer.WriteObjectValue("site_id", SiteId);
+ writer.WriteStringValue("status", Status);
+ writer.WriteStringValue("sub_id", SubId);
+ writer.WriteDoubleValue("subtotal", Subtotal);
+ writer.WriteDoubleValue("total", Total);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_affiliate_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_affiliate_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_affiliate_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_commission : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public double? Double { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_commission CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_commission();
+ if(parseNode.GetDoubleValue() is double doubleValue)
+ {
+ result.Double = doubleValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Double != null)
+ {
+ writer.WriteDoubleValue(null, Double);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_created : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_created CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_created();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_order_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_order_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_order_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserOrderFeedItem_site_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_site_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.UserOrderFeedItem_site_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_conversion_details.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_conversion_details.cs
new file mode 100644
index 0000000..76fe3c9
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_conversion_details.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserOrderFeedItem_conversion_details : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserOrderFeedItem_conversion_details()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_conversion_details CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_conversion_details();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_line_items.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_line_items.cs
new file mode 100644
index 0000000..42a7c79
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedItem_line_items.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserOrderFeedItem_line_items : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserOrderFeedItem_line_items()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_line_items CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserOrderFeedItem_line_items();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedResponse.cs
new file mode 100644
index 0000000..ae26897
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserOrderFeedResponse.cs
@@ -0,0 +1,56 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserOrderFeedResponse : global::GoAffPro.Client.Generated.Models.CountLimitOffsetEnvelope, IParsable
+ #pragma warning restore CS1591
+ {
+ /// The orders property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Orders { get; set; }
+#nullable restore
+#else
+ public List Orders { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static new global::GoAffPro.Client.Generated.Models.UserOrderFeedResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserOrderFeedResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public override IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>(base.GetFieldDeserializers())
+ {
+ { "orders", n => { Orders = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.UserOrderFeedItem.CreateFromDiscriminatorValue)?.AsList(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public override void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ base.Serialize(writer);
+ writer.WriteCollectionOfObjectValues("orders", Orders);
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedItem.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedItem.cs
new file mode 100644
index 0000000..099f9f0
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedItem.cs
@@ -0,0 +1,460 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserPayoutFeedItem : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The affiliate_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_affiliate_id? AffiliateId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_affiliate_id AffiliateId { get; set; }
+#endif
+ /// The amount property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_amount? Amount { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_amount Amount { get; set; }
+#endif
+ /// The created property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_created? Created { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_created Created { get; set; }
+#endif
+ /// The created_at property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? CreatedAt { get; set; }
+#nullable restore
+#else
+ public string CreatedAt { get; set; }
+#endif
+ /// The currency property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Currency { get; set; }
+#nullable restore
+#else
+ public string Currency { get; set; }
+#endif
+ /// The id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_id? Id { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_id Id { get; set; }
+#endif
+ /// The payment_method property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? PaymentMethod { get; set; }
+#nullable restore
+#else
+ public string PaymentMethod { get; set; }
+#endif
+ /// The payout_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_payout_id? PayoutId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_payout_id PayoutId { get; set; }
+#endif
+ /// The status property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Status { get; set; }
+#nullable restore
+#else
+ public string Status { get; set; }
+#endif
+ /// The transaction_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? TransactionId { get; set; }
+#nullable restore
+#else
+ public string TransactionId { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserPayoutFeedItem()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "affiliate_id", n => { AffiliateId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_affiliate_id.CreateFromDiscriminatorValue); } },
+ { "amount", n => { Amount = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_amount.CreateFromDiscriminatorValue); } },
+ { "created", n => { Created = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_created.CreateFromDiscriminatorValue); } },
+ { "created_at", n => { CreatedAt = n.GetStringValue(); } },
+ { "currency", n => { Currency = n.GetStringValue(); } },
+ { "id", n => { Id = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_id.CreateFromDiscriminatorValue); } },
+ { "payment_method", n => { PaymentMethod = n.GetStringValue(); } },
+ { "payout_id", n => { PayoutId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_payout_id.CreateFromDiscriminatorValue); } },
+ { "status", n => { Status = n.GetStringValue(); } },
+ { "transaction_id", n => { TransactionId = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteObjectValue("affiliate_id", AffiliateId);
+ writer.WriteObjectValue("amount", Amount);
+ writer.WriteObjectValue("created", Created);
+ writer.WriteStringValue("created_at", CreatedAt);
+ writer.WriteStringValue("currency", Currency);
+ writer.WriteObjectValue("id", Id);
+ writer.WriteStringValue("payment_method", PaymentMethod);
+ writer.WriteObjectValue("payout_id", PayoutId);
+ writer.WriteStringValue("status", Status);
+ writer.WriteStringValue("transaction_id", TransactionId);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedItem_affiliate_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_affiliate_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_affiliate_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedItem_amount : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public double? Double { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_amount CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_amount();
+ if(parseNode.GetDoubleValue() is double doubleValue)
+ {
+ result.Double = doubleValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Double != null)
+ {
+ writer.WriteDoubleValue(null, Double);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedItem_created : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_created CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_created();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedItem_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedItem_payout_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_payout_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.UserPayoutFeedItem_payout_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedResponse.cs
new file mode 100644
index 0000000..62f1723
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserPayoutFeedResponse.cs
@@ -0,0 +1,148 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserPayoutFeedResponse : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The count property
+ public int? Count { get; set; }
+ /// The limit property
+ public int? Limit { get; set; }
+ /// The offset property
+ public int? Offset { get; set; }
+ /// The payouts property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? Payouts { get; set; }
+#nullable restore
+#else
+ public List Payouts { get; set; }
+#endif
+ /// The since_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse.UserPayoutFeedResponse_since_id? SinceId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse.UserPayoutFeedResponse_since_id SinceId { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserPayoutFeedResponse()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "count", n => { Count = n.GetIntValue(); } },
+ { "limit", n => { Limit = n.GetIntValue(); } },
+ { "offset", n => { Offset = n.GetIntValue(); } },
+ { "payouts", n => { Payouts = n.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.UserPayoutFeedItem.CreateFromDiscriminatorValue)?.AsList(); } },
+ { "since_id", n => { SinceId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse.UserPayoutFeedResponse_since_id.CreateFromDiscriminatorValue); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteIntValue("count", Count);
+ writer.WriteIntValue("limit", Limit);
+ writer.WriteIntValue("offset", Offset);
+ writer.WriteCollectionOfObjectValues("payouts", Payouts);
+ writer.WriteObjectValue("since_id", SinceId);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPayoutFeedResponse_since_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse.UserPayoutFeedResponse_since_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPayoutFeedResponse.UserPayoutFeedResponse_since_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserPendingPayoutsResponse.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserPendingPayoutsResponse.cs
new file mode 100644
index 0000000..2049e2c
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserPendingPayoutsResponse.cs
@@ -0,0 +1,136 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserPendingPayoutsResponse : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The pending property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse.UserPendingPayoutsResponse_pending? Pending { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse.UserPendingPayoutsResponse_pending Pending { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserPendingPayoutsResponse()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "pending", n => { Pending = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse.UserPendingPayoutsResponse_pending.CreateFromDiscriminatorValue); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteObjectValue("pending", Pending);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes , List<global::GoAffPro.Client.Generated.Models.PendingPayoutItem>
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserPendingPayoutsResponse_pending : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.PendingPayoutBreakdown? PendingPayoutBreakdown { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.PendingPayoutBreakdown PendingPayoutBreakdown { get; set; }
+#endif
+ /// Composed type representation for type List<global::GoAffPro.Client.Generated.Models.PendingPayoutItem>
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public List? PendingPayoutItem { get; set; }
+#nullable restore
+#else
+ public List PendingPayoutItem { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse.UserPendingPayoutsResponse_pending CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserPendingPayoutsResponse.UserPendingPayoutsResponse_pending();
+ if("PendingPayoutBreakdown".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
+ {
+ result.PendingPayoutBreakdown = new global::GoAffPro.Client.Generated.Models.PendingPayoutBreakdown();
+ }
+ else if(parseNode.GetCollectionOfObjectValues(global::GoAffPro.Client.Generated.Models.PendingPayoutItem.CreateFromDiscriminatorValue)?.AsList() is List pendingPayoutItemValue)
+ {
+ result.PendingPayoutItem = pendingPayoutItemValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ if(PendingPayoutBreakdown != null)
+ {
+ return PendingPayoutBreakdown.GetFieldDeserializers();
+ }
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(PendingPayoutBreakdown != null)
+ {
+ writer.WriteObjectValue(null, PendingPayoutBreakdown);
+ }
+ else if(PendingPayoutItem != null)
+ {
+ writer.WriteCollectionOfObjectValues(null, PendingPayoutItem);
+ }
+ }
+ }
+ }
+}
+#pragma warning restore CS0618
diff --git a/src/GoAffPro.Client.Generated/Generated/Models/UserProductFeedItem.cs b/src/GoAffPro.Client.Generated/Generated/Models/UserProductFeedItem.cs
new file mode 100644
index 0000000..63b0780
--- /dev/null
+++ b/src/GoAffPro.Client.Generated/Generated/Models/UserProductFeedItem.cs
@@ -0,0 +1,409 @@
+//
+#pragma warning disable CS0618
+using Microsoft.Kiota.Abstractions.Extensions;
+using Microsoft.Kiota.Abstractions.Serialization;
+using System.Collections.Generic;
+using System.IO;
+using System;
+namespace GoAffPro.Client.Generated.Models
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ #pragma warning disable CS1591
+ public partial class UserProductFeedItem : IAdditionalDataHolder, IParsable
+ #pragma warning restore CS1591
+ {
+ /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
+ public IDictionary AdditionalData { get; set; }
+ /// The category property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Category { get; set; }
+#nullable restore
+#else
+ public string Category { get; set; }
+#endif
+ /// The currency property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Currency { get; set; }
+#nullable restore
+#else
+ public string Currency { get; set; }
+#endif
+ /// The description property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Description { get; set; }
+#nullable restore
+#else
+ public string Description { get; set; }
+#endif
+ /// The id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_id? Id { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_id Id { get; set; }
+#endif
+ /// The image_url property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? ImageUrl { get; set; }
+#nullable restore
+#else
+ public string ImageUrl { get; set; }
+#endif
+ /// The name property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Name { get; set; }
+#nullable restore
+#else
+ public string Name { get; set; }
+#endif
+ /// The price property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_price? Price { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_price Price { get; set; }
+#endif
+ /// The product_id property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_product_id? ProductId { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_product_id ProductId { get; set; }
+#endif
+ /// The product_url property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? ProductUrl { get; set; }
+#nullable restore
+#else
+ public string ProductUrl { get; set; }
+#endif
+ /// The sale_price property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_sale_price? SalePrice { get; set; }
+#nullable restore
+#else
+ public global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_sale_price SalePrice { get; set; }
+#endif
+ /// The sku property
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? Sku { get; set; }
+#nullable restore
+#else
+ public string Sku { get; set; }
+#endif
+ ///
+ /// Instantiates a new and sets the default values.
+ ///
+ public UserProductFeedItem()
+ {
+ AdditionalData = new Dictionary();
+ }
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserProductFeedItem CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ return new global::GoAffPro.Client.Generated.Models.UserProductFeedItem();
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>
+ {
+ { "category", n => { Category = n.GetStringValue(); } },
+ { "currency", n => { Currency = n.GetStringValue(); } },
+ { "description", n => { Description = n.GetStringValue(); } },
+ { "id", n => { Id = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_id.CreateFromDiscriminatorValue); } },
+ { "image_url", n => { ImageUrl = n.GetStringValue(); } },
+ { "name", n => { Name = n.GetStringValue(); } },
+ { "price", n => { Price = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_price.CreateFromDiscriminatorValue); } },
+ { "product_id", n => { ProductId = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_product_id.CreateFromDiscriminatorValue); } },
+ { "product_url", n => { ProductUrl = n.GetStringValue(); } },
+ { "sale_price", n => { SalePrice = n.GetObjectValue(global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_sale_price.CreateFromDiscriminatorValue); } },
+ { "sku", n => { Sku = n.GetStringValue(); } },
+ };
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ writer.WriteStringValue("category", Category);
+ writer.WriteStringValue("currency", Currency);
+ writer.WriteStringValue("description", Description);
+ writer.WriteObjectValue("id", Id);
+ writer.WriteStringValue("image_url", ImageUrl);
+ writer.WriteStringValue("name", Name);
+ writer.WriteObjectValue("price", Price);
+ writer.WriteObjectValue("product_id", ProductId);
+ writer.WriteStringValue("product_url", ProductUrl);
+ writer.WriteObjectValue("sale_price", SalePrice);
+ writer.WriteStringValue("sku", Sku);
+ writer.WriteAdditionalData(AdditionalData);
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserProductFeedItem_id : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public int? Integer { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_id CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_id();
+ if(parseNode.GetIntValue() is int integerValue)
+ {
+ result.Integer = integerValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///
+ /// Serializes information the current object
+ ///
+ /// Serialization writer to use to serialize this model
+ public virtual void Serialize(ISerializationWriter writer)
+ {
+ if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
+ if(Integer != null)
+ {
+ writer.WriteIntValue(null, Integer);
+ }
+ else if(String != null)
+ {
+ writer.WriteStringValue(null, String);
+ }
+ }
+ }
+ ///
+ /// Composed type wrapper for classes ,
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
+ public partial class UserProductFeedItem_price : IComposedTypeWrapper, IParsable
+ {
+ /// Composed type representation for type
+ public double? Double { get; set; }
+ /// Composed type representation for type
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public string? String { get; set; }
+#nullable restore
+#else
+ public string String { get; set; }
+#endif
+ ///
+ /// Creates a new instance of the appropriate class based on discriminator value
+ ///
+ /// A
+ /// The parse node to use to read the discriminator value and create the object
+ public static global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_price CreateFromDiscriminatorValue(IParseNode parseNode)
+ {
+ if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
+ var mappingValue = parseNode.GetChildNode("")?.GetStringValue();
+ var result = new global::GoAffPro.Client.Generated.Models.UserProductFeedItem.UserProductFeedItem_price();
+ if(parseNode.GetDoubleValue() is double doubleValue)
+ {
+ result.Double = doubleValue;
+ }
+ else if(parseNode.GetStringValue() is string stringValue)
+ {
+ result.String = stringValue;
+ }
+ return result;
+ }
+ ///
+ /// The deserialization information for the current model
+ ///
+ /// A IDictionary<string, Action<IParseNode>>
+ public virtual IDictionary> GetFieldDeserializers()
+ {
+ return new Dictionary>();
+ }
+ ///