Skip to content

Commit 2218b19

Browse files
authored
feat: add transformation bridge methods (#1586)
1 parent 99ebe3c commit 2218b19

File tree

8 files changed

+488
-96
lines changed

8 files changed

+488
-96
lines changed

.codesandbox/ci.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{
2+
"buildCommand": "build",
23
"packages": ["packages/*"],
3-
"sandboxes": ["github/algolia/create-instantsearch-app/tree/templates/javascript-client"]
4+
"sandboxes": ["vanilla", "github/algolia/instantsearch/tree/3331ed781d3627bc10e73b6eff89b5037a78a0fc/javascript-client"],
5+
"node": "12"
46
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
"bundlesize": [
100100
{
101101
"path": "packages/algoliasearch/dist/algoliasearch.umd.js",
102-
"maxSize": "8.4KB"
102+
"maxSize": "9.2KB"
103103
},
104104
{
105105
"path": "packages/algoliasearch/dist/algoliasearch-lite.umd.js",

packages/algoliasearch/src/__tests__/default.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,47 @@ describe('default preset', () => {
172172
expect(client).toHaveProperty('destroy');
173173
}
174174
});
175+
176+
describe('bridge methods', () => {
177+
const clientWithTransformation = algoliasearch('appId', 'apiKey', {
178+
transformation: { region: 'us' },
179+
});
180+
const indexWithTransformation = clientWithTransformation.initIndex('foo');
181+
const index = client.initIndex('foo');
182+
183+
test('throws when missing transformation.region', () => {
184+
// @ts-ignore
185+
expect(() => algoliasearch('APP_ID', 'API_KEY', { transformation: {} })).toThrow(
186+
'`region` must be provided when leveraging the transformation pipeline'
187+
);
188+
});
189+
190+
test('throws when wrong transformation.region', () => {
191+
expect(() =>
192+
// @ts-ignore
193+
algoliasearch('APP_ID', 'API_KEY', { transformation: { region: 'cn' } })
194+
).toThrow('`region` is required and must be one of the following: eu, us}`');
195+
});
196+
197+
test('throws when calling the transformation methods without init parameters', async () => {
198+
await expect(
199+
index.saveObjectsWithTransformation([{ objectID: 'bar', baz: 42 }], { waitForTasks: true })
200+
).rejects.toThrow(
201+
'`transformation.region` must be provided at client instantiation before calling this method.'
202+
);
203+
204+
await expect(
205+
index.partialUpdateObjectsWithTransformation([{ objectID: 'bar', baz: 42 }], {
206+
waitForTasks: true,
207+
})
208+
).rejects.toThrow(
209+
'`transformation.region` must be provided at client instantiation before calling this method.'
210+
);
211+
});
212+
213+
test('exposes the transformation methods at the root of the client', () => {
214+
expect(indexWithTransformation.saveObjectsWithTransformation).not.toBeUndefined();
215+
expect(indexWithTransformation.partialUpdateObjectsWithTransformation).not.toBeUndefined();
216+
});
217+
});
175218
});

packages/algoliasearch/src/builds/browser.ts

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,24 @@ import {
203203
import { createBrowserXhrRequester } from '@algolia/requester-browser-xhr';
204204
import { createUserAgent, Request, RequestOptions } from '@algolia/transporter';
205205

206-
import { AlgoliaSearchOptions, InitAnalyticsOptions, InitPersonalizationOptions } from '../types';
206+
import {
207+
createIngestionClient,
208+
partialUpdateObjectsWithTransformation,
209+
saveObjectsWithTransformation,
210+
} from '../ingestion';
211+
import {
212+
AlgoliaSearchOptions,
213+
IngestionClient,
214+
IngestionMethods,
215+
InitAnalyticsOptions,
216+
InitPersonalizationOptions,
217+
TransformationOptions,
218+
} from '../types';
207219

208220
export default function algoliasearch(
209221
appId: string,
210222
apiKey: string,
211-
options?: AlgoliaSearchOptions
223+
options?: AlgoliaSearchOptions & TransformationOptions
212224
): SearchClient {
213225
const commonOptions = {
214226
appId,
@@ -244,6 +256,17 @@ export default function algoliasearch(
244256
});
245257
};
246258

259+
/* eslint functional/no-let: "off" */
260+
let ingestionTransporter: IngestionClient | undefined;
261+
262+
if (options && options.transformation) {
263+
if (!options.transformation.region) {
264+
throw new Error('`region` must be provided when leveraging the transformation pipeline');
265+
}
266+
267+
ingestionTransporter = createIngestionClient({ ...options, ...commonOptions });
268+
}
269+
247270
return createSearchClient({
248271
...searchClientOptions,
249272
methods: {
@@ -285,50 +308,60 @@ export default function algoliasearch(
285308
setDictionarySettings,
286309
waitAppTask,
287310
customRequest,
288-
initIndex: base => (indexName: string): SearchIndex => {
289-
return initIndex(base)(indexName, {
290-
methods: {
291-
batch,
292-
delete: deleteIndex,
293-
findAnswers,
294-
getObject,
295-
getObjects,
296-
saveObject,
297-
saveObjects,
298-
search,
299-
searchForFacetValues,
300-
waitTask,
301-
setSettings,
302-
getSettings,
303-
partialUpdateObject,
304-
partialUpdateObjects,
305-
deleteObject,
306-
deleteObjects,
307-
deleteBy,
308-
clearObjects,
309-
browseObjects,
310-
getObjectPosition,
311-
findObject,
312-
exists,
313-
saveSynonym,
314-
saveSynonyms,
315-
getSynonym,
316-
searchSynonyms,
317-
browseSynonyms,
318-
deleteSynonym,
319-
clearSynonyms,
320-
replaceAllObjects,
321-
replaceAllSynonyms,
322-
searchRules,
323-
getRule,
324-
deleteRule,
325-
saveRule,
326-
saveRules,
327-
replaceAllRules,
328-
browseRules,
329-
clearRules,
330-
},
331-
});
311+
initIndex: base => (indexName: string): SearchIndex & IngestionMethods => {
312+
return {
313+
...initIndex(base)(indexName, {
314+
methods: {
315+
batch,
316+
delete: deleteIndex,
317+
findAnswers,
318+
getObject,
319+
getObjects,
320+
saveObject,
321+
saveObjects,
322+
search,
323+
searchForFacetValues,
324+
waitTask,
325+
setSettings,
326+
getSettings,
327+
partialUpdateObject,
328+
partialUpdateObjects,
329+
deleteObject,
330+
deleteObjects,
331+
deleteBy,
332+
clearObjects,
333+
browseObjects,
334+
getObjectPosition,
335+
findObject,
336+
exists,
337+
saveSynonym,
338+
saveSynonyms,
339+
getSynonym,
340+
searchSynonyms,
341+
browseSynonyms,
342+
deleteSynonym,
343+
clearSynonyms,
344+
replaceAllObjects,
345+
replaceAllSynonyms,
346+
searchRules,
347+
getRule,
348+
deleteRule,
349+
saveRule,
350+
saveRules,
351+
replaceAllRules,
352+
browseRules,
353+
clearRules,
354+
},
355+
}),
356+
saveObjectsWithTransformation: saveObjectsWithTransformation(
357+
indexName,
358+
ingestionTransporter
359+
),
360+
partialUpdateObjectsWithTransformation: partialUpdateObjectsWithTransformation(
361+
indexName,
362+
ingestionTransporter
363+
),
364+
};
332365
},
333366
initAnalytics: () => (clientOptions?: InitAnalyticsOptions): AnalyticsClient => {
334367
return createAnalyticsClient({
@@ -546,7 +579,7 @@ export type SearchIndex = BaseSearchIndex & {
546579
};
547580

548581
export type SearchClient = BaseSearchClient & {
549-
readonly initIndex: (indexName: string) => SearchIndex;
582+
readonly initIndex: (indexName: string) => SearchIndex & IngestionMethods;
550583
readonly search: <TObject>(
551584
queries: readonly MultipleQueriesQuery[],
552585
requestOptions?: RequestOptions & MultipleQueriesOptions

packages/algoliasearch/src/builds/node.ts

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,24 @@ import { Destroyable } from '@algolia/requester-common';
205205
import { createNodeHttpRequester } from '@algolia/requester-node-http';
206206
import { createUserAgent, Request, RequestOptions } from '@algolia/transporter';
207207

208-
import { AlgoliaSearchOptions, InitAnalyticsOptions, InitPersonalizationOptions } from '../types';
208+
import {
209+
createIngestionClient,
210+
partialUpdateObjectsWithTransformation,
211+
saveObjectsWithTransformation,
212+
} from '../ingestion';
213+
import {
214+
AlgoliaSearchOptions,
215+
IngestionClient,
216+
IngestionMethods,
217+
InitAnalyticsOptions,
218+
InitPersonalizationOptions,
219+
TransformationOptions,
220+
} from '../types';
209221

210222
export default function algoliasearch(
211223
appId: string,
212224
apiKey: string,
213-
options?: AlgoliaSearchOptions
225+
options?: AlgoliaSearchOptions & TransformationOptions
214226
): SearchClient {
215227
const commonOptions = {
216228
appId,
@@ -244,6 +256,17 @@ export default function algoliasearch(
244256
});
245257
};
246258

259+
/* eslint functional/no-let: "off" */
260+
let ingestionTransporter: IngestionClient | undefined;
261+
262+
if (options && options.transformation) {
263+
if (!options.transformation.region) {
264+
throw new Error('`region` must be provided when leveraging the transformation pipeline');
265+
}
266+
267+
ingestionTransporter = createIngestionClient({ ...options, ...commonOptions });
268+
}
269+
247270
return createSearchClient({
248271
...searchClientOptions,
249272
methods: {
@@ -288,50 +311,60 @@ export default function algoliasearch(
288311
setDictionarySettings,
289312
waitAppTask,
290313
customRequest,
291-
initIndex: base => (indexName: string): SearchIndex => {
292-
return initIndex(base)(indexName, {
293-
methods: {
294-
batch,
295-
delete: deleteIndex,
296-
findAnswers,
297-
getObject,
298-
getObjects,
299-
saveObject,
300-
saveObjects,
301-
search,
302-
searchForFacetValues,
303-
waitTask,
304-
setSettings,
305-
getSettings,
306-
partialUpdateObject,
307-
partialUpdateObjects,
308-
deleteObject,
309-
deleteObjects,
310-
deleteBy,
311-
clearObjects,
312-
browseObjects,
313-
getObjectPosition,
314-
findObject,
315-
exists,
316-
saveSynonym,
317-
saveSynonyms,
318-
getSynonym,
319-
searchSynonyms,
320-
browseSynonyms,
321-
deleteSynonym,
322-
clearSynonyms,
323-
replaceAllObjects,
324-
replaceAllSynonyms,
325-
searchRules,
326-
getRule,
327-
deleteRule,
328-
saveRule,
329-
saveRules,
330-
replaceAllRules,
331-
browseRules,
332-
clearRules,
333-
},
334-
});
314+
initIndex: base => (indexName: string): SearchIndex & IngestionMethods => {
315+
return {
316+
...initIndex(base)(indexName, {
317+
methods: {
318+
batch,
319+
delete: deleteIndex,
320+
findAnswers,
321+
getObject,
322+
getObjects,
323+
saveObject,
324+
saveObjects,
325+
search,
326+
searchForFacetValues,
327+
waitTask,
328+
setSettings,
329+
getSettings,
330+
partialUpdateObject,
331+
partialUpdateObjects,
332+
deleteObject,
333+
deleteObjects,
334+
deleteBy,
335+
clearObjects,
336+
browseObjects,
337+
getObjectPosition,
338+
findObject,
339+
exists,
340+
saveSynonym,
341+
saveSynonyms,
342+
getSynonym,
343+
searchSynonyms,
344+
browseSynonyms,
345+
deleteSynonym,
346+
clearSynonyms,
347+
replaceAllObjects,
348+
replaceAllSynonyms,
349+
searchRules,
350+
getRule,
351+
deleteRule,
352+
saveRule,
353+
saveRules,
354+
replaceAllRules,
355+
browseRules,
356+
clearRules,
357+
},
358+
}),
359+
saveObjectsWithTransformation: saveObjectsWithTransformation(
360+
indexName,
361+
ingestionTransporter
362+
),
363+
partialUpdateObjectsWithTransformation: partialUpdateObjectsWithTransformation(
364+
indexName,
365+
ingestionTransporter
366+
),
367+
};
335368
},
336369
initAnalytics: () => (clientOptions?: InitAnalyticsOptions): AnalyticsClient => {
337370
return createAnalyticsClient({
@@ -549,7 +582,7 @@ export type SearchIndex = BaseSearchIndex & {
549582
};
550583

551584
export type SearchClient = BaseSearchClient & {
552-
readonly initIndex: (indexName: string) => SearchIndex;
585+
readonly initIndex: (indexName: string) => SearchIndex & IngestionMethods;
553586
readonly search: <TObject>(
554587
queries: readonly MultipleQueriesQuery[],
555588
requestOptions?: RequestOptions & MultipleQueriesOptions

0 commit comments

Comments
 (0)