From 07e074806452b2cb590e9c2e34a8e4ffd02345db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 24 Jun 2024 10:55:49 +0200 Subject: [PATCH] feat(clients): add recommend to algoliasearch (#2860) Co-authored-by: Aymeric Giraudet --- .../algoliasearch-client-javascript/yarn.lock | 91 +++++++--- config/clients.config.json | 1 - .../codegen/AlgoliaJavascriptGenerator.java | 2 +- .../cts/manager/JavascriptCTSManager.java | 5 +- .../codegen/cts/tests/TestsRequest.java | 31 +++- scripts/buildClients.ts | 5 +- scripts/ci/githubActions/createMatrix.ts | 10 +- scripts/specs/index.ts | 52 ++++-- scripts/types.ts | 5 +- .../algoliasearch/builds/browser.mustache | 5 +- .../algoliasearch/builds/definition.mustache | 62 ++++--- .../algoliasearch/builds/initClients.mustache | 8 + .../algoliasearch/builds/models.mustache | 162 ++++++++++++++++-- .../algoliasearch/builds/node.mustache | 5 +- .../clients/client/api/imports.mustache | 4 +- .../clients/client/builds/definition.mustache | 6 +- .../client/model/clientMethodProps.mustache | 2 +- templates/javascript/clients/package.mustache | 24 +-- templates/javascript/snippets/method.mustache | 2 +- .../javascript/tests/client/suite.mustache | 4 +- templates/javascript/tests/package.mustache | 4 +- .../tests/requests/requests.mustache | 6 +- tests/output/javascript/yarn.lock | 9 +- .../contributing/testing/common-test-suite.md | 1 - 24 files changed, 371 insertions(+), 135 deletions(-) diff --git a/clients/algoliasearch-client-javascript/yarn.lock b/clients/algoliasearch-client-javascript/yarn.lock index 10b71fb969..ab9c03f3db 100644 --- a/clients/algoliasearch-client-javascript/yarn.lock +++ b/clients/algoliasearch-client-javascript/yarn.lock @@ -3067,7 +3067,16 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2": +"acorn@npm:^8.1.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2": + version: 8.11.3 + resolution: "acorn@npm:8.11.3" + bin: + acorn: bin/acorn + checksum: 10/b688e7e3c64d9bfb17b596e1b35e4da9d50553713b3b3630cf5690f2b023a84eac90c56851e6912b483fe60e8b4ea28b254c07e92f17ef83d72d78745a8352dd + languageName: node + linkType: hard + +"acorn@npm:^8.11.0": version: 8.12.0 resolution: "acorn@npm:8.12.0" bin: @@ -4460,9 +4469,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.796": - version: 1.4.810 - resolution: "electron-to-chromium@npm:1.4.810" - checksum: 10/425de710336094330fd026cc2cfa0b383bfc9a49a2f575ceec2ac76198663ff95d0109bb45b243a43f0bf0f91a2e9c2768693a136d0968ae59728d5e8eea22ef + version: 1.4.805 + resolution: "electron-to-chromium@npm:1.4.805" + checksum: 10/69ff2b7098ec80666c7cfed3ae045894b1bf8ae72a77233c37b4496698a1c20a24e9b97822df7fe5dad226d32ca52defa10dee4b36438da35af6d51810d652d3 languageName: node linkType: hard @@ -5153,18 +5162,17 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.4.2 - resolution: "glob@npm:10.4.2" + version: 10.4.1 + resolution: "glob@npm:10.4.1" dependencies: foreground-child: "npm:^3.1.0" jackspeak: "npm:^3.1.2" minimatch: "npm:^9.0.4" minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10/e412776b5952a818eba790c830bea161c9a56813fd767d8c4c49f855603b1fb962b3e73f1f627a47298a57d2992b9f0f2fe15cf93e74ecaaa63fb45d63fdd090 + checksum: 10/d7bb49d2b413f77bdd59fea4ca86dcc12450deee221af0ca93e09534b81b9ef68fe341345751d8ff0c5b54bad422307e0e44266ff8ad7fbbd0c200e8ec258b16 languageName: node linkType: hard @@ -5333,7 +5341,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.0": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -5675,11 +5683,11 @@ __metadata: linkType: hard "is-core-module@npm:^2.13.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1": - version: 2.14.0 - resolution: "is-core-module@npm:2.14.0" + version: 2.13.1 + resolution: "is-core-module@npm:2.13.1" dependencies: - hasown: "npm:^2.0.2" - checksum: 10/1e0d1a16cb3a94746f6a28db09ccab4562860c94c74bacedb3a6729736d61cfb97001d2052f9622637aa7ea8e0643a3f0f4f16965c70ba6ce30a8ccfe8074af8 + hasown: "npm:^2.0.0" + checksum: 10/d53bd0cc24b0a0351fb4b206ee3908f71b9bbf1c47e9c9e14e5f06d292af1663704d2abd7e67700d6487b2b7864e0d0f6f10a1edf1892864bdffcb197d1845a2 languageName: node linkType: hard @@ -7350,7 +7358,7 @@ __metadata: languageName: node linkType: hard -"node-gyp@npm:^10.0.0, node-gyp@npm:latest": +"node-gyp@npm:^10.0.0": version: 10.1.0 resolution: "node-gyp@npm:10.1.0" dependencies: @@ -7370,6 +7378,26 @@ __metadata: languageName: node linkType: hard +"node-gyp@npm:latest": + version: 10.0.1 + resolution: "node-gyp@npm:10.0.1" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10/578cf0c821f258ce4b6ebce4461eca4c991a4df2dee163c0624f2fe09c7d6d37240be4942285a0048d307230248ee0b18382d6623b9a0136ce9533486deddfa8 + languageName: node + linkType: hard + "node-int64@npm:^0.4.0": version: 0.4.0 resolution: "node-int64@npm:0.4.0" @@ -7721,9 +7749,9 @@ __metadata: linkType: hard "object-inspect@npm:^1.13.1": - version: 1.13.2 - resolution: "object-inspect@npm:1.13.2" - checksum: 10/7ef65583b6397570a17c56f0c1841e0920e83900f2c94638927abb7b81ac08a19c7aae135bd9dcca96208cac0c7332b4650fb927f027b0cf92d71df2990d0561 + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: 10/92f4989ed83422d56431bc39656d4c780348eb15d397ce352ade6b7fec08f973b53744bd41b94af021901e61acaf78fcc19e65bf464ecc0df958586a672700f0 languageName: node linkType: hard @@ -7920,13 +7948,6 @@ __metadata: languageName: node linkType: hard -"package-json-from-dist@npm:^1.0.0": - version: 1.0.0 - resolution: "package-json-from-dist@npm:1.0.0" - checksum: 10/ac706ec856a5a03f5261e4e48fa974f24feb044d51f84f8332e2af0af04fbdbdd5bbbfb9cbbe354190409bc8307c83a9e38c6672c3c8855f709afb0006a009ea - languageName: node - linkType: hard - "pacote@npm:^17.0.5": version: 17.0.7 resolution: "pacote@npm:17.0.7" @@ -9330,7 +9351,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:6.2.1, tar@npm:^6.1.11, tar@npm:^6.1.2": +"tar@npm:6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" dependencies: @@ -9344,6 +9365,20 @@ __metadata: languageName: node linkType: hard +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.0 + resolution: "tar@npm:6.2.0" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10/2042bbb14830b5cd0d584007db0eb0a7e933e66d1397e72a4293768d2332449bc3e312c266a0887ec20156dea388d8965e53b4fc5097f42d78593549016da089 + languageName: node + linkType: hard + "temp-dir@npm:1.0.0": version: 1.0.0 resolution: "temp-dir@npm:1.0.0" @@ -9763,13 +9798,13 @@ __metadata: linkType: hard "v8-to-istanbul@npm:^9.0.1": - version: 9.3.0 - resolution: "v8-to-istanbul@npm:9.3.0" + version: 9.2.0 + resolution: "v8-to-istanbul@npm:9.2.0" dependencies: "@jridgewell/trace-mapping": "npm:^0.3.12" "@types/istanbul-lib-coverage": "npm:^2.0.1" convert-source-map: "npm:^2.0.0" - checksum: 10/fb1d70f1176cb9dc46cabbb3fd5c52c8f3e8738b61877b6e7266029aed0870b04140e3f9f4550ac32aebcfe1d0f38b0bac57e1e8fb97d68fec82f2b416148166 + checksum: 10/18dd8cebfb6790f27f4e41e7cff77c7ab1c8904085f354dd7875e2eb65f4261c4cf40939132502875779d92304bfea46b8336346ecb40b6f33c3a3979e6f5729 languageName: node linkType: hard diff --git a/config/clients.config.json b/config/clients.config.json index 1e536fd756..40cbc461c0 100644 --- a/config/clients.config.json +++ b/config/clients.config.json @@ -165,7 +165,6 @@ } ], "folder": "clients/algoliasearch-client-javascript", - "npmNamespace": "@algolia", "gitRepoId": "algoliasearch-client-javascript", "packageVersion": "5.0.0-beta.5", "modelFolder": "model", diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java index b062e31d07..c5718756eb 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java @@ -155,6 +155,7 @@ private void setDefaultGeneratorOptions() { additionalProperties.put("abtestingVersion", Helpers.getPackageJsonVersion("client-abtesting")); additionalProperties.put("personalizationVersion", Helpers.getPackageJsonVersion("client-personalization")); additionalProperties.put("searchVersion", Helpers.getPackageJsonVersion("client-search")); + additionalProperties.put("recommendVersion", Helpers.getPackageJsonVersion("recommend")); // Files used to generate the `lite` client apiName = "lite" + Helpers.API_SUFFIX; @@ -185,7 +186,6 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List supportingFiles) { @Override public void addDataToBundle(Map bundle) throws GeneratorException { - String npmNamespace = Helpers.getClientConfigField("javascript", "npmNamespace"); - bundle.put("utilsPackageVersion", Helpers.getPackageJsonVersion("client-common")); - bundle.put("npmNamespace", npmNamespace); List> clients = new ArrayList<>(); String importName = ""; @@ -35,7 +32,7 @@ public void addDataToBundle(Map bundle) throws GeneratorExceptio String output = c.get("output").asText(); String packageName = output.substring(output.lastIndexOf("/") + 1); if (!packageName.equals("algoliasearch")) { - packageName = npmNamespace + "/" + packageName; + packageName = "@algolia/" + packageName; } clients.add(Map.of("packageName", packageName, "packagePath", "link:../../../" + output.replace("#{cwd}/", ""))); diff --git a/generators/src/main/java/com/algolia/codegen/cts/tests/TestsRequest.java b/generators/src/main/java/com/algolia/codegen/cts/tests/TestsRequest.java index 12555213a5..fe5ac975c7 100644 --- a/generators/src/main/java/com/algolia/codegen/cts/tests/TestsRequest.java +++ b/generators/src/main/java/com/algolia/codegen/cts/tests/TestsRequest.java @@ -6,6 +6,7 @@ import com.algolia.codegen.utils.*; import java.io.File; import java.util.*; +import org.apache.commons.lang3.ArrayUtils; import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.CodegenResponse; @@ -24,10 +25,32 @@ protected Map loadRequestCTS() throws Exception { String clientName = client; // This special case allow us to read the `search` CTS to generated the tests for the // `lite` client, which is only available in Javascript - if ((language.equals("javascript") || language.equals("dart")) && client.equals("algoliasearch")) { + if (client.equals("algoliasearch")) { clientName = "search"; } - return super.loadCTS("requests", clientName, Request[].class); + + Map baseCTS = super.loadCTS("requests", clientName, Request[].class); + + // The algoliasearch client bundles many client and therefore should provide tests for all the + // subsequent specs + if (client.equals("algoliasearch")) { + Map recommendCTS = super.loadCTS("requests", "recommend", Request[].class); + for (Map.Entry entry : recommendCTS.entrySet()) { + String operation = entry.getKey(); + // custom methods are common to every clients, we don't want duplicate tests + if (operation.startsWith("custom")) { + continue; + } + + if (baseCTS.containsKey(operation)) { + baseCTS.put(operation, ArrayUtils.addAll(baseCTS.get(operation), entry.getValue())); + } else { + baseCTS.put(operation, entry.getValue()); + } + } + } + + return baseCTS; } @Override @@ -75,7 +98,9 @@ public void run(Map models, Map throw new CTSException( "operationId '" + operationId + - "' does not exist in the tests suite, please create the file:" + + "' does not exist in the " + + client + + " tests suite, please create the file:" + " 'tests/CTS/requests/" + client + "/" + diff --git a/scripts/buildClients.ts b/scripts/buildClients.ts index 27a2db1c42..61e778118a 100644 --- a/scripts/buildClients.ts +++ b/scripts/buildClients.ts @@ -2,7 +2,7 @@ import * as fsp from 'fs/promises'; import { run, toAbsolutePath } from './common.js'; -import { getClientsConfigField, getLanguageFolder } from './config.js'; +import { getLanguageFolder } from './config.js'; import { createSpinner } from './spinners.js'; import type { Generator, Language } from './types.js'; @@ -17,9 +17,8 @@ async function buildClient(language: Language, gens: Generator[]): Promise await run('dotnet build --configuration Release', { cwd, language }); break; case 'javascript': - const npmNamespace = getClientsConfigField('javascript', 'npmNamespace'); const packageNames = gens.map(({ additionalProperties: { packageName } }) => - packageName === 'algoliasearch' ? packageName : `${npmNamespace}/${packageName}`, + packageName === 'algoliasearch' ? packageName : `@algolia/${packageName}`, ); await run('YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install', { cwd }); diff --git a/scripts/ci/githubActions/createMatrix.ts b/scripts/ci/githubActions/createMatrix.ts index 7fcd0493f0..5ea15ecd6c 100644 --- a/scripts/ci/githubActions/createMatrix.ts +++ b/scripts/ci/githubActions/createMatrix.ts @@ -2,12 +2,7 @@ import * as core from '@actions/core'; import { CLIENTS, createClientName, GENERATORS, LANGUAGES } from '../../common.js'; -import { - getClientsConfigField, - getLanguageFolder, - getTestExtension, - getTestOutputFolder, -} from '../../config.js'; +import { getLanguageFolder, getTestExtension, getTestOutputFolder } from '../../config.js'; import { COMMON_DEPENDENCIES, DEPENDENCIES } from './setRunVariables.js'; import type { ClientMatrix, CreateMatrix, ToRunMatrix } from './types.js'; @@ -102,12 +97,11 @@ async function createClientMatrix(baseBranch: string): Promise { testsToStore = `${testsToStore} ${testsRootFolder}/build.gradle`; break; case 'javascript': - const npmNamespace = getClientsConfigField('javascript', 'npmNamespace'); const packageNames = matrix[language].toRun.map((client) => { const packageName = GENERATORS[`${language}-${client}`].additionalProperties.packageName; // `algoliasearch` is not preceded by `@algolia` - return client === 'algoliasearch' ? packageName : `${npmNamespace}/${packageName}`; + return client === 'algoliasearch' ? packageName : `@algolia/${packageName}`; }); buildCommand = `cd ${matrix[language].path} && yarn build:many '{${packageNames.join( diff --git a/scripts/specs/index.ts b/scripts/specs/index.ts index 3653ae2fb7..cd6adb8dc2 100644 --- a/scripts/specs/index.ts +++ b/scripts/specs/index.ts @@ -10,7 +10,7 @@ import type { Spec } from '../types.js'; import { lintCommon, transformBundle } from './format.js'; import type { BaseBuildSpecsOptions } from './types.js'; -const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost']; +const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost', 'getRecommendations']; /** * Creates a lite search spec with the `ALGOLIASEARCH_LITE_OPERATIONS` methods @@ -19,27 +19,36 @@ const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost']; async function buildLiteSpec({ spec, bundledPath, + docs, + useCache, }: { spec: string; bundledPath: string; + docs: boolean; + useCache: boolean; }): Promise { - const parsed = yaml.load(await fsp.readFile(toAbsolutePath(bundledPath), 'utf8')) as Spec; - - // Filter methods. - parsed.paths = Object.entries(parsed.paths).reduce( - (acc, [path, operations]) => { - for (const [, operation] of Object.entries(operations)) { - if (ALGOLIASEARCH_LITE_OPERATIONS.includes(operation.operationId)) { - return { ...acc, [path]: { post: operation } }; - } - } + await buildSpec({ spec: 'recommend', outputFormat: 'yml', docs, useCache }); - return acc; - }, - {} as Spec['paths'], - ); + const base = yaml.load(await fsp.readFile(toAbsolutePath(bundledPath), 'utf8')) as Spec; + const recommend = yaml.load( + await fsp.readFile(toAbsolutePath(bundledPath.replace('algoliasearch', 'recommend')), 'utf8'), + ) as Spec; + base.paths = { ...base.paths, ...recommend.paths }; + base.components.schemas = { ...base.components.schemas, ...recommend.components.schemas }; - await fsp.writeFile(bundledPath, yaml.dump(parsed)); + const lite = { ...base, paths: {} }; + + for (const [path, operations] of Object.entries(base.paths)) { + for (const [, operation] of Object.entries(operations)) { + if (ALGOLIASEARCH_LITE_OPERATIONS.includes(operation.operationId)) { + lite.paths[path] = { post: operation }; + + break; + } + } + } + + await fsp.writeFile(bundledPath, yaml.dump(lite)); // remove unused components for the outputted light spec await run( @@ -71,11 +80,12 @@ async function buildSpec({ // In case of lite we use a the `search` spec as a base because only its bundled form exists. const specBase = isAlgoliasearch ? 'search' : spec; + const deps = isAlgoliasearch ? ['search', 'recommend'] : [spec]; const logSuffix = docs ? 'doc spec' : 'spec'; const cache = new Cache({ folder: toAbsolutePath('specs/'), generatedFiles: [docs ? `bundled/${spec}.doc.yml` : `bundled/${spec}.yml`], - filesToCache: [specBase, 'common'], + filesToCache: [...deps, 'common'], cacheFile: toAbsolutePath(`specs/dist/${spec}.${docs ? 'doc.' : ''}cache`), }); @@ -113,6 +123,8 @@ async function buildSpec({ await buildLiteSpec({ spec, bundledPath: toAbsolutePath(bundledPath), + docs, + useCache, }); } @@ -140,6 +152,12 @@ export async function buildSpecs({ await lintCommon(useCache); + // the `lite` spec will build the `recommend` spec, so we remove it from the list + // to prevent concurrent builds + if (clients.includes('algoliasearch') && !docs) { + clients = clients.filter((client) => client !== 'recommend'); + } + await Promise.all( clients.map((client) => buildSpec({ spec: client, outputFormat, docs, useCache })), ); diff --git a/scripts/types.ts b/scripts/types.ts index 9e37ff63e0..8b48667503 100644 --- a/scripts/types.ts +++ b/scripts/types.ts @@ -43,7 +43,10 @@ export type Language = keyof typeof config; export type Spec = { servers: Server[]; tags: Tag[]; - paths: Path[]; + paths: Path; + components: { + schemas: Record; + }; }; /** diff --git a/templates/javascript/clients/algoliasearch/builds/browser.mustache b/templates/javascript/clients/algoliasearch/builds/browser.mustache index 97115d64dd..31118bf6e7 100644 --- a/templates/javascript/clients/algoliasearch/builds/browser.mustache +++ b/templates/javascript/clients/algoliasearch/builds/browser.mustache @@ -1,5 +1,7 @@ // {{{generationBanner}}} +import type { InitClientOptions, InitClientRegion } from "./models" + {{> algoliasearch/builds/definition}} const commonOptions: CreateClientOptions = { apiKey, @@ -33,8 +35,9 @@ get _ua(): string { return this.transporter.algoliaAgent.value; }, + initAbtesting, initAnalytics, initPersonalization, - initAbtesting, + initRecommend, }; } \ No newline at end of file diff --git a/templates/javascript/clients/algoliasearch/builds/definition.mustache b/templates/javascript/clients/algoliasearch/builds/definition.mustache index 9d63efde23..a80230dc37 100644 --- a/templates/javascript/clients/algoliasearch/builds/definition.mustache +++ b/templates/javascript/clients/algoliasearch/builds/definition.mustache @@ -1,28 +1,8 @@ -import type { PersonalizationClient } from '@algolia/client-personalization'; -import type { AnalyticsClient } from '@algolia/client-analytics'; -import type { AbtestingClient } from '@algolia/client-abtesting'; - -import type { Region as AnalyticsRegion } from '{{{npmNamespace}}}/client-analytics/src/analyticsClient'; -import { createAnalyticsClient, REGIONS as analyticsRegions } from '{{{npmNamespace}}}/client-analytics/src/analyticsClient'; - -import type { Region as AbtestingRegion } from '{{{npmNamespace}}}/client-abtesting/src/abtestingClient'; -import { createAbtestingClient, REGIONS as abtestingRegions } from '{{{npmNamespace}}}/client-abtesting/src/abtestingClient'; - -import type { Region as PersonalizationRegion } from '{{{npmNamespace}}}/client-personalization/src/personalizationClient'; -import { createPersonalizationClient, REGIONS as personalizationRegions } from '{{{npmNamespace}}}/client-personalization/src/personalizationClient'; -import { createSearchClient, apiClientVersion as searchClientVersion } from '{{{npmNamespace}}}/client-search/src/searchClient'; - -import { serializeQueryParameters } from '{{{npmNamespace}}}/client-common'; -import type {} from '{{{npmNamespace}}}/client-common'; -import type { InitClientOptions, InitClientRegion, GenerateSecuredApiKeyOptions, GetSecuredApiKeyRemainingValidityOptions } from "./models" - {{#nodeSearchHelpers}} import {createHmac} from 'crypto'; {{/nodeSearchHelpers}} import { - ClientOptions, - CreateClientOptions, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_BROWSER, @@ -33,11 +13,45 @@ import { createFallbackableCache, createMemoryCache, createNullCache, -} from '{{{npmNamespace}}}/client-common'; - -import { createHttpRequester } from '{{{npmNamespace}}}/requester-node-http'; + serializeQueryParameters, +} from '@algolia/client-common'; +import type { AbtestingClient } from '@algolia/client-abtesting'; +import type { Region as AbtestingRegion } from '@algolia/client-abtesting/src/abtestingClient'; +import { + createAbtestingClient, + REGIONS as abtestingRegions, +} from '@algolia/client-abtesting/src/abtestingClient'; +import type { AnalyticsClient } from '@algolia/client-analytics'; +import { + createAnalyticsClient, + REGIONS as analyticsRegions, +} from '@algolia/client-analytics/src/analyticsClient'; +import type { Region as AnalyticsRegion } from '@algolia/client-analytics/src/analyticsClient'; +import type { + ClientOptions, + CreateClientOptions, +} from '@algolia/client-common'; +import type { PersonalizationClient } from '@algolia/client-personalization'; +import type { Region as PersonalizationRegion } from '@algolia/client-personalization/src/personalizationClient'; +import { + createPersonalizationClient, + REGIONS as personalizationRegions, +} from '@algolia/client-personalization/src/personalizationClient'; +import { + createSearchClient, + apiClientVersion as searchClientVersion, +} from '@algolia/client-search/src/searchClient'; +import type { RecommendClient } from '@algolia/recommend'; +import { createRecommendClient } from '@algolia/recommend/src/recommendClient'; +import { createXhrRequester } from '@algolia/requester-browser-xhr'; +import { createHttpRequester } from '@algolia/requester-node-http'; -import { createXhrRequester } from '{{{npmNamespace}}}/requester-browser-xhr'; +import type { + InitClientOptions, + InitClientRegion, + GenerateSecuredApiKeyOptions, + GetSecuredApiKeyRemainingValidityOptions, +} from './models'; export * from './models'; diff --git a/templates/javascript/clients/algoliasearch/builds/initClients.mustache b/templates/javascript/clients/algoliasearch/builds/initClients.mustache index 73d36fe0e9..d2eb88176c 100644 --- a/templates/javascript/clients/algoliasearch/builds/initClients.mustache +++ b/templates/javascript/clients/algoliasearch/builds/initClients.mustache @@ -1,3 +1,11 @@ +function initRecommend(initOptions: InitClientOptions = {}): RecommendClient { + return createRecommendClient({ + ...commonOptions, + ...initOptions.options, + ...initOptions, + }); +} + function initAnalytics(initOptions: InitClientOptions & InitClientRegion = {}): AnalyticsClient { if ( initOptions.region && diff --git a/templates/javascript/clients/algoliasearch/builds/models.mustache b/templates/javascript/clients/algoliasearch/builds/models.mustache index a7cbf278d3..36b601c15c 100644 --- a/templates/javascript/clients/algoliasearch/builds/models.mustache +++ b/templates/javascript/clients/algoliasearch/builds/models.mustache @@ -4,31 +4,161 @@ import type { Host, Requester, ClientOptions, -} from '{{{npmNamespace}}}/client-common'; +} from '@algolia/client-common'; import { - ErrorBase, - CustomPutProps, - CustomPostProps, + AdvancedSyntaxFeatures, + AlternativesAsExact, + Anchoring, + AroundPrecision, + AroundPrecisionFromValueInner, + AroundRadius, + AroundRadiusAll, + AutomaticFacetFilter, + AutomaticFacetFilters, + BaseSearchParams, + BaseSearchParamsWithoutQuery, + BaseSearchResponse, + Condition, + Consequence, + ConsequenceHide, + ConsequenceParams, + ConsequenceQuery, + ConsequenceQueryObject, CustomDeleteProps, CustomGetProps, -} from '{{{npmNamespace}}}/client-search/model'; + CustomPostProps, + CustomPutProps, + DeletedAtResponse, + Distinct, + Edit, + EditType, + ErrorBase, + ExactOnSingleWordQuery, + Exhaustive, + FacetFilters, + FacetOrdering, + Facets, + FacetsStats, + HighlightResult, + HighlightResultOption, + IgnorePlurals, + IndexSettingsAsSearchParams, + MatchLevel, + MatchedGeoLocation, + Mode, + NumericFilters, + OptionalFilters, + Params, + Personalization, + Promote, + PromoteObjectID, + PromoteObjectIDs, + QueryType, + RankingInfo, + ReRankingApplyFilter, + Redirect, + RedirectRuleIndexMetadata, + RedirectRuleIndexMetadataData, + RemoveStopWords, + RemoveWordsIfNoResults, + RenderingContent, + SearchParams, + SearchParamsObject, + SearchParamsQuery, + SemanticSearch, + SnippetResult, + SnippetResultOption, + SortRemainingBy, + SupportedLanguage, + TagFilters, + TaskStatus, + TypoTolerance, + TypoToleranceEnum, + Value, +} from '@algolia/client-search/model'; -export * from '{{{npmNamespace}}}/client-search/model'; -export * from '{{{npmNamespace}}}/client-personalization/model'; -export * from '{{{npmNamespace}}}/client-analytics/model'; -export * from '{{{npmNamespace}}}/client-abtesting/model'; +export * from '@algolia/client-search/model'; +export * from '@algolia/recommend/model'; +export * from '@algolia/client-personalization/model'; +export * from '@algolia/client-analytics/model'; +export * from '@algolia/client-abtesting/model'; -export { SearchClient } from '{{{npmNamespace}}}/client-search'; -export { PersonalizationClient } from '{{{npmNamespace}}}/client-personalization'; -export { AnalyticsClient } from '{{{npmNamespace}}}/client-analytics'; -export { AbtestingClient } from '{{{npmNamespace}}}/client-abtesting'; +export { SearchClient } from '@algolia/client-search'; +export { RecommendClient } from '@algolia/recommend'; +export { PersonalizationClient } from '@algolia/client-personalization'; +export { AnalyticsClient } from '@algolia/client-analytics'; +export { AbtestingClient } from '@algolia/client-abtesting'; export { - ErrorBase, - CustomPutProps, - CustomPostProps, + AdvancedSyntaxFeatures, + AlternativesAsExact, + Anchoring, + AroundPrecision, + AroundPrecisionFromValueInner, + AroundRadius, + AroundRadiusAll, + AutomaticFacetFilter, + AutomaticFacetFilters, + BaseSearchParams, + BaseSearchParamsWithoutQuery, + BaseSearchResponse, + Condition, + Consequence, + ConsequenceHide, + ConsequenceParams, + ConsequenceQuery, + ConsequenceQueryObject, CustomDeleteProps, CustomGetProps, + CustomPostProps, + CustomPutProps, + DeletedAtResponse, + Distinct, + Edit, + EditType, + ErrorBase, + ExactOnSingleWordQuery, + Exhaustive, + FacetFilters, + FacetOrdering, + Facets, + FacetsStats, + HighlightResult, + HighlightResultOption, + IgnorePlurals, + IndexSettingsAsSearchParams, + MatchLevel, + MatchedGeoLocation, + Mode, + NumericFilters, + OptionalFilters, + Params, + Personalization, + Promote, + PromoteObjectID, + PromoteObjectIDs, + QueryType, + RankingInfo, + ReRankingApplyFilter, + Redirect, + RedirectRuleIndexMetadata, + RedirectRuleIndexMetadataData, + RemoveStopWords, + RemoveWordsIfNoResults, + RenderingContent, + SearchParams, + SearchParamsObject, + SearchParamsQuery, + SemanticSearch, + SnippetResult, + SnippetResultOption, + SortRemainingBy, + SupportedLanguage, + TagFilters, + TaskStatus, + TypoTolerance, + TypoToleranceEnum, + Value, }; /** diff --git a/templates/javascript/clients/algoliasearch/builds/node.mustache b/templates/javascript/clients/algoliasearch/builds/node.mustache index 070732ad37..67d4347c16 100644 --- a/templates/javascript/clients/algoliasearch/builds/node.mustache +++ b/templates/javascript/clients/algoliasearch/builds/node.mustache @@ -1,5 +1,7 @@ // {{{generationBanner}}} +import type { InitClientOptions, InitClientRegion {{#nodeSearchHelpers}}, GenerateSecuredApiKeyOptions, GetSecuredApiKeyRemainingValidityOptions {{/nodeSearchHelpers}} } from "./models" + {{> algoliasearch/builds/definition}} const commonOptions: CreateClientOptions = { apiKey, @@ -27,9 +29,10 @@ get _ua(): string { return this.transporter.algoliaAgent.value; }, + initAbtesting, initAnalytics, initPersonalization, - initAbtesting, + initRecommend, {{#nodeSearchHelpers}} {{> client/api/nodeHelpers}} {{/nodeSearchHelpers}} diff --git a/templates/javascript/clients/client/api/imports.mustache b/templates/javascript/clients/client/api/imports.mustache index 552520ca9c..010443f13d 100644 --- a/templates/javascript/clients/client/api/imports.mustache +++ b/templates/javascript/clients/client/api/imports.mustache @@ -7,7 +7,7 @@ import { serializeQueryParameters, createIterablePromise, {{/isSearchClient}} -} from '{{{npmNamespace}}}/client-common'; +} from '@algolia/client-common'; import type { CreateClientOptions, Headers, @@ -19,7 +19,7 @@ import type { ApiError, IterableOptions, {{/isSearchClient}} -} from '{{{npmNamespace}}}/client-common'; +} from '@algolia/client-common'; {{#imports}} import { {{classname}} } from '{{filename}}'; diff --git a/templates/javascript/clients/client/builds/definition.mustache b/templates/javascript/clients/client/builds/definition.mustache index 628efea245..492d8c9d76 100644 --- a/templates/javascript/clients/client/builds/definition.mustache +++ b/templates/javascript/clients/client/builds/definition.mustache @@ -1,6 +1,6 @@ -import { createXhrRequester } from '{{{npmNamespace}}}/requester-browser-xhr'; -import { createHttpRequester } from '{{{npmNamespace}}}/requester-node-http'; -import { createMemoryCache, createFallbackableCache, createBrowserLocalStorageCache, createNullCache, ClientOptions, serializeQueryParameters, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_NODE, DEFAULT_WRITE_TIMEOUT_NODE, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_READ_TIMEOUT_BROWSER, DEFAULT_WRITE_TIMEOUT_BROWSER } from '{{{npmNamespace}}}/client-common'; +import { createXhrRequester } from '@algolia/requester-browser-xhr'; +import { createHttpRequester } from '@algolia/requester-node-http'; +import { createMemoryCache, createFallbackableCache, createBrowserLocalStorageCache, createNullCache, ClientOptions, serializeQueryParameters, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_NODE, DEFAULT_WRITE_TIMEOUT_NODE, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_READ_TIMEOUT_BROWSER, DEFAULT_WRITE_TIMEOUT_BROWSER } from '@algolia/client-common'; import { create{{#lambda.titlecase}}{{apiName}}{{/lambda.titlecase}}, apiClientVersion } from '../src/{{apiName}}'; diff --git a/templates/javascript/clients/client/model/clientMethodProps.mustache b/templates/javascript/clients/client/model/clientMethodProps.mustache index b57af4246a..82db620d7d 100644 --- a/templates/javascript/clients/client/model/clientMethodProps.mustache +++ b/templates/javascript/clients/client/model/clientMethodProps.mustache @@ -11,7 +11,7 @@ import { {{classname}} } from '{{filename}}'; {{! Imports for the helpers method of the search client }} {{#isSearchClient}} -import type { CreateIterablePromise } from '{{{npmNamespace}}}/client-common'; +import type { CreateIterablePromise } from '@algolia/client-common'; import type { Action } from './action'; {{/isSearchClient}} diff --git a/templates/javascript/clients/package.mustache b/templates/javascript/clients/package.mustache index 6d1796d7e8..ca38e63149 100644 --- a/templates/javascript/clients/package.mustache +++ b/templates/javascript/clients/package.mustache @@ -9,7 +9,7 @@ "author": "Algolia", "types": "./index.d.ts", {{^isAlgoliasearchClient}} - "name": "{{{npmNamespace}}}/{{packageName}}", + "name": "@algolia/{{packageName}}", "description": "JavaScript client for {{packageName}}", "jsdelivr": "./dist/{{packageName}}.umd.js", "unpkg": "./dist/{{packageName}}.umd.js", @@ -43,9 +43,9 @@ "clean": "rm -rf ./dist || true" }, "dependencies": { - "{{{npmNamespace}}}/client-common": "{{utilsPackageVersion}}", - "{{{npmNamespace}}}/requester-browser-xhr": "{{utilsPackageVersion}}", - "{{{npmNamespace}}}/requester-node-http": "{{utilsPackageVersion}}" + "@algolia/client-common": "{{utilsPackageVersion}}", + "@algolia/requester-browser-xhr": "{{utilsPackageVersion}}", + "@algolia/requester-node-http": "{{utilsPackageVersion}}" }, "devDependencies": { "@types/node": "20.14.8", @@ -109,13 +109,15 @@ "test": "jest" }, "dependencies": { - "{{{npmNamespace}}}/client-analytics": "{{analyticsVersion}}", - "{{{npmNamespace}}}/client-abtesting": "{{abtestingVersion}}", - "{{{npmNamespace}}}/client-personalization": "{{personalizationVersion}}", - "{{{npmNamespace}}}/client-search": "{{searchVersion}}", - "{{{npmNamespace}}}/client-common": "{{utilsPackageVersion}}", - "{{{npmNamespace}}}/requester-browser-xhr": "{{utilsPackageVersion}}", - "{{{npmNamespace}}}/requester-node-http": "{{utilsPackageVersion}}" + "@algolia/client-analytics": "{{analyticsVersion}}", + "@algolia/client-abtesting": "{{abtestingVersion}}", + "@algolia/client-personalization": "{{personalizationVersion}}", + "@algolia/recommend": "{{recommendVersion}}", + "@algolia/client-search": "{{searchVersion}}", + "@algolia/client-common": "{{utilsPackageVersion}}", + "@algolia/recommend": "{{recommendVersion}}", + "@algolia/requester-browser-xhr": "{{utilsPackageVersion}}", + "@algolia/requester-node-http": "{{utilsPackageVersion}}" }, "devDependencies": { "@babel/preset-env": "7.24.7", diff --git a/templates/javascript/snippets/method.mustache b/templates/javascript/snippets/method.mustache index 43b0bf8d1b..fd28496a54 100644 --- a/templates/javascript/snippets/method.mustache +++ b/templates/javascript/snippets/method.mustache @@ -4,7 +4,7 @@ // >IMPORT import { {{client}} } from '{{{import}}}'; // IMPORT< -import type { RequestOptions } from '{{{npmNamespace}}}/client-common'; +import type { RequestOptions } from '@algolia/client-common'; {{#blocksRequests}} {{#snippets}} diff --git a/templates/javascript/tests/client/suite.mustache b/templates/javascript/tests/client/suite.mustache index 229249ec59..6e365646ce 100644 --- a/templates/javascript/tests/client/suite.mustache +++ b/templates/javascript/tests/client/suite.mustache @@ -2,8 +2,8 @@ /* eslint-disable @typescript-eslint/no-unused-vars, require-await */ // @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. import { {{client}}, {{#lambda.titlecase}}{{client}}{{/lambda.titlecase}} } from '{{{import}}}'; -import { echoRequester } from '{{{npmNamespace}}}/requester-node-http'; -import type { EchoResponse } from '{{{npmNamespace}}}/requester-node-http'; +import { echoRequester } from '@algolia/requester-node-http'; +import type { EchoResponse } from '@algolia/requester-node-http'; const appId = 'test-app-id'; const apiKey = 'test-api-key'; diff --git a/templates/javascript/tests/package.mustache b/templates/javascript/tests/package.mustache index ce573e208f..255a345fd6 100644 --- a/templates/javascript/tests/package.mustache +++ b/templates/javascript/tests/package.mustache @@ -8,8 +8,8 @@ {{#packageDependencies}} "{{{packageName}}}": "{{{packagePath}}}", {{/packageDependencies}} - "{{{npmNamespace}}}/client-common": "link:../../../clients/algoliasearch-client-javascript/packages/client-common", - "{{{npmNamespace}}}/requester-node-http": "link:../../../clients/algoliasearch-client-javascript/packages/requester-node-http" + "@algolia/client-common": "link:../../../clients/algoliasearch-client-javascript/packages/client-common", + "@algolia/requester-node-http": "link:../../../clients/algoliasearch-client-javascript/packages/requester-node-http" }, "devDependencies": { "@types/jest": "29.5.12", diff --git a/templates/javascript/tests/requests/requests.mustache b/templates/javascript/tests/requests/requests.mustache index ef935f4463..f0514c0613 100644 --- a/templates/javascript/tests/requests/requests.mustache +++ b/templates/javascript/tests/requests/requests.mustache @@ -7,9 +7,9 @@ import * as dotenv from 'dotenv'; dotenv.config({path:'../../.env'}); {{/hasE2E}} import { {{client}} } from '{{{import}}}'; -import { echoRequester } from '{{{npmNamespace}}}/requester-node-http'; -import type { EchoResponse } from '{{{npmNamespace}}}/client-common'; -import type { RequestOptions } from '{{{npmNamespace}}}/client-common'; +import { echoRequester } from '@algolia/requester-node-http'; +import type { EchoResponse } from '@algolia/client-common'; +import type { RequestOptions } from '@algolia/client-common'; const appId = process.env.ALGOLIA_APPLICATION_ID || 'test_app_id'; const apiKey = process.env.ALGOLIA_SEARCH_KEY || 'test_api_key'; diff --git a/tests/output/javascript/yarn.lock b/tests/output/javascript/yarn.lock index b466d9547e..2f64be4e22 100644 --- a/tests/output/javascript/yarn.lock +++ b/tests/output/javascript/yarn.lock @@ -2595,7 +2595,14 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": +"lru-cache@npm:^10.0.1": + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: 10/502ec42c3309c0eae1ce41afca471f831c278566d45a5273a0c51102dee31e0e250a62fa9029c3370988df33a14188a38e682c16143b794de78668de3643e302 + languageName: node + linkType: hard + +"lru-cache@npm:^10.2.0": version: 10.2.2 resolution: "lru-cache@npm:10.2.2" checksum: 10/ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37 diff --git a/website/docs/contributing/testing/common-test-suite.md b/website/docs/contributing/testing/common-test-suite.md index 1fced9d107..42e2eb8f54 100644 --- a/website/docs/contributing/testing/common-test-suite.md +++ b/website/docs/contributing/testing/common-test-suite.md @@ -248,7 +248,6 @@ As well as lambdas to transform strings: If specific values are needed for a specific languages, or custom generated files, they can be added using a custom CTS manager: - [javascript](https://github.com/algolia/api-clients-automation/blob/main/generators/src/main/java/com/algolia/codegen/cts/manager/JavaScriptCTSManager.java) - - `npmNamespace`: the npm namespace - `utilsPackageVersion`: the utils version to import - `import`: the name of the package or library to import - [java](https://github.com/algolia/api-clients-automation/blob/main/generators/src/main/java/com/algolia/codegen/cts/manager/JavaCTSManager.java)