@ekodb/ekodb-client 0.1.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.
- package/README.md +329 -0
- package/dist/client.d.ts +404 -0
- package/dist/client.js +553 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +20 -0
- package/dist/join.d.ts +68 -0
- package/dist/join.js +71 -0
- package/dist/query-builder.d.ts +141 -0
- package/dist/query-builder.js +370 -0
- package/dist/schema.d.ts +189 -0
- package/dist/schema.js +186 -0
- package/dist/search.d.ts +172 -0
- package/dist/search.js +183 -0
- package/package.json +27 -0
- package/src/client.ts +757 -0
- package/src/index.ts +29 -0
- package/src/join.ts +102 -0
- package/src/query-builder.ts +419 -0
- package/src/schema.ts +285 -0
- package/src/search.ts +275 -0
- package/tsconfig.json +18 -0
package/src/schema.ts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema management for collections
|
|
3
|
+
*
|
|
4
|
+
* This module provides types and utilities for defining and managing
|
|
5
|
+
* collection schemas with field types, constraints, and indexes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Vector index algorithm
|
|
10
|
+
*/
|
|
11
|
+
export enum VectorIndexAlgorithm {
|
|
12
|
+
/** Simple flat index (brute force) */
|
|
13
|
+
Flat = "flat",
|
|
14
|
+
/** Hierarchical Navigable Small World */
|
|
15
|
+
HNSW = "hnsw",
|
|
16
|
+
/** Inverted File Index (for future) */
|
|
17
|
+
IVF = "ivf",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Distance metric for vector similarity
|
|
22
|
+
*/
|
|
23
|
+
export enum DistanceMetric {
|
|
24
|
+
Cosine = "cosine",
|
|
25
|
+
Euclidean = "euclidean",
|
|
26
|
+
DotProduct = "dotproduct",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Index configuration for a field
|
|
31
|
+
*/
|
|
32
|
+
export type IndexConfig =
|
|
33
|
+
| {
|
|
34
|
+
type: "text";
|
|
35
|
+
language?: string;
|
|
36
|
+
analyzer?: string;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
type: "vector";
|
|
40
|
+
algorithm?: VectorIndexAlgorithm;
|
|
41
|
+
metric?: DistanceMetric;
|
|
42
|
+
m?: number;
|
|
43
|
+
ef_construction?: number;
|
|
44
|
+
}
|
|
45
|
+
| {
|
|
46
|
+
type: "btree";
|
|
47
|
+
}
|
|
48
|
+
| {
|
|
49
|
+
type: "hash";
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Field type schema with constraints
|
|
54
|
+
*
|
|
55
|
+
* Valid field types (case-sensitive):
|
|
56
|
+
* - String, Integer, Float, Boolean, DateTime
|
|
57
|
+
* - Array, Object, Vector, Set
|
|
58
|
+
* - UUID, Decimal, Binary, Bytes, Duration, Number, Null
|
|
59
|
+
*/
|
|
60
|
+
export interface FieldTypeSchema {
|
|
61
|
+
/** Field type - must be one of the valid types (case-sensitive, e.g., "String", "Integer", "Float") */
|
|
62
|
+
field_type: string;
|
|
63
|
+
/** Default value for the field */
|
|
64
|
+
default?: any;
|
|
65
|
+
/** Whether the field must be unique across records */
|
|
66
|
+
unique?: boolean;
|
|
67
|
+
/** Whether the field is required */
|
|
68
|
+
required?: boolean;
|
|
69
|
+
/** Allowed enum values */
|
|
70
|
+
enums?: any[];
|
|
71
|
+
/** Maximum value (for numbers/dates) */
|
|
72
|
+
max?: any;
|
|
73
|
+
/** Minimum value (for numbers/dates) */
|
|
74
|
+
min?: any;
|
|
75
|
+
/** Regex pattern for string validation */
|
|
76
|
+
regex?: string;
|
|
77
|
+
/** Index configuration */
|
|
78
|
+
index?: IndexConfig;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Collection schema
|
|
83
|
+
*/
|
|
84
|
+
export interface Schema {
|
|
85
|
+
/** Field definitions */
|
|
86
|
+
fields: Record<string, FieldTypeSchema>;
|
|
87
|
+
/** Schema version */
|
|
88
|
+
version?: number;
|
|
89
|
+
/** Creation timestamp */
|
|
90
|
+
created_at?: string;
|
|
91
|
+
/** Last modification timestamp */
|
|
92
|
+
last_modified?: string;
|
|
93
|
+
/** Whether to bypass ripple replication */
|
|
94
|
+
bypass_ripple?: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Collection metadata with analytics
|
|
99
|
+
*/
|
|
100
|
+
export interface CollectionMetadata {
|
|
101
|
+
/** Schema definition */
|
|
102
|
+
collection: Schema;
|
|
103
|
+
/** Analytics data (if available) */
|
|
104
|
+
analytics?: any;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Builder for constructing field type schemas
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const field = new FieldTypeSchemaBuilder("string")
|
|
113
|
+
* .required()
|
|
114
|
+
* .unique()
|
|
115
|
+
* .pattern("^[a-z]+$")
|
|
116
|
+
* .build();
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export class FieldTypeSchemaBuilder {
|
|
120
|
+
private schema: FieldTypeSchema;
|
|
121
|
+
|
|
122
|
+
constructor(fieldType: string) {
|
|
123
|
+
this.schema = { field_type: fieldType };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Set the field as required
|
|
128
|
+
*/
|
|
129
|
+
required(): this {
|
|
130
|
+
this.schema.required = true;
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Set the field as unique
|
|
136
|
+
*/
|
|
137
|
+
unique(): this {
|
|
138
|
+
this.schema.unique = true;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Set a default value
|
|
144
|
+
*/
|
|
145
|
+
defaultValue(value: any): this {
|
|
146
|
+
this.schema.default = value;
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Set enum values
|
|
152
|
+
*/
|
|
153
|
+
enums(values: any[]): this {
|
|
154
|
+
this.schema.enums = values;
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Set min/max range
|
|
160
|
+
*/
|
|
161
|
+
range(min?: any, max?: any): this {
|
|
162
|
+
this.schema.min = min;
|
|
163
|
+
this.schema.max = max;
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Set regex pattern
|
|
169
|
+
*/
|
|
170
|
+
pattern(regex: string): this {
|
|
171
|
+
this.schema.regex = regex;
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Add a text index
|
|
177
|
+
*/
|
|
178
|
+
textIndex(language: string = "english", analyzer?: string): this {
|
|
179
|
+
this.schema.index = {
|
|
180
|
+
type: "text",
|
|
181
|
+
language,
|
|
182
|
+
analyzer,
|
|
183
|
+
};
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Add a vector index
|
|
189
|
+
*/
|
|
190
|
+
vectorIndex(
|
|
191
|
+
algorithm: VectorIndexAlgorithm = VectorIndexAlgorithm.Flat,
|
|
192
|
+
metric: DistanceMetric = DistanceMetric.Cosine,
|
|
193
|
+
m: number = 16,
|
|
194
|
+
efConstruction: number = 200
|
|
195
|
+
): this {
|
|
196
|
+
this.schema.index = {
|
|
197
|
+
type: "vector",
|
|
198
|
+
algorithm,
|
|
199
|
+
metric,
|
|
200
|
+
m,
|
|
201
|
+
ef_construction: efConstruction,
|
|
202
|
+
};
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Add a B-tree index
|
|
208
|
+
*/
|
|
209
|
+
btreeIndex(): this {
|
|
210
|
+
this.schema.index = { type: "btree" };
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Add a hash index
|
|
216
|
+
*/
|
|
217
|
+
hashIndex(): this {
|
|
218
|
+
this.schema.index = { type: "hash" };
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Build the final FieldTypeSchema
|
|
224
|
+
*/
|
|
225
|
+
build(): FieldTypeSchema {
|
|
226
|
+
return this.schema;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Builder for constructing collection schemas
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* const schema = new SchemaBuilder()
|
|
236
|
+
* .addField("name", new FieldTypeSchemaBuilder("string").required())
|
|
237
|
+
* .addField("email", new FieldTypeSchemaBuilder("string").unique())
|
|
238
|
+
* .addField("age", new FieldTypeSchemaBuilder("number").range(0, 150))
|
|
239
|
+
* .build();
|
|
240
|
+
*
|
|
241
|
+
* await client.createCollection("users", schema);
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export class SchemaBuilder {
|
|
245
|
+
private schema: Schema;
|
|
246
|
+
|
|
247
|
+
constructor() {
|
|
248
|
+
this.schema = {
|
|
249
|
+
fields: {},
|
|
250
|
+
version: 1,
|
|
251
|
+
bypass_ripple: true,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Add a field to the schema
|
|
257
|
+
*/
|
|
258
|
+
addField(name: string, field: FieldTypeSchema | FieldTypeSchemaBuilder): this {
|
|
259
|
+
this.schema.fields[name] = field instanceof FieldTypeSchemaBuilder ? field.build() : field;
|
|
260
|
+
return this;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Set bypass_ripple flag
|
|
265
|
+
*/
|
|
266
|
+
bypassRipple(bypass: boolean): this {
|
|
267
|
+
this.schema.bypass_ripple = bypass;
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Set schema version
|
|
273
|
+
*/
|
|
274
|
+
version(version: number): this {
|
|
275
|
+
this.schema.version = version;
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Build the final Schema
|
|
281
|
+
*/
|
|
282
|
+
build(): Schema {
|
|
283
|
+
return this.schema;
|
|
284
|
+
}
|
|
285
|
+
}
|
package/src/search.ts
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-text and vector search support for ekoDB
|
|
3
|
+
*
|
|
4
|
+
* This module provides comprehensive search capabilities including:
|
|
5
|
+
* - Full-text search with fuzzy matching
|
|
6
|
+
* - Vector/semantic search
|
|
7
|
+
* - Hybrid search (text + vector)
|
|
8
|
+
* - Field weighting and boosting
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface SearchQuery {
|
|
12
|
+
/** Search query string */
|
|
13
|
+
query: string;
|
|
14
|
+
/** Language for stemming (e.g., "english", "spanish", "french") */
|
|
15
|
+
language?: string;
|
|
16
|
+
/** Case-sensitive search */
|
|
17
|
+
case_sensitive?: boolean;
|
|
18
|
+
/** Enable fuzzy matching (typo tolerance) */
|
|
19
|
+
fuzzy?: boolean;
|
|
20
|
+
/** Minimum score threshold (0.0-1.0) */
|
|
21
|
+
min_score?: number;
|
|
22
|
+
/** Fields to search in (comma-separated or array) */
|
|
23
|
+
fields?: string | string[];
|
|
24
|
+
/** Field weights (format: "field1:2.0,field2:1.5" or object) */
|
|
25
|
+
weights?: string | Record<string, number>;
|
|
26
|
+
/** Enable stemming */
|
|
27
|
+
enable_stemming?: boolean;
|
|
28
|
+
/** Boost exact matches */
|
|
29
|
+
boost_exact?: boolean;
|
|
30
|
+
/** Maximum edit distance for fuzzy matching (0-5) */
|
|
31
|
+
max_edit_distance?: number;
|
|
32
|
+
/** Bypass ripple cache */
|
|
33
|
+
bypass_ripple?: boolean;
|
|
34
|
+
/** Bypass cache */
|
|
35
|
+
bypass_cache?: boolean;
|
|
36
|
+
/** Maximum number of results to return */
|
|
37
|
+
limit?: number;
|
|
38
|
+
|
|
39
|
+
// Vector search parameters
|
|
40
|
+
/** Query vector for semantic search */
|
|
41
|
+
vector?: number[];
|
|
42
|
+
/** Field containing vectors (default: "embedding") */
|
|
43
|
+
vector_field?: string;
|
|
44
|
+
/** Similarity metric: "cosine", "euclidean", "dotproduct" */
|
|
45
|
+
vector_metric?: string;
|
|
46
|
+
/** Number of vector results (k-nearest neighbors) */
|
|
47
|
+
vector_k?: number;
|
|
48
|
+
/** Minimum similarity threshold */
|
|
49
|
+
vector_threshold?: number;
|
|
50
|
+
|
|
51
|
+
// Hybrid search parameters
|
|
52
|
+
/** Weight for text search (0.0-1.0) */
|
|
53
|
+
text_weight?: number;
|
|
54
|
+
/** Weight for vector search (0.0-1.0) */
|
|
55
|
+
vector_weight?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Search result with score and matched fields
|
|
60
|
+
*/
|
|
61
|
+
export interface SearchResult {
|
|
62
|
+
/** The matched record */
|
|
63
|
+
record: any;
|
|
64
|
+
/** Relevance score */
|
|
65
|
+
score: number;
|
|
66
|
+
/** Fields that matched the search query */
|
|
67
|
+
matched_fields: string[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Search response containing results and metadata
|
|
72
|
+
*/
|
|
73
|
+
export interface SearchResponse {
|
|
74
|
+
/** Array of search results */
|
|
75
|
+
results: SearchResult[];
|
|
76
|
+
/** Total number of results found */
|
|
77
|
+
total: number;
|
|
78
|
+
/** Query execution time in milliseconds */
|
|
79
|
+
took_ms?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Builder for constructing search queries with fluent API
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const query = new SearchQueryBuilder("john")
|
|
88
|
+
* .fields(["name", "email"])
|
|
89
|
+
* .fuzzy(true)
|
|
90
|
+
* .minScore(0.5)
|
|
91
|
+
* .limit(10)
|
|
92
|
+
* .build();
|
|
93
|
+
*
|
|
94
|
+
* const results = await client.search("users", query);
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export class SearchQueryBuilder {
|
|
98
|
+
private query: SearchQuery;
|
|
99
|
+
|
|
100
|
+
constructor(queryString: string) {
|
|
101
|
+
this.query = { query: queryString };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set the language for stemming
|
|
106
|
+
*/
|
|
107
|
+
language(language: string): this {
|
|
108
|
+
this.query.language = language;
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Enable case-sensitive search
|
|
114
|
+
*/
|
|
115
|
+
caseSensitive(enabled: boolean = true): this {
|
|
116
|
+
this.query.case_sensitive = enabled;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Enable fuzzy matching
|
|
122
|
+
*/
|
|
123
|
+
fuzzy(enabled: boolean = true): this {
|
|
124
|
+
this.query.fuzzy = enabled;
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Set minimum score threshold
|
|
130
|
+
*/
|
|
131
|
+
minScore(score: number): this {
|
|
132
|
+
this.query.min_score = score;
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Set fields to search in
|
|
138
|
+
*/
|
|
139
|
+
fields(fields: string | string[]): this {
|
|
140
|
+
this.query.fields = fields;
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Set field weights
|
|
146
|
+
*/
|
|
147
|
+
weights(weights: string | Record<string, number>): this {
|
|
148
|
+
this.query.weights = weights;
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Enable stemming
|
|
154
|
+
*/
|
|
155
|
+
enableStemming(enabled: boolean = true): this {
|
|
156
|
+
this.query.enable_stemming = enabled;
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Boost exact matches
|
|
162
|
+
*/
|
|
163
|
+
boostExact(enabled: boolean = true): this {
|
|
164
|
+
this.query.boost_exact = enabled;
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Set maximum edit distance for fuzzy matching
|
|
170
|
+
*/
|
|
171
|
+
maxEditDistance(distance: number): this {
|
|
172
|
+
this.query.max_edit_distance = distance;
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Set query vector for semantic search
|
|
178
|
+
*/
|
|
179
|
+
vector(vector: number[]): this {
|
|
180
|
+
this.query.vector = vector;
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Set vector field name
|
|
186
|
+
*/
|
|
187
|
+
vectorField(field: string): this {
|
|
188
|
+
this.query.vector_field = field;
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Set vector similarity metric
|
|
194
|
+
*/
|
|
195
|
+
vectorMetric(metric: "cosine" | "euclidean" | "dotproduct"): this {
|
|
196
|
+
this.query.vector_metric = metric;
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Set number of vector results (k-nearest neighbors)
|
|
202
|
+
*/
|
|
203
|
+
vectorK(k: number): this {
|
|
204
|
+
this.query.vector_k = k;
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Set minimum similarity threshold
|
|
210
|
+
*/
|
|
211
|
+
vectorThreshold(threshold: number): this {
|
|
212
|
+
this.query.vector_threshold = threshold;
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Set text search weight for hybrid search
|
|
218
|
+
*/
|
|
219
|
+
textWeight(weight: number): this {
|
|
220
|
+
this.query.text_weight = weight;
|
|
221
|
+
return this;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Set vector search weight for hybrid search
|
|
226
|
+
*/
|
|
227
|
+
vectorWeight(weight: number): this {
|
|
228
|
+
this.query.vector_weight = weight;
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Bypass ripple cache
|
|
234
|
+
*/
|
|
235
|
+
bypassRipple(bypass: boolean = true): this {
|
|
236
|
+
this.query.bypass_ripple = bypass;
|
|
237
|
+
return this;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Bypass cache
|
|
242
|
+
*/
|
|
243
|
+
bypassCache(bypass: boolean = true): this {
|
|
244
|
+
this.query.bypass_cache = bypass;
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Set maximum number of results to return
|
|
250
|
+
*/
|
|
251
|
+
limit(limit: number): this {
|
|
252
|
+
this.query.limit = limit;
|
|
253
|
+
return this;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Build the final SearchQuery object
|
|
258
|
+
*/
|
|
259
|
+
build(): SearchQuery {
|
|
260
|
+
// Normalize fields to comma-separated string if array
|
|
261
|
+
if (Array.isArray(this.query.fields)) {
|
|
262
|
+
this.query.fields = this.query.fields.join(",");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Normalize weights to string format if object
|
|
266
|
+
if (this.query.weights && typeof this.query.weights === "object") {
|
|
267
|
+
const weightEntries = Object.entries(this.query.weights)
|
|
268
|
+
.map(([field, weight]) => `${field}:${weight}`)
|
|
269
|
+
.join(",");
|
|
270
|
+
this.query.weights = weightEntries;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return this.query;
|
|
274
|
+
}
|
|
275
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"resolveJsonModule": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|