New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

feathers-solr

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

feathers-solr - npm Package Compare versions

Comparing version 3.0.5 to 3.0.6

example/index.js

15

.eslintrc.js

@@ -1,14 +0,1 @@

/*
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
https://github.com/typescript-eslint/tslint-to-eslint-config
It represents the closest reasonable ESLint configuration to this
project's original TSLint configuration.
We recommend eventually switching this configuration to extend from
the recommended rulesets in typescript-eslint.
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
Happy linting! 💖
*/
module.exports = {

@@ -149,3 +136,3 @@ "env": {

"radix": "error",
"space-before-function-paren": "error",
"space-before-function-paren": 0,
"spaced-comment": [

@@ -152,0 +139,0 @@ "error",

@@ -1,49 +0,25 @@

import { NullableId, Id } from '@feathersjs/feathers';
import { AdapterService, ServiceOptions, InternalServiceMethods, AdapterParams } from '@feathersjs/adapter-commons';
import { SolrClient } from './client';
export declare const escapeFn: (key: string, value: any) => {
key: string;
value: any;
};
export interface SolrServiceOptions extends ServiceOptions {
host: string;
core: string;
commit?: {
softCommit?: boolean;
commitWithin?: number;
overwrite?: boolean;
};
queryHandler?: string;
updateHandler?: string;
defaultSearch?: any;
defaultParams?: any;
createUUID?: boolean;
escapeFn?: (key: string, value: any) => {
key: string;
value: any;
};
requestOptions: {
timeout: 10;
};
import type { AdapterParams, PaginationOptions } from '@feathersjs/adapter-commons';
import type { Paginated, ServiceMethods, Id, NullableId } from '@feathersjs/feathers';
import { SolrAdapter } from './adapter';
export * from './adapter';
export declare class SolrService<T = any, D = Partial<T>, P extends AdapterParams = AdapterParams> extends SolrAdapter<T, D, P> implements ServiceMethods<T | Paginated<T>, D, P> {
find(params?: P & {
paginate?: PaginationOptions;
}): Promise<Paginated<T>>;
find(params?: P & {
paginate: false;
}): Promise<T[]>;
find(params?: P): Promise<Paginated<T> | T[]>;
get(id: NullableId, params?: P): Promise<T>;
get(id: Id, params?: P): Promise<T>;
create(data: D, params?: P): Promise<T>;
create(data: D[], params?: P): Promise<T[]>;
update(id: Id, data: D, params?: P): Promise<T>;
update(id: NullableId, data: D, params?: P): Promise<T>;
patch(id: NullableId, data: Partial<D>, params?: P): Promise<T>;
patch(id: Id, data: Partial<D>, params?: P): Promise<T>;
patch(id: null, data: Partial<D>, params?: P): Promise<T[]>;
remove(id: Id, params?: P): Promise<T>;
remove(id: NullableId, params?: P): Promise<T>;
remove(id: null, params?: P): Promise<T[]>;
}
export declare class Service<T = any, D = Partial<T>> extends AdapterService<T, D> implements InternalServiceMethods<T> {
options: SolrServiceOptions;
client: SolrClient;
queryHandler: string;
updateHandler: string;
constructor(options: Partial<SolrServiceOptions>);
_getOrFind(id: Id, params: AdapterParams): Promise<any>;
_get(id: Id, params?: AdapterParams): Promise<any>;
_find(params?: AdapterParams): Promise<any[] | {
QTime: number;
total: number;
limit: any;
skip: number;
data: any[];
}>;
_create(data: Partial<T> | Partial<T>[], params?: AdapterParams): Promise<T | T[]>;
_update(id: NullableId, data: T, params?: AdapterParams): Promise<any>;
_patch(id: NullableId, data: Partial<T>, params?: AdapterParams): Promise<any>;
_remove(id: NullableId, params?: AdapterParams): Promise<T | T[]>;
}
export default function service(options: Partial<SolrServiceOptions>): Service<any, Partial<any>>;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Service = exports.escapeFn = void 0;
const errors_1 = require("@feathersjs/errors");
const commons_1 = require("@feathersjs/commons");
const adapter_commons_1 = require("@feathersjs/adapter-commons");
const client_1 = require("./client");
const response_1 = require("./response");
const query_1 = require("./query");
const escapeFn = (key, value) => {
return { key, value };
};
exports.escapeFn = escapeFn;
class Service extends adapter_commons_1.AdapterService {
constructor(options) {
const { host, core, requestOptions, ...opts } = options;
super(commons_1._.extend({
id: 'id',
commit: {
softCommit: true,
commitWithin: 10000,
overwrite: true
},
queryHandler: '/query',
updateHandler: '/update/json',
defaultSearch: {},
defaultParams: { echoParams: 'none' },
createUUID: true,
escapeFn: exports.escapeFn
}, opts));
this.queryHandler = `/${core}${this.options.queryHandler}`;
this.updateHandler = `/${core}${this.options.updateHandler}`;
this.client = (0, client_1.solrClient)(host, requestOptions);
exports.SolrService = void 0;
const adapter_1 = require("./adapter");
__exportStar(require("./adapter"), exports);
class SolrService extends adapter_1.SolrAdapter {
async find(params) {
return this._find(params);
}
_getOrFind(id, params) {
if (id !== null)
return this._get(id, params);
return this._find(Object.assign(params, {
paginate: false
}));
async get(id, params) {
return this._get(id, params);
}
async _get(id, params = {}) {
const { query, filters, paginate } = this.filterQuery(params);
const solrQuery = (0, query_1.jsonQuery)(id, filters, query, paginate, this.options.escapeFn);
const response = await this.client.post(this.queryHandler, { data: solrQuery });
if (response.response.numFound === 0)
throw new errors_1.NotFound(`No record found for id '${id}'`);
const result = (0, response_1.responseGet)(response);
return result;
async create(data, params) {
return this._create(data, params);
}
async _find(params = {}) {
const { query, filters, paginate } = this.filterQuery(params);
const solrQuery = (0, query_1.jsonQuery)(null, filters, query, paginate, this.options.escapeFn);
const response = await this.client.post(this.queryHandler, { data: solrQuery });
const result = (0, response_1.responseFind)(filters, paginate, response);
return result;
async update(id, data, params) {
return this._update(id, data, params);
}
async _create(data, params = {}) {
const sel = (0, adapter_commons_1.select)(params, this.id);
if (commons_1._.isEmpty(data))
throw new errors_1.MethodNotAllowed('Data is empty');
let dataToCreate = Array.isArray(data) ? [...data] : [{ ...data }];
if (this.options.createUUID) {
dataToCreate = (0, query_1.addIds)(dataToCreate, this.options.id);
}
await this.client.post(this.updateHandler, { data: dataToCreate, params: this.options.commit });
return sel(Array.isArray(data) ? dataToCreate : dataToCreate[0]);
async patch(id, data, params) {
return this._patch(id, data, params);
}
async _update(id, data, params = {}) {
const sel = (0, adapter_commons_1.select)(params, this.id);
await this._getOrFind(id, params);
const dataToUpdate = id && !Array.isArray(data) ? [{ id, ...data }] : data;
await this.client.post(this.updateHandler, { data: dataToUpdate, params: this.options.commit });
return this._getOrFind(id, params).then(res => sel(commons_1._.omit(res, 'score', '_version_')));
async remove(id, params) {
return this._remove(id, params);
}
async _patch(id, data, params = {}) {
const sel = (0, adapter_commons_1.select)(params, this.id);
const dataToPatch = await this._getOrFind(id, params);
const { ids, patchData } = (0, query_1.patchQuery)(dataToPatch, data, this.id);
await this.client.post(this.updateHandler, { data: patchData, params: this.options.commit });
const result = await this._find({ query: { id: { $in: ids } } });
if (result.data)
return sel(ids.length === 1 ? result.data[0] : result.data);
return sel(ids.length === 1 ? result[0] : result);
}
async _remove(id, params = {}) {
const sel = (0, adapter_commons_1.select)(params, this.id);
const dataToDelete = await this._getOrFind(id, params);
const { query } = this.filterQuery(params);
const queryToDelete = (0, query_1.deleteQuery)(id, query, this.options.escapeFn);
await this.client.post(this.updateHandler, { data: queryToDelete, params: this.options.commit });
return sel(dataToDelete);
}
}
exports.Service = Service;
function service(options) {
return new Service(options);
}
exports.default = service;
exports.SolrService = SolrService;
//# sourceMappingURL=index.js.map
{
"name": "feathers-solr",
"description": "A service plugin for Solr",
"version": "3.0.5",
"version": "3.0.6",
"keywords": [

@@ -9,3 +9,6 @@ "feathers",

"solr",
"solr-client"
"solr-client",
"search",
"database",
"api"
],

@@ -31,3 +34,4 @@ "license": "MIT",

"prepublish": "npm run build",
"lint": "eslint src/**/*.ts test/**/*.ts --fix",
"lint": "eslint src/**/*.ts --fix",
"lint:test": "eslint test/**/*.ts --fix",
"build": "shx rm -rf lib/ && tsc",

@@ -45,23 +49,23 @@ "test": "npm run build && npm run mocha",

"dependencies": {
"@feathersjs/adapter-commons": "^5.0.0-pre.15",
"@feathersjs/commons": "^5.0.0-pre.15",
"@feathersjs/errors": "^5.0.0-pre.15"
"@feathersjs/adapter-commons": "^5.0.0-pre.33",
"@feathersjs/commons": "^5.0.0-pre.33",
"@feathersjs/errors": "^5.0.0-pre.33"
},
"devDependencies": {
"@feathersjs/adapter-tests": "^5.0.0-pre.15",
"@feathersjs/express": "^5.0.0-pre.15",
"@feathersjs/feathers": "^5.0.0-pre.15",
"@types/mocha": "^9.0.0",
"@types/node": "^17.0.5",
"@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0",
"eslint": "^8.5.0",
"eslint-plugin-import": "^2.25.3",
"@feathersjs/adapter-tests": "^5.0.0-pre.33",
"@feathersjs/express": "^5.0.0-pre.33",
"@feathersjs/feathers": "^5.0.0-pre.33",
"@types/mocha": "^10.0.1",
"@types/node": "^18.11.13",
"@typescript-eslint/eslint-plugin": "^5.46.0",
"@typescript-eslint/parser": "^5.46.0",
"eslint": "^8.29.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prefer-arrow": "^1.2.3",
"mocha": "^9.1.3",
"mocha": "^10.1.0",
"nyc": "^15.1.0",
"shx": "^0.3.3",
"ts-node": "^10.4.0",
"typescript": "^4.5.4"
"shx": "^0.3.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.4"
}
}

@@ -8,5 +8,4 @@ # feathers-solr

A [Feathers](https://feathersjs.com/) Solr Adapter. Require >= Solr 5.x.
A [Feathers](https://feathersjs.com/) Solr Adapter. Tested with Solr 8.x, require at least >= Solr 5.x.
> See this [adapter in action](https://feathers.better-search-box.com)

@@ -19,5 +18,5 @@ ## Installation

> **Important:** `feathers-solr` implements the [Feathers Common database adapter API](https://docs.feathersjs.com/api/databases/common.html) and [querying syntax](https://docs.feathersjs.com/api/databases/querying.html).
> __Important:__ `@feathersjs/memory` implements the [Feathers Common database adapter API](https://docs.feathersjs.com/api/databases/common.html) and [querying syntax](https://docs.feathersjs.com/api/databases/querying.html).
> It use sthe native node `http` and `https` module.
## API

@@ -30,14 +29,4 @@

```js
import { solrClient } from '../src/client';
const Client = solrClient(options.host);
const options = {
host: 'http://localhost:8983/solr',
core: 'gettingstarted'
}
const Client = solrClient(options.host);
const app = feathers();
app.use('/gettingstarted', Solr({ ...options, multi: false }));
const service = require('feathers-solr');
app.use('/search', service({host, core}));
```

@@ -48,12 +37,18 @@

- `core` - The name of the Solr Core / Colelction.
- `defaultParams` - This params added to all Solr request.
- `id` (_optional_, default: `'id'`) - The name of the id field property.
- `commitStrategy` - (_optional_, default: `{ softCommit: true, commitWithin: 10000, overwrite: true }`) - Define how Index changes are stored [Solr Commits](https://lucene.apache.org/solr/guide/7_7/updatehandlers-in-solrconfig.html#UpdateHandlersinSolrConfig-commitandsoftCommit).
- `defaultSearch` - (_optional_, default: `{ defType: 'edismax', qf: 'name^10 age^1 gender' }`) - Search strategy if query contains the param `$search` [The Extended DisMax Query Parser](https://lucene.apache.org/solr/guide/6_6/the-extended-dismax-query-parser.html).
- `suggestHandler` - (_optional_, default: `suggest`) - Request a Solr Suggest Handler instead reggular a search if query contains the param `$suggest` [Suggester](https://lucene.apache.org/solr/guide/7_7/suggester.html).
- `events` (_optional_) - A list of [custom service events](https://docs.feathersjs.com/api/events.html#custom-events) sent by this service
- `paginate` (_optional_) - A [pagination object](https://docs.feathersjs.com/api/databases/common.html#pagination) containing a `default` and `max` page size
- `whitelist` (default: `['$search', '$params', '$facet', '$filter']`) [optional] - The list of additional non-standard query parameters to allow, by default populated with all Solr specific ones. You can override, for example in order to restrict access to some queries (see the [options documentation](https://docs.feathersjs.com/api/databases/common.html#serviceoptions)).
- `multi` (_optional_) - Allow `create` with arrays and `update` and `remove` with `id` `null` to change multiple items. Can be `true` for all methods or an array of allowed methods (e.g. `[ 'remove', 'create' ]`)
- `host` - The name of the Solr core / collection.
- `core` - The name of the Solr core / collection.
- `events` (*optional*) - A list of [custom service events](https://docs.feathersjs.com/api/events.html#custom-events) sent by this service
- `paginate` (*optional*) - A [pagination object](https://docs.feathersjs.com/api/databases/common.html#pagination) containing a `default` and `max` page size
- `whitelist` (*DEPRECATED*) - renamed to `allow`
- `allow` (*optional*) - A list of additional query parameters to allow
- `multi` (*optional*) - Allow `create` with arrays and `update` and `remove` with `id` `null` to change multiple items. Can be `true` for all methods or an array of allowed methods (e.g. `[ 'remove', 'create' ]`)
- `id` (*optional*, default: `'id'`) - The name of the id field property.
- `commitStrategy` - (*optional*, default: `{ softCommit: true, commitWithin: 10000, overwrite: true }`) - Define how Index changes are stored [Solr Commits](https://lucene.apache.org/solr/guide/7_7/updatehandlers-in-solrconfig.html#UpdateHandlersinSolrConfig-commitandsoftCommit).
- `defaultParams` (*optional* default: `{ echoParams: 'none' }`)- This params added to all Solr request.
- `defaultSearch` - (*optional*, default: `{ defType: 'edismax', qf: 'name^10 age^1 gender' }`) - Search strategy if query contains the param `$search` [The Extended DisMax Query Parser](https://lucene.apache.org/solr/guide/6_6/the-extended-dismax-query-parser.html).
- `queryHandler` (*optional* default: `'/query'`) - This params defines the Solr request handler to use.
- `updateHandler` (*optional* default: `'/update/json'`) - This params defines the Solr update handler to use.
- `createUUID` (*optional* default: `true`) - This params add aa UUID if not exist on data. Id's generated by `crypto`
- `escapeFn` (*optional* default: `(key: string, value: any) => { key, value }`) - To apply escaping.
- `requestOptions` (*optional* default: `{ timeout: 10 })` - The [options](https://nodejs.org/api/http.html#httprequestoptions-callback) passed to `http.request`.

@@ -67,8 +62,6 @@ ## Getting Started

const express = require('@feathersjs/express');
const fetch = require('node-fetch');
const undici = require('undici');
const Service = require('feathers-solr');
const { SolrClient } = require('feathers-solr');
const solrServer = 'http://localhost:8983/solr/gettingstarted';
const socketio = require('@feathersjs/socketio');
const Service = require('feathers-solr').Service;
// Create an Express compatible Feathers application instance.

@@ -82,7 +75,9 @@ const app = express(feathers());

app.configure(express.rest());
// Enable REST services
// Set up default error handler
app.use(express.errorHandler());
// init Adapter witch Fetch or Undici
// Create a service
const options = {
Model: SolrClient(fetch, solrServer),
host: 'http://localhost:8983/solr',
core: 'gettingstarted',
paginate: {},

@@ -93,15 +88,16 @@ events: ['testing']

app.listen(3030, () => {
console.log(`Feathers server listening on port http://127.0.0.1:3030`);
// Start the server.
const port = 3030;
app.listen(port, () => {
console.log(`Feathers server listening on port ${port}`)
});
```
Install Solr
Start Solr
```
```bash
bin/solr start -e gettingstarted
```
Use `feathers-solr/bin/install-solr.sh` for a kickstart installation.
Run the example with `node app` and go to [localhost:3030/gettingstarted](http://localhost:3030/gettingstarted).

@@ -113,5 +109,5 @@

## Supportet Solr specific queries
## Supported Solr specific queries
This Adapter use the Solr [JSON Request API](https://lucene.apache.org/solr/guide/7_7/json-request-api.html).
This Adapter uses the Solr [JSON Request API](https://lucene.apache.org/solr/guide/7_7/json-request-api.html).

@@ -125,3 +121,3 @@ The following params passed in raw to Solr. This gives the **full** access to the Solr [JSON Request API](https://lucene.apache.org/solr/guide/7_7/json-request-api.html).

To avoid full query (read) access, just whitelist only `$search` and add your query startegy into a Hook.
To avoid full query (read) access, just whitelist only `$search` and add your query strategy into a Hook.

@@ -169,3 +165,3 @@ ### \$search

A alias to Solr param `facet`
An alias to Solr param `facet`

@@ -243,3 +239,3 @@ - [Solr Facet Functions and Analytics](http://yonik.com/solr-facet-functions/)

An alias to Solr param `params`. Allows you to access all solr query (read) features like:
An alias to Solr param `params`. Allows you to access all Solr query (read) features like:

@@ -347,3 +343,3 @@ - [The Extended DisMax (eDismax) Query Parser](https://lucene.apache.org/solr/guide/7_7/the-extended-dismax-query-parser.html)

sort: 'geodist() asc'
}
}
},

@@ -367,3 +363,3 @@ paginate: { max: 10, default: 3 }

The `options.commitStrategy.override` is true in default. This allow to override an existing `id` by `service.create`.
Add the field `_version_` to the `$select` params will return the document content with it's version. Create with an existing `id` and `_version_` for [optimistic concurrency](https://lucene.apache.org/solr/guide/6_6/updating-parts-of-documents.html#UpdatingPartsofDocuments-OptimisticConcurrency)
Add the field `_version_` to the `$select` params will return the document content with its version. Create with an existing `id` and `_version_` for [optimistic concurrency](https://lucene.apache.org/solr/guide/6_6/updating-parts-of-documents.html#UpdatingPartsofDocuments-OptimisticConcurrency)

@@ -405,3 +401,3 @@ ### Service.update

```Javascript
service.remove(null, {query: {id:'*'}});
service.remove(null, {});
```

@@ -411,90 +407,59 @@

Most of the data mutating operations in Solr (create, update, remove) do not return the full resulting document, therefore I had to resolve to using get as well in order to return complete data. This solution is of course adding a bit of an overhead, although it is also compliant with the standard behaviour expected of a feathers database adapter.
Data mutating operations in Solr do not return document data. This is implemented as additional queries to return deletd or modified data.
> Use Raw Query `service.Model.post('update/json', data)` to avoid this overhead. The response is native Solr.
To avoid this overhead use the `client` directly for bulk operations.
```js
const options = {
host: 'http://localhost:8983/solr',
core: 'gettingstarted',
}
## Raw Solr Queries
const client = solrClient('http://localhost:8983/solr');
You can access all Solr API endpoints by using a direct model usage.
Ping the Solr core/collection:
```Javascript
service.Model.get('admin/ping');
await client.post('/update/json', { data: [] })
```
Get Solr schema information:
## Maniging Solr
```Javascript
service.Model.get('schema');
```
Using the `solrClient` for raw communication with solr.
See adapter [test]('//test/../../test/additional.test.ts') how to:
- `create` and `delete` a Solr core
- `add`, 'update' and `delete` the Solr core schema
- `add` and `delete` the Solr core config request handler and components
Modify Solr schema:
```js
const options = {
host: 'http://localhost:8983/solr',
core: 'gettingstarted',
}
```Javascript
service.Model.post('schema',{"add-field":{name:"age",type:"pint"}});
```
const client = solrClient('http://localhost:8983/solr');
await client.post('/admin/cores', { params: {...createCore, name: name} })
await client.post(`/${core}/schema`, { data: addSchema });
await client.post(`/${core}/config`, { data: addConfig });
Get Solr config information:
```Javascript
service.Model.get('config');
```
Modify Solr config:
## License
```Javascript
service.Model.post('config',{"add-requesthandler":{...}});
```
Copyright (c) 2022
## Use a different HTTP Client
The MIT License (MIT)
This Adapter offers a `node-fetch` interface for a maximum on HTTP Client comfort and `undici` for maximum (100% compared to node-fetch) in performance.
If you like to go with your favorite one:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
```Javascript
class CustomClient {
constructor(HTTPModule, conn) {}
get(api, params = {}) {}
post(api, data, params = {}) {}
};
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
const options = {
Model: CustomClient(HTTPModule, solrServer),
paginate: {},
events: ['testing']
};
app.service('solr', new Service(options))
```
## Contributing
If you find a bug or something to improve i will be happy to see your PR!
When adding a new feature, please make sure you write tests for it with decent coverage as well.
## TODO
- Hook Examples
- Schema Migration Hook (drop,alter,safe)
- Json Hook Store Data as JSON
- Validation Hook
- Spellcheck
- Suggester
- MoreLikeThis
## Changelog
**2.3.0**
**2.2.0**
- complete refactoring
- implement @feathers/adapter-tests
## License
Copyright (c) 2015
Licensed under the [MIT license](LICENSE).
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@@ -1,156 +0,49 @@

import { NotFound, MethodNotAllowed } from '@feathersjs/errors';
import { NullableId, Id } from '@feathersjs/feathers';
import { _ } from '@feathersjs/commons';
import { AdapterService, ServiceOptions, InternalServiceMethods, AdapterParams, select } from '@feathersjs/adapter-commons';
import { solrClient, SolrClient } from './client';
import { responseFind, responseGet } from './response';
import { addIds, jsonQuery, patchQuery, deleteQuery } from './query';
export const escapeFn = (key: string, value: any) => {
return { key, value }
}
import type { AdapterParams, PaginationOptions } from '@feathersjs/adapter-commons';
import type { Paginated, ServiceMethods, Id, NullableId } from '@feathersjs/feathers';
import { SolrAdapter } from './adapter'
export interface SolrServiceOptions extends ServiceOptions {
host: string;
core: string;
commit?: {
softCommit?: boolean;
commitWithin?: number;
overwrite?: boolean
};
queryHandler?: string;
updateHandler?: string;
defaultSearch?: any;
defaultParams?: any;
createUUID?: boolean;
escapeFn?: (key: string, value: any) => { key: string, value: any };
requestOptions: { timeout: 10 };
}
export * from './adapter'
export class Service<T = any, D = Partial<T>> extends AdapterService<T, D> implements InternalServiceMethods<T> {
options: SolrServiceOptions;
client: SolrClient;
queryHandler: string;
updateHandler: string;
constructor (options: Partial<SolrServiceOptions>) {
const { host, core, requestOptions, ...opts } = options;
super(_.extend({
id: 'id',
commit: {
softCommit: true,
commitWithin: 10000,
overwrite: true
},
queryHandler: '/query',
updateHandler: '/update/json',
defaultSearch: {},
defaultParams: { echoParams: 'none' },
createUUID: true,
escapeFn
}, opts));
this.queryHandler = `/${core}${this.options.queryHandler}`;
this.updateHandler = `/${core}${this.options.updateHandler}`;
this.client = solrClient(host, requestOptions)
export class SolrService<T = any, D = Partial<T>, P extends AdapterParams = AdapterParams>
extends SolrAdapter<T, D, P>
implements ServiceMethods<T | Paginated<T>, D, P>
{
async find(params?: P & { paginate?: PaginationOptions }): Promise<Paginated<T>>
async find(params?: P & { paginate: false }): Promise<T[]>
async find(params?: P): Promise<Paginated<T> | T[]>
async find(params?: P): Promise<Paginated<T> | T[]> {
return this._find(params) as any
}
_getOrFind (id: Id, params: AdapterParams) {
if (id !== null) return this._get(id, params);
return this._find(
Object.assign(params, {
paginate: false
})
);
async get(id: NullableId, params?: P): Promise<T>
async get(id: Id, params?: P): Promise<T>
async get(id: Id | NullableId, params?: P): Promise<T> {
return this._get(id as Id, params)
}
async _get (id: Id, params: AdapterParams = {}) {
const { query, filters, paginate } = this.filterQuery(params);
const solrQuery = jsonQuery(id, filters, query, paginate, this.options.escapeFn);
const response = await this.client.post(this.queryHandler, { data: solrQuery })
if (response.response.numFound === 0) throw new NotFound(`No record found for id '${id}'`);
const result = responseGet(response);
return result;
async create(data: D, params?: P): Promise<T>
async create(data: D[], params?: P): Promise<T[]>
async create(data: D | D[], params?: P): Promise<T | T[]> {
return this._create(data, params)
}
async _find (params: AdapterParams = {}) {
const { query, filters, paginate } = this.filterQuery(params);
const solrQuery = jsonQuery(null, filters, query, paginate, this.options.escapeFn);
const response = await this.client.post(this.queryHandler, { data: solrQuery })
const result = responseFind(filters, paginate, response);
return result;
async update(id: Id, data: D, params?: P): Promise<T>
async update(id: NullableId, data: D, params?: P): Promise<T>
async update(id: Id | NullableId, data: D, params?: P): Promise<T> {
return this._update(id as Id, data, params)
}
async _create (data: Partial<T> | Partial<T>[], params: AdapterParams = {}): Promise<T | T[]> {
const sel = select(params, this.id);
if (_.isEmpty(data)) throw new MethodNotAllowed('Data is empty');
let dataToCreate: any | any[] = Array.isArray(data) ? [...data] : [{ ...data }];
if (this.options.createUUID) {
dataToCreate = addIds(dataToCreate, this.options.id);
}
await this.client.post(this.updateHandler, { data: dataToCreate, params: this.options.commit });
return sel(Array.isArray(data) ? dataToCreate : dataToCreate[0]);
async patch(id: NullableId, data: Partial<D>, params?: P): Promise<T>
async patch(id: Id, data: Partial<D>, params?: P): Promise<T>
async patch(id: null, data: Partial<D>, params?: P): Promise<T[]>
async patch(id: NullableId | NullableId, data: Partial<D>, params?: P): Promise<T | T[]> {
return this._patch(id as NullableId, data, params)
}
async _update (id: NullableId, data: T, params: AdapterParams = {}) {
const sel = select(params, this.id);
await this._getOrFind(id, params);
const dataToUpdate: any = id && !Array.isArray(data) ? [{ id, ...data }] : data;
await this.client.post(this.updateHandler, { data: dataToUpdate, params: this.options.commit });
return this._getOrFind(id, params).then(res => sel(_.omit(res, 'score', '_version_')));
async remove(id: Id, params?: P): Promise<T>
async remove(id: NullableId, params?: P): Promise<T>
async remove(id: null, params?: P): Promise<T[]>
async remove(id: NullableId | NullableId, params?: P): Promise<T | T[]> {
return this._remove(id as NullableId, params)
}
async _patch (id: NullableId, data: Partial<T>, params: AdapterParams = {}) {
const sel = select(params, this.id);
const dataToPatch = await this._getOrFind(id, params);
const { ids, patchData } = patchQuery(dataToPatch, data, this.id);
await this.client.post(this.updateHandler, { data: patchData, params: this.options.commit });
const result: any = await this._find({ query: { id: { $in: ids } } });
if (result.data) return sel(ids.length === 1 ? result.data[0] : result.data)
return sel(ids.length === 1 ? result[0] : result)
}
async _remove (id: NullableId, params: AdapterParams = {}): Promise<T | T[]> {
const sel = select(params, this.id);
const dataToDelete = await this._getOrFind(id, params);
const { query } = this.filterQuery(params);
const queryToDelete = deleteQuery(id, query, this.options.escapeFn);
await this.client.post(this.updateHandler, { data: queryToDelete, params: this.options.commit });
return sel(dataToDelete);
}
}
export default function service (options: Partial<SolrServiceOptions>) {
return new Service(options);
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc