From 2f296895ce2370c0ff94d7fefb91fa443c7315b8 Mon Sep 17 00:00:00 2001 From: Dhaya <154633+dhayab@users.noreply.github.com> Date: Wed, 6 Aug 2025 16:47:04 +0200 Subject: [PATCH 1/8] feat(clients): add collections --- .../package.json | 2 +- .../algoliasearch-client-javascript/yarn.lock | 17 ++++ config/clients.config.json | 19 ++++ config/clients.schema.json | 2 + specs/collections/common/parameters.yml | 40 ++++++++ .../common/responses/CollectionNotFound.yml | 10 ++ .../collections/common/schemas/collection.yml | 81 ++++++++++++++++ specs/collections/common/schemas/common.yml | 10 ++ .../collections/common/schemas/condition.yml | 8 ++ .../collections/common/schemas/pagination.yml | 30 ++++++ specs/collections/paths/collectionID.yml | 45 +++++++++ specs/collections/paths/collections.yml | 55 +++++++++++ specs/collections/paths/commitCollection.yml | 26 +++++ specs/collections/spec.yml | 95 +++++++++++++++++++ templates/javascript/tests/package.mustache | 1 + .../collections/commitCollection.json | 12 +++ .../collections/deleteCollection.json | 12 +++ .../requests/collections/getCollection.json | 12 +++ .../requests/collections/listCollections.json | 34 +++++++ .../collections/upsertCollection.json | 52 ++++++++++ tests/output/javascript/yarn.lock | 35 ++++--- 21 files changed, 583 insertions(+), 15 deletions(-) create mode 100644 specs/collections/common/parameters.yml create mode 100644 specs/collections/common/responses/CollectionNotFound.yml create mode 100644 specs/collections/common/schemas/collection.yml create mode 100644 specs/collections/common/schemas/common.yml create mode 100644 specs/collections/common/schemas/condition.yml create mode 100644 specs/collections/common/schemas/pagination.yml create mode 100644 specs/collections/paths/collectionID.yml create mode 100644 specs/collections/paths/collections.yml create mode 100644 specs/collections/paths/commitCollection.yml create mode 100644 specs/collections/spec.yml create mode 100644 tests/CTS/requests/collections/commitCollection.json create mode 100644 tests/CTS/requests/collections/deleteCollection.json create mode 100644 tests/CTS/requests/collections/getCollection.json create mode 100644 tests/CTS/requests/collections/listCollections.json create mode 100644 tests/CTS/requests/collections/upsertCollection.json diff --git a/clients/algoliasearch-client-javascript/package.json b/clients/algoliasearch-client-javascript/package.json index 3e1a516b27..552550fbc2 100644 --- a/clients/algoliasearch-client-javascript/package.json +++ b/clients/algoliasearch-client-javascript/package.json @@ -7,7 +7,7 @@ "packages/*" ], "scripts": { - "build": "lerna run build --skip-nx-cache --scope '@algolia/requester-testing' --scope '@algolia/logger-console' --scope 'algoliasearch' --scope '@algolia/client-composition' --scope '@algolia/composition' --scope '@algolia/advanced-personalization' --include-dependencies ", + "build": "lerna run build --skip-nx-cache --scope '@algolia/requester-testing' --scope '@algolia/logger-console' --scope 'algoliasearch' --scope '@algolia/collections' --scope '@algolia/client-composition' --scope '@algolia/composition' --scope '@algolia/advanced-personalization' --include-dependencies ", "clean": "lerna run clean", "release:publish": "tsc --project scripts/tsconfig.json && node scripts/dist/publish.js", "test": "lerna run test $*", diff --git a/clients/algoliasearch-client-javascript/yarn.lock b/clients/algoliasearch-client-javascript/yarn.lock index face9ed263..38b1651751 100644 --- a/clients/algoliasearch-client-javascript/yarn.lock +++ b/clients/algoliasearch-client-javascript/yarn.lock @@ -173,6 +173,23 @@ __metadata: languageName: unknown linkType: soft +"@algolia/collections@workspace:packages/collections": + version: 0.0.0-use.local + resolution: "@algolia/collections@workspace:packages/collections" + dependencies: + "@algolia/client-common": "npm:5.35.0" + "@algolia/requester-browser-xhr": "npm:5.35.0" + "@algolia/requester-fetch": "npm:5.35.0" + "@algolia/requester-node-http": "npm:5.35.0" + "@arethetypeswrong/cli": "npm:0.18.2" + "@types/node": "npm:22.17.0" + publint: "npm:0.3.12" + rollup: "npm:4.41.0" + tsup: "npm:8.5.0" + typescript: "npm:5.9.2" + languageName: unknown + linkType: soft + "@algolia/composition@workspace:packages/composition": version: 0.0.0-use.local resolution: "@algolia/composition@workspace:packages/composition" diff --git a/config/clients.config.json b/config/clients.config.json index 4d989e676a..4ab4736cdd 100644 --- a/config/clients.config.json +++ b/config/clients.config.json @@ -5,6 +5,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -39,6 +40,10 @@ "name": "abtesting-v3", "output": "clients/algoliasearch-client-dart/packages/client_abtesting_v3" }, + { + "name": "collections", + "output": "clients/algoliasearch-client-dart/packages/client_collections" + }, { "name": "composition", "output": "clients/algoliasearch-client-dart/packages/client_composition" @@ -76,6 +81,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -105,6 +111,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -153,6 +160,12 @@ "name": "analytics", "output": "clients/algoliasearch-client-javascript/packages/client-analytics" }, + { + "name": "collections", + "output": "clients/algoliasearch-client-javascript/packages/collections", + "isStandaloneClient": true, + "clientName": "collections" + }, { "name": "composition", "output": "clients/algoliasearch-client-javascript/packages/composition", @@ -218,6 +231,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -247,6 +261,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -276,6 +291,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -312,6 +328,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -341,6 +358,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -370,6 +388,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", diff --git a/config/clients.schema.json b/config/clients.schema.json index 9ee26837dd..1760aafe45 100644 --- a/config/clients.schema.json +++ b/config/clients.schema.json @@ -14,6 +14,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "ingestion", "insights", @@ -38,6 +39,7 @@ "abtesting", "abtesting-v3", "analytics", + "collections", "composition", "composition-full", "ingestion", diff --git a/specs/collections/common/parameters.yml b/specs/collections/common/parameters.yml new file mode 100644 index 0000000000..d1982c21c0 --- /dev/null +++ b/specs/collections/common/parameters.yml @@ -0,0 +1,40 @@ +indexName: + name: indexName + in: query + required: true + description: Name of the index. + schema: + type: string + example: ALGOLIA_INDEX_NAME + +paginationLimit: + name: limit + in: query + description: Number of items to fetch. + required: false + schema: + $ref: './schemas/pagination.yml#/limit' + +paginationOffset: + name: offset + in: query + description: Number of items to skip. + required: false + schema: + $ref: './schemas/pagination.yml#/offset' + +pathCollectionID: + name: collectionID + in: path + required: true + description: Unique identifier of a collection. + schema: + $ref: './schemas/common.yml#/collectionID' + +query: + name: query + in: query + required: false + description: Query to filter collections. + schema: + $ref: './schemas/common.yml#/query' diff --git a/specs/collections/common/responses/CollectionNotFound.yml b/specs/collections/common/responses/CollectionNotFound.yml new file mode 100644 index 0000000000..d618292d8f --- /dev/null +++ b/specs/collections/common/responses/CollectionNotFound.yml @@ -0,0 +1,10 @@ +description: Collection not found. +content: + application/json: + schema: + title: collectionNotFoundResponse + type: object + properties: + message: + type: string + example: 'Collection not found' diff --git a/specs/collections/common/schemas/collection.yml b/specs/collections/common/schemas/collection.yml new file mode 100644 index 0000000000..5f08be7911 --- /dev/null +++ b/specs/collections/common/schemas/collection.yml @@ -0,0 +1,81 @@ +Collection: + type: object + properties: + id: + type: string + example: '5db3039e-04b5-4ed6-a00e-ba3304032c5a' + name: + type: string + example: 'Summer Deals' + indexName: + type: string + example: 'prod_products_EN' + createdAt: + type: string + format: date-time + example: '2024-10-07T00:00:00Z' + updatedAt: + type: string + format: date-time + example: '2024-10-07T00:00:00Z' + status: + $ref: '#/CollectionStatus' + conditions: + $ref: 'condition.yml#/Conditions' + records: + type: array + items: + type: string + +CollectionStatus: + type: string + description: | + Collection commit status. + Only returned if the request API key has write ACLs. + enum: + - COMMITTED + - COMMITTING + - TO_COMMIT + +CollectionUpsert: + type: object + description: API request body for upserting a Collection. + properties: + id: + type: string + indexName: + type: string + name: + type: string + description: + type: string + add: + type: array + description: a list of objectIDs. + minItems: 0 + items: + type: string + remove: + type: array + description: a list of objectIDs. + minItems: 0 + items: + type: string + conditions: + $ref: 'condition.yml#/Conditions' + required: + - indexName + - name + +CollectionsResponse: + type: object + allOf: + - type: object + properties: + items: + type: array + items: + $ref: '#/Collection' + required: + - items + - $ref: 'pagination.yml#/Pagination' diff --git a/specs/collections/common/schemas/common.yml b/specs/collections/common/schemas/common.yml new file mode 100644 index 0000000000..4676984fc4 --- /dev/null +++ b/specs/collections/common/schemas/common.yml @@ -0,0 +1,10 @@ +collectionID: + type: string + # format: uuid + description: Universally unique identifier (UUID) of a collection. + example: 6c02aeb1-775e-418e-870b-1faccd4b2c0f + +query: + type: string + description: Query to filter collections. + example: Summer collection diff --git a/specs/collections/common/schemas/condition.yml b/specs/collections/common/schemas/condition.yml new file mode 100644 index 0000000000..5ac06ae9db --- /dev/null +++ b/specs/collections/common/schemas/condition.yml @@ -0,0 +1,8 @@ +Conditions: + type: object + description: Conditions to filter records. + properties: + facetFilters: + $ref: '../../../common/schemas/SearchParams.yml#/facetFilters' + numericFilters: + $ref: '../../../common/schemas/SearchParams.yml#/numericFilters' diff --git a/specs/collections/common/schemas/pagination.yml b/specs/collections/common/schemas/pagination.yml new file mode 100644 index 0000000000..270a3b2b04 --- /dev/null +++ b/specs/collections/common/schemas/pagination.yml @@ -0,0 +1,30 @@ +Pagination: + type: object + description: Paginated API response. + additionalProperties: false + properties: + total: + type: integer + minimum: 0 + description: Total number of items across all pages. + limit: + $ref: '#/limit' + offset: + $ref: '#/offset' + required: + - total + - limit + - offset + +limit: + type: integer + description: Number of items to fetch. + minimum: 1 + maximum: 50 + default: 10 + +offset: + type: integer + description: Number of items to skip. + minimum: 0 + default: 0 diff --git a/specs/collections/paths/collectionID.yml b/specs/collections/paths/collectionID.yml new file mode 100644 index 0000000000..19481bfda0 --- /dev/null +++ b/specs/collections/paths/collectionID.yml @@ -0,0 +1,45 @@ +get: + summary: Retrieve a collection + description: Retrieves a collection by its ID. + operationId: getCollection + x-acl: + - search + parameters: + - $ref: '../common/parameters.yml#/pathCollectionID' + responses: + '404': + $ref: '../common/responses/CollectionNotFound.yml' + '200': + description: The requested collection. + content: + application/json: + schema: + title: getCollectionResponse + $ref: '../common/schemas/collection.yml#/Collection' + +delete: + summary: Delete a collection + description: Deletes a collection by its ID. + operationId: deleteCollection + x-acl: + - search + - addObject + - deleteIndex + - settings + - editSettings + parameters: + - $ref: '../common/parameters.yml#/pathCollectionID' + responses: + '404': + $ref: '../common/responses/CollectionNotFound.yml' + '200': + description: Collection deleted successfully. + content: + application/json: + schema: + title: deleteCollectionResponse + type: object + properties: + message: + type: string + example: 'Collection with id {collectionID} deleted.' diff --git a/specs/collections/paths/collections.yml b/specs/collections/paths/collections.yml new file mode 100644 index 0000000000..3da3c50d04 --- /dev/null +++ b/specs/collections/paths/collections.yml @@ -0,0 +1,55 @@ +get: + summary: List collections + description: Retrieves a list of collections for a specific index. + operationId: listCollections + x-acl: + - search + parameters: + - $ref: '../common/parameters.yml#/indexName' + - $ref: '../common/parameters.yml#/query' + - $ref: '../common/parameters.yml#/paginationLimit' + - $ref: '../common/parameters.yml#/paginationOffset' + responses: + '400': + $ref: '../../common/responses/BadRequest.yml' + '200': + description: A list of collections. + content: + application/json: + schema: + title: listCollectionsResponse + $ref: '../common/schemas/collection.yml#/CollectionsResponse' + +post: + summary: Upsert a collection + description: Upserts a collection. + operationId: upsertCollection + x-acl: + - search + - addObject + - deleteIndex + - settings + - editSettings + requestBody: + description: Request body for upserting a Collection. + content: + application/json: + schema: + $ref: '../common/schemas/collection.yml#/CollectionUpsert' + responses: + '400': + $ref: '../../common/responses/BadRequest.yml' + '201': + description: Collection created. + content: + application/json: + schema: + title: upsertCollectionResponse + $ref: '../common/schemas/collection.yml#/Collection' + '200': + description: Collection updated. + content: + application/json: + schema: + title: upsertCollectionResponse + $ref: '../common/schemas/collection.yml#/Collection' diff --git a/specs/collections/paths/commitCollection.yml b/specs/collections/paths/commitCollection.yml new file mode 100644 index 0000000000..5551dcb014 --- /dev/null +++ b/specs/collections/paths/commitCollection.yml @@ -0,0 +1,26 @@ +post: + summary: Commit a collection + description: Evaluates the changes on a collection and applies them on the index. + operationId: commitCollection + x-acl: + - search + - addObject + - deleteIndex + - settings + - editSettings + parameters: + - $ref: '../common/parameters.yml#/pathCollectionID' + responses: + '404': + $ref: '../common/responses/CollectionNotFound.yml' + '202': + description: Committing collection. + content: + application/json: + schema: + title: commitCollectionResponse + type: object + properties: + message: + type: string + example: 'Committing collection' diff --git a/specs/collections/spec.yml b/specs/collections/spec.yml new file mode 100644 index 0000000000..ba828704a4 --- /dev/null +++ b/specs/collections/spec.yml @@ -0,0 +1,95 @@ +openapi: 3.0.2 +info: + title: Collections API + description: | + The Algolia Collections API lets you create and curate product listings. + + ## Client libraries + + Use Algolia's API clients and libraries to reliably integrate Algolia's APIs with your apps. + + See: [Algolia's ecosystem](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/) + + ## Base URLs + + The base URL for requests to the Collections API is: + + - `https://experiences.algolia.com` + + **All requests must use HTTPS.** + + ## Availability and authentication + + Access to the Collections API is available as part of the [Premium or Elevate plans](https://www.algolia.com/pricing). + + 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). + + ## Rate limits + + You can make up to **150 requests per minute per app** to the Collections API. + + ## 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 Collections 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 Collections API is version 1, as indicated by the `/1/` in each endpoint's URL. + + version: 1.0.0 +components: + securitySchemes: + appId: + $ref: '../common/securitySchemes.yml#/appId' + apiKey: + $ref: '../common/securitySchemes.yml#/apiKey' +servers: + - url: https://experiences.algolia.com +security: + - appId: [] + apiKey: [] +tags: [] +x-tagGroups: [] +paths: + # ###################### + # ### Custom request ### + # ###################### + /{path}: + $ref: '../common/paths/customRequest.yml' + + # ############################# + # ### Collections Endpoints ### + # ############################# + /1/collections: + $ref: 'paths/collections.yml' + /1/collections/{collectionID}: + $ref: 'paths/collectionID.yml' + /1/collections/{collectionID}/commit: + $ref: 'paths/commitCollection.yml' diff --git a/templates/javascript/tests/package.mustache b/templates/javascript/tests/package.mustache index 974e24aded..48d163a2a1 100644 --- a/templates/javascript/tests/package.mustache +++ b/templates/javascript/tests/package.mustache @@ -8,6 +8,7 @@ "dependencies": { "algoliasearch": "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch", "@algolia/client-composition": "link:../../../clients/algoliasearch-client-javascript/packages/client-composition", + "@algolia/collections": "link:../../../clients/algoliasearch-client-javascript/packages/collections", "@algolia/composition": "link:../../../clients/algoliasearch-client-javascript/packages/composition", "@algolia/requester-testing": "link:../../../clients/algoliasearch-client-javascript/packages/requester-testing" }, diff --git a/tests/CTS/requests/collections/commitCollection.json b/tests/CTS/requests/collections/commitCollection.json new file mode 100644 index 0000000000..a106268944 --- /dev/null +++ b/tests/CTS/requests/collections/commitCollection.json @@ -0,0 +1,12 @@ +[ + { + "testName": "commitCollection", + "parameters": { + "collectionID": "75eeb306-51d3-4e5e-a279-3c92bd8893ac" + }, + "request": { + "path": "/1/collections/75eeb306-51d3-4e5e-a279-3c92bd8893ac/commit", + "method": "POST" + } + } +] diff --git a/tests/CTS/requests/collections/deleteCollection.json b/tests/CTS/requests/collections/deleteCollection.json new file mode 100644 index 0000000000..f92aa19a38 --- /dev/null +++ b/tests/CTS/requests/collections/deleteCollection.json @@ -0,0 +1,12 @@ +[ + { + "testName": "deleteCollection", + "parameters": { + "collectionID": "75eeb306-51d3-4e5e-a279-3c92bd8893ac" + }, + "request": { + "path": "/1/collections/75eeb306-51d3-4e5e-a279-3c92bd8893ac", + "method": "DELETE" + } + } +] diff --git a/tests/CTS/requests/collections/getCollection.json b/tests/CTS/requests/collections/getCollection.json new file mode 100644 index 0000000000..a492065eb4 --- /dev/null +++ b/tests/CTS/requests/collections/getCollection.json @@ -0,0 +1,12 @@ +[ + { + "testName": "getCollection", + "parameters": { + "collectionID": "75eeb306-51d3-4e5e-a279-3c92bd8893ac" + }, + "request": { + "path": "/1/collections/75eeb306-51d3-4e5e-a279-3c92bd8893ac", + "method": "GET" + } + } +] diff --git a/tests/CTS/requests/collections/listCollections.json b/tests/CTS/requests/collections/listCollections.json new file mode 100644 index 0000000000..eac3b53340 --- /dev/null +++ b/tests/CTS/requests/collections/listCollections.json @@ -0,0 +1,34 @@ +[ + { + "testName": "listCollections", + "parameters": { + "indexName": "indexName" + }, + "request": { + "path": "/1/collections", + "method": "GET", + "queryParameters": { + "indexName": "indexName" + } + } + }, + { + "testName": "listCollections with query, offset and limit", + "parameters": { + "indexName": "indexName", + "query": "Summer", + "offset": 100, + "limit": 50 + }, + "request": { + "path": "/1/collections", + "method": "GET", + "queryParameters": { + "indexName": "indexName", + "query": "Summer", + "offset": "100", + "limit": "50" + } + } + } +] diff --git a/tests/CTS/requests/collections/upsertCollection.json b/tests/CTS/requests/collections/upsertCollection.json new file mode 100644 index 0000000000..876edd4afc --- /dev/null +++ b/tests/CTS/requests/collections/upsertCollection.json @@ -0,0 +1,52 @@ +[ + { + "testName": "upsertCollection / insert", + "parameters": { + "name": "Summer Deals", + "indexName": "prod_products_EN", + "description": "This is a test collection", + "add": ["objectID1", "objectID2"], + "conditions": { + "facetFilters": ["category:Book"], + "numericFilters": ["price > 50"] + } + }, + "request": { + "path": "/1/collections", + "method": "POST", + "body": { + "name": "Summer Deals", + "indexName": "prod_products_EN", + "description": "This is a test collection", + "add": ["objectID1", "objectID2"], + "conditions": { + "facetFilters": ["category:Book"], + "numericFilters": ["price > 50"] + } + } + } + }, + { + "testName": "upsertCollection / update", + "parameters": { + "id": "75eeb306-51d3-4e5e-a279-3c92bd8893ac", + "name": "Summer Deals", + "indexName": "prod_products_EN", + "add": ["objectID3"], + "remove": ["objectID1"], + "conditions": {} + }, + "request": { + "path": "/1/collections", + "method": "POST", + "body": { + "id": "75eeb306-51d3-4e5e-a279-3c92bd8893ac", + "name": "Summer Deals", + "indexName": "prod_products_EN", + "add": ["objectID3"], + "remove": ["objectID1"], + "conditions": {} + } + } + } +] diff --git a/tests/output/javascript/yarn.lock b/tests/output/javascript/yarn.lock index 9a1e070563..8aa896beba 100644 --- a/tests/output/javascript/yarn.lock +++ b/tests/output/javascript/yarn.lock @@ -11,6 +11,12 @@ __metadata: languageName: node linkType: soft +"@algolia/collections@link:../../../clients/algoliasearch-client-javascript/packages/collections::locator=javascript-tests%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@algolia/collections@link:../../../clients/algoliasearch-client-javascript/packages/collections::locator=javascript-tests%40workspace%3A." + languageName: node + linkType: soft + "@algolia/composition@link:../../../clients/algoliasearch-client-javascript/packages/composition::locator=javascript-tests%40workspace%3A.": version: 0.0.0-use.local resolution: "@algolia/composition@link:../../../clients/algoliasearch-client-javascript/packages/composition::locator=javascript-tests%40workspace%3A." @@ -427,12 +433,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:22.16.5": - version: 22.16.5 - resolution: "@types/node@npm:22.16.5" +"@types/node@npm:22.17.0": + version: 22.17.0 + resolution: "@types/node@npm:22.17.0" dependencies: undici-types: "npm:~6.21.0" - checksum: 10/ba45b5c9113cbc5edb12960fcfe7e80db2c998af5c1931264240695b27d756570d92462150b95781bd67a03aa82111cc970ab0f4504eb99213edff8bf425354e + checksum: 10/f77b0e1c3c00e438b56c726d6b1170d4969c600cc8d4ecf2c2aa7692243a8ff455a3d530760da95e0b6aab059c4605a384b43d18f96646c745ff133c00b84875 languageName: node linkType: hard @@ -1020,11 +1026,12 @@ __metadata: resolution: "javascript-tests@workspace:." dependencies: "@algolia/client-composition": "link:../../../clients/algoliasearch-client-javascript/packages/client-composition" + "@algolia/collections": "link:../../../clients/algoliasearch-client-javascript/packages/collections" "@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.5" + "@types/node": "npm:22.17.0" algoliasearch: "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch" - typescript: "npm:5.8.3" + typescript: "npm:5.9.2" vitest: "npm:3.2.4" languageName: unknown linkType: soft @@ -1621,23 +1628,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.8.3": - version: 5.8.3 - resolution: "typescript@npm:5.8.3" +"typescript@npm:5.9.2": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/65c40944c51b513b0172c6710ee62e951b70af6f75d5a5da745cb7fab132c09ae27ffdf7838996e3ed603bb015dadd099006658046941bd0ba30340cc563ae92 + checksum: 10/cc2fe6c822819de5d453fa25aa9f32096bf70dde215d481faa1ad84a283dfb264e33988ed8f6d36bc803dd0b16dbe943efa311a798ef76d5b3892a05dfbfd628 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.8.3#optional!builtin": - version: 5.8.3 - resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" +"typescript@patch:typescript@npm%3A5.9.2#optional!builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/b9b1e73dabac5dc730c041325dbd9c99467c1b0d239f1b74ec3b90d831384af3e2ba973946232df670519147eb51a2c20f6f96163cea2b359f03de1e2091cc4f + checksum: 10/bd810ab13e8e557225a8b5122370385440b933e4e077d5c7641a8afd207fdc8be9c346e3c678adba934b64e0e70b0acf5eef9493ea05170a48ce22bef845fdc7 languageName: node linkType: hard From f74582db3bf17a064ee776ac900bf011d2eec801 Mon Sep 17 00:00:00 2001 From: Dhaya <154633+dhayab@users.noreply.github.com> Date: Thu, 7 Aug 2025 17:39:08 +0200 Subject: [PATCH 2/8] remove format in spec and reorder parameters in tests --- specs/collections/common/schemas/collection.yml | 8 ++++++-- tests/CTS/requests/collections/listCollections.json | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/specs/collections/common/schemas/collection.yml b/specs/collections/common/schemas/collection.yml index 5f08be7911..9f8d34362e 100644 --- a/specs/collections/common/schemas/collection.yml +++ b/specs/collections/common/schemas/collection.yml @@ -12,11 +12,15 @@ Collection: example: 'prod_products_EN' createdAt: type: string - format: date-time + # format: date-time + description: | + Date and time when the collection was created, in RFC 3339 format. example: '2024-10-07T00:00:00Z' updatedAt: type: string - format: date-time + # format: date-time + description: | + Date and time when the collection was last updated, in RFC 3339 format. example: '2024-10-07T00:00:00Z' status: $ref: '#/CollectionStatus' diff --git a/tests/CTS/requests/collections/listCollections.json b/tests/CTS/requests/collections/listCollections.json index eac3b53340..9540b6db3a 100644 --- a/tests/CTS/requests/collections/listCollections.json +++ b/tests/CTS/requests/collections/listCollections.json @@ -17,8 +17,8 @@ "parameters": { "indexName": "indexName", "query": "Summer", - "offset": 100, - "limit": 50 + "limit": 50, + "offset": 100 }, "request": { "path": "/1/collections", @@ -26,8 +26,8 @@ "queryParameters": { "indexName": "indexName", "query": "Summer", - "offset": "100", - "limit": "50" + "limit": "50", + "offset": "100" } } } From 49de4c5c68086524ee014aa354554748c1dc58bb Mon Sep 17 00:00:00 2001 From: Dhaya <154633+dhayab@users.noreply.github.com> Date: Fri, 8 Aug 2025 10:00:43 +0200 Subject: [PATCH 3/8] add js playground and fix duplicate issue in swift --- playground/javascript/node/collections.ts | 24 +++++++++++++++++++ playground/javascript/node/package.json | 1 + .../collections/common/schemas/collection.yml | 2 +- .../collections/common/schemas/pagination.yml | 2 +- .../collections/upsertCollection.json | 6 ++--- 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 playground/javascript/node/collections.ts diff --git a/playground/javascript/node/collections.ts b/playground/javascript/node/collections.ts new file mode 100644 index 0000000000..27115ae2c9 --- /dev/null +++ b/playground/javascript/node/collections.ts @@ -0,0 +1,24 @@ +import { ApiError } from '@algolia/client-common'; +import { collectionsClient } from '@algolia/collections'; + +const appId = process.env.ALGOLIA_APPLICATION_ID || '**** APP_ID *****'; +const apiKey = process.env.ALGOLIA_ADMIN_KEY || '**** ADMIN_KEY *****'; +const indexName = process.env.SEARCH_INDEX || '**** INDEX_NAME *****'; + +// Init client with appId and apiKey +const client = collectionsClient(appId, apiKey); + +async function testCollections() { + try { + // list collections + console.log(await client.listCollections({ indexName })); + } catch (e) { + if (e instanceof ApiError) { + return console.log(`[${e.status}] ${e.message}`, e.stackTrace, e); + } + + console.log('[ERROR]', e); + } +} + +testCollections(); diff --git a/playground/javascript/node/package.json b/playground/javascript/node/package.json index e4bd8ba976..85fd4400e1 100644 --- a/playground/javascript/node/package.json +++ b/playground/javascript/node/package.json @@ -17,6 +17,7 @@ "@algolia/client-personalization": "link:../../../clients/algoliasearch-client-javascript/packages/client-personalization", "@algolia/client-query-suggestions": "link:../../../clients/algoliasearch-client-javascript/packages/client-query-suggestions", "@algolia/client-search": "link:../../../clients/algoliasearch-client-javascript/packages/client-search", + "@algolia/collections": "link:../../../clients/algoliasearch-client-javascript/packages/collections", "@algolia/composition": "link:../../../clients/algoliasearch-client-javascript/packages/composition", "@algolia/ingestion": "link:../../../clients/algoliasearch-client-javascript/packages/ingestion", "@algolia/monitoring": "link:../../../clients/algoliasearch-client-javascript/packages/monitoring", diff --git a/specs/collections/common/schemas/collection.yml b/specs/collections/common/schemas/collection.yml index 9f8d34362e..4d23c7fc60 100644 --- a/specs/collections/common/schemas/collection.yml +++ b/specs/collections/common/schemas/collection.yml @@ -82,4 +82,4 @@ CollectionsResponse: $ref: '#/Collection' required: - items - - $ref: 'pagination.yml#/Pagination' + - $ref: 'pagination.yml#/CollectionPagination' diff --git a/specs/collections/common/schemas/pagination.yml b/specs/collections/common/schemas/pagination.yml index 270a3b2b04..15eb038eb0 100644 --- a/specs/collections/common/schemas/pagination.yml +++ b/specs/collections/common/schemas/pagination.yml @@ -1,4 +1,4 @@ -Pagination: +CollectionPagination: type: object description: Paginated API response. additionalProperties: false diff --git a/tests/CTS/requests/collections/upsertCollection.json b/tests/CTS/requests/collections/upsertCollection.json index 876edd4afc..d53964cc68 100644 --- a/tests/CTS/requests/collections/upsertCollection.json +++ b/tests/CTS/requests/collections/upsertCollection.json @@ -33,8 +33,7 @@ "name": "Summer Deals", "indexName": "prod_products_EN", "add": ["objectID3"], - "remove": ["objectID1"], - "conditions": {} + "remove": ["objectID1"] }, "request": { "path": "/1/collections", @@ -44,8 +43,7 @@ "name": "Summer Deals", "indexName": "prod_products_EN", "add": ["objectID3"], - "remove": ["objectID1"], - "conditions": {} + "remove": ["objectID1"] } } } From bda186816cf0007671d936e6f6d20329cd23355e Mon Sep 17 00:00:00 2001 From: shortcuts Date: Fri, 8 Aug 2025 11:44:11 +0200 Subject: [PATCH 4/8] fix: dart --- config/generation.config.mjs | 1 + .../main/java/com/algolia/codegen/AlgoliaDartGenerator.java | 1 + templates/dart/extension.mustache | 4 ++++ 3 files changed, 6 insertions(+) create mode 100644 templates/dart/extension.mustache diff --git a/config/generation.config.mjs b/config/generation.config.mjs index a913819541..ac1ea846f4 100644 --- a/config/generation.config.mjs +++ b/config/generation.config.mjs @@ -90,6 +90,7 @@ export const patterns = [ // PHP '!clients/algoliasearch-client-php/**', + 'clients/algoliasearch-client-php/lib/FormDataProcessor.php', 'clients/algoliasearch-client-php/lib/Api/*', 'clients/algoliasearch-client-php/lib/Model/**', '!clients/algoliasearch-client-php/lib/Model/AbstractModel.php', diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java index 34e25406e7..59b44f3f0d 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaDartGenerator.java @@ -102,6 +102,7 @@ public void processOpts() { supportingFiles.removeIf(file -> file.getTemplateFile().contains("README")); supportingFiles.add(new SupportingFile("version.mustache", srcFolder, "version.dart")); + supportingFiles.add(new SupportingFile("extension.mustache", srcFolder, "extension.dart")); supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE")); supportingFiles.add(new SupportingFile("LICENSE", "../client_core/", "LICENSE")); diff --git a/templates/dart/extension.mustache b/templates/dart/extension.mustache new file mode 100644 index 0000000000..11ee022a43 --- /dev/null +++ b/templates/dart/extension.mustache @@ -0,0 +1,4 @@ +{{#isSearchClient}} +export 'extension/search.dart'; +export 'extension/wait_task.dart'; +{{/isSearchClient}} \ No newline at end of file From 503faa1a7e2ae197df5b7450a545f83d63ddeb50 Mon Sep 17 00:00:00 2001 From: shortcuts Date: Fri, 8 Aug 2025 11:54:29 +0200 Subject: [PATCH 5/8] fix: dart (for real) --- config/generation.config.mjs | 2 +- templates/dart/extension.mustache | 44 ++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/config/generation.config.mjs b/config/generation.config.mjs index ac1ea846f4..2dd8f03798 100644 --- a/config/generation.config.mjs +++ b/config/generation.config.mjs @@ -30,6 +30,7 @@ export const patterns = [ // Dart '!clients/algoliasearch-client-dart/**', 'clients/algoliasearch-client-dart/packages/*/pubspec.yaml', + 'clients/algoliasearch-client-dart/packages/*/build.yaml', 'clients/algoliasearch-client-dart/packages/*/lib/*.dart', 'clients/algoliasearch-client-dart/packages/*/lib/src/*.dart', 'clients/algoliasearch-client-dart/packages/client_core/pubspec.yaml', @@ -37,7 +38,6 @@ export const patterns = [ 'clients/algoliasearch-client-dart/packages/*/lib/src/model/**', '!clients/algoliasearch-client-dart/packages/client_core/**', 'clients/algoliasearch-client-dart/packages/client_core/lib/src/version.dart', - '!clients/algoliasearch-client-dart/packages/*/lib/src/extension.dart', '!clients/algoliasearch-client-dart/packages/algoliasearch/lib/algoliasearch.dart', // GO diff --git a/templates/dart/extension.mustache b/templates/dart/extension.mustache index 11ee022a43..63547631c8 100644 --- a/templates/dart/extension.mustache +++ b/templates/dart/extension.mustache @@ -1,4 +1,46 @@ {{#isSearchClient}} export 'extension/search.dart'; export 'extension/wait_task.dart'; -{{/isSearchClient}} \ No newline at end of file +{{/isSearchClient}} +{{#isAlgoliasearchClient}} +import 'package:algoliasearch/algoliasearch_lite.dart'; + +extension SearchClientExt on SearchClient { + /// Perform a search operation targeting one index. + Future searchIndex({ + required SearchForHits request, + RequestOptions? requestOptions, + }) async { + final response = await search( + searchMethodParams: SearchMethodParams(requests: [request]), + requestOptions: requestOptions, + ); + return SearchResponse.fromJson(response.results.first); + } + + /// Calls the `search` method but with certainty that we will only request + /// Algolia records (hits). + Future> searchForHits({ + required List requests, + SearchStrategy? strategy, + RequestOptions? requestOptions, + }) async { + final request = SearchMethodParams(requests: requests, strategy: strategy); + return search(searchMethodParams: request, requestOptions: requestOptions) + .then((res) => res.results.map((e) => SearchResponse.fromJson(e))); + } + + /// Calls the `search` method but with certainty that we will only request + /// Algolia facets. + Future> searchForFacets({ + required List requests, + SearchStrategy? strategy, + RequestOptions? requestOptions, + }) async { + final request = SearchMethodParams(requests: requests, strategy: strategy); + return search(searchMethodParams: request, requestOptions: requestOptions) + .then((res) => + res.results.map((e) => SearchForFacetValuesResponse.fromJson(e))); + } +} +{{/isAlgoliasearchClient}} \ No newline at end of file From f504f2c1bbe16e4d72fba3cbd1609b1b36cf1859 Mon Sep 17 00:00:00 2001 From: shortcuts Date: Fri, 8 Aug 2025 12:19:45 +0200 Subject: [PATCH 6/8] fix: php and maybe more --- specs/collections/spec.yml | 7 ++++ tests/CTS/client/collections/parameters.json | 41 ++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/CTS/client/collections/parameters.json diff --git a/specs/collections/spec.yml b/specs/collections/spec.yml index ba828704a4..cb1d8423fd 100644 --- a/specs/collections/spec.yml +++ b/specs/collections/spec.yml @@ -93,3 +93,10 @@ paths: $ref: 'paths/collectionID.yml' /1/collections/{collectionID}/commit: $ref: 'paths/commitCollection.yml' + + # ############### + # ### Helpers ### + # ############### + + /setClientApiKey: + $ref: '../common/helpers/setClientApiKey.yml#/method' diff --git a/tests/CTS/client/collections/parameters.json b/tests/CTS/client/collections/parameters.json new file mode 100644 index 0000000000..225faef2b0 --- /dev/null +++ b/tests/CTS/client/collections/parameters.json @@ -0,0 +1,41 @@ +[ + { + "testName": "sets the correct host", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key" + } + }, + { + "type": "method", + "method": "listCollections", + "parameters": { + "indexName": "indexName" + }, + "expected": { + "type": "host", + "match": "experiences.algolia.com" + } + } + ] + }, + { + "testName": "listCollections throws without index", + "steps": [ + { + "type": "method", + "method": "listCollections", + "parameters": { + "indexName": null + }, + "expected": { + "error": "Parameter `indexName` is required when calling `listCollections`." + } + } + ] + } +] From 60f42747daef925bf81d53c767ccacbc114e9682 Mon Sep 17 00:00:00 2001 From: shortcuts Date: Fri, 8 Aug 2025 12:36:46 +0200 Subject: [PATCH 7/8] fix: dart (for real again) --- templates/dart/pubspec.tests.mustache | 1 + templates/dart/pubspec_overrides.tests.mustache | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/dart/pubspec.tests.mustache b/templates/dart/pubspec.tests.mustache index 419fb3820e..85c6d9a51b 100644 --- a/templates/dart/pubspec.tests.mustache +++ b/templates/dart/pubspec.tests.mustache @@ -10,6 +10,7 @@ dependencies: algolia_client_insights: ^1.0.0 algolia_client_recommend: ^1.0.0 algolia_client_search: ^1.0.0 + algolia_client_collections: ^1.0.0 algoliasearch: ^1.0.0 collection: ^1.17.2 dotenv: ^4.1.0 diff --git a/templates/dart/pubspec_overrides.tests.mustache b/templates/dart/pubspec_overrides.tests.mustache index 5b2a15fb57..295754a450 100644 --- a/templates/dart/pubspec_overrides.tests.mustache +++ b/templates/dart/pubspec_overrides.tests.mustache @@ -12,4 +12,6 @@ dependency_overrides: algolia_client_composition: path: ../../../clients/algoliasearch-client-dart/packages/client_composition algolia_client_abtesting_v3: - path: ../../../clients/algoliasearch-client-dart/packages/client_abtesting_v3 \ No newline at end of file + path: ../../../clients/algoliasearch-client-dart/packages/client_abtesting_v3 + algolia_client_collections: + path: ../../../clients/algoliasearch-client-dart/packages/client_collections \ No newline at end of file From 4888057a1fd7346b1be8981630216dc8915b06ce Mon Sep 17 00:00:00 2001 From: shortcuts Date: Fri, 8 Aug 2025 14:16:18 +0200 Subject: [PATCH 8/8] chore: no swifty --- config/clients.config.json | 1 - 1 file changed, 1 deletion(-) diff --git a/config/clients.config.json b/config/clients.config.json index 4ab4736cdd..bd37776b20 100644 --- a/config/clients.config.json +++ b/config/clients.config.json @@ -388,7 +388,6 @@ "abtesting", "abtesting-v3", "analytics", - "collections", "composition", "ingestion", "insights",