diff --git a/.github/.cache_version b/.github/.cache_version
index f8f3c08725..140333f6da 100644
--- a/.github/.cache_version
+++ b/.github/.cache_version
@@ -1 +1 @@
-1.0.18
+1.0.19
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestriction.cs b/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestriction.cs
deleted file mode 100644
index bae4306070..0000000000
--- a/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestriction.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-using Algolia.Search.Models.Search;
-
-namespace Algolia.Search.Models.Common;
-
-public partial class SecuredApiKeyRestriction
-{
- ///
- /// Search query parameters
- ///
- public IndexSettingsAsSearchParams Query { get; set; }
-
- ///
- /// A Unix timestamp used to define the expiration date of the API key.
- ///
- [JsonPropertyName("validUntil")]
- public long? ValidUntil { get; set; }
-
- ///
- /// List of index names that can be queried.
- ///
- [JsonPropertyName("restrictIndices")]
- public List RestrictIndices { get; set; }
-
- ///
- /// IPv4 network allowed to use the generated key. This is used for more protection against API key leaking and reuse.
- ///
- [JsonPropertyName("restrictSources")]
- public List RestrictSources { get; set; }
-
- ///
- /// Specify a user identifier. This is often used with rate limits.
- ///
- [JsonPropertyName("userToken")]
- public string UserToken { get; set; }
-
-}
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestrictionHelper.cs b/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestrictionHelper.cs
index 347d1415c0..272fb54710 100644
--- a/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestrictionHelper.cs
+++ b/clients/algoliasearch-client-csharp/algoliasearch/Models/Common/SecuredApiKeyRestrictionHelper.cs
@@ -4,12 +4,12 @@
using Algolia.Search.Http;
using Algolia.Search.Utils;
-namespace Algolia.Search.Models.Common;
+namespace Algolia.Search.Models.Search;
///
/// Secured Api Key restrictions
///
-public partial class SecuredApiKeyRestriction
+public partial class SecuredAPIKeyRestrictions
{
///
@@ -19,12 +19,12 @@ public partial class SecuredApiKeyRestriction
public string ToQueryString()
{
string restrictionQuery = null;
- if (Query != null)
+ if (SearchParams != null)
{
- restrictionQuery = ToQueryString(Query);
+ restrictionQuery = ToQueryString(SearchParams);
}
- var restrictions = ToQueryString(this, nameof(Query));
+ var restrictions = ToQueryString(this, nameof(SearchParams));
var array = new[] { restrictionQuery, restrictions };
return string.Join("&", array.Where(s => !string.IsNullOrEmpty(s)));
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/ApiKeyOperation.cs b/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/ApiKeyOperation.cs
new file mode 100644
index 0000000000..b483d23098
--- /dev/null
+++ b/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/ApiKeyOperation.cs
@@ -0,0 +1,37 @@
+//
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+//
+using System;
+using System.Text;
+using System.Linq;
+using System.Text.Json.Serialization;
+using System.Collections.Generic;
+using Algolia.Search.Serializer;
+using System.Text.Json;
+
+namespace Algolia.Search.Models.Search;
+
+///
+/// Defines apiKeyOperation
+///
+public enum ApiKeyOperation
+{
+ ///
+ /// Enum Add for value: add
+ ///
+ [JsonPropertyName("add")]
+ Add = 1,
+
+ ///
+ /// Enum Delete for value: delete
+ ///
+ [JsonPropertyName("delete")]
+ Delete = 2,
+
+ ///
+ /// Enum Update for value: update
+ ///
+ [JsonPropertyName("update")]
+ Update = 3
+}
+
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/SecuredAPIKeyRestrictions.cs b/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/SecuredAPIKeyRestrictions.cs
new file mode 100644
index 0000000000..b07ee144e0
--- /dev/null
+++ b/clients/algoliasearch-client-csharp/algoliasearch/Models/Search/SecuredAPIKeyRestrictions.cs
@@ -0,0 +1,150 @@
+//
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+//
+using System;
+using System.Text;
+using System.Linq;
+using System.Text.Json.Serialization;
+using System.Collections.Generic;
+using Algolia.Search.Serializer;
+using System.Text.Json;
+
+namespace Algolia.Search.Models.Search;
+
+///
+/// SecuredAPIKeyRestrictions
+///
+public partial class SecuredAPIKeyRestrictions
+{
+ ///
+ /// Initializes a new instance of the SecuredAPIKeyRestrictions class.
+ ///
+ public SecuredAPIKeyRestrictions()
+ {
+ }
+
+ ///
+ /// Gets or Sets SearchParams
+ ///
+ [JsonPropertyName("searchParams")]
+ public SearchParamsObject SearchParams { get; set; }
+
+ ///
+ /// Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ ///
+ /// Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ [JsonPropertyName("filters")]
+ public string Filters { get; set; }
+
+ ///
+ /// Unix timestamp used to set the expiration date of the API key.
+ ///
+ /// Unix timestamp used to set the expiration date of the API key.
+ [JsonPropertyName("validUntil")]
+ public decimal? ValidUntil { get; set; }
+
+ ///
+ /// Index names that can be queried.
+ ///
+ /// Index names that can be queried.
+ [JsonPropertyName("restrictIndices")]
+ public List RestrictIndices { get; set; }
+
+ ///
+ /// IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ ///
+ /// IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ [JsonPropertyName("restrictSources")]
+ public string RestrictSources { get; set; }
+
+ ///
+ /// Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ ///
+ /// Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ [JsonPropertyName("userToken")]
+ public string UserToken { get; set; }
+
+ ///
+ /// Returns the string presentation of the object
+ ///
+ /// String presentation of the object
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("class SecuredAPIKeyRestrictions {\n");
+ sb.Append(" SearchParams: ").Append(SearchParams).Append("\n");
+ sb.Append(" Filters: ").Append(Filters).Append("\n");
+ sb.Append(" ValidUntil: ").Append(ValidUntil).Append("\n");
+ sb.Append(" RestrictIndices: ").Append(RestrictIndices).Append("\n");
+ sb.Append(" RestrictSources: ").Append(RestrictSources).Append("\n");
+ sb.Append(" UserToken: ").Append(UserToken).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+
+ ///
+ /// Returns the JSON string presentation of the object
+ ///
+ /// JSON string presentation of the object
+ public virtual string ToJson()
+ {
+ return JsonSerializer.Serialize(this, JsonConfig.Options);
+ }
+
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object obj)
+ {
+ if (obj is not SecuredAPIKeyRestrictions input)
+ {
+ return false;
+ }
+
+ return
+ (SearchParams == input.SearchParams || (SearchParams != null && SearchParams.Equals(input.SearchParams))) &&
+ (Filters == input.Filters || (Filters != null && Filters.Equals(input.Filters))) &&
+ (ValidUntil == input.ValidUntil || ValidUntil.Equals(input.ValidUntil)) &&
+ (RestrictIndices == input.RestrictIndices || RestrictIndices != null && input.RestrictIndices != null && RestrictIndices.SequenceEqual(input.RestrictIndices)) &&
+ (RestrictSources == input.RestrictSources || (RestrictSources != null && RestrictSources.Equals(input.RestrictSources))) &&
+ (UserToken == input.UserToken || (UserToken != null && UserToken.Equals(input.UserToken)));
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = 41;
+ if (SearchParams != null)
+ {
+ hashCode = (hashCode * 59) + SearchParams.GetHashCode();
+ }
+ if (Filters != null)
+ {
+ hashCode = (hashCode * 59) + Filters.GetHashCode();
+ }
+ hashCode = (hashCode * 59) + ValidUntil.GetHashCode();
+ if (RestrictIndices != null)
+ {
+ hashCode = (hashCode * 59) + RestrictIndices.GetHashCode();
+ }
+ if (RestrictSources != null)
+ {
+ hashCode = (hashCode * 59) + RestrictSources.GetHashCode();
+ }
+ if (UserToken != null)
+ {
+ hashCode = (hashCode * 59) + UserToken.GetHashCode();
+ }
+ return hashCode;
+ }
+ }
+
+}
+
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Utils/ApiKeyOperation.cs b/clients/algoliasearch-client-csharp/algoliasearch/Utils/ApiKeyOperation.cs
deleted file mode 100644
index 407d5bd4e5..0000000000
--- a/clients/algoliasearch-client-csharp/algoliasearch/Utils/ApiKeyOperation.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Algolia.Search.Utils;
-
-///
-/// ApiKey operations
-///
-public enum ApiKeyOperation
-{
- ///
- /// Add a new ApiKey
- ///
- Add,
- ///
- /// Delete an existing ApiKey
- ///
- Delete,
- ///
- /// Update an existing ApiKey
- ///
- Update,
-}
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Utils/ClientExtensions.cs b/clients/algoliasearch-client-csharp/algoliasearch/Utils/ClientExtensions.cs
index 8433a38175..b976f0060a 100644
--- a/clients/algoliasearch-client-csharp/algoliasearch/Utils/ClientExtensions.cs
+++ b/clients/algoliasearch-client-csharp/algoliasearch/Utils/ClientExtensions.cs
@@ -268,7 +268,7 @@ public static IEnumerable BrowseSynonyms(this SearchClient client, s
/// Restriction to add the key
///
public static string GenerateSecuredApiKey(this SearchClient client, string parentApiKey,
- SecuredApiKeyRestriction restriction)
+ SecuredAPIKeyRestrictions restriction)
{
var queryParams = restriction.ToQueryString();
var hash = HmacShaHelper.GetHash(parentApiKey, queryParams);
@@ -425,12 +425,15 @@ private static async Task RetryUntil(Func> func, Func val
///
///
/// The index in which to perform the request.
- /// The list of records to replace.
+ /// The list of `objects` to store in the given Algolia `indexName`.
+ /// The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.
/// Add extra http header or query parameters to Algolia.
/// Cancellation Token to cancel the request.
- public static List ReplaceAllObjects(this SearchClient client, string indexName,
- IEnumerable data, RequestOptions options = null, CancellationToken cancellationToken = default) where T : class
- => AsyncHelper.RunSync(() => client.ReplaceAllObjectsAsync(indexName, data, options, cancellationToken));
+ public static ReplaceAllObjectsResponse ReplaceAllObjects(this SearchClient client, string indexName,
+ IEnumerable objects, int batchSize = 1000, RequestOptions options = null,
+ CancellationToken cancellationToken = default) where T : class
+ => AsyncHelper.RunSync(() =>
+ client.ReplaceAllObjectsAsync(indexName, objects, batchSize, options, cancellationToken));
///
/// Push a new set of objects and remove all previous ones. Settings, synonyms and query rules are untouched.
@@ -439,15 +442,17 @@ public static List ReplaceAllObjects(this SearchClient client, string i
///
///
/// The index in which to perform the request.
- /// The list of records to replace.
+ /// The list of `objects` to store in the given Algolia `indexName`.
+ /// The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.
/// Add extra http header or query parameters to Algolia.
/// Cancellation Token to cancel the request.
- public static async Task> ReplaceAllObjectsAsync(this SearchClient client, string indexName,
- IEnumerable data, RequestOptions options = null, CancellationToken cancellationToken = default) where T : class
+ public static async Task ReplaceAllObjectsAsync(this SearchClient client,
+ string indexName, IEnumerable objects, int batchSize = 1000, RequestOptions options = null,
+ CancellationToken cancellationToken = default) where T : class
{
- if (data == null)
+ if (objects == null)
{
- throw new ArgumentNullException(nameof(data));
+ throw new ArgumentNullException(nameof(objects));
}
var rnd = new Random();
@@ -456,26 +461,84 @@ public static async Task> ReplaceAllObjectsAsync(this SearchClient
// Copy settings, synonyms and query rules into the temporary index
var copyResponse = await client.OperationIndexAsync(indexName,
new OperationIndexParams(OperationType.Copy, tmpIndexName)
- { Scope = [ScopeType.Rules, ScopeType.Settings, ScopeType.Synonyms] }, options, cancellationToken)
+ { Scope = [ScopeType.Rules, ScopeType.Settings, ScopeType.Synonyms] }, options, cancellationToken)
.ConfigureAwait(false);
- await client.WaitForTaskAsync(indexName, copyResponse.TaskID, requestOptions: options, ct: cancellationToken).ConfigureAwait(false);
+ await client.WaitForTaskAsync(indexName, copyResponse.TaskID, requestOptions: options, ct: cancellationToken)
+ .ConfigureAwait(false);
// Add objects to the temporary index
- var batchResponse = await client.BatchAsync(tmpIndexName,
- new BatchWriteParams(data.Select(x => new BatchRequest(Action.AddObject, x)).ToList()),
+ var batchResponse = await client.ChunkedBatchAsync(tmpIndexName, objects, Action.AddObject, batchSize,
options, cancellationToken).ConfigureAwait(false);
- await client.WaitForTaskAsync(tmpIndexName, batchResponse.TaskID, requestOptions: options, ct: cancellationToken).ConfigureAwait(false);
-
// Move the temporary index to the main one
var moveResponse = await client.OperationIndexAsync(tmpIndexName,
new OperationIndexParams(OperationType.Move, indexName), options, cancellationToken)
.ConfigureAwait(false);
- await client.WaitForTaskAsync(tmpIndexName, moveResponse.TaskID, requestOptions: options, ct: cancellationToken).ConfigureAwait(false);
+ await client.WaitForTaskAsync(tmpIndexName, moveResponse.TaskID, requestOptions: options, ct: cancellationToken)
+ .ConfigureAwait(false);
+
+ return new ReplaceAllObjectsResponse
+ {
+ CopyOperationResponse = copyResponse,
+ MoveOperationResponse = moveResponse,
+ BatchResponses = batchResponse
+ };
+ }
+
+ ///
+ /// Helper: Chunks the given `objects` list in subset of 1000 elements max in order to make it fit in `batch` requests. (Synchronous version)
+ ///
+ ///
+ /// The index in which to perform the request.
+ /// The list of `objects` to store in the given Algolia `indexName`.
+ /// The `batch` `action` to perform on the given array of `objects`, defaults to `addObject`.
+ /// The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.
+ /// Add extra http header or query parameters to Algolia.
+ /// Cancellation Token to cancel the request.
+ ///
+ public static List ChunkedBatch(this SearchClient client, string indexName,
+ IEnumerable objects, Action action = Action.AddObject, int batchSize = 1000, RequestOptions options = null,
+ CancellationToken cancellationToken = default) where T : class =>
+ AsyncHelper.RunSync(() =>
+ client.ChunkedBatchAsync(indexName, objects, action, batchSize, options, cancellationToken));
+
+ ///
+ /// Helper: Chunks the given `objects` list in subset of 1000 elements max in order to make it fit in `batch` requests.
+ ///
+ ///
+ /// The index in which to perform the request.
+ /// The list of `objects` to store in the given Algolia `indexName`.
+ /// The `batch` `action` to perform on the given array of `objects`, defaults to `addObject`.
+ /// The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.
+ /// Add extra http header or query parameters to Algolia.
+ /// Cancellation Token to cancel the request.
+ ///
+ public static async Task> ChunkedBatchAsync(this SearchClient client, string indexName,
+ IEnumerable objects, Action action = Action.AddObject, int batchSize = 1000, RequestOptions options = null,
+ CancellationToken cancellationToken = default) where T : class
+ {
+ var batchCount = (int)Math.Ceiling((double)objects.Count() / batchSize);
+ var responses = new List();
- return [copyResponse.TaskID, batchResponse.TaskID, moveResponse.TaskID];
+ for (var i = 0; i < batchCount; i++)
+ {
+ var chunk = objects.Skip(i * batchSize).Take(batchSize);
+ var batchResponse = await client.BatchAsync(indexName,
+ new BatchWriteParams(chunk.Select(x => new BatchRequest(action, x)).ToList()),
+ options, cancellationToken).ConfigureAwait(false);
+
+ responses.Add(batchResponse);
+ }
+
+ foreach (var batch in responses)
+ {
+ await client.WaitForTaskAsync(indexName, batch.TaskID, requestOptions: options, ct: cancellationToken)
+ .ConfigureAwait(false);
+ }
+
+ return responses;
}
private static int NextDelay(int retryCount)
diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Utils/ReplaceAllObjectsResponse.cs b/clients/algoliasearch-client-csharp/algoliasearch/Utils/ReplaceAllObjectsResponse.cs
new file mode 100644
index 0000000000..3d47233e95
--- /dev/null
+++ b/clients/algoliasearch-client-csharp/algoliasearch/Utils/ReplaceAllObjectsResponse.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using Algolia.Search.Models.Search;
+
+namespace Algolia.Search.Utils;
+
+///
+/// All responses from the ReplaceAllObjects calls.
+///
+public class ReplaceAllObjectsResponse
+{
+ ///
+ /// The response of the copy operation.
+ ///
+ public UpdatedAtResponse CopyOperationResponse { get; set; }
+
+ ///
+ /// The response of the batch operations.
+ ///
+ public List BatchResponses { get; set; }
+
+ ///
+ /// The response of the move operation.
+ ///
+ public UpdatedAtResponse MoveOperationResponse { get; set; }
+}
diff --git a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/algoliasearch_lite.dart b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/algoliasearch_lite.dart
index 7d7de87d3b..39ece0ff5a 100644
--- a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/algoliasearch_lite.dart
+++ b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/algoliasearch_lite.dart
@@ -12,6 +12,7 @@ export 'src/model/advanced_syntax_features.dart';
export 'src/model/alternatives_as_exact.dart';
export 'src/model/anchoring.dart';
export 'src/model/api_key.dart';
+export 'src/model/api_key_operation.dart';
export 'src/model/around_precision_from_value_inner.dart';
export 'src/model/around_radius_all.dart';
export 'src/model/automatic_facet_filter.dart';
@@ -87,6 +88,7 @@ export 'src/model/search_strategy.dart';
export 'src/model/search_synonyms_response.dart';
export 'src/model/search_type_default.dart';
export 'src/model/search_type_facet.dart';
+export 'src/model/secured_api_key_restrictions.dart';
export 'src/model/semantic_search.dart';
export 'src/model/snippet_result_option.dart';
export 'src/model/sort_remaining_by.dart';
diff --git a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/deserialize.dart b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/deserialize.dart
index 60830e1d22..495a6f6b9f 100644
--- a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/deserialize.dart
+++ b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/deserialize.dart
@@ -5,6 +5,7 @@ import 'package:algoliasearch/src/model/advanced_syntax_features.dart';
import 'package:algoliasearch/src/model/alternatives_as_exact.dart';
import 'package:algoliasearch/src/model/anchoring.dart';
import 'package:algoliasearch/src/model/api_key.dart';
+import 'package:algoliasearch/src/model/api_key_operation.dart';
import 'package:algoliasearch/src/model/around_precision_from_value_inner.dart';
import 'package:algoliasearch/src/model/around_radius_all.dart';
import 'package:algoliasearch/src/model/automatic_facet_filter.dart';
@@ -80,6 +81,7 @@ import 'package:algoliasearch/src/model/search_strategy.dart';
import 'package:algoliasearch/src/model/search_synonyms_response.dart';
import 'package:algoliasearch/src/model/search_type_default.dart';
import 'package:algoliasearch/src/model/search_type_facet.dart';
+import 'package:algoliasearch/src/model/secured_api_key_restrictions.dart';
import 'package:algoliasearch/src/model/semantic_search.dart';
import 'package:algoliasearch/src/model/snippet_result_option.dart';
import 'package:algoliasearch/src/model/sort_remaining_by.dart';
@@ -128,6 +130,8 @@ ReturnType deserialize(dynamic value, String targetType,
return Anchoring.fromJson(value) as ReturnType;
case 'ApiKey':
return ApiKey.fromJson(value as Map) as ReturnType;
+ case 'ApiKeyOperation':
+ return ApiKeyOperation.fromJson(value) as ReturnType;
case 'AroundPrecisionFromValueInner':
return AroundPrecisionFromValueInner.fromJson(
value as Map) as ReturnType;
@@ -319,6 +323,9 @@ ReturnType deserialize(dynamic value, String targetType,
return SearchTypeDefault.fromJson(value) as ReturnType;
case 'SearchTypeFacet':
return SearchTypeFacet.fromJson(value) as ReturnType;
+ case 'SecuredAPIKeyRestrictions':
+ return SecuredAPIKeyRestrictions.fromJson(value as Map)
+ as ReturnType;
case 'SemanticSearch':
return SemanticSearch.fromJson(value as Map)
as ReturnType;
diff --git a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/api_key_operation.dart b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/api_key_operation.dart
new file mode 100644
index 0000000000..fa0e583b2b
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/api_key_operation.dart
@@ -0,0 +1,25 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+// ignore_for_file: unused_element
+import 'package:json_annotation/json_annotation.dart';
+
+@JsonEnum(valueField: 'raw')
+enum ApiKeyOperation {
+ add(r'add'),
+ delete(r'delete'),
+ update(r'update');
+
+ const ApiKeyOperation(this.raw);
+ final dynamic raw;
+
+ dynamic toJson() => raw;
+
+ static ApiKeyOperation fromJson(dynamic json) {
+ for (final value in values) {
+ if (value.raw == json) return value;
+ }
+ throw ArgumentError.value(json, "raw", "No enum value with that value");
+ }
+
+ @override
+ String toString() => raw.toString();
+}
diff --git a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.dart b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.dart
new file mode 100644
index 0000000000..debc3fef2b
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.dart
@@ -0,0 +1,73 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+// ignore_for_file: unused_element
+import 'package:algoliasearch/src/model/search_params_object.dart';
+
+import 'package:json_annotation/json_annotation.dart';
+
+part 'secured_api_key_restrictions.g.dart';
+
+@JsonSerializable()
+final class SecuredAPIKeyRestrictions {
+ /// Returns a new [SecuredAPIKeyRestrictions] instance.
+ const SecuredAPIKeyRestrictions({
+ this.searchParams,
+ this.filters,
+ this.validUntil,
+ this.restrictIndices,
+ this.restrictSources,
+ this.userToken,
+ });
+
+ @JsonKey(name: r'searchParams')
+ final SearchParamsObject? searchParams;
+
+ /// Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ @JsonKey(name: r'filters')
+ final String? filters;
+
+ /// Unix timestamp used to set the expiration date of the API key.
+ @JsonKey(name: r'validUntil')
+ final num? validUntil;
+
+ /// Index names that can be queried.
+ @JsonKey(name: r'restrictIndices')
+ final List? restrictIndices;
+
+ /// IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ @JsonKey(name: r'restrictSources')
+ final String? restrictSources;
+
+ /// Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ @JsonKey(name: r'userToken')
+ final String? userToken;
+
+ @override
+ bool operator ==(Object other) =>
+ identical(this, other) ||
+ other is SecuredAPIKeyRestrictions &&
+ other.searchParams == searchParams &&
+ other.filters == filters &&
+ other.validUntil == validUntil &&
+ other.restrictIndices == restrictIndices &&
+ other.restrictSources == restrictSources &&
+ other.userToken == userToken;
+
+ @override
+ int get hashCode =>
+ searchParams.hashCode +
+ filters.hashCode +
+ validUntil.hashCode +
+ restrictIndices.hashCode +
+ restrictSources.hashCode +
+ userToken.hashCode;
+
+ factory SecuredAPIKeyRestrictions.fromJson(Map json) =>
+ _$SecuredAPIKeyRestrictionsFromJson(json);
+
+ Map toJson() => _$SecuredAPIKeyRestrictionsToJson(this);
+
+ @override
+ String toString() {
+ return toJson().toString();
+ }
+}
diff --git a/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.g.dart b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.g.dart
new file mode 100644
index 0000000000..2706ba068e
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/algoliasearch/lib/src/model/secured_api_key_restrictions.g.dart
@@ -0,0 +1,50 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'secured_api_key_restrictions.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+SecuredAPIKeyRestrictions _$SecuredAPIKeyRestrictionsFromJson(
+ Map json) =>
+ $checkedCreate(
+ 'SecuredAPIKeyRestrictions',
+ json,
+ ($checkedConvert) {
+ final val = SecuredAPIKeyRestrictions(
+ searchParams: $checkedConvert(
+ 'searchParams',
+ (v) => v == null
+ ? null
+ : SearchParamsObject.fromJson(v as Map)),
+ filters: $checkedConvert('filters', (v) => v as String?),
+ validUntil: $checkedConvert('validUntil', (v) => v as num?),
+ restrictIndices: $checkedConvert('restrictIndices',
+ (v) => (v as List?)?.map((e) => e as String).toList()),
+ restrictSources:
+ $checkedConvert('restrictSources', (v) => v as String?),
+ userToken: $checkedConvert('userToken', (v) => v as String?),
+ );
+ return val;
+ },
+ );
+
+Map _$SecuredAPIKeyRestrictionsToJson(
+ SecuredAPIKeyRestrictions instance) {
+ final val = {};
+
+ void writeNotNull(String key, dynamic value) {
+ if (value != null) {
+ val[key] = value;
+ }
+ }
+
+ writeNotNull('searchParams', instance.searchParams?.toJson());
+ writeNotNull('filters', instance.filters);
+ writeNotNull('validUntil', instance.validUntil);
+ writeNotNull('restrictIndices', instance.restrictIndices);
+ writeNotNull('restrictSources', instance.restrictSources);
+ writeNotNull('userToken', instance.userToken);
+ return val;
+}
diff --git a/clients/algoliasearch-client-dart/packages/client_search/lib/algolia_client_search.dart b/clients/algoliasearch-client-dart/packages/client_search/lib/algolia_client_search.dart
index 5166c86f6f..35422e2d9c 100644
--- a/clients/algoliasearch-client-dart/packages/client_search/lib/algolia_client_search.dart
+++ b/clients/algoliasearch-client-dart/packages/client_search/lib/algolia_client_search.dart
@@ -12,6 +12,7 @@ export 'src/model/advanced_syntax_features.dart';
export 'src/model/alternatives_as_exact.dart';
export 'src/model/anchoring.dart';
export 'src/model/api_key.dart';
+export 'src/model/api_key_operation.dart';
export 'src/model/around_precision_from_value_inner.dart';
export 'src/model/around_radius_all.dart';
export 'src/model/assign_user_id_params.dart';
@@ -127,6 +128,7 @@ export 'src/model/search_type_default.dart';
export 'src/model/search_type_facet.dart';
export 'src/model/search_user_ids_params.dart';
export 'src/model/search_user_ids_response.dart';
+export 'src/model/secured_api_key_restrictions.dart';
export 'src/model/semantic_search.dart';
export 'src/model/snippet_result_option.dart';
export 'src/model/sort_remaining_by.dart';
diff --git a/clients/algoliasearch-client-dart/packages/client_search/lib/src/deserialize.dart b/clients/algoliasearch-client-dart/packages/client_search/lib/src/deserialize.dart
index 1928578f7c..bddcd5a7bd 100644
--- a/clients/algoliasearch-client-dart/packages/client_search/lib/src/deserialize.dart
+++ b/clients/algoliasearch-client-dart/packages/client_search/lib/src/deserialize.dart
@@ -5,6 +5,7 @@ import 'package:algolia_client_search/src/model/advanced_syntax_features.dart';
import 'package:algolia_client_search/src/model/alternatives_as_exact.dart';
import 'package:algolia_client_search/src/model/anchoring.dart';
import 'package:algolia_client_search/src/model/api_key.dart';
+import 'package:algolia_client_search/src/model/api_key_operation.dart';
import 'package:algolia_client_search/src/model/around_precision_from_value_inner.dart';
import 'package:algolia_client_search/src/model/around_radius_all.dart';
import 'package:algolia_client_search/src/model/assign_user_id_params.dart';
@@ -120,6 +121,7 @@ import 'package:algolia_client_search/src/model/search_type_default.dart';
import 'package:algolia_client_search/src/model/search_type_facet.dart';
import 'package:algolia_client_search/src/model/search_user_ids_params.dart';
import 'package:algolia_client_search/src/model/search_user_ids_response.dart';
+import 'package:algolia_client_search/src/model/secured_api_key_restrictions.dart';
import 'package:algolia_client_search/src/model/semantic_search.dart';
import 'package:algolia_client_search/src/model/snippet_result_option.dart';
import 'package:algolia_client_search/src/model/sort_remaining_by.dart';
@@ -173,6 +175,8 @@ ReturnType deserialize(dynamic value, String targetType,
return Anchoring.fromJson(value) as ReturnType;
case 'ApiKey':
return ApiKey.fromJson(value as Map) as ReturnType;
+ case 'ApiKeyOperation':
+ return ApiKeyOperation.fromJson(value) as ReturnType;
case 'AroundPrecisionFromValueInner':
return AroundPrecisionFromValueInner.fromJson(
value as Map) as ReturnType;
@@ -480,6 +484,9 @@ ReturnType deserialize(dynamic value, String targetType,
case 'SearchUserIdsResponse':
return SearchUserIdsResponse.fromJson(value as Map)
as ReturnType;
+ case 'SecuredAPIKeyRestrictions':
+ return SecuredAPIKeyRestrictions.fromJson(value as Map)
+ as ReturnType;
case 'SemanticSearch':
return SemanticSearch.fromJson(value as Map)
as ReturnType;
diff --git a/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/api_key_operation.dart b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/api_key_operation.dart
new file mode 100644
index 0000000000..fa0e583b2b
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/api_key_operation.dart
@@ -0,0 +1,25 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+// ignore_for_file: unused_element
+import 'package:json_annotation/json_annotation.dart';
+
+@JsonEnum(valueField: 'raw')
+enum ApiKeyOperation {
+ add(r'add'),
+ delete(r'delete'),
+ update(r'update');
+
+ const ApiKeyOperation(this.raw);
+ final dynamic raw;
+
+ dynamic toJson() => raw;
+
+ static ApiKeyOperation fromJson(dynamic json) {
+ for (final value in values) {
+ if (value.raw == json) return value;
+ }
+ throw ArgumentError.value(json, "raw", "No enum value with that value");
+ }
+
+ @override
+ String toString() => raw.toString();
+}
diff --git a/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.dart b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.dart
new file mode 100644
index 0000000000..87ef4a4a9c
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.dart
@@ -0,0 +1,73 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+// ignore_for_file: unused_element
+import 'package:algolia_client_search/src/model/search_params_object.dart';
+
+import 'package:json_annotation/json_annotation.dart';
+
+part 'secured_api_key_restrictions.g.dart';
+
+@JsonSerializable()
+final class SecuredAPIKeyRestrictions {
+ /// Returns a new [SecuredAPIKeyRestrictions] instance.
+ const SecuredAPIKeyRestrictions({
+ this.searchParams,
+ this.filters,
+ this.validUntil,
+ this.restrictIndices,
+ this.restrictSources,
+ this.userToken,
+ });
+
+ @JsonKey(name: r'searchParams')
+ final SearchParamsObject? searchParams;
+
+ /// Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ @JsonKey(name: r'filters')
+ final String? filters;
+
+ /// Unix timestamp used to set the expiration date of the API key.
+ @JsonKey(name: r'validUntil')
+ final num? validUntil;
+
+ /// Index names that can be queried.
+ @JsonKey(name: r'restrictIndices')
+ final List? restrictIndices;
+
+ /// IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ @JsonKey(name: r'restrictSources')
+ final String? restrictSources;
+
+ /// Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ @JsonKey(name: r'userToken')
+ final String? userToken;
+
+ @override
+ bool operator ==(Object other) =>
+ identical(this, other) ||
+ other is SecuredAPIKeyRestrictions &&
+ other.searchParams == searchParams &&
+ other.filters == filters &&
+ other.validUntil == validUntil &&
+ other.restrictIndices == restrictIndices &&
+ other.restrictSources == restrictSources &&
+ other.userToken == userToken;
+
+ @override
+ int get hashCode =>
+ searchParams.hashCode +
+ filters.hashCode +
+ validUntil.hashCode +
+ restrictIndices.hashCode +
+ restrictSources.hashCode +
+ userToken.hashCode;
+
+ factory SecuredAPIKeyRestrictions.fromJson(Map json) =>
+ _$SecuredAPIKeyRestrictionsFromJson(json);
+
+ Map toJson() => _$SecuredAPIKeyRestrictionsToJson(this);
+
+ @override
+ String toString() {
+ return toJson().toString();
+ }
+}
diff --git a/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.g.dart b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.g.dart
new file mode 100644
index 0000000000..2706ba068e
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/client_search/lib/src/model/secured_api_key_restrictions.g.dart
@@ -0,0 +1,50 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'secured_api_key_restrictions.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+SecuredAPIKeyRestrictions _$SecuredAPIKeyRestrictionsFromJson(
+ Map json) =>
+ $checkedCreate(
+ 'SecuredAPIKeyRestrictions',
+ json,
+ ($checkedConvert) {
+ final val = SecuredAPIKeyRestrictions(
+ searchParams: $checkedConvert(
+ 'searchParams',
+ (v) => v == null
+ ? null
+ : SearchParamsObject.fromJson(v as Map)),
+ filters: $checkedConvert('filters', (v) => v as String?),
+ validUntil: $checkedConvert('validUntil', (v) => v as num?),
+ restrictIndices: $checkedConvert('restrictIndices',
+ (v) => (v as List?)?.map((e) => e as String).toList()),
+ restrictSources:
+ $checkedConvert('restrictSources', (v) => v as String?),
+ userToken: $checkedConvert('userToken', (v) => v as String?),
+ );
+ return val;
+ },
+ );
+
+Map _$SecuredAPIKeyRestrictionsToJson(
+ SecuredAPIKeyRestrictions instance) {
+ final val = {};
+
+ void writeNotNull(String key, dynamic value) {
+ if (value != null) {
+ val[key] = value;
+ }
+ }
+
+ writeNotNull('searchParams', instance.searchParams?.toJson());
+ writeNotNull('filters', instance.filters);
+ writeNotNull('validUntil', instance.validUntil);
+ writeNotNull('restrictIndices', instance.restrictIndices);
+ writeNotNull('restrictSources', instance.restrictSources);
+ writeNotNull('userToken', instance.userToken);
+ return val;
+}
diff --git a/clients/algoliasearch-client-go/algolia/search/api_search.go b/clients/algoliasearch-client-go/algolia/search/api_search.go
index 75b7ed61a6..f61a634aa3 100644
--- a/clients/algoliasearch-client-go/algolia/search/api_search.go
+++ b/clients/algoliasearch-client-go/algolia/search/api_search.go
@@ -8591,6 +8591,44 @@ func (c *APIClient) WaitForTaskWithContext(
)
}
+/*
+WaitForApiKey waits for an API key to be created, deleted or updated.
+It returns the API key response if the operation was successful.
+It returns an error if the operation failed.
+
+The operation can be one of the following:
+ - "add": wait for the API key to be created
+ - "delete": wait for the API key to be deleted
+ - "update": wait for the API key to be updated
+
+If the operation is "update", the apiKey parameter must be set.
+If the operation is "delete" or "add", the apiKey parameter is not used.
+
+ @param operation ApiKeyOperation - Operation type - add, delete or update.
+ @param key string - API key.
+ @param apiKey *ApiKey - API key structure - required for update operation.
+ @param opts ...Option - Optional parameters for the request.
+ @return *GetApiKeyResponse - API key response.
+ @return error - Error if any.
+*/
+func (c *APIClient) WaitForApiKey(
+ operation ApiKeyOperation,
+ key string,
+ apiKey *ApiKey,
+ opts ...Option,
+) (*GetApiKeyResponse, error) {
+ return c.WaitForApiKeyWithContext(
+ context.Background(),
+ operation,
+ key,
+ apiKey,
+ nil,
+ nil,
+ nil,
+ opts...,
+ )
+}
+
/*
WaitForApiKey waits for an API key to be created, deleted or updated.
Wraps WaitForApiKeyWithContext with context.Background().
@@ -8609,9 +8647,9 @@ The maxDelay parameter is the maximum delay between each retry.
If the operation is "update", the apiKey parameter must be set.
If the operation is "delete" or "add", the apiKey parameter is not used.
+ @param operation ApiKeyOperation - Operation type - add, delete or update.
@param key string - API key.
@param apiKey *ApiKey - API key structure - required for update operation.
- @param operation string - Operation type - add, delete or update.
@param maxRetries *int - Maximum number of retries.
@param initialDelay *time.Duration - Initial delay between retries.
@param maxDelay *time.Duration - Maximum delay between retries.
@@ -8619,10 +8657,10 @@ If the operation is "delete" or "add", the apiKey parameter is not used.
@return *GetApiKeyResponse - API key response.
@return error - Error if any.
*/
-func (c *APIClient) WaitForApiKey(
+func (c *APIClient) WaitForApiKeyWitOptions(
+ operation ApiKeyOperation,
key string,
apiKey *ApiKey,
- operation string,
maxRetries *int,
initialDelay *time.Duration,
maxDelay *time.Duration,
@@ -8630,9 +8668,9 @@ func (c *APIClient) WaitForApiKey(
) (*GetApiKeyResponse, error) {
return c.WaitForApiKeyWithContext(
context.Background(),
+ operation,
key,
apiKey,
- operation,
maxRetries,
initialDelay,
maxDelay,
@@ -8658,9 +8696,9 @@ If the operation is "update", the apiKey parameter must be set.
If the operation is "delete" or "add", the apiKey parameter is not used.
@param ctx context.Context - The context that will be drilled down to the actual request.
+ @param operation ApiKeyOperation - Operation type - add, delete or update.
@param key string - API key.
@param apiKey *ApiKey - API key structure - required for update operation.
- @param operation string - Operation type - add, delete or update.
@param maxRetries *int - Maximum number of retries.
@param initialDelay *time.Duration - Initial delay between retries.
@param maxDelay *time.Duration - Maximum delay between retries.
@@ -8670,19 +8708,19 @@ If the operation is "delete" or "add", the apiKey parameter is not used.
*/
func (c *APIClient) WaitForApiKeyWithContext(
ctx context.Context,
+ operation ApiKeyOperation,
key string,
apiKey *ApiKey,
- operation string,
maxRetries *int,
initialDelay *time.Duration,
maxDelay *time.Duration,
opts ...Option,
) (*GetApiKeyResponse, error) {
- if operation != "add" && operation != "delete" && operation != "update" {
+ if operation != APIKEYOPERATION_ADD && operation != APIKEYOPERATION_DELETE && operation != APIKEYOPERATION_UPDATE {
return nil, &errs.WaitKeyOperationError{}
}
- if operation == "update" {
+ if operation == APIKEYOPERATION_UPDATE {
if apiKey == nil {
return nil, &errs.WaitKeyUpdateError{}
}
@@ -8747,9 +8785,9 @@ func (c *APIClient) WaitForApiKeyWithContext(
},
func(response *GetApiKeyResponse, err error) bool {
switch operation {
- case "add":
+ case APIKEYOPERATION_ADD:
return err == nil && response != nil && response.CreatedAt > 0
- case "delete":
+ case APIKEYOPERATION_DELETE:
if _, ok := err.(*APIError); ok {
apiErr := err.(*APIError)
diff --git a/clients/algoliasearch-client-go/algolia/search/model_api_key_operation.go b/clients/algoliasearch-client-go/algolia/search/model_api_key_operation.go
new file mode 100644
index 0000000000..e57ed6320e
--- /dev/null
+++ b/clients/algoliasearch-client-go/algolia/search/model_api_key_operation.go
@@ -0,0 +1,103 @@
+// File generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation.
+package search
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// ApiKeyOperation the model 'ApiKeyOperation'.
+type ApiKeyOperation string
+
+// List of apiKeyOperation.
+const (
+ APIKEYOPERATION_ADD ApiKeyOperation = "add"
+ APIKEYOPERATION_DELETE ApiKeyOperation = "delete"
+ APIKEYOPERATION_UPDATE ApiKeyOperation = "update"
+)
+
+// All allowed values of ApiKeyOperation enum.
+var AllowedApiKeyOperationEnumValues = []ApiKeyOperation{
+ "add",
+ "delete",
+ "update",
+}
+
+func (v *ApiKeyOperation) UnmarshalJSON(src []byte) error {
+ var value string
+ err := json.Unmarshal(src, &value)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal value '%s' for enum 'ApiKeyOperation': %w", string(src), err)
+ }
+ enumTypeValue := ApiKeyOperation(value)
+ for _, existing := range AllowedApiKeyOperationEnumValues {
+ if existing == enumTypeValue {
+ *v = enumTypeValue
+ return nil
+ }
+ }
+
+ return fmt.Errorf("%+v is not a valid ApiKeyOperation", value)
+}
+
+// NewApiKeyOperationFromValue returns a pointer to a valid ApiKeyOperation
+// for the value passed as argument, or an error if the value passed is not allowed by the enum.
+func NewApiKeyOperationFromValue(v string) (*ApiKeyOperation, error) {
+ ev := ApiKeyOperation(v)
+ if ev.IsValid() {
+ return &ev, nil
+ } else {
+ return nil, fmt.Errorf("invalid value '%v' for ApiKeyOperation: valid values are %v", v, AllowedApiKeyOperationEnumValues)
+ }
+}
+
+// IsValid return true if the value is valid for the enum, false otherwise.
+func (v ApiKeyOperation) IsValid() bool {
+ for _, existing := range AllowedApiKeyOperationEnumValues {
+ if existing == v {
+ return true
+ }
+ }
+ return false
+}
+
+// Ptr returns reference to apiKeyOperation value.
+func (v ApiKeyOperation) Ptr() *ApiKeyOperation {
+ return &v
+}
+
+type NullableApiKeyOperation struct {
+ value *ApiKeyOperation
+ isSet bool
+}
+
+func (v NullableApiKeyOperation) Get() *ApiKeyOperation {
+ return v.value
+}
+
+func (v *NullableApiKeyOperation) Set(val *ApiKeyOperation) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableApiKeyOperation) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableApiKeyOperation) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableApiKeyOperation(val *ApiKeyOperation) *NullableApiKeyOperation {
+ return &NullableApiKeyOperation{value: val, isSet: true}
+}
+
+func (v NullableApiKeyOperation) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value) //nolint:wrapcheck
+}
+
+func (v *NullableApiKeyOperation) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value) //nolint:wrapcheck
+}
diff --git a/clients/algoliasearch-client-go/algolia/search/model_secured_api_key_restrictions.go b/clients/algoliasearch-client-go/algolia/search/model_secured_api_key_restrictions.go
new file mode 100644
index 0000000000..8b4b88b2b3
--- /dev/null
+++ b/clients/algoliasearch-client-go/algolia/search/model_secured_api_key_restrictions.go
@@ -0,0 +1,350 @@
+// File generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation.
+package search
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// SecuredAPIKeyRestrictions struct for SecuredAPIKeyRestrictions.
+type SecuredAPIKeyRestrictions struct {
+ SearchParams *SearchParamsObject `json:"searchParams,omitempty"`
+ // Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ Filters *string `json:"filters,omitempty"`
+ // Unix timestamp used to set the expiration date of the API key.
+ ValidUntil *float32 `json:"validUntil,omitempty"`
+ // Index names that can be queried.
+ RestrictIndices []string `json:"restrictIndices,omitempty"`
+ // IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ RestrictSources *string `json:"restrictSources,omitempty"`
+ // Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ UserToken *string `json:"userToken,omitempty"`
+}
+
+type SecuredAPIKeyRestrictionsOption func(f *SecuredAPIKeyRestrictions)
+
+func WithSecuredAPIKeyRestrictionsSearchParams(val SearchParamsObject) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.SearchParams = &val
+ }
+}
+
+func WithSecuredAPIKeyRestrictionsFilters(val string) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.Filters = &val
+ }
+}
+
+func WithSecuredAPIKeyRestrictionsValidUntil(val float32) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.ValidUntil = &val
+ }
+}
+
+func WithSecuredAPIKeyRestrictionsRestrictIndices(val []string) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.RestrictIndices = val
+ }
+}
+
+func WithSecuredAPIKeyRestrictionsRestrictSources(val string) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.RestrictSources = &val
+ }
+}
+
+func WithSecuredAPIKeyRestrictionsUserToken(val string) SecuredAPIKeyRestrictionsOption {
+ return func(f *SecuredAPIKeyRestrictions) {
+ f.UserToken = &val
+ }
+}
+
+// NewSecuredAPIKeyRestrictions instantiates a new SecuredAPIKeyRestrictions object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed.
+func NewSecuredAPIKeyRestrictions(opts ...SecuredAPIKeyRestrictionsOption) *SecuredAPIKeyRestrictions {
+ this := &SecuredAPIKeyRestrictions{}
+ for _, opt := range opts {
+ opt(this)
+ }
+ return this
+}
+
+// NewEmptySecuredAPIKeyRestrictions return a pointer to an empty SecuredAPIKeyRestrictions object.
+func NewEmptySecuredAPIKeyRestrictions() *SecuredAPIKeyRestrictions {
+ return &SecuredAPIKeyRestrictions{}
+}
+
+// GetSearchParams returns the SearchParams field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetSearchParams() SearchParamsObject {
+ if o == nil || o.SearchParams == nil {
+ var ret SearchParamsObject
+ return ret
+ }
+ return *o.SearchParams
+}
+
+// GetSearchParamsOk returns a tuple with the SearchParams field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetSearchParamsOk() (*SearchParamsObject, bool) {
+ if o == nil || o.SearchParams == nil {
+ return nil, false
+ }
+ return o.SearchParams, true
+}
+
+// HasSearchParams returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasSearchParams() bool {
+ if o != nil && o.SearchParams != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetSearchParams gets a reference to the given SearchParamsObject and assigns it to the SearchParams field.
+func (o *SecuredAPIKeyRestrictions) SetSearchParams(v *SearchParamsObject) *SecuredAPIKeyRestrictions {
+ o.SearchParams = v
+ return o
+}
+
+// GetFilters returns the Filters field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetFilters() string {
+ if o == nil || o.Filters == nil {
+ var ret string
+ return ret
+ }
+ return *o.Filters
+}
+
+// GetFiltersOk returns a tuple with the Filters field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetFiltersOk() (*string, bool) {
+ if o == nil || o.Filters == nil {
+ return nil, false
+ }
+ return o.Filters, true
+}
+
+// HasFilters returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasFilters() bool {
+ if o != nil && o.Filters != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetFilters gets a reference to the given string and assigns it to the Filters field.
+func (o *SecuredAPIKeyRestrictions) SetFilters(v string) *SecuredAPIKeyRestrictions {
+ o.Filters = &v
+ return o
+}
+
+// GetValidUntil returns the ValidUntil field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetValidUntil() float32 {
+ if o == nil || o.ValidUntil == nil {
+ var ret float32
+ return ret
+ }
+ return *o.ValidUntil
+}
+
+// GetValidUntilOk returns a tuple with the ValidUntil field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetValidUntilOk() (*float32, bool) {
+ if o == nil || o.ValidUntil == nil {
+ return nil, false
+ }
+ return o.ValidUntil, true
+}
+
+// HasValidUntil returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasValidUntil() bool {
+ if o != nil && o.ValidUntil != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetValidUntil gets a reference to the given float32 and assigns it to the ValidUntil field.
+func (o *SecuredAPIKeyRestrictions) SetValidUntil(v float32) *SecuredAPIKeyRestrictions {
+ o.ValidUntil = &v
+ return o
+}
+
+// GetRestrictIndices returns the RestrictIndices field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetRestrictIndices() []string {
+ if o == nil || o.RestrictIndices == nil {
+ var ret []string
+ return ret
+ }
+ return o.RestrictIndices
+}
+
+// GetRestrictIndicesOk returns a tuple with the RestrictIndices field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetRestrictIndicesOk() ([]string, bool) {
+ if o == nil || o.RestrictIndices == nil {
+ return nil, false
+ }
+ return o.RestrictIndices, true
+}
+
+// HasRestrictIndices returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasRestrictIndices() bool {
+ if o != nil && o.RestrictIndices != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetRestrictIndices gets a reference to the given []string and assigns it to the RestrictIndices field.
+func (o *SecuredAPIKeyRestrictions) SetRestrictIndices(v []string) *SecuredAPIKeyRestrictions {
+ o.RestrictIndices = v
+ return o
+}
+
+// GetRestrictSources returns the RestrictSources field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetRestrictSources() string {
+ if o == nil || o.RestrictSources == nil {
+ var ret string
+ return ret
+ }
+ return *o.RestrictSources
+}
+
+// GetRestrictSourcesOk returns a tuple with the RestrictSources field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetRestrictSourcesOk() (*string, bool) {
+ if o == nil || o.RestrictSources == nil {
+ return nil, false
+ }
+ return o.RestrictSources, true
+}
+
+// HasRestrictSources returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasRestrictSources() bool {
+ if o != nil && o.RestrictSources != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetRestrictSources gets a reference to the given string and assigns it to the RestrictSources field.
+func (o *SecuredAPIKeyRestrictions) SetRestrictSources(v string) *SecuredAPIKeyRestrictions {
+ o.RestrictSources = &v
+ return o
+}
+
+// GetUserToken returns the UserToken field value if set, zero value otherwise.
+func (o *SecuredAPIKeyRestrictions) GetUserToken() string {
+ if o == nil || o.UserToken == nil {
+ var ret string
+ return ret
+ }
+ return *o.UserToken
+}
+
+// GetUserTokenOk returns a tuple with the UserToken field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *SecuredAPIKeyRestrictions) GetUserTokenOk() (*string, bool) {
+ if o == nil || o.UserToken == nil {
+ return nil, false
+ }
+ return o.UserToken, true
+}
+
+// HasUserToken returns a boolean if a field has been set.
+func (o *SecuredAPIKeyRestrictions) HasUserToken() bool {
+ if o != nil && o.UserToken != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetUserToken gets a reference to the given string and assigns it to the UserToken field.
+func (o *SecuredAPIKeyRestrictions) SetUserToken(v string) *SecuredAPIKeyRestrictions {
+ o.UserToken = &v
+ return o
+}
+
+func (o SecuredAPIKeyRestrictions) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]any{}
+ if o.SearchParams != nil {
+ toSerialize["searchParams"] = o.SearchParams
+ }
+ if o.Filters != nil {
+ toSerialize["filters"] = o.Filters
+ }
+ if o.ValidUntil != nil {
+ toSerialize["validUntil"] = o.ValidUntil
+ }
+ if o.RestrictIndices != nil {
+ toSerialize["restrictIndices"] = o.RestrictIndices
+ }
+ if o.RestrictSources != nil {
+ toSerialize["restrictSources"] = o.RestrictSources
+ }
+ if o.UserToken != nil {
+ toSerialize["userToken"] = o.UserToken
+ }
+ serialized, err := json.Marshal(toSerialize)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal SecuredAPIKeyRestrictions: %w", err)
+ }
+
+ return serialized, nil
+}
+
+func (o SecuredAPIKeyRestrictions) String() string {
+ out := ""
+ out += fmt.Sprintf(" searchParams=%v\n", o.SearchParams)
+ out += fmt.Sprintf(" filters=%v\n", o.Filters)
+ out += fmt.Sprintf(" validUntil=%v\n", o.ValidUntil)
+ out += fmt.Sprintf(" restrictIndices=%v\n", o.RestrictIndices)
+ out += fmt.Sprintf(" restrictSources=%v\n", o.RestrictSources)
+ out += fmt.Sprintf(" userToken=%v\n", o.UserToken)
+ return fmt.Sprintf("SecuredAPIKeyRestrictions {\n%s}", out)
+}
+
+type NullableSecuredAPIKeyRestrictions struct {
+ value *SecuredAPIKeyRestrictions
+ isSet bool
+}
+
+func (v NullableSecuredAPIKeyRestrictions) Get() *SecuredAPIKeyRestrictions {
+ return v.value
+}
+
+func (v *NullableSecuredAPIKeyRestrictions) Set(val *SecuredAPIKeyRestrictions) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableSecuredAPIKeyRestrictions) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableSecuredAPIKeyRestrictions) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableSecuredAPIKeyRestrictions(val *SecuredAPIKeyRestrictions) *NullableSecuredAPIKeyRestrictions {
+ return &NullableSecuredAPIKeyRestrictions{value: val, isSet: true}
+}
+
+func (v NullableSecuredAPIKeyRestrictions) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value) //nolint:wrapcheck
+}
+
+func (v *NullableSecuredAPIKeyRestrictions) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value) //nolint:wrapcheck
+}
diff --git a/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/ApiKeyOperation.java b/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/ApiKeyOperation.java
new file mode 100644
index 0000000000..1939bda306
--- /dev/null
+++ b/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/ApiKeyOperation.java
@@ -0,0 +1,42 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost
+// - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+package com.algolia.model.search;
+
+import com.fasterxml.jackson.annotation.*;
+import com.fasterxml.jackson.databind.annotation.*;
+
+/** Gets or Sets apiKeyOperation */
+public enum ApiKeyOperation {
+ ADD("add"),
+
+ DELETE("delete"),
+
+ UPDATE("update");
+
+ private final String value;
+
+ ApiKeyOperation(String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static ApiKeyOperation fromValue(String value) {
+ for (ApiKeyOperation b : ApiKeyOperation.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+}
diff --git a/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/SecuredAPIKeyRestrictions.java b/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/SecuredAPIKeyRestrictions.java
new file mode 100644
index 0000000000..1a5c5d6273
--- /dev/null
+++ b/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/model/search/SecuredAPIKeyRestrictions.java
@@ -0,0 +1,175 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost
+// - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+package com.algolia.model.search;
+
+import com.fasterxml.jackson.annotation.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/** SecuredAPIKeyRestrictions */
+public class SecuredAPIKeyRestrictions {
+
+ @JsonProperty("searchParams")
+ private SearchParamsObject searchParams;
+
+ @JsonProperty("filters")
+ private String filters;
+
+ @JsonProperty("validUntil")
+ private BigDecimal validUntil;
+
+ @JsonProperty("restrictIndices")
+ private List restrictIndices;
+
+ @JsonProperty("restrictSources")
+ private String restrictSources;
+
+ @JsonProperty("userToken")
+ private String userToken;
+
+ public SecuredAPIKeyRestrictions setSearchParams(SearchParamsObject searchParams) {
+ this.searchParams = searchParams;
+ return this;
+ }
+
+ /** Get searchParams */
+ @javax.annotation.Nullable
+ public SearchParamsObject getSearchParams() {
+ return searchParams;
+ }
+
+ public SecuredAPIKeyRestrictions setFilters(String filters) {
+ this.filters = filters;
+ return this;
+ }
+
+ /**
+ * Filters that apply to every search made with the secured API key. You can add extra filters at
+ * search time with the filters query parameter. For example, if you set the filter group:admin on
+ * your generated API key, and you add groups:press OR groups:visitors with the filters query
+ * parameter, your final search filter is equivalent to groups:admin AND (groups:press OR
+ * groups:visitors).
+ */
+ @javax.annotation.Nullable
+ public String getFilters() {
+ return filters;
+ }
+
+ public SecuredAPIKeyRestrictions setValidUntil(BigDecimal validUntil) {
+ this.validUntil = validUntil;
+ return this;
+ }
+
+ /** Unix timestamp used to set the expiration date of the API key. */
+ @javax.annotation.Nullable
+ public BigDecimal getValidUntil() {
+ return validUntil;
+ }
+
+ public SecuredAPIKeyRestrictions setRestrictIndices(List restrictIndices) {
+ this.restrictIndices = restrictIndices;
+ return this;
+ }
+
+ public SecuredAPIKeyRestrictions addRestrictIndices(String restrictIndicesItem) {
+ if (this.restrictIndices == null) {
+ this.restrictIndices = new ArrayList<>();
+ }
+ this.restrictIndices.add(restrictIndicesItem);
+ return this;
+ }
+
+ /** Index names that can be queried. */
+ @javax.annotation.Nullable
+ public List getRestrictIndices() {
+ return restrictIndices;
+ }
+
+ public SecuredAPIKeyRestrictions setRestrictSources(String restrictSources) {
+ this.restrictSources = restrictSources;
+ return this;
+ }
+
+ /**
+ * IPv4 network allowed to use the generated key. Use this to protect against API key leaking and
+ * reuse. You can only provide a single source, but you can specify a range of IPs (for example,
+ * 192.168.1.0/24).
+ */
+ @javax.annotation.Nullable
+ public String getRestrictSources() {
+ return restrictSources;
+ }
+
+ public SecuredAPIKeyRestrictions setUserToken(String userToken) {
+ this.userToken = userToken;
+ return this;
+ }
+
+ /**
+ * Unique user IP address. This can be useful when you want to impose a rate limit on specific
+ * users. By default, rate limits are set based on the IP address. This can become an issue when
+ * several users search from the same IP address. To avoid this, you can set a unique userToken
+ * for each user when generating their API key. This lets you restrict each user to a maximum
+ * number of API calls per hour, even if they share their IP with another user. Specifying the
+ * userToken in a secured API key is also a good security practice as it ensures users don't
+ * change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the
+ * authenticity of user identifiers. Setting the userToken at the API key level ensures that
+ * downstream services work as expected and prevents abuse.
+ */
+ @javax.annotation.Nullable
+ public String getUserToken() {
+ return userToken;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SecuredAPIKeyRestrictions securedAPIKeyRestrictions = (SecuredAPIKeyRestrictions) o;
+ return (
+ Objects.equals(this.searchParams, securedAPIKeyRestrictions.searchParams) &&
+ Objects.equals(this.filters, securedAPIKeyRestrictions.filters) &&
+ Objects.equals(this.validUntil, securedAPIKeyRestrictions.validUntil) &&
+ Objects.equals(this.restrictIndices, securedAPIKeyRestrictions.restrictIndices) &&
+ Objects.equals(this.restrictSources, securedAPIKeyRestrictions.restrictSources) &&
+ Objects.equals(this.userToken, securedAPIKeyRestrictions.userToken)
+ );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(searchParams, filters, validUntil, restrictIndices, restrictSources, userToken);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class SecuredAPIKeyRestrictions {\n");
+ sb.append(" searchParams: ").append(toIndentedString(searchParams)).append("\n");
+ sb.append(" filters: ").append(toIndentedString(filters)).append("\n");
+ sb.append(" validUntil: ").append(toIndentedString(validUntil)).append("\n");
+ sb.append(" restrictIndices: ").append(toIndentedString(restrictIndices)).append("\n");
+ sb.append(" restrictSources: ").append(toIndentedString(restrictSources)).append("\n");
+ sb.append(" userToken: ").append(toIndentedString(userToken)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
diff --git a/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/utils/ApiKeyOperation.java b/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/utils/ApiKeyOperation.java
deleted file mode 100644
index a1db4e6805..0000000000
--- a/clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/utils/ApiKeyOperation.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.algolia.utils;
-
-public enum ApiKeyOperation {
- ADD,
- DELETE,
- UPDATE,
-}
diff --git a/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/apiKeyOperation.ts b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/apiKeyOperation.ts
new file mode 100644
index 0000000000..736b63c668
--- /dev/null
+++ b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/apiKeyOperation.ts
@@ -0,0 +1,3 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+export type ApiKeyOperation = 'add' | 'delete' | 'update';
diff --git a/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/index.ts b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/index.ts
index 936c9a3f8f..3dcf44d602 100644
--- a/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/index.ts
+++ b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/index.ts
@@ -7,6 +7,7 @@ export * from './advancedSyntaxFeatures';
export * from './alternativesAsExact';
export * from './anchoring';
export * from './apiKey';
+export * from './apiKeyOperation';
export * from './aroundPrecision';
export * from './aroundPrecisionFromValueInner';
export * from './aroundRadius';
@@ -101,6 +102,7 @@ export * from './searchStrategy';
export * from './searchSynonymsResponse';
export * from './searchTypeDefault';
export * from './searchTypeFacet';
+export * from './securedAPIKeyRestrictions';
export * from './semanticSearch';
export * from './snippetResult';
export * from './snippetResultOption';
diff --git a/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/securedAPIKeyRestrictions.ts b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/securedAPIKeyRestrictions.ts
new file mode 100644
index 0000000000..bba07db289
--- /dev/null
+++ b/clients/algoliasearch-client-javascript/packages/algoliasearch/lite/model/securedAPIKeyRestrictions.ts
@@ -0,0 +1,32 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+import type { SearchParamsObject } from './searchParamsObject';
+
+export type SecuredAPIKeyRestrictions = {
+ searchParams?: SearchParamsObject;
+
+ /**
+ * Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ */
+ filters?: string;
+
+ /**
+ * Unix timestamp used to set the expiration date of the API key.
+ */
+ validUntil?: number;
+
+ /**
+ * Index names that can be queried.
+ */
+ restrictIndices?: string[];
+
+ /**
+ * IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ */
+ restrictSources?: string;
+
+ /**
+ * Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don\'t change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ */
+ userToken?: string;
+};
diff --git a/clients/algoliasearch-client-javascript/packages/client-search/model/apiKeyOperation.ts b/clients/algoliasearch-client-javascript/packages/client-search/model/apiKeyOperation.ts
new file mode 100644
index 0000000000..736b63c668
--- /dev/null
+++ b/clients/algoliasearch-client-javascript/packages/client-search/model/apiKeyOperation.ts
@@ -0,0 +1,3 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+export type ApiKeyOperation = 'add' | 'delete' | 'update';
diff --git a/clients/algoliasearch-client-javascript/packages/client-search/model/clientMethodProps.ts b/clients/algoliasearch-client-javascript/packages/client-search/model/clientMethodProps.ts
index 0ee0456dfd..086014edea 100644
--- a/clients/algoliasearch-client-javascript/packages/client-search/model/clientMethodProps.ts
+++ b/clients/algoliasearch-client-javascript/packages/client-search/model/clientMethodProps.ts
@@ -4,6 +4,7 @@ import type { CreateIterablePromise } from '@algolia/client-common';
import type { Action } from './action';
import type { ApiKey } from './apiKey';
+import type { ApiKeyOperation } from './apiKeyOperation';
import type { AssignUserIdParams } from './assignUserIdParams';
import type { AttributeToUpdate } from './attributeToUpdate';
import type { BatchAssignUserIdsParams } from './batchAssignUserIdsParams';
@@ -25,6 +26,7 @@ import type { SearchParams } from './searchParams';
import type { SearchParamsObject } from './searchParamsObject';
import type { SearchRulesParams } from './searchRulesParams';
import type { SearchSynonymsParams } from './searchSynonymsParams';
+import type { SecuredAPIKeyRestrictions } from './securedAPIKeyRestrictions';
import type { Source } from './source';
import type { SynonymHit } from './synonymHit';
import type { UpdatedAtResponse } from './updatedAtResponse';
@@ -759,14 +761,14 @@ export type WaitForApiKeyOptions = WaitForOptions & {
/**
* The operation that has been performed, used to compute the stop condition.
*/
- operation: 'add' | 'delete';
+ operation: Extract;
apiKey?: never;
}
| {
/**
* The operation that has been performed, used to compute the stop condition.
*/
- operation: 'update';
+ operation: Extract;
/**
* The updated fields, used to compute the stop condition.
*/
@@ -783,7 +785,7 @@ export type GenerateSecuredApiKeyOptions = {
/**
* A set of properties defining the restrictions of the secured API key.
*/
- restrictions?: SecuredApiKeyRestrictions;
+ restrictions?: SecuredAPIKeyRestrictions;
};
export type GetSecuredApiKeyRemainingValidityOptions = {
@@ -793,30 +795,6 @@ export type GetSecuredApiKeyRemainingValidityOptions = {
securedApiKey: string;
};
-export type SecuredApiKeyRestrictions = {
- /**
- * A Unix timestamp used to define the expiration date of the API key.
- */
- validUntil?: number;
-
- /**
- * List of index names that can be queried.
- */
- restrictIndices?: string[] | string;
-
- /**
- * IPv4 network allowed to use the generated key. This is used for more protection against API key leaking and reuse.
- */
- restrictSources?: string;
-
- /**
- * Specify a user identifier. This is often used with rate limits.
- */
- userToken?: string;
-
- searchParams?: SearchParamsObject;
-};
-
export type ChunkedBatchOptions = ReplaceAllObjectsOptions & {
/**
* The `batch` `action` to perform on the given array of `objects`, defaults to `addObject`.
diff --git a/clients/algoliasearch-client-javascript/packages/client-search/model/index.ts b/clients/algoliasearch-client-javascript/packages/client-search/model/index.ts
index 8db900701a..edfc461022 100644
--- a/clients/algoliasearch-client-javascript/packages/client-search/model/index.ts
+++ b/clients/algoliasearch-client-javascript/packages/client-search/model/index.ts
@@ -7,6 +7,7 @@ export * from './advancedSyntaxFeatures';
export * from './alternativesAsExact';
export * from './anchoring';
export * from './apiKey';
+export * from './apiKeyOperation';
export * from './aroundPrecision';
export * from './aroundPrecisionFromValueInner';
export * from './aroundRadius';
@@ -141,6 +142,7 @@ export * from './searchTypeDefault';
export * from './searchTypeFacet';
export * from './searchUserIdsParams';
export * from './searchUserIdsResponse';
+export * from './securedAPIKeyRestrictions';
export * from './semanticSearch';
export * from './snippetResult';
export * from './snippetResultOption';
diff --git a/clients/algoliasearch-client-javascript/packages/client-search/model/securedAPIKeyRestrictions.ts b/clients/algoliasearch-client-javascript/packages/client-search/model/securedAPIKeyRestrictions.ts
new file mode 100644
index 0000000000..bba07db289
--- /dev/null
+++ b/clients/algoliasearch-client-javascript/packages/client-search/model/securedAPIKeyRestrictions.ts
@@ -0,0 +1,32 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+import type { SearchParamsObject } from './searchParamsObject';
+
+export type SecuredAPIKeyRestrictions = {
+ searchParams?: SearchParamsObject;
+
+ /**
+ * Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ */
+ filters?: string;
+
+ /**
+ * Unix timestamp used to set the expiration date of the API key.
+ */
+ validUntil?: number;
+
+ /**
+ * Index names that can be queried.
+ */
+ restrictIndices?: string[];
+
+ /**
+ * IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ */
+ restrictSources?: string;
+
+ /**
+ * Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don\'t change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ */
+ userToken?: string;
+};
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/ApiKeyOperation.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/ApiKeyOperation.kt
deleted file mode 100644
index f5dd78d28d..0000000000
--- a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/ApiKeyOperation.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.algolia.client.extensions
-
-/**
- * Enum for the operations that can be performed.
- */
-public enum class ApiKeyOperation {
- Create,
- Update,
- Delete
-}
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SearchClient.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SearchClient.kt
index db58c64f57..94f82734a0 100644
--- a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SearchClient.kt
+++ b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SearchClient.kt
@@ -41,7 +41,7 @@ public suspend fun SearchClient.waitForApiKey(
requestOptions: RequestOptions? = null,
) {
when (operation) {
- ApiKeyOperation.Create -> waitKeyCreation(
+ ApiKeyOperation.Add -> waitKeyCreation(
key = key,
maxRetries = maxRetries,
timeout = timeout,
@@ -311,7 +311,7 @@ public suspend fun SearchClient.replaceAllObjects(
* @param restriction Restriction to add the key
* @throws Exception if an error occurs during the encoding
*/
-public fun SearchClient.generateSecuredApiKey(parentAPIKey: String, restriction: SecuredAPIKeyRestriction): String {
+public fun SearchClient.generateSecuredApiKey(parentAPIKey: String, restriction: SecuredAPIKeyRestrictions): String {
val restrictionString = buildRestrictionString(restriction)
val hash = encodeKeySHA256(parentAPIKey, restrictionString)
return "$hash$restrictionString".encodeBase64()
@@ -322,7 +322,7 @@ public fun SearchClient.generateSecuredApiKey(parentAPIKey: String, restriction:
*
* @param apiKey The secured API Key to check.
* @return Duration left before the secured API key expires.
- * @throws IllegalArgumentException if [apiKey] doesn't have a [SecuredAPIKeyRestriction.validUntil].
+ * @throws IllegalArgumentException if [apiKey] doesn't have a [SecuredAPIKeyRestrictions.validUntil].
*/
public fun securedApiKeyRemainingValidity(apiKey: String): Duration {
val decoded = apiKey.decodeBase64String()
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SecuredAPIKeyRestriction.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SecuredAPIKeyRestriction.kt
deleted file mode 100644
index 1e30aeb518..0000000000
--- a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/SecuredAPIKeyRestriction.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.algolia.client.extensions
-
-import com.algolia.client.model.search.SearchParamsObject
-import kotlinx.datetime.Instant
-
-/**
- * Create restrictions for an API key.
- *
- * @param query A mapping of search parameters that will be forced at query time.
- * @param restrictIndices List of index names that can be queried.
- * @param restrictSources IPv4 network allowed using the generated key. This is used for more protection against
- * the api key leaking and reuse.
- * @param validUntil A Unix timestamp used to define the expiration date of the API key.
- * @param userToken Specify a user identifier. This is often used with rate limits. By default, rate limits will only
- * use the IP. This can be an issue when several of your end users are using the same IP. To avoid that, you can set a
- * userToken query parameter when generating the key. When set, a unique user will be identified by their IP + user_token
- * instead of only by their IP. This allows you to restrict a single user from performing a maximum of N API calls per hour,
- * even if he shares his IP with another user.
- */
-public data class SecuredAPIKeyRestriction(
- val query: SearchParamsObject? = null,
- val restrictIndices: List? = null,
- val restrictSources: List? = null,
- val validUntil: Instant? = null,
- val userToken: String? = null
-)
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/internal/SearchClient.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/internal/SearchClient.kt
index e017d24fef..ef176120dc 100644
--- a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/internal/SearchClient.kt
+++ b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/extensions/internal/SearchClient.kt
@@ -1,20 +1,20 @@
package com.algolia.client.extensions.internal
import com.algolia.client.api.SearchClient
-import com.algolia.client.extensions.SecuredAPIKeyRestriction
import com.algolia.client.model.search.SearchParamsObject
+import com.algolia.client.model.search.SecuredAPIKeyRestrictions
import io.ktor.http.*
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
/**
- * Builds a restriction string based on provided [SecuredAPIKeyRestriction].
+ * Builds a restriction string based on provided [SecuredAPIKeyRestrictions].
*/
-internal fun SearchClient.buildRestrictionString(restriction: SecuredAPIKeyRestriction): String {
+internal fun SearchClient.buildRestrictionString(restriction: SecuredAPIKeyRestrictions): String {
return Parameters.build {
- restriction.query?.let { query ->
- val json = options.json.encodeToJsonElement(SearchParamsObject.serializer(), query).jsonObject
+ restriction.searchParams?.let { searchParams ->
+ val json = options.json.encodeToJsonElement(SearchParamsObject.serializer(), searchParams).jsonObject
json.forEach { (key, element) ->
when (element) {
is JsonArray -> appendAll(key, element.jsonPrimitive.content.map { it.toString() })
@@ -23,8 +23,8 @@ internal fun SearchClient.buildRestrictionString(restriction: SecuredAPIKeyRestr
}
}
restriction.restrictIndices?.let { append("restrictIndices", it.joinToString(";")) }
- restriction.restrictSources?.let { append("restrictSources", it.joinToString(";")) }
+ restriction.restrictSources?.let { append("restrictSources", it) }
restriction.userToken?.let { append("userToken", it) }
- restriction.validUntil?.let { append("validUntil", it.toEpochMilliseconds().toString()) }
+ restriction.validUntil?.let { append("validUntil", it.toString()) }
}.formUrlEncode()
}
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/ApiKeyOperation.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/ApiKeyOperation.kt
new file mode 100644
index 0000000000..5adaf8de0b
--- /dev/null
+++ b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/ApiKeyOperation.kt
@@ -0,0 +1,19 @@
+/** Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT. */
+package com.algolia.client.model.search
+
+import kotlinx.serialization.*
+
+@Serializable
+public enum class ApiKeyOperation(public val value: kotlin.String) {
+
+ @SerialName(value = "add")
+ Add("add"),
+
+ @SerialName(value = "delete")
+ Delete("delete"),
+
+ @SerialName(value = "update")
+ Update("update");
+
+ override fun toString(): kotlin.String = value
+}
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/SecuredAPIKeyRestrictions.kt b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/SecuredAPIKeyRestrictions.kt
new file mode 100644
index 0000000000..7064b80b63
--- /dev/null
+++ b/clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/model/search/SecuredAPIKeyRestrictions.kt
@@ -0,0 +1,36 @@
+/** Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT. */
+package com.algolia.client.model.search
+
+import kotlinx.serialization.*
+import kotlinx.serialization.json.*
+
+/**
+ * SecuredAPIKeyRestrictions
+ *
+ * @param searchParams
+ * @param filters Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ * @param validUntil Unix timestamp used to set the expiration date of the API key.
+ * @param restrictIndices Index names that can be queried.
+ * @param restrictSources IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ * @param userToken Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ */
+@Serializable
+public data class SecuredAPIKeyRestrictions(
+
+ @SerialName(value = "searchParams") val searchParams: SearchParamsObject? = null,
+
+ /** Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors). */
+ @SerialName(value = "filters") val filters: String? = null,
+
+ /** Unix timestamp used to set the expiration date of the API key. */
+ @SerialName(value = "validUntil") val validUntil: Double? = null,
+
+ /** Index names that can be queried. */
+ @SerialName(value = "restrictIndices") val restrictIndices: List? = null,
+
+ /** IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24). */
+ @SerialName(value = "restrictSources") val restrictSources: String? = null,
+
+ /** Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse. */
+ @SerialName(value = "userToken") val userToken: String? = null,
+)
diff --git a/clients/algoliasearch-client-kotlin/client/src/commonTest/kotlin/com/algolia/client/TestSecureApiKey.kt b/clients/algoliasearch-client-kotlin/client/src/commonTest/kotlin/com/algolia/client/TestSecureApiKey.kt
index 0d86691edc..e061cd633d 100644
--- a/clients/algoliasearch-client-kotlin/client/src/commonTest/kotlin/com/algolia/client/TestSecureApiKey.kt
+++ b/clients/algoliasearch-client-kotlin/client/src/commonTest/kotlin/com/algolia/client/TestSecureApiKey.kt
@@ -1,7 +1,7 @@
package com.algolia.client
import com.algolia.client.api.SearchClient
-import com.algolia.client.extensions.SecuredAPIKeyRestriction
+import com.algolia.client.extensions.SecuredAPIKeyRestrictions
import com.algolia.client.extensions.generateSecuredApiKey
import com.algolia.client.extensions.securedApiKeyRemainingValidity
import com.algolia.client.model.search.SearchParamsObject
@@ -15,7 +15,7 @@ class TestSecureApiKey {
@Test
fun securedApiKey() {
val parentAPIKey = "SearchOnlyApiKeyKeptPrivate"
- val restriction = SecuredAPIKeyRestriction(
+ val restriction = SecuredAPIKeyRestrictions(
query = SearchParamsObject(filters = "_tags:user_42"),
validUntil = Clock.System.now() + 2.days,
)
diff --git a/clients/algoliasearch-client-php/lib/Model/Search/ApiKeyOperation.php b/clients/algoliasearch-client-php/lib/Model/Search/ApiKeyOperation.php
new file mode 100644
index 0000000000..0c75e7d422
--- /dev/null
+++ b/clients/algoliasearch-client-php/lib/Model/Search/ApiKeyOperation.php
@@ -0,0 +1,36 @@
+ '\Algolia\AlgoliaSearch\Model\Search\SearchParamsObject',
+ 'filters' => 'string',
+ 'validUntil' => 'float',
+ 'restrictIndices' => 'string[]',
+ 'restrictSources' => 'string',
+ 'userToken' => 'string',
+ ];
+
+ /**
+ * Array of property to format mappings. Used for (de)serialization.
+ *
+ * @var string[]
+ */
+ protected static $modelFormats = [
+ 'searchParams' => null,
+ 'filters' => null,
+ 'validUntil' => 'duration',
+ 'restrictIndices' => null,
+ 'restrictSources' => null,
+ 'userToken' => null,
+ ];
+
+ /**
+ * Array of attributes where the key is the local name,
+ * and the value is the original name.
+ *
+ * @var string[]
+ */
+ protected static $attributeMap = [
+ 'searchParams' => 'searchParams',
+ 'filters' => 'filters',
+ 'validUntil' => 'validUntil',
+ 'restrictIndices' => 'restrictIndices',
+ 'restrictSources' => 'restrictSources',
+ 'userToken' => 'userToken',
+ ];
+
+ /**
+ * Array of attributes to setter functions (for deserialization of responses).
+ *
+ * @var string[]
+ */
+ protected static $setters = [
+ 'searchParams' => 'setSearchParams',
+ 'filters' => 'setFilters',
+ 'validUntil' => 'setValidUntil',
+ 'restrictIndices' => 'setRestrictIndices',
+ 'restrictSources' => 'setRestrictSources',
+ 'userToken' => 'setUserToken',
+ ];
+
+ /**
+ * Array of attributes to getter functions (for serialization of requests).
+ *
+ * @var string[]
+ */
+ protected static $getters = [
+ 'searchParams' => 'getSearchParams',
+ 'filters' => 'getFilters',
+ 'validUntil' => 'getValidUntil',
+ 'restrictIndices' => 'getRestrictIndices',
+ 'restrictSources' => 'getRestrictSources',
+ 'userToken' => 'getUserToken',
+ ];
+
+ /**
+ * Associative array for storing property values.
+ *
+ * @var mixed[]
+ */
+ protected $container = [];
+
+ /**
+ * Constructor.
+ *
+ * @param mixed[] $data Associated array of property values
+ */
+ public function __construct(array $data = null)
+ {
+ if (isset($data['searchParams'])) {
+ $this->container['searchParams'] = $data['searchParams'];
+ }
+ if (isset($data['filters'])) {
+ $this->container['filters'] = $data['filters'];
+ }
+ if (isset($data['validUntil'])) {
+ $this->container['validUntil'] = $data['validUntil'];
+ }
+ if (isset($data['restrictIndices'])) {
+ $this->container['restrictIndices'] = $data['restrictIndices'];
+ }
+ if (isset($data['restrictSources'])) {
+ $this->container['restrictSources'] = $data['restrictSources'];
+ }
+ if (isset($data['userToken'])) {
+ $this->container['userToken'] = $data['userToken'];
+ }
+ }
+
+ /**
+ * Array of attributes where the key is the local name,
+ * and the value is the original name.
+ *
+ * @return array
+ */
+ public static function attributeMap()
+ {
+ return self::$attributeMap;
+ }
+
+ /**
+ * Array of property to type mappings. Used for (de)serialization.
+ *
+ * @return array
+ */
+ public static function modelTypes()
+ {
+ return self::$modelTypes;
+ }
+
+ /**
+ * Array of property to format mappings. Used for (de)serialization.
+ *
+ * @return array
+ */
+ public static function modelFormats()
+ {
+ return self::$modelFormats;
+ }
+
+ /**
+ * Array of attributes to setter functions (for deserialization of responses).
+ *
+ * @return array
+ */
+ public static function setters()
+ {
+ return self::$setters;
+ }
+
+ /**
+ * Array of attributes to getter functions (for serialization of requests).
+ *
+ * @return array
+ */
+ public static function getters()
+ {
+ return self::$getters;
+ }
+
+ /**
+ * Show all the invalid properties with reasons.
+ *
+ * @return array invalid properties with reasons
+ */
+ public function listInvalidProperties()
+ {
+ return [];
+ }
+
+ /**
+ * Validate all the properties in the model
+ * return true if all passed.
+ *
+ * @return bool True if all properties are valid
+ */
+ public function valid()
+ {
+ return 0 === count($this->listInvalidProperties());
+ }
+
+ /**
+ * Gets searchParams.
+ *
+ * @return null|\Algolia\AlgoliaSearch\Model\Search\SearchParamsObject
+ */
+ public function getSearchParams()
+ {
+ return $this->container['searchParams'] ?? null;
+ }
+
+ /**
+ * Sets searchParams.
+ *
+ * @param null|\Algolia\AlgoliaSearch\Model\Search\SearchParamsObject $searchParams searchParams
+ *
+ * @return self
+ */
+ public function setSearchParams($searchParams)
+ {
+ $this->container['searchParams'] = $searchParams;
+
+ return $this;
+ }
+
+ /**
+ * Gets filters.
+ *
+ * @return null|string
+ */
+ public function getFilters()
+ {
+ return $this->container['filters'] ?? null;
+ }
+
+ /**
+ * Sets filters.
+ *
+ * @param null|string $filters Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ *
+ * @return self
+ */
+ public function setFilters($filters)
+ {
+ $this->container['filters'] = $filters;
+
+ return $this;
+ }
+
+ /**
+ * Gets validUntil.
+ *
+ * @return null|float
+ */
+ public function getValidUntil()
+ {
+ return $this->container['validUntil'] ?? null;
+ }
+
+ /**
+ * Sets validUntil.
+ *
+ * @param null|float $validUntil unix timestamp used to set the expiration date of the API key
+ *
+ * @return self
+ */
+ public function setValidUntil($validUntil)
+ {
+ $this->container['validUntil'] = $validUntil;
+
+ return $this;
+ }
+
+ /**
+ * Gets restrictIndices.
+ *
+ * @return null|string[]
+ */
+ public function getRestrictIndices()
+ {
+ return $this->container['restrictIndices'] ?? null;
+ }
+
+ /**
+ * Sets restrictIndices.
+ *
+ * @param null|string[] $restrictIndices index names that can be queried
+ *
+ * @return self
+ */
+ public function setRestrictIndices($restrictIndices)
+ {
+ $this->container['restrictIndices'] = $restrictIndices;
+
+ return $this;
+ }
+
+ /**
+ * Gets restrictSources.
+ *
+ * @return null|string
+ */
+ public function getRestrictSources()
+ {
+ return $this->container['restrictSources'] ?? null;
+ }
+
+ /**
+ * Sets restrictSources.
+ *
+ * @param null|string $restrictSources IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ *
+ * @return self
+ */
+ public function setRestrictSources($restrictSources)
+ {
+ $this->container['restrictSources'] = $restrictSources;
+
+ return $this;
+ }
+
+ /**
+ * Gets userToken.
+ *
+ * @return null|string
+ */
+ public function getUserToken()
+ {
+ return $this->container['userToken'] ?? null;
+ }
+
+ /**
+ * Sets userToken.
+ *
+ * @param null|string $userToken Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ *
+ * @return self
+ */
+ public function setUserToken($userToken)
+ {
+ $this->container['userToken'] = $userToken;
+
+ return $this;
+ }
+
+ /**
+ * Returns true if offset exists. False otherwise.
+ *
+ * @param int $offset Offset
+ *
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->container[$offset]);
+ }
+
+ /**
+ * Gets offset.
+ *
+ * @param int $offset Offset
+ *
+ * @return null|mixed
+ */
+ public function offsetGet($offset)
+ {
+ return $this->container[$offset] ?? null;
+ }
+
+ /**
+ * Sets value based on offset.
+ *
+ * @param null|int $offset Offset
+ * @param mixed $value Value to be set
+ */
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ $this->container[] = $value;
+ } else {
+ $this->container[$offset] = $value;
+ }
+ }
+
+ /**
+ * Unsets offset.
+ *
+ * @param int $offset Offset
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->container[$offset]);
+ }
+}
diff --git a/clients/algoliasearch-client-python/algoliasearch/http/helpers.py b/clients/algoliasearch-client-python/algoliasearch/http/helpers.py
index 4acb59e6a4..c6ec476498 100644
--- a/clients/algoliasearch-client-python/algoliasearch/http/helpers.py
+++ b/clients/algoliasearch-client-python/algoliasearch/http/helpers.py
@@ -1,12 +1,7 @@
# coding: utf-8
from asyncio import sleep
-from json import loads
-from typing import Any, Callable, Dict, List, Optional, Protocol, Self, TypeVar, Union
-
-from pydantic import BaseModel
-
-from algoliasearch.search.models.search_params_object import SearchParamsObject
+from typing import Callable, Protocol, TypeVar
T = TypeVar("T")
@@ -57,59 +52,3 @@ async def retry(prev: T = None) -> T:
return await retry(resp)
return await retry()
-
-
-class SecuredApiKeyRestrictions(BaseModel):
- """
- SecuredApiKeyRestrictions
- """
-
- search_params: SearchParamsObject = SearchParamsObject()
- valid_until: Optional[int] = 0
- restrict_indices: Optional[Union[List[str], str]] = None
- restrict_sources: Optional[str] = None
- user_token: Optional[str] = None
-
- model_config = {"populate_by_name": True, "validate_assignment": True}
-
- def to_json(self) -> str:
- return self.model_dump_json(by_alias=True, exclude_unset=True)
-
- @classmethod
- def from_json(cls, json_str: str) -> Self:
- """Create an instance of SecuredApiKeyRestrictions from a JSON string"""
- return cls.from_dict(loads(json_str))
-
- def to_dict(self) -> Dict[str, Any]:
- """Return the dictionary representation of the model using alias.
-
- This has the following differences from calling pydantic's
- `self.model_dump(by_alias=True)`:
-
- * `None` is only added to the output dict for nullable fields that
- were set at model initialization. Other fields with value `None`
- are ignored.
- * Fields in `self.additional_properties` are added to the output dict.
- """
- return self.model_dump(
- by_alias=True,
- exclude={},
- exclude_none=True,
- )
-
- @classmethod
- def from_dict(cls, obj: Dict) -> Self:
- """Create an instance of SecuredApiKeyRestrictions from a dict"""
- if obj is None:
- return None
- if not isinstance(obj, dict):
- return cls.model_validate(obj)
- return cls.model_validate(
- {
- "search_params": SearchParamsObject.from_dict(obj.get("search_params")),
- "valid_until": int(obj.get("valid_until")),
- "restrict_indices": obj.get("restrict_indices"),
- "restrict_sources": obj.get("restrict_sources"),
- "user_token": obj.get("user_token"),
- }
- )
diff --git a/clients/algoliasearch-client-python/algoliasearch/search/client.py b/clients/algoliasearch-client-python/algoliasearch/search/client.py
index 804374b28f..845b779db2 100644
--- a/clients/algoliasearch-client-python/algoliasearch/search/client.py
+++ b/clients/algoliasearch-client-python/algoliasearch/search/client.py
@@ -20,11 +20,7 @@
from algoliasearch.http.api_response import ApiResponse
from algoliasearch.http.exceptions import RequestException, ValidUntilNotFoundException
-from algoliasearch.http.helpers import (
- RetryTimeout,
- SecuredApiKeyRestrictions,
- create_iterable,
-)
+from algoliasearch.http.helpers import RetryTimeout, create_iterable
from algoliasearch.http.request_options import RequestOptions
from algoliasearch.http.serializer import QueryParametersSerializer, bodySerializer
from algoliasearch.http.transporter import Transporter
@@ -102,6 +98,9 @@
from algoliasearch.search.models.search_synonyms_response import SearchSynonymsResponse
from algoliasearch.search.models.search_user_ids_params import SearchUserIdsParams
from algoliasearch.search.models.search_user_ids_response import SearchUserIdsResponse
+from algoliasearch.search.models.secured_api_key_restrictions import (
+ SecuredAPIKeyRestrictions,
+)
from algoliasearch.search.models.source import Source
from algoliasearch.search.models.synonym_hit import SynonymHit
from algoliasearch.search.models.update_api_key_response import UpdateApiKeyResponse
@@ -365,7 +364,7 @@ async def _func(_prev: SearchRulesResponse) -> SearchRulesResponse:
def generate_secured_api_key(
self,
parent_api_key: str,
- restrictions: Optional[SecuredApiKeyRestrictions] = SecuredApiKeyRestrictions(),
+ restrictions: Optional[SecuredAPIKeyRestrictions] = SecuredAPIKeyRestrictions(),
) -> str:
"""
Helper: Generates a secured API key based on the given `parent_api_key` and given `restrictions`.
@@ -373,7 +372,7 @@ def generate_secured_api_key(
query_parameters = dumps(
QueryParametersSerializer(
restrictions.to_dict()
- if isinstance(restrictions, SecuredApiKeyRestrictions)
+ if isinstance(restrictions, SecuredAPIKeyRestrictions)
else restrictions
).query_parameters
)
diff --git a/clients/algoliasearch-client-python/algoliasearch/search/models/api_key_operation.py b/clients/algoliasearch-client-python/algoliasearch/search/models/api_key_operation.py
new file mode 100644
index 0000000000..ed60a70b39
--- /dev/null
+++ b/clients/algoliasearch-client-python/algoliasearch/search/models/api_key_operation.py
@@ -0,0 +1,28 @@
+# coding: utf-8
+
+"""
+Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+"""
+from __future__ import annotations
+
+from enum import Enum
+from json import loads
+from typing import Self
+
+
+class ApiKeyOperation(str, Enum):
+ """
+ ApiKeyOperation
+ """
+
+ """
+ allowed enum values
+ """
+ ADD = "add"
+ DELETE = "delete"
+ UPDATE = "update"
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Self:
+ """Create an instance of ApiKeyOperation from a JSON string"""
+ return cls(loads(json_str))
diff --git a/clients/algoliasearch-client-python/algoliasearch/search/models/secured_api_key_restrictions.py b/clients/algoliasearch-client-python/algoliasearch/search/models/secured_api_key_restrictions.py
new file mode 100644
index 0000000000..e0b572a212
--- /dev/null
+++ b/clients/algoliasearch-client-python/algoliasearch/search/models/secured_api_key_restrictions.py
@@ -0,0 +1,99 @@
+# coding: utf-8
+
+"""
+Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+"""
+from __future__ import annotations
+
+from json import loads
+from typing import Any, Dict, List, Optional, Self, Union
+
+from pydantic import BaseModel, Field, StrictFloat, StrictInt, StrictStr
+
+from algoliasearch.search.models.search_params_object import SearchParamsObject
+
+
+class SecuredAPIKeyRestrictions(BaseModel):
+ """
+ SecuredAPIKeyRestrictions
+ """
+
+ search_params: Optional[SearchParamsObject] = Field(
+ default=None, alias="searchParams"
+ )
+ filters: Optional[StrictStr] = Field(
+ default=None,
+ description="Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors). ",
+ )
+ valid_until: Optional[Union[StrictFloat, StrictInt]] = Field(
+ default=None,
+ description="Unix timestamp used to set the expiration date of the API key.",
+ alias="validUntil",
+ )
+ restrict_indices: Optional[List[StrictStr]] = Field(
+ default=None,
+ description="Index names that can be queried.",
+ alias="restrictIndices",
+ )
+ restrict_sources: Optional[StrictStr] = Field(
+ default=None,
+ description="IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24). ",
+ alias="restrictSources",
+ )
+ user_token: Optional[StrictStr] = Field(
+ default=None,
+ description="Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse. ",
+ alias="userToken",
+ )
+
+ model_config = {"populate_by_name": True, "validate_assignment": True}
+
+ def to_json(self) -> str:
+ return self.model_dump_json(by_alias=True, exclude_unset=True)
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Self:
+ """Create an instance of SecuredAPIKeyRestrictions from a JSON string"""
+ return cls.from_dict(loads(json_str))
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Return the dictionary representation of the model using alias.
+
+ This has the following differences from calling pydantic's
+ `self.model_dump(by_alias=True)`:
+
+ * `None` is only added to the output dict for nullable fields that
+ were set at model initialization. Other fields with value `None`
+ are ignored.
+ """
+ _dict = self.model_dump(
+ by_alias=True,
+ exclude={},
+ exclude_none=True,
+ )
+ if self.search_params:
+ _dict["searchParams"] = self.search_params.to_dict()
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: Dict) -> Self:
+ """Create an instance of SecuredAPIKeyRestrictions from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return cls.model_validate(obj)
+
+ _obj = cls.model_validate(
+ {
+ "searchParams": SearchParamsObject.from_dict(obj.get("searchParams"))
+ if obj.get("searchParams") is not None
+ else None,
+ "filters": obj.get("filters"),
+ "validUntil": obj.get("validUntil"),
+ "restrictIndices": obj.get("restrictIndices"),
+ "restrictSources": obj.get("restrictSources"),
+ "userToken": obj.get("userToken"),
+ }
+ )
+ return _obj
diff --git a/clients/algoliasearch-client-ruby/lib/algolia/models/search/api_key_operation.rb b/clients/algoliasearch-client-ruby/lib/algolia/models/search/api_key_operation.rb
new file mode 100644
index 0000000000..517def2abb
--- /dev/null
+++ b/clients/algoliasearch-client-ruby/lib/algolia/models/search/api_key_operation.rb
@@ -0,0 +1,34 @@
+# Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+require 'date'
+require 'time'
+
+module Algolia
+ module Search
+ class ApiKeyOperation
+ ADD = "add".freeze
+ DELETE = "delete".freeze
+ UPDATE = "update".freeze
+
+ def self.all_vars
+ @all_vars ||= [ADD, DELETE, UPDATE].freeze
+ end
+
+ # Builds the enum from string
+ # @param [String] The enum value in the form of the string
+ # @return [String] The enum value
+ def self.build_from_hash(value)
+ new.build_from_hash(value)
+ end
+
+ # Builds the enum from string
+ # @param [String] The enum value in the form of the string
+ # @return [String] The enum value
+ def build_from_hash(value)
+ return value if ApiKeyOperation.all_vars.include?(value)
+
+ raise "Invalid ENUM value #{value} for class #ApiKeyOperation"
+ end
+ end
+ end
+end
diff --git a/clients/algoliasearch-client-ruby/lib/algolia/models/search/secured_api_key_restrictions.rb b/clients/algoliasearch-client-ruby/lib/algolia/models/search/secured_api_key_restrictions.rb
new file mode 100644
index 0000000000..48451feb37
--- /dev/null
+++ b/clients/algoliasearch-client-ruby/lib/algolia/models/search/secured_api_key_restrictions.rb
@@ -0,0 +1,248 @@
+# Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+require 'date'
+require 'time'
+
+module Algolia
+ module Search
+ class SecuredAPIKeyRestrictions
+ attr_accessor :search_params
+
+ # Filters that apply to every search made with the secured API key. You can add extra filters at search time with the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to groups:admin AND (groups:press OR groups:visitors).
+ attr_accessor :filters
+
+ # Unix timestamp used to set the expiration date of the API key.
+ attr_accessor :valid_until
+
+ # Index names that can be queried.
+ attr_accessor :restrict_indices
+
+ # IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ attr_accessor :restrict_sources
+
+ # Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default, rate limits are set based on the IP address. This can become an issue when several users search from the same IP address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user. Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and prevents abuse.
+ attr_accessor :user_token
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :search_params => :searchParams,
+ :filters => :filters,
+ :valid_until => :validUntil,
+ :restrict_indices => :restrictIndices,
+ :restrict_sources => :restrictSources,
+ :user_token => :userToken
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.types_mapping
+ {
+ :search_params => :SearchParamsObject,
+ :filters => :String,
+ :valid_until => :Float,
+ :restrict_indices => :'Array',
+ :restrict_sources => :String,
+ :user_token => :String
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ unless attributes.is_a?(Hash)
+ raise ArgumentError, "The input argument (attributes) must be a hash in `Algolia::SecuredAPIKeyRestrictions` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) do |(k, v), h|
+ unless self.class.attribute_map.key?(k.to_sym)
+ raise ArgumentError,
+ "`#{k}` is not a valid attribute in `Algolia::SecuredAPIKeyRestrictions`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+
+ h[k.to_sym] = v
+ end
+
+ if attributes.key?(:search_params)
+ self.search_params = attributes[:search_params]
+ end
+
+ if attributes.key?(:filters)
+ self.filters = attributes[:filters]
+ end
+
+ if attributes.key?(:valid_until)
+ self.valid_until = attributes[:valid_until]
+ end
+
+ if attributes.key?(:restrict_indices)
+ if (value = attributes[:restrict_indices]).is_a?(Array)
+ self.restrict_indices = value
+ end
+ end
+
+ if attributes.key?(:restrict_sources)
+ self.restrict_sources = attributes[:restrict_sources]
+ end
+
+ if attributes.key?(:user_token)
+ self.user_token = attributes[:user_token]
+ end
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(other)
+ return true if equal?(other)
+
+ self.class == other.class &&
+ search_params == other.search_params &&
+ filters == other.filters &&
+ valid_until == other.valid_until &&
+ restrict_indices == other.restrict_indices &&
+ restrict_sources == other.restrict_sources &&
+ user_token == other.user_token
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(other)
+ self == other
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [search_params, filters, valid_until, restrict_indices, restrict_sources, user_token].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ types_mapping.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash[key.to_sym] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash[key.to_sym] = attributes[attribute_map[key]].map { |v| _deserialize(::Regexp.last_match(1), v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash[key.to_sym] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Algolia::Search.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ def to_json(*_args)
+ to_hash.to_json
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+ end
+ end
+end
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/api/SearchClient.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/api/SearchClient.scala
index 37f73fe337..82c30eae47 100644
--- a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/api/SearchClient.scala
+++ b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/api/SearchClient.scala
@@ -5,6 +5,7 @@ package algoliasearch.api
import algoliasearch.search.AddApiKeyResponse
import algoliasearch.search.ApiKey
+import algoliasearch.search.ApiKeyOperation._
import algoliasearch.search.AssignUserIdParams
import algoliasearch.search.AttributeToUpdate
import algoliasearch.search.BatchAssignUserIdsParams
@@ -57,6 +58,7 @@ import algoliasearch.search.SearchSynonymsParams
import algoliasearch.search.SearchSynonymsResponse
import algoliasearch.search.SearchUserIdsParams
import algoliasearch.search.SearchUserIdsResponse
+import algoliasearch.search.SecuredAPIKeyRestrictions
import algoliasearch.search.Source
import algoliasearch.search.SynonymHit
import algoliasearch.search.UpdateApiKeyResponse
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/ApiKeyOperation.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/ApiKeyOperation.scala
deleted file mode 100644
index f2dd585976..0000000000
--- a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/ApiKeyOperation.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package algoliasearch.extension
-
-sealed trait ApiKeyOperation
-
-object ApiKeyOperation {
- case object Create extends ApiKeyOperation
- case object Update extends ApiKeyOperation
- case object Delete extends ApiKeyOperation
-}
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/package.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/package.scala
index c33534d672..023332d213 100644
--- a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/package.scala
+++ b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/extension/package.scala
@@ -34,7 +34,7 @@ package object extension {
requestOptions: Option[RequestOptions] = None
)(implicit ec: ExecutionContext): Future[Any] = {
operation match {
- case ApiKeyOperation.Create =>
+ case ApiKeyOperation.Add =>
client.waitKeyCreation(key, maxRetries, delay, requestOptions)
case ApiKeyOperation.Update =>
client.waitKeyUpdate(key, apiKey.get, maxRetries, delay, requestOptions)
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/ApiKeyOperation.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/ApiKeyOperation.scala
new file mode 100644
index 0000000000..85dfa7982d
--- /dev/null
+++ b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/ApiKeyOperation.scala
@@ -0,0 +1,48 @@
+/** Search API Use the Search REST API to manage your data (indices and records), implement search, and improve
+ * relevance (with Rules, synonyms, and language dictionaries). Although Algolia provides a REST API, you should use
+ * the official open source API [clients, libraries, and
+ * tools](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/) instead. There's no
+ * [SLA](https://www.algolia.com/policies/sla/) if you use the REST API directly.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech Do not edit the class manually.
+ */
+package algoliasearch.search
+
+import org.json4s._
+
+sealed trait ApiKeyOperation
+
+/** ApiKeyOperation enumeration
+ */
+object ApiKeyOperation {
+ case object Add extends ApiKeyOperation {
+ override def toString = "add"
+ }
+ case object Delete extends ApiKeyOperation {
+ override def toString = "delete"
+ }
+ case object Update extends ApiKeyOperation {
+ override def toString = "update"
+ }
+ val values: Seq[ApiKeyOperation] = Seq(Add, Delete, Update)
+
+ def withName(name: String): ApiKeyOperation = ApiKeyOperation.values
+ .find(_.toString == name)
+ .getOrElse(throw new MappingException(s"Unknown ApiKeyOperation value: $name"))
+}
+
+class ApiKeyOperationSerializer
+ extends CustomSerializer[ApiKeyOperation](_ =>
+ (
+ {
+ case JString(value) => ApiKeyOperation.withName(value)
+ case JNull => null
+ },
+ { case value: ApiKeyOperation =>
+ JString(value.toString)
+ }
+ )
+ )
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/JsonSupport.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/JsonSupport.scala
index 8f095b2006..f2af940c60 100644
--- a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/JsonSupport.scala
+++ b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/JsonSupport.scala
@@ -20,6 +20,7 @@ object JsonSupport {
new AdvancedSyntaxFeaturesSerializer() :+
new AlternativesAsExactSerializer() :+
new AnchoringSerializer() :+
+ new ApiKeyOperationSerializer() :+
new AroundRadiusAllSerializer() :+
new BuiltInOperationTypeSerializer() :+
new DictionaryActionSerializer() :+
diff --git a/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/SecuredAPIKeyRestrictions.scala b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/SecuredAPIKeyRestrictions.scala
new file mode 100644
index 0000000000..5abec92259
--- /dev/null
+++ b/clients/algoliasearch-client-scala/src/main/scala/algoliasearch/search/SecuredAPIKeyRestrictions.scala
@@ -0,0 +1,45 @@
+/** Search API Use the Search REST API to manage your data (indices and records), implement search, and improve
+ * relevance (with Rules, synonyms, and language dictionaries). Although Algolia provides a REST API, you should use
+ * the official open source API [clients, libraries, and
+ * tools](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/) instead. There's no
+ * [SLA](https://www.algolia.com/policies/sla/) if you use the REST API directly.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech Do not edit the class manually.
+ */
+package algoliasearch.search
+
+/** SecuredAPIKeyRestrictions
+ *
+ * @param filters
+ * Filters that apply to every search made with the secured API key. You can add extra filters at search time with
+ * the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you add
+ * groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to
+ * groups:admin AND (groups:press OR groups:visitors).
+ * @param validUntil
+ * Unix timestamp used to set the expiration date of the API key.
+ * @param restrictIndices
+ * Index names that can be queried.
+ * @param restrictSources
+ * IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can only
+ * provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ * @param userToken
+ * Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default,
+ * rate limits are set based on the IP address. This can become an issue when several users search from the same IP
+ * address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets you
+ * restrict each user to a maximum number of API calls per hour, even if they share their IP with another user.
+ * Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change
+ * it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user
+ * identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and
+ * prevents abuse.
+ */
+case class SecuredAPIKeyRestrictions(
+ searchParams: Option[SearchParamsObject] = scala.None,
+ filters: Option[String] = scala.None,
+ validUntil: Option[Double] = scala.None,
+ restrictIndices: Option[Seq[String]] = scala.None,
+ restrictSources: Option[String] = scala.None,
+ userToken: Option[String] = scala.None
+)
diff --git a/clients/algoliasearch-client-swift/Sources/Search/Extra/APIKeyOperation.swift b/clients/algoliasearch-client-swift/Sources/Search/Extra/APIKeyOperation.swift
deleted file mode 100644
index 7b1912be2d..0000000000
--- a/clients/algoliasearch-client-swift/Sources/Search/Extra/APIKeyOperation.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// APIKeyOperation.swift
-//
-//
-// Created by Algolia on 26/02/2024.
-//
-
-import Foundation
-
-public enum ApiKeyOperation: String {
- case add
- case update
- case delete
-}
diff --git a/clients/algoliasearch-client-swift/Sources/Search/Extra/SearchHelpers.swift b/clients/algoliasearch-client-swift/Sources/Search/Extra/SearchHelpers.swift
index ea06a39cdc..74b0e94b4a 100644
--- a/clients/algoliasearch-client-swift/Sources/Search/Extra/SearchHelpers.swift
+++ b/clients/algoliasearch-client-swift/Sources/Search/Extra/SearchHelpers.swift
@@ -445,7 +445,7 @@ public extension SearchClient {
/// - returns: String?
func generateSecuredApiKey(
parentApiKey: String,
- with restriction: SecuredAPIKeyRestriction = SecuredAPIKeyRestriction()
+ with restriction: SecuredAPIKeyRestrictions = SecuredAPIKeyRestrictions()
) throws -> String? {
let queryParams = try restriction.toURLEncodedString()
let hash = queryParams.hmac256(withKey: parentApiKey)
diff --git a/clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredAPIKeyRestriction.swift b/clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredApiKeyRestrictionExtension.swift
similarity index 58%
rename from clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredAPIKeyRestriction.swift
rename to clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredApiKeyRestrictionExtension.swift
index 935b1dee2c..845bbbe6b2 100644
--- a/clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredAPIKeyRestriction.swift
+++ b/clients/algoliasearch-client-swift/Sources/Search/Extra/SecuredApiKeyRestrictionExtension.swift
@@ -1,54 +1,30 @@
-//
-// SecuredAPIKeyRestriction.swift
-//
-//
-// Created by Algolia on 26/02/2024.
-//
-
import Core
import Foundation
-public struct SecuredAPIKeyRestriction {
- let searchParams: SearchParamsObject?
- let validUntil: TimeInterval?
- let restrictIndices: [String]?
- let restrictSources: [String]?
- let userToken: String?
-
- public init(
- searchParams: SearchParamsObject? = nil,
- validUntil: TimeInterval? = nil,
- restrictIndices: [String]? = nil,
- restrictSources: [String]? = nil,
- userToken: String? = nil
- ) {
- self.searchParams = searchParams
- self.validUntil = validUntil
- self.restrictIndices = restrictIndices
- self.restrictSources = restrictSources
- self.userToken = userToken
- }
-
+public extension SecuredAPIKeyRestrictions {
func toURLEncodedString() throws -> String {
var queryDictionary: [String: Any] = [:]
if let searchParams {
- let searchParamsData = try CodableHelper.jsonEncoder.encode(self.searchParams)
+ let searchParamsData = try CodableHelper.jsonEncoder.encode(searchParams)
guard let searchParamsDictionary = try JSONSerialization.jsonObject(
with: searchParamsData,
options: .fragmentsAllowed
) as? [String: Any] else {
- throw AlgoliaError.runtimeError("Unable to encode Secured API Key Restrictions search parameters")
+ throw AlgoliaError.runtimeError("Unable to encode Secured API Key restrictions search parameters")
}
queryDictionary = searchParamsDictionary
}
+ if let filters {
+ queryDictionary["filters"] = filters
+ }
if let validUntil {
queryDictionary["validUntil"] = Int(validUntil)
}
if let restrictIndices {
- queryDictionary["restrictIndices"] = restrictIndices
+ queryDictionary["restrictIndices"] = restrictIndices.joined(separator: ",")
}
if let restrictSources {
queryDictionary["restrictSources"] = restrictSources
diff --git a/clients/algoliasearch-client-swift/Sources/Search/Models/ApiKeyOperation.swift b/clients/algoliasearch-client-swift/Sources/Search/Models/ApiKeyOperation.swift
new file mode 100644
index 0000000000..3a6c40d248
--- /dev/null
+++ b/clients/algoliasearch-client-swift/Sources/Search/Models/ApiKeyOperation.swift
@@ -0,0 +1,12 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on
+// https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+import AnyCodable
+import Core
+import Foundation
+
+public enum ApiKeyOperation: String, Codable, CaseIterable {
+ case add
+ case delete
+ case update
+}
diff --git a/clients/algoliasearch-client-swift/Sources/Search/Models/SecuredAPIKeyRestrictions.swift b/clients/algoliasearch-client-swift/Sources/Search/Models/SecuredAPIKeyRestrictions.swift
new file mode 100644
index 0000000000..49aa441294
--- /dev/null
+++ b/clients/algoliasearch-client-swift/Sources/Search/Models/SecuredAPIKeyRestrictions.swift
@@ -0,0 +1,68 @@
+// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on
+// https://github.com/algolia/api-clients-automation. DO NOT EDIT.
+
+import AnyCodable
+import Core
+import Foundation
+
+public struct SecuredAPIKeyRestrictions: Codable, JSONEncodable, Hashable {
+ public var searchParams: SearchParamsObject?
+ /// Filters that apply to every search made with the secured API key. You can add extra filters at search time with
+ /// the filters query parameter. For example, if you set the filter group:admin on your generated API key, and you
+ /// add groups:press OR groups:visitors with the filters query parameter, your final search filter is equivalent to
+ /// groups:admin AND (groups:press OR groups:visitors).
+ public var filters: String?
+ /// Unix timestamp used to set the expiration date of the API key.
+ public var validUntil: Double?
+ /// Index names that can be queried.
+ public var restrictIndices: [String]?
+ /// IPv4 network allowed to use the generated key. Use this to protect against API key leaking and reuse. You can
+ /// only provide a single source, but you can specify a range of IPs (for example, 192.168.1.0/24).
+ public var restrictSources: String?
+ /// Unique user IP address. This can be useful when you want to impose a rate limit on specific users. By default,
+ /// rate limits are set based on the IP address. This can become an issue when several users search from the same IP
+ /// address. To avoid this, you can set a unique userToken for each user when generating their API key. This lets
+ /// you restrict each user to a maximum number of API calls per hour, even if they share their IP with another user.
+ /// Specifying the userToken in a secured API key is also a good security practice as it ensures users don't change
+ /// it. Many features like Analytics, Personalization, and Dynamic Re-ranking rely on the authenticity of user
+ /// identifiers. Setting the userToken at the API key level ensures that downstream services work as expected and
+ /// prevents abuse.
+ public var userToken: String?
+
+ public init(
+ searchParams: SearchParamsObject? = nil,
+ filters: String? = nil,
+ validUntil: Double? = nil,
+ restrictIndices: [String]? = nil,
+ restrictSources: String? = nil,
+ userToken: String? = nil
+ ) {
+ self.searchParams = searchParams
+ self.filters = filters
+ self.validUntil = validUntil
+ self.restrictIndices = restrictIndices
+ self.restrictSources = restrictSources
+ self.userToken = userToken
+ }
+
+ public enum CodingKeys: String, CodingKey, CaseIterable {
+ case searchParams
+ case filters
+ case validUntil
+ case restrictIndices
+ case restrictSources
+ case userToken
+ }
+
+ // Encodable protocol methods
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+ try container.encodeIfPresent(self.searchParams, forKey: .searchParams)
+ try container.encodeIfPresent(self.filters, forKey: .filters)
+ try container.encodeIfPresent(self.validUntil, forKey: .validUntil)
+ try container.encodeIfPresent(self.restrictIndices, forKey: .restrictIndices)
+ try container.encodeIfPresent(self.restrictSources, forKey: .restrictSources)
+ try container.encodeIfPresent(self.userToken, forKey: .userToken)
+ }
+}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaCSharpGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaCSharpGenerator.java
index 7d35933e5e..431cde929c 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaCSharpGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaCSharpGenerator.java
@@ -151,6 +151,7 @@ public void processOpenAPI(OpenAPI openAPI) {
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
return operations;
}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java
index 5cedf8ce8a..3cb99c75ee 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java
@@ -133,6 +133,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) {
OperationsMap operationsMap = super.postProcessOperationsWithModels(objs, allModels);
+ Helpers.removeHelpers(operationsMap);
return support.clearOneOfFromApiImports(operationsMap);
}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaGoGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaGoGenerator.java
index b6d102e82f..37fe797aff 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaGoGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaGoGenerator.java
@@ -129,6 +129,7 @@ public Map postProcessAllModels(Map objs)
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
return operations;
}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java
index b77d30fdc8..18778b31f0 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java
@@ -3,7 +3,9 @@
import com.algolia.codegen.exceptions.*;
import com.algolia.codegen.utils.*;
import com.algolia.codegen.utils.OneOf;
+import com.google.common.collect.ImmutableMap.Builder;
import com.samskivert.mustache.Mustache;
+import com.samskivert.mustache.Mustache.Lambda;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
@@ -50,7 +52,6 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("build_config.mustache", invokerFolder, "BuildConfig.java"));
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties"));
additionalProperties.put("isSearchClient", client.equals("search"));
- additionalProperties.put("lambda.type-to-name", (Mustache.Lambda) (fragment, writer) -> writer.write(typeToName(fragment.execute())));
try {
additionalProperties.put("packageVersion", Helpers.getClientConfigField("java", "packageVersion"));
@@ -89,6 +90,7 @@ public Map postProcessAllModels(Map objs)
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
return operations;
}
@@ -119,4 +121,13 @@ public String toEnumVarName(String value, String datatype) {
private String typeToName(String content) {
return content.trim().replace("<", "Of").replace(">", "").replace(",", "").replace(" ", "");
}
+
+ @Override
+ protected Builder addMustacheLambdas() {
+ Builder lambdas = super.addMustacheLambdas();
+
+ lambdas.put("type-to-name", (Mustache.Lambda) (fragment, writer) -> writer.write(typeToName(fragment.execute())));
+
+ return lambdas;
+ }
}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java
index 109982fae8..7f3644e2ed 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java
@@ -178,6 +178,7 @@ public Map postProcessAllModels(Map objs)
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) {
OperationsMap results = super.postProcessOperationsWithModels(objs, allModels);
+ Helpers.removeHelpers(results);
setDefaultGeneratorOptions();
try {
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaKotlinGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaKotlinGenerator.java
index 0f03d8bfa9..9c8aab456d 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaKotlinGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaKotlinGenerator.java
@@ -187,6 +187,7 @@ private static void jsonParent(Map models) {
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
return operations;
}
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java
index 9b0bcc4bc7..5f916bf918 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java
@@ -9,6 +9,8 @@
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.languages.PhpClientCodegen;
+import org.openapitools.codegen.model.ModelMap;
+import org.openapitools.codegen.model.OperationsMap;
public class AlgoliaPhpGenerator extends PhpClientCodegen {
@@ -70,6 +72,13 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
return Helpers.specifyCustomRequest(super.fromOperation(path, httpMethod, operation, servers));
}
+ @Override
+ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
+ OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
+ return operations;
+ }
+
@Override
public String getComposerPackageName() {
return "algolia/algoliasearch-client-php";
diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaPythonGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaPythonGenerator.java
index f8e0f6bd1e..b63e8bb3a7 100644
--- a/generators/src/main/java/com/algolia/codegen/AlgoliaPythonGenerator.java
+++ b/generators/src/main/java/com/algolia/codegen/AlgoliaPythonGenerator.java
@@ -117,6 +117,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List models) {
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
+ Helpers.removeHelpers(operations);
List