@florajs/datasource-solr 6.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +22 -73
  2. package/package.json +9 -8
package/index.js CHANGED
@@ -1,8 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const http = require('http');
4
- const querystring = require('querystring');
5
-
6
3
  const { ImplementationError } = require('@florajs/errors');
7
4
 
8
5
  const SUPPORTED_FILTERS = ['equal', 'notEqual', 'less', 'lessOrEqual', 'greater', 'greaterOrEqual', 'range'];
@@ -23,15 +20,15 @@ const NO_LIMIT = 1000000;
23
20
  * @private
24
21
  */
25
22
  function createRangeFilter(attributeFilters) {
26
- // make sure greaterOrEqual filter comes first
27
- attributeFilters.sort((filter) => (['greater', 'greaterOrEqual'].includes(filter.operator) ? -1 : 1));
23
+ const lowerBoundFilter = attributeFilters.find(({ operator }) => ['greater', 'greaterOrEqual'].includes(operator));
24
+ const upperBoundFilter = attributeFilters.find(({ operator }) => ['less', 'lessOrEqual'].includes(operator));
28
25
 
29
26
  return {
30
- attribute: attributeFilters[0].attribute,
27
+ attribute: lowerBoundFilter.attribute,
31
28
  operator: 'range',
32
- lowerSolrRangeOperator: RANGE_OPERATOR_FILTER_MAPPING[attributeFilters[0].operator],
33
- upperSolrRangeOperator: RANGE_OPERATOR_FILTER_MAPPING[attributeFilters[1].operator],
34
- value: [attributeFilters[0].value, attributeFilters[1].value]
29
+ lowerSolrRangeOperator: RANGE_OPERATOR_FILTER_MAPPING[lowerBoundFilter.operator],
30
+ upperSolrRangeOperator: RANGE_OPERATOR_FILTER_MAPPING[upperBoundFilter.operator],
31
+ value: [lowerBoundFilter.value, upperBoundFilter.value]
35
32
  };
36
33
  }
37
34
 
@@ -52,11 +49,7 @@ function rangify(filters) {
52
49
  return filters;
53
50
  }
54
51
 
55
- const groupedAttrs = filters.reduce((acc, filter) => {
56
- acc[filter.attribute] = acc[filter.attribute] || [];
57
- acc[filter.attribute].push(filter);
58
- return acc;
59
- }, {});
52
+ const groupedAttrs = Object.groupBy(filters, (filter) => filter.attribute);
60
53
  const rangeQueries = Object.values(groupedAttrs).filter((filters) => {
61
54
  if (filters.length !== 2) return false;
62
55
 
@@ -185,14 +178,6 @@ function buildSolrOrderString(floraOrders) {
185
178
  return floraOrders.map((order) => order.attribute + ' ' + order.direction).join(',');
186
179
  }
187
180
 
188
- function parseData(str) {
189
- try {
190
- return JSON.parse(str);
191
- } catch (e) {
192
- return new Error('Could not parse response: ' + str);
193
- }
194
- }
195
-
196
181
  function prepareQueryAddition(queryAdditions) {
197
182
  return queryAdditions
198
183
  .replace(/[\r\n]+/g, ' ')
@@ -224,50 +209,24 @@ function getUrlGenerators(servers) {
224
209
  *
225
210
  * @param {string} requestUrl
226
211
  * @param {Object} params
227
- * @param {Object} requestOptions
228
- * @param {Agent} agent
212
+ * @param {number} timeout
229
213
  * @returns {Promise}
230
214
  * @private
231
215
  */
232
- function querySolr(requestUrl, params, requestOptions, agent) {
233
- return new Promise((resolve, reject) => {
234
- const options = {
235
- method: 'POST',
236
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
237
- timeout: requestOptions.connectTimeout,
238
- agent
239
- };
240
-
241
- const req = http.request(requestUrl, options, (res) => {
242
- const chunks = [];
243
-
244
- res.on('data', (chunk) => chunks.push(chunk));
245
-
246
- res.on('end', () => {
247
- const data = parseData(Buffer.concat(chunks).toString('utf8'));
248
-
249
- if (res.statusCode >= 400 || data instanceof Error) {
250
- const error = new Error(`Solr error: ${res.statusCode} ${http.STATUS_CODES[res.statusCode]}`);
251
- return reject(error);
252
- }
253
-
254
- return resolve({ totalCount: data.response.numFound, data: data.response.docs });
255
- });
256
- });
257
-
258
- req.write(querystring.stringify(params)); // add params to POST body
216
+ async function querySolr(requestUrl, params, timeout) {
217
+ const response = await fetch(requestUrl, {
218
+ method: 'POST',
219
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
220
+ body: new URLSearchParams(params).toString(),
221
+ signal: AbortSignal.timeout(timeout)
222
+ });
259
223
 
260
- req.on('error', (err) => {
261
- err.message = `Solr error: ${err.message} (${options.host})`;
262
- reject(err);
263
- });
264
- req.on('timeout', () => {
265
- req.destroy();
266
- reject(new Error('Request timed out'));
267
- });
224
+ if (!response.ok) {
225
+ throw new Error(`Solr error: ${response.status} - ${response.statusText}`);
226
+ }
268
227
 
269
- req.end();
270
- });
228
+ const { numFound, docs } = (await response.json()).response;
229
+ return { totalCount: numFound, data: docs };
271
230
  }
272
231
 
273
232
  function prepareSearchTerm(request) {
@@ -301,12 +260,6 @@ class DataSource {
301
260
  this._urls = getUrlGenerators(config.servers);
302
261
  this._status = config._status;
303
262
  delete config._status;
304
-
305
- this._agent = new http.Agent({
306
- maxSockets: 5,
307
- keepAlive: true,
308
- keepAliveMsecs: 10000
309
- });
310
263
  }
311
264
 
312
265
  /**
@@ -360,12 +313,8 @@ class DataSource {
360
313
  if (request._explain) Object.assign(request._explain, { url: requestUrl, params });
361
314
  if (this._status) this._status.increment('dataSourceQueries');
362
315
 
363
- const requestOpts = {
364
- connectTimeout: serverOpts[server].connectTimeout || 2000,
365
- requestTimeout: serverOpts[server].requestTimeout || 5000
366
- };
367
-
368
- return querySolr(requestUrl, params, requestOpts, this._agent);
316
+ const timeout = serverOpts[server].timeout || 5000;
317
+ return querySolr(requestUrl, params, timeout);
369
318
  }
370
319
 
371
320
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@florajs/datasource-solr",
3
- "version": "6.0.0",
3
+ "version": "8.0.0",
4
4
  "description": "Solr connection for Flora",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -37,17 +37,18 @@
37
37
  }
38
38
  ],
39
39
  "engines": {
40
- "node": ">=18"
40
+ "node": ">=20"
41
41
  },
42
42
  "dependencies": {
43
43
  "@florajs/errors": "^4.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "eslint": "^9.16.0",
47
- "eslint-config-prettier": "^9.1.0",
48
- "eslint-plugin-prettier": "^5.2.1",
49
- "globals": "^15.13.0",
50
- "nock": "^13.5.6",
51
- "prettier": "^3.0.1"
46
+ "@eslint/js": "^10.0.1",
47
+ "eslint": "^10.4.1",
48
+ "eslint-config-prettier": "^10.1.8",
49
+ "eslint-plugin-prettier": "^5.5.6",
50
+ "globals": "^17.6.0",
51
+ "nock": "^14.0.15",
52
+ "prettier": "^3.8.3"
52
53
  }
53
54
  }