diff --git a/Makefile b/Makefile
index 2bdb907a..17bb191d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
# Main config
OPENFGA_DOCKER_TAG = v1
-OPEN_API_REF ?= e53c69cc55317404d02a6d8e418d626268f28a59
+OPEN_API_REF ?= 0ac19aac54f21f3c78970126b84b4c69c6e3b9a2
OPEN_API_URL = https://raw.githubusercontent.com/openfga/api/${OPEN_API_REF}/docs/openapiv2/apidocs.swagger.json
-OPENAPI_GENERATOR_CLI_DOCKER_TAG ?= v6.4.0
+OPENAPI_GENERATOR_CLI_DOCKER_TAG ?= v7.15.0
NODE_DOCKER_TAG = 20-alpine
GO_DOCKER_TAG = 1
DOTNET_DOCKER_TAG = 9.0
diff --git a/config/clients/dotnet/config.overrides.json b/config/clients/dotnet/config.overrides.json
index 5bb78cb7..7aef7e5f 100644
--- a/config/clients/dotnet/config.overrides.json
+++ b/config/clients/dotnet/config.overrides.json
@@ -66,6 +66,10 @@
"destinationFilename": "src/OpenFga.Sdk/Client/Client.cs",
"templateType": "SupportingFiles"
},
+ "Client/IClient.mustache": {
+ "destinationFilename": "src/OpenFga.Sdk/Client/IClient.cs",
+ "templateType": "SupportingFiles"
+ },
"Client/ClientConfiguration.mustache": {
"destinationFilename": "src/OpenFga.Sdk/Client/ClientConfiguration.cs",
"templateType": "SupportingFiles"
diff --git a/config/clients/dotnet/template/Client/Client.mustache b/config/clients/dotnet/template/Client/Client.mustache
index 483d1632..d47b077e 100644
--- a/config/clients/dotnet/template/Client/Client.mustache
+++ b/config/clients/dotnet/template/Client/Client.mustache
@@ -19,7 +19,7 @@ using {{packageName}}.Model;
namespace {{packageName}}.Client;
-public class {{appShortName}}Client : IDisposable {
+public class {{appShortName}}Client : I{{appShortName}}Client, IDisposable {
private readonly ClientConfiguration _configuration;
protected {{appShortName}}Api api;
private string CLIENT_BULK_REQUEST_ID_HEADER = "{{clientBulkRequestIdHeader}}";
diff --git a/config/clients/dotnet/template/Client/IClient.mustache b/config/clients/dotnet/template/Client/IClient.mustache
new file mode 100644
index 00000000..fee1948f
--- /dev/null
+++ b/config/clients/dotnet/template/Client/IClient.mustache
@@ -0,0 +1,190 @@
+{{>partial_header}}
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+using {{packageName}}.Api;
+using {{packageName}}.ApiClient;
+using {{packageName}}.Client.Model;
+#if NETSTANDARD2_0 || NET48
+using {{packageName}}.Client.Extensions;
+#endif
+using {{packageName}}.Exceptions;
+using {{packageName}}.Model;
+
+namespace {{packageName}}.Client;
+
+public interface I{{appShortName}}Client {
+ ///
+ /// Store ID
+ ///
+ string? StoreId { get; set; }
+
+ ///
+ /// Authorization Model ID
+ ///
+ string? AuthorizationModelId { get; set; }
+
+ /**********
+ * Stores *
+ **********/
+
+ /**
+ * ListStores - Get a paginated list of stores.
+ */
+ Task ListStores(IClientListStoresRequest? body, IClientListStoresOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * CreateStore - Initialize a store
+ */
+ Task CreateStore(ClientCreateStoreRequest body,
+ IClientRequestOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * GetStore - Get information about the current store
+ */
+ Task GetStore(IClientRequestOptionsWithStoreId? options = default, CancellationToken cancellationToken = default);
+
+ /**
+ * DeleteStore - Delete a store
+ */
+ Task DeleteStore(IClientRequestOptionsWithStoreId? options = default, CancellationToken cancellationToken = default);
+
+ /************************
+ * Authorization Models *
+ ************************/
+
+ /**
+ * ReadAuthorizationModels - Read all authorization models
+ */
+ Task ReadAuthorizationModels(
+ IClientReadAuthorizationModelsOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * WriteAuthorizationModel - Create a new version of the authorization model
+ */
+ Task WriteAuthorizationModel(ClientWriteAuthorizationModelRequest body,
+ IClientRequestOptionsWithStoreId? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * ReadAuthorizationModel - Read the current authorization model
+ */
+ Task ReadAuthorizationModel(
+ IClientReadAuthorizationModelOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * ReadLatestAuthorizationModel - Read the latest authorization model for the current store
+ */
+ Task ReadLatestAuthorizationModel(
+ IClientRequestOptionsWithAuthZModelId? options = default,
+ CancellationToken cancellationToken = default);
+
+ /***********************
+ * Relationship Tuples *
+ ***********************/
+
+ /**
+ * Read Changes - Read the list of historical relationship tuple writes and deletes
+ */
+ Task ReadChanges(ClientReadChangesRequest? body = default,
+ ClientReadChangesOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * Read - Read tuples previously written to the store (does not evaluate)
+ */
+ Task Read(ClientReadRequest? body = default, IClientReadOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * Write - Create or delete relationship tuples
+ */
+ Task Write(ClientWriteRequest body, IClientWriteOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * WriteTuples - Utility method to write tuples, wraps Write
+ */
+ Task WriteTuples(List body, IClientWriteOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * DeleteTuples - Utility method to delete tuples, wraps Write
+ */
+ Task DeleteTuples(List body, IClientWriteOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /************************
+ * Relationship Queries *
+ ************************/
+
+ /**
+ * Check - Check if a user has a particular relation with an object (evaluates)
+ */
+ Task Check(IClientCheckRequest body,
+ IClientCheckOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * BatchCheck - Run a set of checks (evaluates)
+ */
+ Task BatchCheck(List body,
+ IClientBatchCheckOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * Expand - Expands the relationships in userset tree format (evaluates)
+ */
+ Task Expand(IClientExpandRequest body,
+ IClientExpandOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * ListObjects - List the objects of a particular type that the user has a certain relation to (evaluates)
+ */
+ Task ListObjects(IClientListObjectsRequest body,
+ IClientListObjectsOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+
+ /**
+ * ListRelations - List all the relations a user has with an object (evaluates)
+ */
+ Task ListRelations(IClientListRelationsRequest body,
+ IClientListRelationsOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * ListUsers - List all users of the given type that the object has a relation with (evaluates)
+ */
+ Task ListUsers(IClientListUsersRequest body,
+ IClientListUsersOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**************
+ * Assertions *
+ **************/
+
+ /**
+ * ReadAssertions - Read assertions for a particular authorization model
+ */
+ Task ReadAssertions(IClientReadAssertionsOptions? options = default,
+ CancellationToken cancellationToken = default);
+
+ /**
+ * WriteAssertions - Updates assertions for a particular authorization model
+ */
+ Task WriteAssertions(List body,
+ IClientWriteAssertionsOptions? options = default,
+ CancellationToken cancellationToken = default);
+}
diff --git a/config/clients/dotnet/template/modelWriteRequestDeletes.mustache b/config/clients/dotnet/template/modelWriteRequestDeletes.mustache
new file mode 100644
index 00000000..e1ca2de6
--- /dev/null
+++ b/config/clients/dotnet/template/modelWriteRequestDeletes.mustache
@@ -0,0 +1,338 @@
+{{>partial_header}}
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+{{#validatable}}
+using System.ComponentModel.DataAnnotations;
+{{/validatable}}
+using System.Runtime.Serialization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+
+namespace {{packageName}}.{{modelPackage}}
+{
+{{#models}}
+{{#model}}
+ ///
+ /// {{description}}{{^description}}{{classname}}{{/description}}
+ ///
+ [DataContract(Name = "{{{name}}}")]
+ {{#discriminator}}
+ [JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")]
+ {{#mappedModels}}
+ [JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{{mappingName}}}")]
+ {{/mappedModels}}
+ {{/discriminator}}
+ public {{#isEnum}}{{^isArray}}{{>visibility}}{{/isArray}}{{/isEnum}}{{^isEnum}}partial {{/isEnum}}class {{{classname}}}{{#parent}} : {{{.}}}{{/parent}}{{^parent}} : IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}{{/parent}}
+ {
+ ///
+ /// Defines OnMissing behavior
+ ///
+ public enum OnMissingEnum
+ {
+ ///
+ /// Enum Error for value: error
+ ///
+ [EnumMember(Value = "error")]
+ Error = 1,
+
+ ///
+ /// Enum Ignore for value: ignore
+ ///
+ [EnumMember(Value = "ignore")]
+ Ignore = 2
+ }
+
+{{#vars}}
+{{#isEnum}}
+{{#allowableValues}}
+ ///
+ /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
+ ///
+{{#description}}
+ /// {{.}}
+{{/description}}
+{{#isContainer}}
+ [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]
+{{/isContainer}}
+ public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; }
+{{^isContainer}}
+{{>modelInnerEnum}}
+{{/isContainer}}
+{{/allowableValues}}
+{{/isEnum}}
+{{/vars}}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [JsonConstructor]
+ public {{{classname}}}()
+ {
+ {{#vars}}
+ {{#defaultValue}}
+ {{^isReadOnly}}
+ {{^isContainer}}
+ this.{{name}} = {{{defaultValue}}};
+ {{/isContainer}}
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ {{/vars}}
+ this.AdditionalProperties = new Dictionary();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+{{#vars}}
+{{^isReadOnly}}
+ /// {{#description}}{{.}}{{/description}}{{^description}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{/description}}{{^required}} (default to {{defaultValue}}){{/required}}{{#isDeprecated}} (deprecated){{/isDeprecated}}.
+{{/isReadOnly}}
+{{/vars}}
+ public {{{classname}}}({{#readWriteVars}}{{{dataType}}} {{#lambda.camelcase_param}}{{{name}}}{{/lambda.camelcase_param}} = default{{^-last}}, {{/-last}}{{/readWriteVars}})
+ {
+{{#vars}}
+{{#required}}
+ {{^defaultValue}}
+ {{^isReadOnly}}
+ {{^isNullable}}
+ // to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
+ if ({{#lambda.camelcase_param}}{{{name}}}{{/lambda.camelcase_param}} == null)
+ {
+ throw new ArgumentNullException("{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} is a required property for {{classname}} and cannot be null");
+ }
+ {{/isNullable}}
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
+{{/required}}
+{{/vars}}
+{{#vars}}
+{{^required}}
+ {{#defaultValue}}
+ {{^isReadOnly}}
+ // use default value if no "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" provided
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} ?? {{{defaultValue}}};
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ {{^defaultValue}}
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
+ {{/defaultValue}}
+{{/required}}
+{{/vars}}
+ this.AdditionalProperties = new Dictionary();
+ }
+
+{{#vars}}
+ ///
+ /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
+ /// {{#description}}
+ /// {{.}}{{/description}}
+{{^isEnum}}
+ [DataMember(Name = "{{baseName}}", {{#required}}IsRequired = true, {{/required}}EmitDefaultValue = {{emitDefaultValue}})]
+{{/isEnum}}
+{{#deprecated}}
+ [Obsolete]
+{{/deprecated}}
+{{#minimum}}
+{{#maximum}}
+ [Range({{minimum}}, {{maximum}})]
+{{/maximum}}
+{{/minimum}}
+{{#minLength}}
+{{#maxLength}}
+ [StringLength({{maxLength}}, MinimumLength={{minLength}})]
+{{/maxLength}}
+{{^maxLength}}
+ [MinLength({{.}})]
+{{/maxLength}}
+{{/minLength}}
+{{^minLength}}
+{{#maxLength}}
+ [MaxLength({{.}})]
+{{/maxLength}}
+{{/minLength}}
+{{#pattern}}
+ [RegularExpression("{{.}}")]
+{{/pattern}}
+ [JsonPropertyName("{{baseName}}")]
+{{#isNullable}}
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
+{{/isNullable}}
+ public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
+
+{{/vars}}
+ ///
+ /// Gets or Sets additional properties
+ ///
+ [JsonExtensionData]
+ public IDictionary AdditionalProperties { get; set; }
+
+{{#vendorExtensions.x-serialization-methods}}
+
+ ///
+ /// Returns the JSON string presentation of the object
+ ///
+ /// JSON string presentation of the object
+ public virtual string ToJson()
+ {
+ return JsonSerializer.Serialize(this);
+ }
+
+ ///
+ /// Builds a {{classname}} from the JSON string presentation of the object
+ ///
+ /// {{classname}}
+ public static {{classname}} FromJson(string jsonString) {
+ return JsonSerializer.Deserialize<{{classname}}>(jsonString) ?? throw new InvalidOperationException();
+ }
+
+{{/vendorExtensions.x-serialization-methods}}
+{{^isEnum}}
+{{^parent}}
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object input)
+ {
+ {{#useCompareNetObjects}}
+ return OpenAPIClientUtils.compareLogic.Compare(this, input as {{classname}}).AreEqual;
+ {{/useCompareNetObjects}}
+ {{^useCompareNetObjects}}
+ return this.Equals(input as {{classname}});
+ {{/useCompareNetObjects}}
+ }
+
+ ///
+ /// Returns true if {{classname}} instances are equal
+ ///
+ /// Instance of {{classname}} to be compared
+ /// Boolean
+ public bool Equals({{classname}} input)
+ {
+ {{#useCompareNetObjects}}
+ return OpenAPIClientUtils.compareLogic.Compare(this, input).AreEqual;
+ {{/useCompareNetObjects}}
+ {{^useCompareNetObjects}}
+ if (input == null)
+ {
+ return false;
+ }
+ return {{#vars}}{{#parent}}base.Equals(input) && {{/parent}}{{^isContainer}}
+ (
+ this.{{name}} == input.{{name}} ||
+ {{^vendorExtensions.x-is-value-type}}
+ {{#required}}
+ {{^isNullable}}
+ this.{{name}} != null &&
+ {{/isNullable}}
+ {{/required}}
+ {{^required}}
+ (this.{{name}} != null &&
+ {{/required}}
+ {{/vendorExtensions.x-is-value-type}}
+ this.{{name}}.Equals(input.{{name}}){{^vendorExtensions.x-is-value-type}}){{/vendorExtensions.x-is-value-type}}
+ ){{^-last}} && {{/-last}}{{/isContainer}}{{#isContainer}}
+ (
+ this.{{name}} == input.{{name}} ||
+ {{^vendorExtensions.x-is-value-type}}
+ this.{{name}} != null &&
+ input.{{name}} != null &&
+ {{/vendorExtensions.x-is-value-type}}
+ this.{{name}}.SequenceEqual(input.{{name}})
+ ){{^-last}} && {{/-last}}{{/isContainer}}{{/vars}}
+ && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && this.AdditionalProperties.All(kv => input.AdditionalProperties.ContainsKey(kv.Key) && Equals(kv.Value, input.AdditionalProperties[kv.Key])));
+ {{/useCompareNetObjects}}
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = {{hashCodeBasePrimeNumber}};
+{{#vars}}
+ if (this.{{name}} != null)
+ {
+ hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + this.{{name}}.GetHashCode();
+ }
+{{/vars}}
+ if (this.AdditionalProperties != null)
+ {
+ hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + this.AdditionalProperties.GetHashCode();
+ }
+ return hashCode;
+ }
+ }
+
+{{/parent}}
+{{/isEnum}}
+{{#validatable}}
+{{^parent}}
+ ///
+ /// To validate all properties of the instance
+ ///
+ /// Validation context
+ /// Validation Result
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+{{#vars}}
+{{#hasValidation}}
+{{#maxLength}}
+ // {{{name}}} ({{{dataType}}}) maxLength
+ if (this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be less than {{maxLength}}.", new [] { "{{{name}}}" });
+ }
+
+{{/maxLength}}
+{{#minLength}}
+ // {{{name}}} ({{{dataType}}}) minLength
+ if (this.{{{name}}} != null && this.{{{name}}}.Length < {{minLength}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be greater than {{minLength}}.", new [] { "{{{name}}}" });
+ }
+
+{{/minLength}}
+{{#maximum}}
+ // {{{name}}} ({{{dataType}}}) maximum
+ if (this.{{{name}}} > ({{{dataType}}}){{maximum}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value less than or equal to {{maximum}}.", new [] { "{{{name}}}" });
+ }
+
+{{/maximum}}
+{{#minimum}}
+ // {{{name}}} ({{{dataType}}}) minimum
+ if (this.{{{name}}} < ({{{dataType}}}){{minimum}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value greater than or equal to {{minimum}}.", new [] { "{{{name}}}" });
+ }
+
+{{/minimum}}
+{{#pattern}}
+ // {{{name}}} ({{{dataType}}}) pattern
+ Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
+ if (false == regex{{{name}}}.Match(this.{{{name}}}).Success)
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" });
+ }
+
+{{/pattern}}
+{{/hasValidation}}
+{{/vars}}
+ yield break;
+ }
+{{/parent}}
+{{/validatable}}
+ }
+{{/model}}
+{{/models}}
+}
diff --git a/config/clients/dotnet/template/modelWriteRequestWrites.mustache b/config/clients/dotnet/template/modelWriteRequestWrites.mustache
new file mode 100644
index 00000000..5bc5d657
--- /dev/null
+++ b/config/clients/dotnet/template/modelWriteRequestWrites.mustache
@@ -0,0 +1,338 @@
+{{>partial_header}}
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+{{#validatable}}
+using System.ComponentModel.DataAnnotations;
+{{/validatable}}
+using System.Runtime.Serialization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+
+namespace {{packageName}}.{{modelPackage}}
+{
+{{#models}}
+{{#model}}
+ ///
+ /// {{description}}{{^description}}{{classname}}{{/description}}
+ ///
+ [DataContract(Name = "{{{name}}}")]
+ {{#discriminator}}
+ [JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")]
+ {{#mappedModels}}
+ [JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{{mappingName}}}")]
+ {{/mappedModels}}
+ {{/discriminator}}
+ public {{#isEnum}}{{^isArray}}{{>visibility}}{{/isArray}}{{/isEnum}}{{^isEnum}}partial {{/isEnum}}class {{{classname}}}{{#parent}} : {{{.}}}{{/parent}}{{^parent}} : IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}{{/parent}}
+ {
+ ///
+ /// Defines OnDuplicate behavior
+ ///
+ public enum OnDuplicateEnum
+ {
+ ///
+ /// Enum Error for value: error
+ ///
+ [EnumMember(Value = "error")]
+ Error = 1,
+
+ ///
+ /// Enum Ignore for value: ignore
+ ///
+ [EnumMember(Value = "ignore")]
+ Ignore = 2
+ }
+
+{{#vars}}
+{{#isEnum}}
+{{#allowableValues}}
+ ///
+ /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
+ ///
+{{#description}}
+ /// {{.}}
+{{/description}}
+{{#isContainer}}
+ [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]
+{{/isContainer}}
+ public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; }
+{{^isContainer}}
+{{>modelInnerEnum}}
+{{/isContainer}}
+{{/allowableValues}}
+{{/isEnum}}
+{{/vars}}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [JsonConstructor]
+ public {{{classname}}}()
+ {
+ {{#vars}}
+ {{#defaultValue}}
+ {{^isReadOnly}}
+ {{^isContainer}}
+ this.{{name}} = {{{defaultValue}}};
+ {{/isContainer}}
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ {{/vars}}
+ this.AdditionalProperties = new Dictionary();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+{{#vars}}
+{{^isReadOnly}}
+ /// {{#description}}{{.}}{{/description}}{{^description}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{/description}}{{^required}} (default to {{defaultValue}}){{/required}}{{#isDeprecated}} (deprecated){{/isDeprecated}}.
+{{/isReadOnly}}
+{{/vars}}
+ public {{{classname}}}({{#readWriteVars}}{{{dataType}}} {{#lambda.camelcase_param}}{{{name}}}{{/lambda.camelcase_param}} = default{{^-last}}, {{/-last}}{{/readWriteVars}})
+ {
+{{#vars}}
+{{#required}}
+ {{^defaultValue}}
+ {{^isReadOnly}}
+ {{^isNullable}}
+ // to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
+ if ({{#lambda.camelcase_param}}{{{name}}}{{/lambda.camelcase_param}} == null)
+ {
+ throw new ArgumentNullException("{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} is a required property for {{classname}} and cannot be null");
+ }
+ {{/isNullable}}
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
+{{/required}}
+{{/vars}}
+{{#vars}}
+{{^required}}
+ {{#defaultValue}}
+ {{^isReadOnly}}
+ // use default value if no "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" provided
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} ?? {{{defaultValue}}};
+ {{/isReadOnly}}
+ {{/defaultValue}}
+ {{^defaultValue}}
+ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
+ {{/defaultValue}}
+{{/required}}
+{{/vars}}
+ this.AdditionalProperties = new Dictionary();
+ }
+
+{{#vars}}
+ ///
+ /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
+ /// {{#description}}
+ /// {{.}}{{/description}}
+{{^isEnum}}
+ [DataMember(Name = "{{baseName}}", {{#required}}IsRequired = true, {{/required}}EmitDefaultValue = {{emitDefaultValue}})]
+{{/isEnum}}
+{{#deprecated}}
+ [Obsolete]
+{{/deprecated}}
+{{#minimum}}
+{{#maximum}}
+ [Range({{minimum}}, {{maximum}})]
+{{/maximum}}
+{{/minimum}}
+{{#minLength}}
+{{#maxLength}}
+ [StringLength({{maxLength}}, MinimumLength={{minLength}})]
+{{/maxLength}}
+{{^maxLength}}
+ [MinLength({{.}})]
+{{/maxLength}}
+{{/minLength}}
+{{^minLength}}
+{{#maxLength}}
+ [MaxLength({{.}})]
+{{/maxLength}}
+{{/minLength}}
+{{#pattern}}
+ [RegularExpression("{{.}}")]
+{{/pattern}}
+ [JsonPropertyName("{{baseName}}")]
+{{#isNullable}}
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
+{{/isNullable}}
+ public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
+
+{{/vars}}
+ ///
+ /// Gets or Sets additional properties
+ ///
+ [JsonExtensionData]
+ public IDictionary AdditionalProperties { get; set; }
+
+{{#vendorExtensions.x-serialization-methods}}
+
+ ///
+ /// Returns the JSON string presentation of the object
+ ///
+ /// JSON string presentation of the object
+ public virtual string ToJson()
+ {
+ return JsonSerializer.Serialize(this);
+ }
+
+ ///
+ /// Builds a {{classname}} from the JSON string presentation of the object
+ ///
+ /// {{classname}}
+ public static {{classname}} FromJson(string jsonString) {
+ return JsonSerializer.Deserialize<{{classname}}>(jsonString) ?? throw new InvalidOperationException();
+ }
+
+{{/vendorExtensions.x-serialization-methods}}
+{{^isEnum}}
+{{^parent}}
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object input)
+ {
+ {{#useCompareNetObjects}}
+ return OpenAPIClientUtils.compareLogic.Compare(this, input as {{classname}}).AreEqual;
+ {{/useCompareNetObjects}}
+ {{^useCompareNetObjects}}
+ return this.Equals(input as {{classname}});
+ {{/useCompareNetObjects}}
+ }
+
+ ///
+ /// Returns true if {{classname}} instances are equal
+ ///
+ /// Instance of {{classname}} to be compared
+ /// Boolean
+ public bool Equals({{classname}} input)
+ {
+ {{#useCompareNetObjects}}
+ return OpenAPIClientUtils.compareLogic.Compare(this, input).AreEqual;
+ {{/useCompareNetObjects}}
+ {{^useCompareNetObjects}}
+ if (input == null)
+ {
+ return false;
+ }
+ return {{#vars}}{{#parent}}base.Equals(input) && {{/parent}}{{^isContainer}}
+ (
+ this.{{name}} == input.{{name}} ||
+ {{^vendorExtensions.x-is-value-type}}
+ {{#required}}
+ {{^isNullable}}
+ this.{{name}} != null &&
+ {{/isNullable}}
+ {{/required}}
+ {{^required}}
+ (this.{{name}} != null &&
+ {{/required}}
+ {{/vendorExtensions.x-is-value-type}}
+ this.{{name}}.Equals(input.{{name}}){{^vendorExtensions.x-is-value-type}}){{/vendorExtensions.x-is-value-type}}
+ ){{^-last}} && {{/-last}}{{/isContainer}}{{#isContainer}}
+ (
+ this.{{name}} == input.{{name}} ||
+ {{^vendorExtensions.x-is-value-type}}
+ this.{{name}} != null &&
+ input.{{name}} != null &&
+ {{/vendorExtensions.x-is-value-type}}
+ this.{{name}}.SequenceEqual(input.{{name}})
+ ){{^-last}} && {{/-last}}{{/isContainer}}{{/vars}}
+ && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && this.AdditionalProperties.All(kv => input.AdditionalProperties.ContainsKey(kv.Key) && Equals(kv.Value, input.AdditionalProperties[kv.Key])));
+ {{/useCompareNetObjects}}
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = {{hashCodeBasePrimeNumber}};
+{{#vars}}
+ if (this.{{name}} != null)
+ {
+ hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + this.{{name}}.GetHashCode();
+ }
+{{/vars}}
+ if (this.AdditionalProperties != null)
+ {
+ hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + this.AdditionalProperties.GetHashCode();
+ }
+ return hashCode;
+ }
+ }
+
+{{/parent}}
+{{/isEnum}}
+{{#validatable}}
+{{^parent}}
+ ///
+ /// To validate all properties of the instance
+ ///
+ /// Validation context
+ /// Validation Result
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+{{#vars}}
+{{#hasValidation}}
+{{#maxLength}}
+ // {{{name}}} ({{{dataType}}}) maxLength
+ if (this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be less than {{maxLength}}.", new [] { "{{{name}}}" });
+ }
+
+{{/maxLength}}
+{{#minLength}}
+ // {{{name}}} ({{{dataType}}}) minLength
+ if (this.{{{name}}} != null && this.{{{name}}}.Length < {{minLength}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be greater than {{minLength}}.", new [] { "{{{name}}}" });
+ }
+
+{{/minLength}}
+{{#maximum}}
+ // {{{name}}} ({{{dataType}}}) maximum
+ if (this.{{{name}}} > ({{{dataType}}}){{maximum}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value less than or equal to {{maximum}}.", new [] { "{{{name}}}" });
+ }
+
+{{/maximum}}
+{{#minimum}}
+ // {{{name}}} ({{{dataType}}}) minimum
+ if (this.{{{name}}} < ({{{dataType}}}){{minimum}})
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value greater than or equal to {{minimum}}.", new [] { "{{{name}}}" });
+ }
+
+{{/minimum}}
+{{#pattern}}
+ // {{{name}}} ({{{dataType}}}) pattern
+ Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
+ if (false == regex{{{name}}}.Match(this.{{{name}}}).Success)
+ {
+ yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" });
+ }
+
+{{/pattern}}
+{{/hasValidation}}
+{{/vars}}
+ yield break;
+ }
+{{/parent}}
+{{/validatable}}
+ }
+{{/model}}
+{{/models}}
+}