Skip to content

Commit 5064d64

Browse files
committed
feat(clients): add recommend to algoliasearch
1 parent 24ea158 commit 5064d64

File tree

25 files changed

+385
-96
lines changed

25 files changed

+385
-96
lines changed

clients/algoliasearch-client-javascript/yarn.lock

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,11 +2928,11 @@ __metadata:
29282928
linkType: hard
29292929

29302930
"@types/node@npm:*":
2931-
version: 20.14.5
2932-
resolution: "@types/node@npm:20.14.5"
2931+
version: 20.11.25
2932+
resolution: "@types/node@npm:20.11.25"
29332933
dependencies:
29342934
undici-types: "npm:~5.26.4"
2935-
checksum: 10/74c7974a8c75280f9397f22ce34d10d5575668e3c357a165f385c9365c39b3ccda3aa2e7237e7e907fc72e515afb93cc0be1f3e2074cc1889c1ffeb01d2843cc
2935+
checksum: 10/861265f1bbb151404bd8842b595f027a4ff067c61ecff9a37b9f7f53922c18dd532c8e795e8e7675dd8dba056645623fd2b9848d5ef72863ec3609096cd2923e
29362936
languageName: node
29372937
linkType: hard
29382938

@@ -3088,7 +3088,16 @@ __metadata:
30883088
languageName: node
30893089
linkType: hard
30903090

3091-
"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2":
3091+
"acorn@npm:^8.1.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2":
3092+
version: 8.11.3
3093+
resolution: "acorn@npm:8.11.3"
3094+
bin:
3095+
acorn: bin/acorn
3096+
checksum: 10/b688e7e3c64d9bfb17b596e1b35e4da9d50553713b3b3630cf5690f2b023a84eac90c56851e6912b483fe60e8b4ea28b254c07e92f17ef83d72d78745a8352dd
3097+
languageName: node
3098+
linkType: hard
3099+
3100+
"acorn@npm:^8.11.0":
30923101
version: 8.12.0
30933102
resolution: "acorn@npm:8.12.0"
30943103
bin:
@@ -6847,7 +6856,14 @@ __metadata:
68476856
languageName: node
68486857
linkType: hard
68496858

6850-
"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
6859+
"lru-cache@npm:^10.0.1":
6860+
version: 10.2.0
6861+
resolution: "lru-cache@npm:10.2.0"
6862+
checksum: 10/502ec42c3309c0eae1ce41afca471f831c278566d45a5273a0c51102dee31e0e250a62fa9029c3370988df33a14188a38e682c16143b794de78668de3643e302
6863+
languageName: node
6864+
linkType: hard
6865+
6866+
"lru-cache@npm:^10.2.0":
68516867
version: 10.2.2
68526868
resolution: "lru-cache@npm:10.2.2"
68536869
checksum: 10/ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37
@@ -7370,7 +7386,7 @@ __metadata:
73707386
languageName: node
73717387
linkType: hard
73727388

7373-
"node-gyp@npm:^10.0.0, node-gyp@npm:latest":
7389+
"node-gyp@npm:^10.0.0":
73747390
version: 10.1.0
73757391
resolution: "node-gyp@npm:10.1.0"
73767392
dependencies:
@@ -7390,6 +7406,26 @@ __metadata:
73907406
languageName: node
73917407
linkType: hard
73927408

7409+
"node-gyp@npm:latest":
7410+
version: 10.0.1
7411+
resolution: "node-gyp@npm:10.0.1"
7412+
dependencies:
7413+
env-paths: "npm:^2.2.0"
7414+
exponential-backoff: "npm:^3.1.1"
7415+
glob: "npm:^10.3.10"
7416+
graceful-fs: "npm:^4.2.6"
7417+
make-fetch-happen: "npm:^13.0.0"
7418+
nopt: "npm:^7.0.0"
7419+
proc-log: "npm:^3.0.0"
7420+
semver: "npm:^7.3.5"
7421+
tar: "npm:^6.1.2"
7422+
which: "npm:^4.0.0"
7423+
bin:
7424+
node-gyp: bin/node-gyp.js
7425+
checksum: 10/578cf0c821f258ce4b6ebce4461eca4c991a4df2dee163c0624f2fe09c7d6d37240be4942285a0048d307230248ee0b18382d6623b9a0136ce9533486deddfa8
7426+
languageName: node
7427+
linkType: hard
7428+
73937429
"node-int64@npm:^0.4.0":
73947430
version: 0.4.0
73957431
resolution: "node-int64@npm:0.4.0"
@@ -9343,7 +9379,7 @@ __metadata:
93439379
languageName: node
93449380
linkType: hard
93459381

