Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .speakeasy/workflow.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
speakeasyVersion: 1.709.1
speakeasyVersion: 1.701.0
sources:
bank-feeds-source:
Expand Down Expand Up @@ -42,11 +43,11 @@ sources:
- prealpha
sync-for-payables-source:
sourceNamespace: sync-for-payables-source
sourceRevisionDigest: sha256:9bf594a869e0b9e326b3437e9661b5a7f2f7da420d4fb7375a4a9938a168951c
sourceBlobDigest: sha256:57b656eed2c5a98f97da8f59e196bb8052ead3cc7c87673cdf5e19c6badbb570
sourceRevisionDigest: sha256:9bd9e36fdb60e3d73fe7cc209c24ce0325919a523acec3edd84ee2f26420bedc
sourceBlobDigest: sha256:59b5c9d3aa1a43fa4186c6ae1bf1108bf40d44d22f65ed6118b763574e0cf669
tags:
- latest
- speakeasy-sdk-regen-1732641065
- speakeasy-sdk-regen-1770645493
- 3.0.0
sync-for-payables-version-1-source:
sourceNamespace: sync-for-payables-version-1-source
Expand Down Expand Up @@ -101,10 +102,10 @@ targets:
sync-for-payables-library:
source: sync-for-payables-source
sourceNamespace: sync-for-payables-source
sourceRevisionDigest: sha256:9bf594a869e0b9e326b3437e9661b5a7f2f7da420d4fb7375a4a9938a168951c
sourceBlobDigest: sha256:57b656eed2c5a98f97da8f59e196bb8052ead3cc7c87673cdf5e19c6badbb570
codeSamplesNamespace: sync-for-payables-source-code-samples
codeSamplesRevisionDigest: sha256:956525cb89c12c0ab52334de08ce92639ff61c9c97e9a34aa55aa2e9a4177fe6
sourceRevisionDigest: sha256:9bd9e36fdb60e3d73fe7cc209c24ce0325919a523acec3edd84ee2f26420bedc
sourceBlobDigest: sha256:59b5c9d3aa1a43fa4186c6ae1bf1108bf40d44d22f65ed6118b763574e0cf669
codeSamplesNamespace: sync-for-payables-source-csharp-code-samples
codeSamplesRevisionDigest: sha256:30bcb4eb66da40861ecadbd3ff5846ab49f3c978ac1fa7a46ef43be2f525c071
sync-for-payables-version-1-library:
source: sync-for-payables-version-1-source
sourceNamespace: sync-for-payables-version-1-source
Expand Down
5 changes: 5 additions & 0 deletions sync-for-payables/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.DS_Store
**/.speakeasy/temp/
**/.speakeasy/logs/
.env
.env.local
obj/
bin/
debug/
2,111 changes: 1,661 additions & 450 deletions sync-for-payables/.speakeasy/gen.lock

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion sync-for-payables/.speakeasy/gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,44 @@ generation:
maintainOpenAPIOrder: true
usageSnippets:
optionalPropertyRendering: withExample
sdkInitStyle: constructor
useClassNamesForArrayFields: true
fixes:
nameResolutionDec2023: true
nameResolutionFeb2025: false
parameterOrderingFeb2024: true
requestResponseComponentNamesFeb2024: true
securityFeb2025: false
sharedErrorComponentsApr2025: false
sharedNestedComponentsJan2026: false
auth:
oAuth2ClientCredentialsEnabled: false
oAuth2PasswordEnabled: false
hoistGlobalSecurity: true
schemas:
allOfMergeStrategy: shallowMerge
requestBodyFieldName: ""
versioningStrategy: automatic
persistentEdits: {}
tests:
generateTests: true
generateNewTests: false
skipResponseBodyAssertions: false
csharp:
version: 10.0.0
version: 10.1.0
additionalDependencies: []
author: Codat
baseErrorName: CodatSyncPayablesException
clientServerStatusCodesAsErrors: true
defaultErrorName: SDKException
description: Streamline your customers' accounts payable workflow.
disableNamespacePascalCasingApr2024: true
dotnetVersion: net8.0
enableCancellationToken: false
enableSourceLink: false
flattenGlobalSecurity: true
flatteningOrder: ""
httpClientPrefix: Speakeasy
imports:
option: openapi
paths:
Expand All @@ -33,11 +51,15 @@ csharp:
shared: Models/Components
webhooks: Models/Webhooks
includeDebugSymbols: false
inferUnionDiscriminators: false
inputModelSuffix: input
maxMethodParams: 0
methodArguments: infer-optional-args
multipartArrayFormat: legacy
outputModelSuffix: output
packageName: Codat.Sync.Payables
packageTags: ""
respectTitlesForPrimitiveUnionMembers: false
responseFormat: envelope
sourceDirectory: ""
useNodatime: true
152 changes: 110 additions & 42 deletions sync-for-payables/Codat/Sync/Payables/BankAccounts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,86 @@ namespace Codat.Sync.Payables
using Codat.Sync.Payables.Models.Components;
using Codat.Sync.Payables.Models.Errors;
using Codat.Sync.Payables.Models.Requests;
using Codat.Sync.Payables.Utils.Retries;
using Codat.Sync.Payables.Utils;
using Codat.Sync.Payables.Utils.Retries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System;

