diff --git a/clients/algoliasearch-client-javascript/packages/abtesting/package.json b/clients/algoliasearch-client-javascript/packages/abtesting/package.json new file mode 100644 index 0000000000..b59120c087 --- /dev/null +++ b/clients/algoliasearch-client-javascript/packages/abtesting/package.json @@ -0,0 +1,68 @@ +{ + "version": "0.0.1-alpha.1", + "repository": { + "type": "git", + "url": "git+https://github.com/algolia/algoliasearch-client-javascript.git" + }, + "homepage": "https://github.com/algolia/algoliasearch-client-javascript/packages/abtesting#readme", + "type": "module", + "license": "MIT", + "author": "Algolia", + "scripts": { + "build": "yarn clean && yarn tsup && yarn rollup -c rollup.config.js", + "clean": "rm -rf ./dist || true", + "test:bundle": "publint . && attw --pack ." + }, + "name": "@algolia/abtesting", + "description": "JavaScript client for abtesting", + "exports": { + ".": { + "node": { + "types": { + "import": "./dist/node.d.ts", + "module": "./dist/node.d.ts", + "require": "./dist/node.d.cts" + }, + "import": "./dist/builds/node.js", + "module": "./dist/builds/node.js", + "require": "./dist/builds/node.cjs" + }, + "worker": { + "types": "./dist/worker.d.ts", + "default": "./dist/builds/worker.js" + }, + "default": { + "types": "./dist/browser.d.ts", + "module": "./dist/builds/browser.js", + "import": "./dist/builds/browser.js", + "default": "./dist/builds/browser.umd.js" + } + }, + "./dist/builds/*": "./dist/builds/*.js" + }, + "jsdelivr": "./dist/builds/browser.umd.js", + "unpkg": "./dist/builds/browser.umd.js", + "react-native": "./dist/builds/browser.js", + "files": [ + "dist", + "index.js", + "index.d.ts" + ], + "dependencies": { + "@algolia/client-common": "5.23.4", + "@algolia/requester-browser-xhr": "5.23.4", + "@algolia/requester-node-http": "5.23.4", + "@algolia/requester-fetch": "5.23.4" + }, + "devDependencies": { + "@arethetypeswrong/cli": "0.17.4", + "@types/node": "22.14.1", + "publint": "0.3.12", + "rollup": "4.39.0", + "tsup": "8.4.0", + "typescript": "5.8.3" + }, + "engines": { + "node": ">= 14.0.0" + } +} diff --git a/config/clients.config.json b/config/clients.config.json index 79a4b48ade..d7c588771a 100644 --- a/config/clients.config.json +++ b/config/clients.config.json @@ -137,6 +137,11 @@ "name": "abtesting", "output": "clients/algoliasearch-client-javascript/packages/client-abtesting" }, + { + "name": "abtesting-v3", + "output": "clients/algoliasearch-client-javascript/packages/abtesting", + "isStandaloneClient": true + }, { "name": "analytics", "output": "clients/algoliasearch-client-javascript/packages/client-analytics" diff --git a/config/clients.schema.json b/config/clients.schema.json new file mode 100644 index 0000000000..774baabefc --- /dev/null +++ b/config/clients.schema.json @@ -0,0 +1,102 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "clients": { + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "abtesting", + "abtesting-v3", + "analytics", + "composition", + "ingestion", + "insights", + "monitoring", + "personalization", + "query-suggestions", + "recommend", + "search" + ] + } + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": [ + "algoliasearch", + "abtesting", + "abtesting-v3", + "analytics", + "composition", + "composition-full", + "ingestion", + "insights", + "monitoring", + "personalization", + "query-suggestions", + "recommend", + "search" + ] + }, + "output": { "type": "string" }, + "isStandaloneClient": { "type": "boolean", "description": "this property only matters for the javascript client, when `true`, your package will be built as a standalone client and not be part of `algoliasearch` directly. This is recommended for non stable APIs." }, + "clientName": { "type": "string", "description": "when defined, the name of the generated instance of the client will be hardcoded, otherwise it defaults to the `spec` name, e.g. search -> searchClient" } + }, + "required": ["name", "output"], + "additionalProperties": false + } + } + ] + }, + "folder": { "type": "string", "description": "the output folder of your client, usually matching the github repository name, e.g. clients/algoliasearch-client-dart" }, + "gitRepoId": { "type": "string", "description": "the github repository name, without the organization or username that owns it, e.g. algoliasearch-client-php"}, + "packageVersion": { "type": "string", "description": "the version to publish the packages with, it must be semver compatible, e.g. 1.2.3" }, + "modelFolder": { "type": "string", "description": "the models folder, e.g. algoliasearch/models"}, + "apiFolder": { "type": "string", "description": "the api folder, e.g. lib/src"}, + "dockerImage": { + "type": "string", + "description": "whether your client requires a custom docker image with specific needs, most clients require 'apic_base'", + "enum": [ + "apic_base", + "apic_ruby", + "apic_swift" + ] + }, + "tests": { + "type": "object", + "properties": { + "extension": { "type": "string", "description": "the test file extension, e.g. .test.ts" }, + "outputFolder": { "type": "string", "description": "the test output folder, e.g. src/generated" } + }, + "required": ["extension", "outputFolder"], + "additionalProperties": false + }, + "snippets": { + "type": "object", + "properties": { + "extension": { "type": "string", "description": "the snippet file extension, e.g. .cs" }, + "outputFolder": { "type": "string", "description": "the snippet output folder, e.g. src" } + }, + "required": ["extension", "outputFolder"], + "additionalProperties": false + }, + "supportedVersions": { + "type": "array", + "description": "hints the CI on what matrix to generate for this client, this must be language specific versions, e.g. versions of node", + "items": { "type": "string" } + } + }, + "required": ["clients", "folder", "gitRepoId", "packageVersion", "modelFolder", "apiFolder", "tests", "snippets"], + "additionalProperties": false + } +} diff --git a/specs/abtesting-v3/common/parameters.yml b/specs/abtesting-v3/common/parameters.yml index 77d924b6f6..e88c606ebf 100644 --- a/specs/abtesting-v3/common/parameters.yml +++ b/specs/abtesting-v3/common/parameters.yml @@ -5,13 +5,13 @@ ID: description: Unique A/B test identifier. required: true schema: - $ref: "#/abTestID" + $ref: '#/abTestID' # misc index: type: string description: Index name of the A/B test variant (case-sensitive). - example: "delcourt_production" + example: 'delcourt_production' abTestID: type: integer @@ -75,7 +75,7 @@ currencies: mean: 43.7 standardDeviation: 10.3 additionalProperties: - $ref: "#/currency" + $ref: '#/currency' x-additionalPropertiesName: currency code currency: @@ -84,7 +84,7 @@ currency: currency: type: string description: Currency code. - example: "USD" + example: 'USD' revenue: type: number format: double diff --git a/specs/abtesting-v3/common/schemas/ABTest.yml b/specs/abtesting-v3/common/schemas/ABTest.yml index 4818799f98..7eafb7a000 100644 --- a/specs/abtesting-v3/common/schemas/ABTest.yml +++ b/specs/abtesting-v3/common/schemas/ABTest.yml @@ -3,32 +3,31 @@ ABTests: - type: array description: A/B tests. items: - $ref: "#/ABTest" - - type: "null" - description: No A/B tests are configured for this application. + $ref: '#/ABTest' + - type: 'null' ABTest: type: object additionalProperties: false properties: abTestID: - $ref: "../parameters.yml#/abTestID" + $ref: '../parameters.yml#/abTestID' updatedAt: - $ref: "../parameters.yml#/updatedAt" + $ref: '../parameters.yml#/updatedAt' createdAt: - $ref: "../parameters.yml#/createdAt" + $ref: '../parameters.yml#/createdAt' endAt: - $ref: "../parameters.yml#/endAt" + $ref: '../parameters.yml#/endAt' name: - $ref: "../parameters.yml#/name" + $ref: '../parameters.yml#/name' status: - $ref: "#/Status" + $ref: '#/Status' variants: - $ref: "Variant.yml#/variants" + $ref: 'Variant.yml#/variants' configuration: - $ref: "#/ABTestConfiguration" + $ref: '#/ABTestConfiguration' migratedAbTestID: - $ref: "#/MigratedABTestId" + $ref: '#/MigratedABTestId' required: - status - name @@ -60,11 +59,11 @@ ABTestConfiguration: description: A/B test configuration. properties: outliers: - $ref: "#/Outliers" + $ref: '#/Outliers' emptySearch: - $ref: "#/EmptySearch" + $ref: '#/EmptySearch' minimumDetectableEffect: - $ref: "#/MinimumDetectableEffect" + $ref: '#/MinimumDetectableEffect' Outliers: type: object @@ -96,7 +95,7 @@ MinimumDetectableEffect: Smallest difference in an observable metric between variants. For example, to detect a 10% difference between variants, set this value to 0.1. metric: - $ref: "#/EffectMetric" + $ref: '#/EffectMetric' required: - size - metric diff --git a/specs/abtesting-v3/common/schemas/Timeseries.yml b/specs/abtesting-v3/common/schemas/Timeseries.yml index 2f2f3c00ca..952433b5f6 100644 --- a/specs/abtesting-v3/common/schemas/Timeseries.yml +++ b/specs/abtesting-v3/common/schemas/Timeseries.yml @@ -3,9 +3,9 @@ Timeseries: additionalProperties: false properties: abTestID: - $ref: "../parameters.yml#/abTestID" + $ref: '../parameters.yml#/abTestID' variants: - $ref: "#/timeseriesVariants" + $ref: '#/timeseriesVariants' required: - abTestID - variants @@ -18,18 +18,18 @@ timeseriesVariants: The first variant is your _control_ index, typically your production index. All of the additional variants are indexes with changed settings that you want to test against the control. items: - $ref: "#/timeseriesVariant" + $ref: '#/timeseriesVariant' timeseriesVariant: type: object properties: dates: - $ref: "#/metricDates" + $ref: '#/metricDates' metricDates: type: array items: - $ref: "#/metricDate" + $ref: '#/metricDate' metricDate: type: object @@ -40,4 +40,4 @@ metricDate: format: date example: 2025-06-15 metrics: - $ref: "Variant.yml#/metrics" + $ref: 'Variant.yml#/metrics' diff --git a/specs/abtesting-v3/paths/abtests.yml b/specs/abtesting-v3/paths/abtests.yml index dcf14bd1df..e31ce03e6c 100644 --- a/specs/abtesting-v3/paths/abtests.yml +++ b/specs/abtesting-v3/paths/abtests.yml @@ -16,49 +16,49 @@ post: additionalProperties: false properties: name: - $ref: "../common/parameters.yml#/name" + $ref: '../common/parameters.yml#/name' variants: type: array description: A/B test variants. minItems: 2 items: - $ref: "../common/schemas/AddABTestsVariant.yml#/AddABTestsVariant" + $ref: '../common/schemas/AddABTestsVariant.yml#/AddABTestsVariant' metrics: type: array description: A/B test metrics involved in the test. Only these metrics will be considered when calculating results. items: - $ref: "../common/parameters.yml#/metric" + $ref: '../common/parameters.yml#/metric' configuration: - $ref: "../common/schemas/ABTest.yml#/ABTestConfiguration" + $ref: '../common/schemas/ABTest.yml#/ABTestConfiguration' endAt: - $ref: "../common/parameters.yml#/endAt" + $ref: '../common/parameters.yml#/endAt' required: - name - variants - metrics - endAt responses: - "200": + '200': description: OK headers: x-ratelimit-limit: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-limit" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-limit' x-ratelimit-remaining: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-remaining" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-remaining' x-ratelimit-reset: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-reset" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-reset' content: application/json: schema: - $ref: "../common/schemas/ABTestResponse.yml#/ABTestResponse" - "400": - $ref: "../../common/responses/BadRequest.yml" - "402": - $ref: "../../common/responses/FeatureNotEnabled.yml" - "403": - $ref: "../../common/responses/MethodNotAllowed.yml" - "404": - $ref: "../../common/responses/IndexNotFound.yml" + $ref: '../common/schemas/ABTestResponse.yml#/ABTestResponse' + '400': + $ref: '../../common/responses/BadRequest.yml' + '402': + $ref: '../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../common/responses/IndexNotFound.yml' get: tags: @@ -87,25 +87,25 @@ get: - name: indexPrefix in: query description: Index name prefix. Only A/B tests for indices starting with this string are included in the response. - example: "dev_" + example: 'dev_' schema: type: string - name: indexSuffix in: query description: Index name suffix. Only A/B tests for indices ending with this string are included in the response. - example: "_development" + example: '_development' schema: type: string responses: - "200": + '200': description: OK headers: x-ratelimit-limit: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-limit" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-limit' x-ratelimit-remaining: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-remaining" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-remaining' x-ratelimit-reset: - $ref: "../../common/responses/rateLimit.yml#/x-ratelimit-reset" + $ref: '../../common/responses/rateLimit.yml#/x-ratelimit-reset' content: application/json: schema: @@ -114,7 +114,7 @@ get: additionalProperties: false properties: abtests: - $ref: "../common/schemas/ABTest.yml#/ABTests" + $ref: '../common/schemas/ABTest.yml#/ABTests' count: type: integer description: Number of A/B tests. @@ -127,11 +127,11 @@ get: - abtests - count - total - "400": - $ref: "../../common/responses/BadRequest.yml" - "402": - $ref: "../../common/responses/FeatureNotEnabled.yml" - "403": - $ref: "../../common/responses/MethodNotAllowed.yml" - "404": - $ref: "../../common/responses/IndexNotFound.yml" + '400': + $ref: '../../common/responses/BadRequest.yml' + '402': + $ref: '../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../common/responses/IndexNotFound.yml' diff --git a/specs/abtesting-v3/spec.yml b/specs/abtesting-v3/spec.yml index 5d39a52e19..d25d3cf387 100644 --- a/specs/abtesting-v3/spec.yml +++ b/specs/abtesting-v3/spec.yml @@ -58,9 +58,9 @@ info: components: securitySchemes: appId: - $ref: "../common/securitySchemes.yml#/appId" + $ref: '../common/securitySchemes.yml#/appId' apiKey: - $ref: "../common/securitySchemes.yml#/apiKey" + $ref: '../common/securitySchemes.yml#/apiKey' servers: - url: https://analytics.{region}.algolia.com variables: @@ -89,23 +89,23 @@ paths: # ### Custom request ### # ###################### /{path}: - $ref: "../common/paths/customRequest.yml" + $ref: '../common/paths/customRequest.yml' /3/abtests: - $ref: "paths/abtests.yml" + $ref: 'paths/abtests.yml' /3/abtests/{id}: - $ref: "paths/abtest.yml" + $ref: 'paths/abtest.yml' /3/abtests/{id}/stop: - $ref: "paths/stopABTest.yml" + $ref: 'paths/stopABTest.yml' /3/abtests/schedule: - $ref: "paths/scheduleABTest.yml" + $ref: 'paths/scheduleABTest.yml' /3/abtests/estimate: - $ref: "paths/estimate.yml" + $ref: 'paths/estimate.yml' /3/abtests/{id}/timeseries: - $ref: "paths/timeseries.yml" + $ref: 'paths/timeseries.yml' # ############### # ### Helpers ### # ############### /setClientApiKey: - $ref: "../common/helpers/setClientApiKey.yml#/method" + $ref: '../common/helpers/setClientApiKey.yml#/method'