diff --git a/clients/algoliasearch-client-java/.java-version b/clients/algoliasearch-client-java/.java-version index 7f4e82686d6..d79aa6586ce 100644 --- a/clients/algoliasearch-client-java/.java-version +++ b/clients/algoliasearch-client-java/.java-version @@ -1 +1 @@ -21.0.8 +21.0.6 diff --git a/clients/algoliasearch-client-php/lib/FormDataProcessor.php b/clients/algoliasearch-client-php/lib/FormDataProcessor.php index bc221fd9856..1e2d657ca20 100644 --- a/clients/algoliasearch-client-php/lib/FormDataProcessor.php +++ b/clients/algoliasearch-client-php/lib/FormDataProcessor.php @@ -12,9 +12,9 @@ */ /** - * Search API. + * Ingestion API. * - * The Algolia Search API lets you search, configure, and manage your indices and records. ## Client libraries Use Algolia's API clients and libraries to reliably integrate Algolia's APIs with your apps. The official API clients are covered by Algolia's [Service Level Agreement](https://www.algolia.com/policies/sla/). See: [Algolia's ecosystem](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/) ## Base URLs The base URLs for requests to the Search API are: - `https://{APPLICATION_ID}.algolia.net` - `https://{APPLICATION_ID}-dsn.algolia.net`. If your subscription includes a [Distributed Search Network](https://dashboard.algolia.com/infra), this ensures that requests are sent to servers closest to users. Both URLs provide high availability by distributing requests with load balancing. **All requests must use HTTPS.** ## Retry strategy To guarantee high availability, implement a retry strategy for all API requests using the URLs of your servers as fallbacks: - `https://{APPLICATION_ID}-1.algolianet.com` - `https://{APPLICATION_ID}-2.algolianet.com` - `https://{APPLICATION_ID}-3.algolianet.com` These URLs use a different DNS provider than the primary URLs. You should randomize this list to ensure an even load across the three servers. All Algolia API clients implement this retry strategy. ## Authentication To authenticate your API requests, add these headers: - `x-algolia-application-id`. Your Algolia application ID. - `x-algolia-api-key`. An API key with the necessary permissions to make the request. The required access control list (ACL) to make a request is listed in each endpoint's reference. You can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account). ## Request format Depending on the endpoint, request bodies are either JSON objects or arrays of JSON objects, ## Parameters Parameters are passed as query parameters for GET and DELETE requests, and in the request body for POST and PUT requests. Query parameters must be [URL-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding). Non-ASCII characters must be UTF-8 encoded. Plus characters (`+`) are interpreted as spaces. Arrays as query parameters must be one of: - A comma-separated string: `attributesToRetrieve=title,description` - A URL-encoded JSON array: `attributesToRetrieve=%5B%22title%22,%22description%22%D` ## Response status and errors The Search API returns JSON responses. Since JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response. Successful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status. Error responses have a `message` property with more information. ## Version The current version of the Search API is version 1, as indicated by the `/1/` in each endpoint's URL. + * The Ingestion API lets you connect third-party services and platforms with Algolia and schedule tasks to ingest your data. The Ingestion API powers the no-code [data connectors](https://dashboard.algolia.com/connectors). ## Base URLs The base URLs for requests to the Ingestion API are: - `https://data.us.algolia.com` - `https://data.eu.algolia.com` Use the URL that matches your [analytics region](https://dashboard.algolia.com/account/infrastructure/analytics). **All requests must use HTTPS.** ## Authentication To authenticate your API requests, add these headers: - `x-algolia-application-id`. Your Algolia application ID. - `x-algolia-api-key`. An API key with the necessary permissions to make the request. The required access control list (ACL) to make a request is listed in each endpoint's reference. You can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account). ## Request format Request bodies must be JSON objects. ## Response status and errors Response bodies are JSON objects. Successful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status. Error responses have a `message` property with more information. ## Version The current version of the Ingestion API is version 1, as indicated by the `/1/` in each endpoint's URL. * * The version of the OpenAPI document: 1.0.0 * Generated by: https://openapi-generator.tech @@ -29,7 +29,7 @@ namespace Algolia\AlgoliaSearch; -use Algolia\AlgoliaSearch\Model\Search\ModelInterface; +use Algolia\AlgoliaSearch\Model\Ingestion\ModelInterface; use DateTime; use GuzzleHttp\Psr7\Utils; use Psr\Http\Message\StreamInterface; diff --git a/playground/javascript/node/algoliasearch.ts b/playground/javascript/node/algoliasearch.ts index 2853bbaa08f..b2343ec6063 100644 --- a/playground/javascript/node/algoliasearch.ts +++ b/playground/javascript/node/algoliasearch.ts @@ -152,7 +152,7 @@ async function testAlgoliasearchBridgeIngestion() { console.log('replaceAllObjectsWithTransformation', await client.replaceAllObjectsWithTransformation({ indexName: 'boyd', objects: [{ objectID: 'foo', data: { baz: 'baz', win: 42 } }, { objectID: 'bar', data: { baz: 'baz', win: 24 } }], - batchSize: 2 + batchSize: 1 })); } diff --git a/scripts/cts/testServer/replaceAllObjectsWithTransformation.ts b/scripts/cts/testServer/replaceAllObjectsWithTransformation.ts index 29b83a57aeb..09d70ba9692 100644 --- a/scripts/cts/testServer/replaceAllObjectsWithTransformation.ts +++ b/scripts/cts/testServer/replaceAllObjectsWithTransformation.ts @@ -10,7 +10,9 @@ const raowtState: Record< string, { copyCount: number; + deleteCount: number; pushCount: number; + getEventCount: number; tmpIndexName: string; waitTaskCount: number; waitingForFinalWaitTask: boolean; @@ -33,6 +35,28 @@ function addRoutes(app: Express): void { }), ); + app.delete('/1/indexes/:indexName', (req, res) => { + expect(req.params.indexName).to.match(/^cts_e2e_replace_all_objects_with_transformation_(.*)$/); + + const lang = req.params.indexName.replace('cts_e2e_replace_all_objects_with_transformation_', ''); + if (!raowtState[lang] || raowtState[lang].successful) { + raowtState[lang] = { + copyCount: 0, + pushCount: 0, + getEventCount: 0, + deleteCount: 1, + waitTaskCount: 0, + tmpIndexName: req.params.indexName, + waitingForFinalWaitTask: false, + successful: false, + }; + } else { + raowtState[lang].deleteCount++; + } + + res.json({ taskID: 123 + raowtState[lang].copyCount, deletedAt: '2021-01-01T00:00:00.000Z' }); + }); + app.post('/1/indexes/:indexName/operation', (req, res) => { expect(req.params.indexName).to.match(/^cts_e2e_replace_all_objects_with_transformation_(.*)$/); @@ -47,6 +71,8 @@ function addRoutes(app: Express): void { raowtState[lang] = { copyCount: 1, pushCount: 0, + getEventCount: 0, + deleteCount: 0, waitTaskCount: 0, tmpIndexName: req.body.destination, waitingForFinalWaitTask: false, @@ -62,9 +88,12 @@ function addRoutes(app: Express): void { case 'move': { const lang = req.body.destination.replace('cts_e2e_replace_all_objects_with_transformation_', ''); expect(raowtState).to.include.keys(lang); + console.log(raowtState[lang]); expect(raowtState[lang]).to.deep.equal({ copyCount: 2, - pushCount: 10, + pushCount: 4, + getEventCount: 4, + deleteCount: 0, waitTaskCount: 2, tmpIndexName: req.params.indexName, waitingForFinalWaitTask: false, @@ -94,10 +123,10 @@ function addRoutes(app: Express): void { expect(req.body.action === 'addObject').to.equal(true); expect(req.query.referenceIndexName === `cts_e2e_replace_all_objects_with_transformation_${lang}`).to.equal(true); - raowtState[lang].pushCount += req.body.records.length; + raowtState[lang].pushCount++; res.json({ - runID: 'b1b7a982-524c-40d2-bb7f-48aab075abda', + runID: `b1b7a982-524c-40d2-bb7f-48aab075abda_${lang}`, eventID: `113b2068-6337-4c85-b5c2-e7b213d8292${raowtState[lang].pushCount}`, message: 'OK', createdAt: '2022-05-12T06:24:30.049Z', @@ -105,10 +134,14 @@ function addRoutes(app: Express): void { }); app.get('/1/runs/:runID/events/:eventID', (req, res) => { + const lang = req.params.runID.match(/^b1b7a982-524c-40d2-bb7f-48aab075abda_(.*)$/)?.[1] as string; + + raowtState[lang].getEventCount++; + res.json({ status: 'succeeded', - eventID: '113b2068-6337-4c85-b5c2-e7b213d82921', - runID: 'b1b7a982-524c-40d2-bb7f-48aab075abda', + eventID: req.params.eventID, + runID: req.params.runID, type: 'fetch', batchSize: 1, publishedAt: '2022-05-12T06:24:30.049Z', @@ -123,10 +156,18 @@ function addRoutes(app: Express): void { raowtState[lang].waitTaskCount++; if (raowtState[lang].waitingForFinalWaitTask) { - expect(req.params.taskID).to.equal('777'); - expect(raowtState[lang].waitTaskCount).to.equal(3); - raowtState[lang].successful = true; + expect(req.params.taskID).to.equal('777'); + expect(raowtState[lang]).to.deep.equal({ + copyCount: 2, + pushCount: 4, + getEventCount: 4, + deleteCount: 0, + waitTaskCount: 3, + tmpIndexName: req.params.indexName, + waitingForFinalWaitTask: true, + successful: true, + }); } res.json({ status: 'published', updatedAt: '2021-01-01T00:00:00.000Z' }); diff --git a/templates/go/ingestion_helpers.mustache b/templates/go/ingestion_helpers.mustache index 2e2229799cb..bfa11410336 100644 --- a/templates/go/ingestion_helpers.mustache +++ b/templates/go/ingestion_helpers.mustache @@ -16,6 +16,12 @@ func (c *APIClient) ChunkedPush(indexName string, objects []map[string]any, acti batchSize: 1000, } + offset := 0 + waitBatchSize := conf.batchSize / 10 + if waitBatchSize < 1 { + waitBatchSize = conf.batchSize + } + for _, opt := range opts { opt.apply(&conf) } @@ -58,31 +64,42 @@ func (c *APIClient) ChunkedPush(indexName string, objects []map[string]any, acti responses = append(responses, *resp) records = make([]map[string]any, 0, len(objects)%conf.batchSize) } - } - if conf.waitForTasks { - for _, resp := range responses { - _, err := CreateIterable( //nolint:wrapcheck - func(*Event, error) (*Event, error) { - if resp.EventID == nil { - return nil, reportError("received unexpected response from the push endpoint, eventID must not be undefined") - } - - return c.GetEvent(c.NewApiGetEventRequest(resp.RunID, *resp.EventID)) - }, - func(response *Event, err error) (bool, error) { - var apiErr *APIError - if errors.As(err, &apiErr) { - return apiErr.Status != 404, nil - } - - return true, err - }, - WithTimeout(func(count int) time.Duration { return time.Duration(min(500*count, 5000)) * time.Millisecond }), WithMaxRetries(50), - ) - if err != nil { - return nil, err + + if conf.waitForTasks && len(responses) > 0 && (len(responses)%waitBatchSize == 0 || i == len(objects)-1) { + var waitableResponses []WatchResponse + + if len(responses) > offset+waitBatchSize { + waitableResponses = responses[offset:waitBatchSize] + } else { + waitableResponses = responses[offset:] } + + for _, resp := range waitableResponses { + _, err := CreateIterable( + func(*Event, error) (*Event, error) { + if resp.EventID == nil { + return nil, reportError("received unexpected response from the push endpoint, eventID must not be undefined") + } + + return c.GetEvent(c.NewApiGetEventRequest(resp.RunID, *resp.EventID)) + }, + func(response *Event, err error) (bool, error) { + var apiErr *APIError + if errors.As(err, &apiErr) { + return apiErr.Status != 404, nil + } + + return true, err + }, + WithTimeout(func(count int) time.Duration { return time.Duration(min(500*count, 5000)) * time.Millisecond }), WithMaxRetries(50), + ) + if err != nil { + return nil, err + } + } + + offset += waitBatchSize } } diff --git a/templates/java/api.mustache b/templates/java/api.mustache index 8f7f38baad8..beaf00b0eab 100644 --- a/templates/java/api.mustache +++ b/templates/java/api.mustache @@ -20,6 +20,7 @@ import java.util.function.IntUnaryOperator; import java.time.Duration; import java.util.EnumSet; +import java.util.Iterator; import java.util.Random; import java.util.Collections; import java.util.ArrayList; diff --git a/templates/java/api_helpers.mustache b/templates/java/api_helpers.mustache index 4445d8238cb..a96fc262e11 100644 --- a/templates/java/api_helpers.mustache +++ b/templates/java/api_helpers.mustache @@ -44,58 +44,62 @@ public List chunkedPush( ) { List responses = new ArrayList<>(); List records = new ArrayList<>(); + int offset = 0; + int waitBatchSize = batchSize / 10; + if (waitBatchSize < 1) { + waitBatchSize = batchSize; + } - for (T item : objects) { - if (records.size() == batchSize) { - WatchResponse watch = - this.push( - indexName, - new PushTaskPayload().setAction(action).setRecords(this.objectsToPushTaskRecords(records)), - waitForTasks, - referenceIndexName, - requestOptions - ); + Iterator it = objects.iterator(); + T current = it.next(); + + while (true) { + records.add(current); + + if (records.size() == batchSize || !it.hasNext()) { + WatchResponse watch = this.push( + indexName, + new PushTaskPayload().setAction(action).setRecords(this.objectsToPushTaskRecords(records)), + waitForTasks, + referenceIndexName, + requestOptions + ); responses.add(watch); records.clear(); } - records.add(item); - } + if (waitForTasks && responses.size() > 0 && (responses.size() % waitBatchSize == 0 || !it.hasNext())) { + responses + .subList(offset, Math.min(offset + waitBatchSize, responses.size())) + .forEach(response -> { + TaskUtils.retryUntil( + () -> { + try { + return this.getEvent(response.getRunID(), response.getEventID()); + } catch (AlgoliaApiException e) { + if (e.getStatusCode() == 404) { + return null; + } + + throw e; + } + }, + (Event resp) -> { + return resp != null; + }, + 50, + null + ); + }); - if (records.size() > 0) { - WatchResponse watch = - this.push( - indexName, - new PushTaskPayload().setAction(action).setRecords(this.objectsToPushTaskRecords(records)), - waitForTasks, - referenceIndexName, - requestOptions - ); - responses.add(watch); - } + offset += waitBatchSize; + } - if (waitForTasks) { - responses.forEach(response -> { - TaskUtils.retryUntil( - () -> { - try { - return this.getEvent(response.getRunID(), response.getEventID()); - } catch (AlgoliaApiException e) { - if (e.getStatusCode() == 404) { - return null; - } + if (!it.hasNext()) { + break; + } - throw e; - } - }, - (Event resp) -> { - return resp != null; - }, - 50, - null - ); - } - ); + current = it.next(); } return responses; diff --git a/templates/javascript/clients/client/api/ingestionHelpers.mustache b/templates/javascript/clients/client/api/ingestionHelpers.mustache index ad9ff089179..2d8102ae94d 100644 --- a/templates/javascript/clients/client/api/ingestionHelpers.mustache +++ b/templates/javascript/clients/client/api/ingestionHelpers.mustache @@ -12,58 +12,65 @@ * @param requestOptions - The requestOptions to send along with the query, they will be forwarded to the `getEvent` method and merged with the transporter requestOptions. */ async chunkedPush( - { indexName, objects, action = 'addObject', waitForTasks, batchSize = 1000, referenceIndexName }: ChunkedPushOptions, + { + indexName, + objects, + action = 'addObject', + waitForTasks, + batchSize = 1000, + referenceIndexName, + }: ChunkedPushOptions, requestOptions?: RequestOptions, ): Promise> { let records: Array = []; + let offset = 0; const responses: Array = []; + const waitBatchSize = Math.floor(batchSize / 10) || batchSize; const objectEntries = objects.entries(); for (const [i, obj] of objectEntries) { records.push(obj as PushTaskRecords); if (records.length === batchSize || i === objects.length - 1) { responses.push( - await this.push( - { indexName, pushTaskPayload: { action, records }, referenceIndexName }, - requestOptions, - ), + await this.push({ indexName, pushTaskPayload: { action, records }, referenceIndexName }, requestOptions), ); records = []; } - } - - let retryCount = 0; - if (waitForTasks) { - for (const resp of responses) { - if (!resp.eventID) { - throw new Error('received unexpected response from the push endpoint, eventID must not be undefined'); - } + if (waitForTasks && responses.length > 0 && (responses.length % waitBatchSize === 0 || i === objects.length - 1)) { + for (const resp of responses.slice(offset, offset+waitBatchSize)) { + if (!resp.eventID) { + throw new Error('received unexpected response from the push endpoint, eventID must not be undefined'); + } - await createIterablePromise({ - func: async () => { - if (resp.eventID === undefined || !resp.eventID) { - throw new Error('received unexpected response from the push endpoint, eventID must not be undefined'); - } + let retryCount = 0; - return this.getEvent({ runID: resp.runID, eventID: resp.eventID }).catch((error: ApiError) => { - if (error.status === 404) { - return undefined; + await createIterablePromise({ + func: async () => { + if (resp.eventID === undefined || !resp.eventID) { + throw new Error('received unexpected response from the push endpoint, eventID must not be undefined'); } - throw error; - }) - }, - validate: (response) => response !== undefined, - aggregator: () => (retryCount += 1), - error: { - validate: () => retryCount >= 50, - message: () => `The maximum number of retries exceeded. (${retryCount}/${50})`, - }, - timeout: (): number => Math.min(retryCount * 500, 5000), - }); + return this.getEvent({ runID: resp.runID, eventID: resp.eventID }).catch((error: ApiError) => { + if (error.status === 404) { + return undefined; + } + + throw error; + }); + }, + validate: (response) => response !== undefined, + aggregator: () => (retryCount += 1), + error: { + validate: () => retryCount >= 50, + message: () => `The maximum number of retries exceeded. (${retryCount}/${50})`, + }, + timeout: (): number => Math.min(retryCount * 500, 5000), + }); + } + offset += waitBatchSize; } } return responses; -}, +}, \ No newline at end of file diff --git a/templates/php/api.mustache b/templates/php/api.mustache index a7ff22fb826..ef85c064f57 100644 --- a/templates/php/api.mustache +++ b/templates/php/api.mustache @@ -337,49 +337,50 @@ use Algolia\AlgoliaSearch\Exceptions\NotFoundException; $responses = []; $records = []; $count = 0; + $offset = 0; + $waitBatchSize = (int) ($batchSize / 10); + if ($waitBatchSize < 1) { + $waitBatchSize = $batchSize; + } foreach ($objects as $object) { $records[] = $object; $ok = false; + ++$count; - if (sizeof($records) === $batchSize || $count === sizeof($objects) - 1) { + if (sizeof($records) === $batchSize || $count === sizeof($objects)) { $responses[] = $this->push($indexName, ['action' => $action, 'records' => $records], false, $referenceIndexName, $requestOptions); $records = []; } - ++$count; - } + if ($waitForTasks && !empty($responses) && (0 === sizeof($responses) % $waitBatchSize || $count === sizeof($objects))) { + $timeoutCalculation = 'Algolia\AlgoliaSearch\Support\Helpers::linearTimeout'; - if (!empty($records)) { - $responses[] = $this->push($indexName, ['action' => $action, 'records' => $records], false, $referenceIndexName, $requestOptions); - } + foreach (array_slice($responses, $offset, $waitBatchSize) as $response) { + $retry = 0; - if ($waitForTasks && !empty($responses)) { - $timeoutCalculation = 'Algolia\AlgoliaSearch\Support\Helpers::linearTimeout'; + while ($retry < 50) { + try { + $this->getEvent($response['runID'], $response['eventID']); - foreach ($responses as $response) { - $retry = 0; - - while ($retry < 50) { - try { - $this->getEvent($response['runID'], $response['eventID']); + $ok = true; - $ok = true; + break; + } catch (NotFoundException $e) { + // just retry + } - break; - } catch (NotFoundException $e) { - // just retry + ++$retry; + usleep( + call_user_func_array($timeoutCalculation, [$this->config->getWaitTaskTimeBeforeRetry(), $retry]) + ); } - ++$retry; - usleep( - call_user_func_array($timeoutCalculation, [$this->config->getWaitTaskTimeBeforeRetry(), $retry]) - ); - } - - if (false === $ok) { - throw new ExceededRetriesException('Maximum number of retries (50) exceeded.'); + if (false === $ok) { + throw new ExceededRetriesException('Maximum number of retries (50) exceeded.'); + } } + $offset = $offset + $waitBatchSize; } } @@ -892,4 +893,4 @@ use Algolia\AlgoliaSearch\Exceptions\NotFoundException; ); } } -{{/operations}} +{{/operations}} \ No newline at end of file diff --git a/templates/python/ingestion_helpers.mustache b/templates/python/ingestion_helpers.mustache index d2e9662d8ce..4d36470b022 100644 --- a/templates/python/ingestion_helpers.mustache +++ b/templates/python/ingestion_helpers.mustache @@ -11,8 +11,12 @@ """ Helper: Chunks the given `objects` list in subset of 1000 elements max in order to make it fit in `push` requests by leveraging the Transformation pipeline setup in the Push connector (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/). """ + offset = 0 records: List[PushTaskRecords] = [] responses: List[WatchResponse] = [] + wait_batch_size = batch_size // 10 + if wait_batch_size < 1: + wait_batch_size = batch_size for i, obj in enumerate(objects): records.append(obj) # pyright: ignore if len(records) == batch_size or i == len(objects) - 1: @@ -28,37 +32,47 @@ ) ) records = [] - if wait_for_tasks: - for response in responses: - {{^isSyncClient}}async {{/isSyncClient}}def _func(_: Optional[Event]) -> Event: - if response.event_id is None: - raise ValueError( - "received unexpected response from the push endpoint, eventID must not be undefined" - ) - try: - return {{^isSyncClient}}await {{/isSyncClient}}self.get_event(run_id=response.run_id, event_id=response.event_id, request_options=request_options) - except RequestException as e: - if e.status_code == 404: - return None # pyright: ignore - raise e + if ( + wait_for_tasks + and len(responses) > 0 + and (len(responses) % wait_batch_size == 0 or i == len(objects) - 1) + ): + for response in responses[offset:offset+wait_batch_size]: - _retry_count = 0 + {{^isSyncClient}}async {{/isSyncClient}}def _func(_: Optional[Event]) -> Event: + if response.event_id is None: + raise ValueError( + "received unexpected response from the push endpoint, eventID must not be undefined" + ) + try: + return {{^isSyncClient}}await {{/isSyncClient}}self.get_event( + run_id=response.run_id, + event_id=response.event_id, + request_options=request_options, + ) + except RequestException as e: + if e.status_code == 404: + return None # pyright: ignore + raise e - def _aggregator(_: Event | None) -> None: - nonlocal _retry_count - _retry_count += 1 + _retry_count = 0 - def _validate(_resp: Event | None) -> bool: - return _resp is not None + def _aggregator(_: Event | None) -> None: + nonlocal _retry_count + _retry_count += 1 - timeout = RetryTimeout() + def _validate(_resp: Event | None) -> bool: + return _resp is not None - {{^isSyncClient}}await {{/isSyncClient}}create_iterable{{#isSyncClient}}_sync{{/isSyncClient}}( - func=_func, - validate=_validate, - aggregator=_aggregator, - timeout=lambda: timeout(_retry_count), - error_validate=lambda _: _retry_count >= 50, - error_message=lambda _: f"The maximum number of retries exceeded. (${_retry_count}/${50})", - ) + timeout = RetryTimeout() + + {{^isSyncClient}}await {{/isSyncClient}}create_iterable{{#isSyncClient}}_sync{{/isSyncClient}}( + func=_func, + validate=_validate, + aggregator=_aggregator, + timeout=lambda: timeout(_retry_count), + error_validate=lambda _: _retry_count >= 50, + error_message=lambda _: f"The maximum number of retries exceeded. (${_retry_count}/${50})", + ) + offset += wait_batch_size return responses \ No newline at end of file diff --git a/tests/CTS/client/search/replaceAllObjectsWithTransformation.json b/tests/CTS/client/search/replaceAllObjectsWithTransformation.json index b28ee420dac..1c4b5426000 100644 --- a/tests/CTS/client/search/replaceAllObjectsWithTransformation.json +++ b/tests/CTS/client/search/replaceAllObjectsWithTransformation.json @@ -74,26 +74,26 @@ }, "watchResponses": [ { - "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda", - "eventID": "113b2068-6337-4c85-b5c2-e7b213d82923", + "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda_${{language}}", + "eventID": "113b2068-6337-4c85-b5c2-e7b213d82921", "message": "OK", "createdAt": "2022-05-12T06:24:30.049Z" }, { - "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda", - "eventID": "113b2068-6337-4c85-b5c2-e7b213d82926", + "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda_${{language}}", + "eventID": "113b2068-6337-4c85-b5c2-e7b213d82922", "message": "OK", "createdAt": "2022-05-12T06:24:30.049Z" }, { - "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda", - "eventID": "113b2068-6337-4c85-b5c2-e7b213d82929", + "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda_${{language}}", + "eventID": "113b2068-6337-4c85-b5c2-e7b213d82923", "message": "OK", "createdAt": "2022-05-12T06:24:30.049Z" }, { - "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda", - "eventID": "113b2068-6337-4c85-b5c2-e7b213d829210", + "runID": "b1b7a982-524c-40d2-bb7f-48aab075abda_${{language}}", + "eventID": "113b2068-6337-4c85-b5c2-e7b213d82924", "message": "OK", "createdAt": "2022-05-12T06:24:30.049Z" } diff --git a/tests/output/javascript/yarn.lock b/tests/output/javascript/yarn.lock index e4d765fb896..9a9ccaef62f 100644 --- a/tests/output/javascript/yarn.lock +++ b/tests/output/javascript/yarn.lock @@ -427,12 +427,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:22.16.0": - version: 22.16.0 - resolution: "@types/node@npm:22.16.0" +"@types/node@npm:22.16.5": + version: 22.16.5 + resolution: "@types/node@npm:22.16.5" dependencies: undici-types: "npm:~6.21.0" - checksum: 10/26ebbbd24749caa4a692664290c53cdca63ec717ca250cd2babf3d3da796e9d3d0b6b9814d160693261b5e881796bf0f3c1887fef355b19e9a78fe27cd5e2ce2 + checksum: 10/ba45b5c9113cbc5edb12960fcfe7e80db2c998af5c1931264240695b27d756570d92462150b95781bd67a03aa82111cc970ab0f4504eb99213edff8bf425354e languageName: node linkType: hard @@ -1022,7 +1022,7 @@ __metadata: "@algolia/client-composition": "link:../../../clients/algoliasearch-client-javascript/packages/client-composition" "@algolia/composition": "link:../../../clients/algoliasearch-client-javascript/packages/composition" "@algolia/requester-testing": "link:../../../clients/algoliasearch-client-javascript/packages/requester-testing" - "@types/node": "npm:22.16.0" + "@types/node": "npm:22.16.5" algoliasearch: "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch" typescript: "npm:5.8.3" vitest: "npm:3.2.4" diff --git a/tests/output/swift/Tests/Utils/Utils.swift b/tests/output/swift/Tests/Utils/Utils.swift index 16f4e701722..66390db2c28 100644 --- a/tests/output/swift/Tests/Utils/Utils.swift +++ b/tests/output/swift/Tests/Utils/Utils.swift @@ -65,7 +65,10 @@ public func XCTLenientAssertEqual(received: some Encodable, expected: String) { guard let unionizedData = try? JSONSerialization.data(withJSONObject: unionizedObject, options: .fragmentsAllowed), let unionizedJSON = unionizedData.jsonString?.data(using: .utf8), let unionizedString = String(data: unionizedJSON, encoding: .utf8), - let expectedJSON = try? JSONSerialization.jsonObject(with: expected.data(using: .utf8)!, options: .fragmentsAllowed), + let expectedJSON = try? JSONSerialization.jsonObject( + with: expected.data(using: .utf8)!, + options: .fragmentsAllowed + ), let expectedData = try? JSONSerialization.data(withJSONObject: expectedJSON, options: .fragmentsAllowed), let expectedMinifiedJSON = expectedData.jsonString?.data(using: .utf8), let expectedString = String(data: expectedMinifiedJSON, encoding: .utf8)