/// <summary>
/// Create a bank account for a given company&apos;s connection.
/// Create a bank account for a given company's connection.
/// </summary>
public interface IBankAccounts
{

/// <summary>
/// Create bank account
///
/// Create bank account.
/// </summary>
/// <remarks>
/// The *Create bank account* endpoint creates a new <a href="https://docs.codat.io/sync-for-payables-api#/schemas/BankAccount">bank account</a> for a given company&apos;s connection.<br/>
/// The *Create bank account* endpoint creates a new <a href="https://docs.codat.io/sync-for-payables-api#/schemas/BankAccount">bank account</a> for a given company's connection.<br/>
/// <br/>
/// <a href="https://docs.codat.io/sync-for-payables-api#/schemas/BankAccount">Bank accounts</a> are financial accounts maintained by a bank or other financial institution.
/// </remarks>
/// </summary>
Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountRequest request, RetryConfig? retryConfig = null);
/// <param name="request">A <see cref="CreateBankAccountRequest"/> parameter.</param>
/// <param name="retryConfig">The retry configuration to use for this operation.</param>
/// <returns>An awaitable task that returns a <see cref="CreateBankAccountResponse"/> response envelope when completed.</returns>
/// <exception cref="ArgumentNullException">The required parameter <paramref name="request"/> is null.</exception>
/// <exception cref="HttpRequestException">The HTTP request failed due to network issues.</exception>
/// <exception cref="ResponseValidationException">The response body could not be deserialized.</exception>
/// <exception cref="ErrorMessage">The request made is not valid. Thrown when the API returns a 400, 401, 402, 403, 404, 429, 500 or 503 response.</exception>
/// <exception cref="SDKException">Default API Exception. Thrown when the API returns a 4XX or 5XX response.</exception>
public Task<CreateBankAccountResponse> CreateAsync(
CreateBankAccountRequest request,
RetryConfig? retryConfig = null
);
}

/// <summary>
/// Create a bank account for a given company&apos;s connection.
/// Create a bank account for a given company's connection.
/// </summary>
public class BankAccounts: IBankAccounts
{
/// <summary>
/// SDK Configuration.
/// <see cref="SDKConfig"/>
/// </summary>
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "10.0.0";
private const string _sdkGenVersion = "2.463.0";
private const string _openapiDocVersion = "3.0.0";
private const string _userAgent = "speakeasy-sdk/csharp 10.0.0 2.463.0 3.0.0 Codat.Sync.Payables";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<Codat.Sync.Payables.Models.Components.Security>? _securitySource;

public BankAccounts(ISpeakeasyHttpClient client, Func<Codat.Sync.Payables.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)

public BankAccounts(SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}

public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountRequest request, RetryConfig? retryConfig = null)
/// <summary>
/// Create bank account.
/// </summary>
/// <remarks>
/// The *Create bank account* endpoint creates a new <a href="https://docs.codat.io/sync-for-payables-api#/schemas/BankAccount">bank account</a> for a given company's connection.<br/>
/// <br/>
/// <a href="https://docs.codat.io/sync-for-payables-api#/schemas/BankAccount">Bank accounts</a> are financial accounts maintained by a bank or other financial institution.
/// </remarks>
/// <param name="request">A <see cref="CreateBankAccountRequest"/> parameter.</param>
/// <param name="retryConfig">The retry configuration to use for this operation.</param>
/// <returns>An awaitable task that returns a <see cref="CreateBankAccountResponse"/> response envelope when completed.</returns>
/// <exception cref="ArgumentNullException">The required parameter <paramref name="request"/> is null.</exception>
/// <exception cref="HttpRequestException">The HTTP request failed due to network issues.</exception>
/// <exception cref="ResponseValidationException">The response body could not be deserialized.</exception>
/// <exception cref="ErrorMessage">The request made is not valid. Thrown when the API returns a 400, 401, 402, 403, 404, 429, 500 or 503 response.</exception>
/// <exception cref="SDKException">Default API Exception. Thrown when the API returns a 4XX or 5XX response.</exception>
public async Task<CreateBankAccountResponse> CreateAsync(
CreateBankAccountRequest request,
RetryConfig? retryConfig = null
)
{
if (request == null) throw new ArgumentNullException(nameof(request));

string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/companies/{companyId}/connections/{connectionId}/payables/bankAccounts", request);
var urlString = URLBuilder.Build(baseUrl, "/companies/{companyId}/connections/{connectionId}/payables/bankAccounts", request, null);

var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);

var serializedBody = RequestBodySerializer.Serialize(request, "BankAccountPrototype", "json", false, true);
Expand All @@ -78,12 +101,12 @@ public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountReques
httpRequest.Content = serializedBody;
}

if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}

var hookCtx = new HookContext("create-bank-account", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "create-bank-account", null, SDKConfiguration.SecuritySource);

httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
if (retryConfig == null)
Expand Down Expand Up @@ -117,8 +140,8 @@ public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountReques

Func<Task<HttpResponseMessage>> retrySend = async () =>
{
var _httpRequest = await _client.CloneAsync(httpRequest);
return await _client.SendAsync(_httpRequest);
var _httpRequest = await SDKConfiguration.Client.CloneAsync(httpRequest);
return await SDKConfiguration.Client.SendAsync(_httpRequest);
};
var retries = new Codat.Sync.Payables.Utils.Retries.Retries(retrySend, retryConfig, statusCodes);

Expand All @@ -128,7 +151,7 @@ public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountReques
httpResponse = await retries.Run();
int _statusCode = (int)httpResponse.StatusCode;

if (_statusCode == 400 || _statusCode == 401 || _statusCode == 402 || _statusCode == 403 || _statusCode == 404 || _statusCode == 429 || _statusCode >= 400 && _statusCode < 500 || _statusCode == 500 || _statusCode == 503 || _statusCode >= 500 && _statusCode < 600)
if (_statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
Expand Down Expand Up @@ -158,7 +181,17 @@ public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountReques
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<BankAccount>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
BankAccount obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<BankAccount>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into BankAccount.", httpResponse, httpResponseBody, ex);
}

var response = new CreateBankAccountResponse()
{
StatusCode = responseStatusCode,
Expand All @@ -169,24 +202,59 @@ public async Task<CreateBankAccountResponse> CreateAsync(CreateBankAccountReques
return response;
}

throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(new List<int>{400, 401, 402, 403, 404, 429, 500, 503}.Contains(responseStatusCode))
else if(new List<int>{400, 401, 402, 403, 404, 429}.Contains(responseStatusCode))
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<ErrorMessage>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
throw obj!;
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
ErrorMessagePayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<ErrorMessagePayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into ErrorMessagePayload.", httpResponse, httpResponseBody, ex);
}

throw new ErrorMessage(payload, httpResponse, httpResponseBody);
}

throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
else if(new List<int>{500, 503}.Contains(responseStatusCode))
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
ErrorMessagePayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<ErrorMessagePayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into ErrorMessagePayload.", httpResponse, httpResponseBody, ex);
}

throw new ErrorMessage(payload, httpResponse, httpResponseBody);
}

throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}

throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}

}
}
Loading