-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathAdvancedSearchManager.ts
More file actions
140 lines (120 loc) · 3.52 KB
/
AdvancedSearchManager.ts
File metadata and controls
140 lines (120 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// set up environment
import * as dotenv from 'dotenv';
dotenv.config();
import { CveResult } from '../result/CveResult.js';
import { SearchResultData } from "./SearchResultData.js";
import { SearchProviderSpec } from '../adapters/search/SearchAdapter.js';
import { BasicSearchManager, SearchOptions } from "./BasicSearchManager.js"
export class SearchAPIOptions extends SearchOptions {
searchFields: Array<string>;
filters: Array<object>;
resultsPerPage: number;
pageNumber: number;
rangeObjects: Array<rangeObject>
rangeStart: Date;
rangeEnd: Date;
rangeField: string;
}
//support for date ranges
export class rangeObject {
rangeField: string;
rangeStart: Date;
rangeEnd: Date;
}
export class AdvancedSearchManager extends BasicSearchManager {
/** constructor that sets up provider information
* @param searchProviderSpec optional specifications providing provider information
* default is to read it from environment variables
*/
constructor(searchProviderSpec: SearchProviderSpec = undefined) {
super(searchProviderSpec);
}
/** search for text at search provider
* @param searchText the text string to search for
* @param options options to specify how to search, with well-defined defaults
* @param queryString query strings for each filter on the search request
*/
async apiSearch(searchText: string, options: Partial<SearchAPIOptions> = undefined, queryStrings?: Array<object>): Promise<CveResult> {
let response = undefined;
if (!options) {
options = {
useCache: true,
searchFields: null,
filters: null,
resultsPerPage: 20,
pageNumber: 0,
rangeObjects: null,
rangeStart: null,
rangeEnd: null,
rangeField: null,
track_total_hits: true,
default_operator: "AND",
metadataOnly: false,
fields: []
};
}
const validateResult = this.validateSearchText(searchText, options.filters)
//Build range object to add to the query
const rangeArray = [...(options.rangeObjects ?? [])];
//Build query object
const queryObj = {
must: [],
filter: [
...options.filters
],
};
//Add rangeObj only if it exists
if (rangeArray) {
queryObj.filter.push(...rangeArray);
}
if (searchText != null) {
queryObj.must = [
{
query_string: {
query: searchText,
fields: ["containers.cna.descriptions.value"]
},
}
];
}
//Add query_string only if there is text to search
else if (queryStrings != null) {
queryObj.must = [
...queryStrings
];
} else {
delete queryObj.must
}
if (validateResult.isOk()) {
response = await this._searchReader._client.search({
index: this._searchReader._cveIndex,
body: {
query: {
bool: queryObj
},
track_total_hits: true,
size: options.resultsPerPage,
from: options.from
}
});
return CveResult.ok(response.body as SearchResultData);
}
else {
return validateResult
}
}
/** validates search text string and marks up CveResult
* with errors and/or notes, if any
*/
// @todo
validateSearchText(text: string, filters: Array<object>): CveResult {
let result: CveResult
if (!text && !filters) {
result = CveResult.error(9002)
}
else {
result = CveResult.ok("", ["no validation was done"])
}
return result
}
}