9346-
"tar@npm:6.2.1, tar@npm:^6.1.11, tar@npm:^6.1.2":
9382+
"tar@npm:6.2.1":
93479383
version: 6.2.1
93489384
resolution: "tar@npm:6.2.1"
93499385
dependencies:
@@ -9357,6 +9393,20 @@ __metadata:
93579393
languageName: node
93589394
linkType: hard
93599395

9396+
"tar@npm:^6.1.11, tar@npm:^6.1.2":
9397+
version: 6.2.0
9398+
resolution: "tar@npm:6.2.0"
9399+
dependencies:
9400+
chownr: "npm:^2.0.0"
9401+
fs-minipass: "npm:^2.0.0"
9402+
minipass: "npm:^5.0.0"
9403+
minizlib: "npm:^2.1.1"
9404+
mkdirp: "npm:^1.0.3"
9405+
yallist: "npm:^4.0.0"
9406+
checksum: 10/2042bbb14830b5cd0d584007db0eb0a7e933e66d1397e72a4293768d2332449bc3e312c266a0887ec20156dea388d8965e53b4fc5097f42d78593549016da089
9407+
languageName: node
9408+
linkType: hard
9409+
93609410
"temp-dir@npm:1.0.0":
93619411
version: 1.0.0
93629412
resolution: "temp-dir@npm:1.0.0"

config/clients.config.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@
165165
}
166166
],
167167
"folder": "clients/algoliasearch-client-javascript",
168-
"npmNamespace": "@algolia",
169168
"gitRepoId": "algoliasearch-client-javascript",
170169
"packageVersion": "5.0.0-beta.4",
171170
"modelFolder": "model",

generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ private void setDefaultGeneratorOptions() {
155155
additionalProperties.put("abtestingVersion", Helpers.getPackageJsonVersion("client-abtesting"));
156156
additionalProperties.put("personalizationVersion", Helpers.getPackageJsonVersion("client-personalization"));
157157
additionalProperties.put("searchVersion", Helpers.getPackageJsonVersion("client-search"));
158+
additionalProperties.put("recommendVersion", Helpers.getPackageJsonVersion("recommend"));
158159

159160
// Files used to generate the `lite` client
160161
apiName = "lite" + Helpers.API_SUFFIX;
@@ -185,7 +186,6 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
185186
setDefaultGeneratorOptions();
186187
try {
187188
additionalProperties.put("utilsPackageVersion", Helpers.getPackageJsonVersion("client-common"));
188-
additionalProperties.put("npmNamespace", Helpers.getClientConfigField("javascript", "npmNamespace"));
189189
} catch (GeneratorException e) {
190190
e.printStackTrace();
191191
System.exit(1);

generators/src/main/java/com/algolia/codegen/cts/manager/JavascriptCTSManager.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ public void addTestsSupportingFiles(List<SupportingFile> supportingFiles) {
2121

2222
@Override
2323
public void addDataToBundle(Map<String, Object> bundle) throws GeneratorException {
24-
String npmNamespace = Helpers.getClientConfigField("javascript", "npmNamespace");
25-
2624
bundle.put("utilsPackageVersion", Helpers.getPackageJsonVersion("client-common"));
27-
bundle.put("npmNamespace", npmNamespace);
2825

2926
List<Map<String, String>> clients = new ArrayList<>();
3027
String importName = "";
@@ -35,7 +32,7 @@ public void addDataToBundle(Map<String, Object> bundle) throws GeneratorExceptio
3532
String output = c.get("output").asText();
3633
String packageName = output.substring(output.lastIndexOf("/") + 1);
3734
if (!packageName.equals("algoliasearch")) {
38-
packageName = npmNamespace + "/" + packageName;
35+
packageName = "@algolia/" + packageName;
3936
}
4037

4138
clients.add(Map.of("packageName", packageName, "packagePath", "link:../../../" + output.replace("#{cwd}/", "")));

generators/src/main/java/com/algolia/codegen/cts/tests/TestsRequest.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.algolia.codegen.utils.*;
77
import java.io.File;
88
import java.util.*;
9+
import org.apache.commons.lang3.ArrayUtils;
910
import org.openapitools.codegen.CodegenModel;
1011
import org.openapitools.codegen.CodegenOperation;
1112
import org.openapitools.codegen.CodegenResponse;
@@ -24,10 +25,32 @@ protected Map<String, Request[]> loadRequestCTS() throws Exception {
2425
String clientName = client;
2526
// This special case allow us to read the `search` CTS to generated the tests for the
2627
// `lite` client, which is only available in Javascript
27-
if ((language.equals("javascript") || language.equals("dart")) && client.equals("algoliasearch")) {
28+
if (client.equals("algoliasearch")) {
2829
clientName = "search";
2930
}
30-
return super.loadCTS("requests", clientName, Request[].class);
31+
32+
Map<String, Request[]> baseCTS = super.loadCTS("requests", clientName, Request[].class);
33+
34+
// The algoliasearch client bundles many client and therefore should provide tests for all the
35+
// subsequent specs
36+
if (client.equals("algoliasearch")) {
37+
Map<String, Request[]> recommendCTS = super.loadCTS("requests", "recommend", Request[].class);
38+
for (Map.Entry<String, Request[]> entry : recommendCTS.entrySet()) {
39+
String operation = entry.getKey();
40+
// custom methods are common to every clients, we don't want duplicate tests
41+
if (operation.startsWith("custom")) {
42+
continue;
43+
}
44+
45+
if (baseCTS.containsKey(operation)) {
46+
baseCTS.put(operation, ArrayUtils.addAll(baseCTS.get(operation), entry.getValue()));
47+
} else {
48+
baseCTS.put(operation, entry.getValue());
49+
}
50+
}
51+
}
52+
53+
return baseCTS;
3154
}
3255

3356
@Override
@@ -75,7 +98,9 @@ public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation>
7598
throw new CTSException(
7699
"operationId '" +
77100
operationId +
78-
"' does not exist in the tests suite, please create the file:" +
101+
"' does not exist in the " +
102+
client +
103+
" tests suite, please create the file:" +
79104
" 'tests/CTS/requests/" +
80105
client +
81106
"/" +

scripts/buildClients.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import * as fsp from 'fs/promises';
33

44
import { run, toAbsolutePath } from './common.js';
5-
import { getClientsConfigField, getLanguageFolder } from './config.js';
5+
import { getLanguageFolder } from './config.js';
66
import { createSpinner } from './spinners.js';
77
import type { Generator, Language } from './types.js';
88

@@ -17,9 +17,8 @@ async function buildClient(language: Language, gens: Generator[]): Promise<void>
1717
await run('dotnet build --configuration Release', { cwd, language });
1818
break;
1919
case 'javascript':
20-
const npmNamespace = getClientsConfigField('javascript', 'npmNamespace');
2120
const packageNames = gens.map(({ additionalProperties: { packageName } }) =>
22-
packageName === 'algoliasearch' ? packageName : `${npmNamespace}/${packageName}`,
21+
packageName === 'algoliasearch' ? packageName : `@algolia/${packageName}`,
2322
);
2423

2524
await run('YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install', { cwd });

scripts/ci/githubActions/createMatrix.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@
22
import * as core from '@actions/core';
33

44
import { CLIENTS, createClientName, GENERATORS, LANGUAGES } from '../../common.js';
5-
import {
6-
getClientsConfigField,
7-
getLanguageFolder,
8-
getTestExtension,
9-
getTestOutputFolder,
10-
} from '../../config.js';
5+
import { getLanguageFolder, getTestExtension, getTestOutputFolder } from '../../config.js';
116

127
import { COMMON_DEPENDENCIES, DEPENDENCIES } from './setRunVariables.js';
138
import type { ClientMatrix, CreateMatrix, ToRunMatrix } from './types.js';
@@ -102,12 +97,11 @@ async function createClientMatrix(baseBranch: string): Promise<void> {
10297
testsToStore = `${testsToStore} ${testsRootFolder}/build.gradle`;
10398
break;
10499
case 'javascript':
105-
const npmNamespace = getClientsConfigField('javascript', 'npmNamespace');
106100
const packageNames = matrix[language].toRun.map((client) => {
107101
const packageName = GENERATORS[`${language}-${client}`].additionalProperties.packageName;
108102

109103
// `algoliasearch` is not preceded by `@algolia`
110-
return client === 'algoliasearch' ? packageName : `${npmNamespace}/${packageName}`;
104+
return client === 'algoliasearch' ? packageName : `@algolia/${packageName}`;
111105
});
112106

113107
buildCommand = `cd ${matrix[language].path} && yarn build:many '{${packageNames.join(

scripts/formatter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export async function formatter(language: string, cwd: string): Promise<void> {
2828
await run('goimports -w . && golangci-lint run --fix', { cwd, language });
2929
break;
3030
case 'javascript':
31-
await run(`yarn eslint --ext=ts,json ${cwd} --fix --no-error-on-unmatched-pattern`);
31+
await run(`yarn eslint --fix --no-error-on-unmatched-pattern --ext=ts,json ${cwd}`);
3232
break;
3333
case 'java':
3434
await run(

scripts/specs/index.ts

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { Spec } from '../types.js';
1010
import { lintCommon, transformBundle } from './format.js';
1111
import type { BaseBuildSpecsOptions } from './types.js';
1212

13-
const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost'];
13+
const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost', 'getRecommendations'];
1414

1515
/**
1616
* Creates a lite search spec with the `ALGOLIASEARCH_LITE_OPERATIONS` methods
@@ -19,32 +19,36 @@ const ALGOLIASEARCH_LITE_OPERATIONS = ['search', 'customPost'];
1919
async function buildLiteSpec({
2020
spec,
2121
bundledPath,
22+
docs,
23+
useCache,
2224
}: {
2325
spec: string;
2426
bundledPath: string;
27+
docs: boolean;
28+
useCache: boolean;
2529
}): Promise<void> {
26-
const parsed = yaml.load(await fsp.readFile(toAbsolutePath(bundledPath), 'utf8')) as Spec;
27-
28-
// Filter methods.
29-
parsed.paths = Object.entries(parsed.paths).reduce(
30-
(acc, [path, operations]) => {
31-
for (const [, operation] of Object.entries(operations)) {
32-
if (ALGOLIASEARCH_LITE_OPERATIONS.includes(operation.operationId)) {
33-
return { ...acc, [path]: { post: operation } };
34-
}
35-
}
30+
await buildSpec({ spec: 'recommend', outputFormat: 'yml', docs, useCache });
3631

37-
return acc;
38-
},
39-
{} as Spec['paths'],
40-
);
32+
const base = yaml.load(await fsp.readFile(toAbsolutePath(bundledPath), 'utf8')) as Spec;
33+
const recommend = yaml.load(
34+
await fsp.readFile(toAbsolutePath(bundledPath.replace('algoliasearch', 'recommend')), 'utf8'),
35+
) as Spec;
36+
base.paths = { ...base.paths, ...recommend.paths };
37+
base.components.schemas = { ...base.components.schemas, ...recommend.components.schemas };
4138

42-
await fsp.writeFile(bundledPath, yaml.dump(parsed));
39+
const lite = { ...base, paths: {} };
4340

44-
// remove unused components for the outputted light spec
45-
await run(
46-
`yarn openapi bundle ${bundledPath} -o ${bundledPath} --ext yml --remove-unused-components`,
47-
);
41+
for (const [path, operations] of Object.entries(base.paths)) {
42+
for (const [, operation] of Object.entries(operations)) {
43+
if (ALGOLIASEARCH_LITE_OPERATIONS.includes(operation.operationId)) {
44+
lite.paths[path] = { post: operation };
45+
46+
break;
47+
}
48+
}
49+
}
50+
51+
await fsp.writeFile(bundledPath, yaml.dump(lite));
4852

4953
await transformBundle({
5054
bundledPath,
@@ -71,11 +75,12 @@ async function buildSpec({
7175

7276
// In case of lite we use a the `search` spec as a base because only its bundled form exists.
7377
const specBase = isAlgoliasearch ? 'search' : spec;
78+
const deps = isAlgoliasearch ? ['search', 'recommend'] : [spec];
7479
const logSuffix = docs ? 'doc spec' : 'spec';
7580
const cache = new Cache({
7681
folder: toAbsolutePath('specs/'),
7782
generatedFiles: [docs ? `bundled/${spec}.doc.yml` : `bundled/${spec}.yml`],
78-
filesToCache: [specBase, 'common'],
83+
filesToCache: [...deps, 'common'],
7984
cacheFile: toAbsolutePath(`specs/dist/${spec}.${docs ? 'doc.' : ''}cache`),
8085
});
8186

@@ -113,6 +118,8 @@ async function buildSpec({
113118
await buildLiteSpec({
114119
spec,
115120
bundledPath: toAbsolutePath(bundledPath),
121+
docs,
122+
useCache,
116123
});
117124
}
118125

@@ -140,6 +147,13 @@ export async function buildSpecs({
140147

141148
await lintCommon(useCache);
142149

150+
// the `lite` spec will build the `recommend` spec, so we remove it from the list
151+
// to prevent concurrent builds
152+
if (clients.includes('algoliasearch')) {
153+
// eslint-disable-next-line no-param-reassign
154+
clients = clients.filter((client) => client !== 'recommend');
155+
}
156+
143157
await Promise.all(
144158
clients.map((client) => buildSpec({ spec: client, outputFormat, docs, useCache })),
145159
);

scripts/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ export type Language = keyof typeof config;
4343
export type Spec = {
4444
servers: Server[];
4545
tags: Tag[];
46-
paths: Path[];
46+
paths: Path;
47+
components: {
48+
schemas: Record<string, any>;
49+
};
4750
};
4851

4952
/**

0 commit comments

Comments
 (0)