tsense 0.1.0 → 0.2.0-next.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 +99 -104
- package/dist/filters/filter-state.d.ts +22 -0
- package/dist/filters/filter-state.js +145 -0
- package/dist/filters/index.d.ts +40 -0
- package/dist/filters/index.js +128 -0
- package/dist/filters/url.d.ts +3 -0
- package/dist/filters/url.js +93 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/migrator.d.ts +1 -1
- package/dist/migrator.js +2 -2
- package/dist/rank.d.ts +7 -0
- package/dist/rank.js +12 -0
- package/dist/react/filter-builder.d.ts +60 -0
- package/dist/react/filter-builder.js +102 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +2 -0
- package/dist/react/use-filter-builder.d.ts +23 -0
- package/dist/react/use-filter-builder.js +22 -0
- package/dist/tsense.d.ts +5 -4
- package/dist/tsense.js +151 -92
- package/dist/types.d.ts +37 -10
- package/package.json +69 -50
package/dist/tsense.js
CHANGED
|
@@ -9,6 +9,23 @@ function chunkArray(arr, size) {
|
|
|
9
9
|
return chunks;
|
|
10
10
|
}
|
|
11
11
|
const redaxiosInstance = redaxios.default ?? redaxios;
|
|
12
|
+
function escapeFilterValue(value) {
|
|
13
|
+
if (typeof value === "string") {
|
|
14
|
+
return `\`${value.replaceAll("`", "")}\``;
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(value)) {
|
|
17
|
+
return value.map(escapeFilterValue);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
const filterOperators = {
|
|
22
|
+
not: (k, v) => `${k}:!=${v}`,
|
|
23
|
+
gt: (k, v) => `${k}:>${v}`,
|
|
24
|
+
gte: (k, v) => `${k}:>=${v}`,
|
|
25
|
+
lt: (k, v) => `${k}:<${v}`,
|
|
26
|
+
lte: (k, v) => `${k}:<=${v}`,
|
|
27
|
+
notIn: (k, v) => `${k}:!=[${v.join(",")}]`,
|
|
28
|
+
};
|
|
12
29
|
const arkToTsense = {
|
|
13
30
|
string: "string",
|
|
14
31
|
number: "float",
|
|
@@ -27,16 +44,13 @@ export class TSense {
|
|
|
27
44
|
fieldTransformers = new Map();
|
|
28
45
|
dataSyncConfig;
|
|
29
46
|
infer = undefined;
|
|
30
|
-
getFields() {
|
|
31
|
-
return this.fields;
|
|
32
|
-
}
|
|
33
47
|
constructor(options) {
|
|
34
48
|
this.options = options;
|
|
35
49
|
this.axios = redaxiosInstance.create({
|
|
36
50
|
baseURL: `${options.connection.protocol}://${options.connection.host}:${options.connection.port}`,
|
|
37
51
|
headers: { "X-TYPESENSE-API-KEY": options.connection.apiKey },
|
|
38
52
|
});
|
|
39
|
-
this.extractFields(options.transformers ?? defaultTransformers);
|
|
53
|
+
this.fields = this.extractFields(options.transformers ?? defaultTransformers);
|
|
40
54
|
this.dataSyncConfig = options.dataSync;
|
|
41
55
|
}
|
|
42
56
|
getBaseType(expression, domain) {
|
|
@@ -80,27 +94,38 @@ export class TSense {
|
|
|
80
94
|
if (Array.isArray(value)) {
|
|
81
95
|
return value.map((v) => transformer.serialize(v));
|
|
82
96
|
}
|
|
83
|
-
if (typeof value === "object" &&
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
if (typeof value === "object" &&
|
|
98
|
+
value !== null &&
|
|
99
|
+
Object.getPrototypeOf(value) === Object.prototype) {
|
|
100
|
+
const result = {};
|
|
101
|
+
for (const [opKey, opValue] of Object.entries(value)) {
|
|
102
|
+
if (opValue == null) {
|
|
103
|
+
result[opKey] = opValue;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (Array.isArray(opValue)) {
|
|
107
|
+
result[opKey] = opValue.map((item) => transformer.serialize(item));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
result[opKey] = transformer.serialize(opValue);
|
|
111
|
+
}
|
|
88
112
|
}
|
|
89
|
-
const result = { ...v };
|
|
90
|
-
if ("min" in v && v.min != null)
|
|
91
|
-
result.min = transformer.serialize(v.min);
|
|
92
|
-
if ("max" in v && v.max != null)
|
|
93
|
-
result.max = transformer.serialize(v.max);
|
|
94
|
-
if ("not" in v && v.not != null)
|
|
95
|
-
result.not = transformer.serialize(v.not);
|
|
96
113
|
return result;
|
|
97
114
|
}
|
|
98
115
|
return transformer.serialize(value);
|
|
99
116
|
}
|
|
100
117
|
extractFields(transformers) {
|
|
101
118
|
const internal = this.options.schema;
|
|
119
|
+
const fields = [];
|
|
102
120
|
for (const prop of internal.structure.props) {
|
|
103
|
-
const
|
|
121
|
+
const branches = prop.value.branches ?? [];
|
|
122
|
+
const enumValues = [];
|
|
123
|
+
for (const branch of branches) {
|
|
124
|
+
if (typeof branch.unit === "string") {
|
|
125
|
+
enumValues.push(branch.unit);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const innerType = branches[0] ?? prop.value;
|
|
104
129
|
const meta = (innerType.meta ?? prop.value.meta);
|
|
105
130
|
const expression = String(prop.value.expression);
|
|
106
131
|
const domain = prop.value.domain;
|
|
@@ -108,26 +133,31 @@ export class TSense {
|
|
|
108
133
|
const transformer = transformers.find((t) => t.match(expression, domain) || t.match(baseType, domain));
|
|
109
134
|
if (transformer) {
|
|
110
135
|
this.fieldTransformers.set(prop.key, transformer);
|
|
111
|
-
|
|
136
|
+
fields.push({
|
|
112
137
|
name: prop.key,
|
|
113
138
|
type: transformer.storageType,
|
|
139
|
+
sourceExpression: expression,
|
|
114
140
|
optional: prop.kind === "optional",
|
|
115
141
|
facet: meta?.facet,
|
|
116
142
|
sort: meta?.sort,
|
|
117
143
|
index: meta?.index,
|
|
144
|
+
enumValues,
|
|
118
145
|
});
|
|
119
146
|
continue;
|
|
120
147
|
}
|
|
121
148
|
const type = meta?.type ?? this.inferType(baseType);
|
|
122
|
-
|
|
149
|
+
fields.push({
|
|
123
150
|
name: prop.key,
|
|
124
151
|
type,
|
|
152
|
+
sourceExpression: expression,
|
|
125
153
|
optional: prop.kind === "optional",
|
|
126
154
|
facet: meta?.facet,
|
|
127
155
|
sort: meta?.sort,
|
|
128
156
|
index: meta?.index,
|
|
157
|
+
enumValues,
|
|
129
158
|
});
|
|
130
159
|
}
|
|
160
|
+
return fields;
|
|
131
161
|
}
|
|
132
162
|
async ensureSynced(force) {
|
|
133
163
|
if (!force && (this.synced || !this.options.autoSyncSchema))
|
|
@@ -139,24 +169,30 @@ export class TSense {
|
|
|
139
169
|
await this.ensureSynced(true);
|
|
140
170
|
}
|
|
141
171
|
buildObjectFilter(key, value) {
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return `${key}:<=${max}`;
|
|
172
|
+
if (value.gte != null && value.lte != null) {
|
|
173
|
+
const escaped = escapeFilterValue(value.gte);
|
|
174
|
+
const escapedLte = escapeFilterValue(value.lte);
|
|
175
|
+
const parts = [`${key}:[${escaped}..${escapedLte}]`];
|
|
176
|
+
for (const [op, opValue] of Object.entries(value)) {
|
|
177
|
+
if (op === "gte" || op === "lte" || opValue == null)
|
|
178
|
+
continue;
|
|
179
|
+
const builder = filterOperators[op];
|
|
180
|
+
if (builder) {
|
|
181
|
+
parts.push(builder(key, escapeFilterValue(opValue)));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return parts;
|
|
156
185
|
}
|
|
157
|
-
|
|
158
|
-
|
|
186
|
+
const parts = [];
|
|
187
|
+
for (const [op, opValue] of Object.entries(value)) {
|
|
188
|
+
if (opValue == null)
|
|
189
|
+
continue;
|
|
190
|
+
const builder = filterOperators[op];
|
|
191
|
+
if (builder) {
|
|
192
|
+
parts.push(builder(key, escapeFilterValue(opValue)));
|
|
193
|
+
}
|
|
159
194
|
}
|
|
195
|
+
return parts;
|
|
160
196
|
}
|
|
161
197
|
buildFilter(filter) {
|
|
162
198
|
const result = [];
|
|
@@ -165,33 +201,40 @@ export class TSense {
|
|
|
165
201
|
if (rawValue == null)
|
|
166
202
|
continue;
|
|
167
203
|
if (key === "OR") {
|
|
168
|
-
const
|
|
204
|
+
const orParts = [];
|
|
169
205
|
for (const condition of rawValue) {
|
|
170
206
|
const inner = this.buildFilter(condition);
|
|
171
|
-
|
|
207
|
+
orParts.push(`(${inner.join("&&")})`);
|
|
172
208
|
}
|
|
173
|
-
result.push(`(${
|
|
209
|
+
result.push(`(${orParts.join("||")})`);
|
|
174
210
|
continue;
|
|
175
211
|
}
|
|
176
212
|
const value = this.serializeFilterValue(key, rawValue);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
break;
|
|
213
|
+
const escaped = escapeFilterValue(value);
|
|
214
|
+
if (typeof escaped === "string" ||
|
|
215
|
+
typeof escaped === "number" ||
|
|
216
|
+
typeof escaped === "boolean") {
|
|
217
|
+
result.push(`${key}:=${escaped}`);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(escaped)) {
|
|
221
|
+
result.push(`${key}:[${escaped.join(",")}]`);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (typeof value === "object" && value !== null) {
|
|
225
|
+
result.push(...this.buildObjectFilter(key, value));
|
|
191
226
|
}
|
|
192
227
|
}
|
|
193
228
|
return result;
|
|
194
229
|
}
|
|
230
|
+
validateFields(fields) {
|
|
231
|
+
const valid = new Set(this.fields.map((f) => f.name));
|
|
232
|
+
for (const field of fields) {
|
|
233
|
+
if (field !== "score" && !valid.has(field)) {
|
|
234
|
+
throw new Error(`INVALID_FIELD: ${field}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
195
238
|
buildSort(options) {
|
|
196
239
|
if (!options.sortBy)
|
|
197
240
|
return;
|
|
@@ -289,9 +332,22 @@ export class TSense {
|
|
|
289
332
|
}
|
|
290
333
|
async search(options) {
|
|
291
334
|
await this.ensureSynced();
|
|
335
|
+
const queryByFields = options.queryBy ?? [
|
|
336
|
+
this.options.defaultSearchField,
|
|
337
|
+
];
|
|
338
|
+
this.validateFields(queryByFields);
|
|
339
|
+
if (options.sortBy) {
|
|
340
|
+
this.validateFields(options.sortBy
|
|
341
|
+
.map((s) => s.split(":")[0])
|
|
342
|
+
.filter((f) => f !== "undefined"));
|
|
343
|
+
}
|
|
344
|
+
if (options.facetBy) {
|
|
345
|
+
this.validateFields(options.facetBy);
|
|
346
|
+
}
|
|
347
|
+
const queryBy = queryByFields.join(",");
|
|
292
348
|
const params = {
|
|
293
|
-
q: options.query ?? "",
|
|
294
|
-
query_by:
|
|
349
|
+
q: options.query ?? "*",
|
|
350
|
+
query_by: queryBy,
|
|
295
351
|
};
|
|
296
352
|
const sortBy = this.buildSort(options);
|
|
297
353
|
if (sortBy)
|
|
@@ -313,10 +369,8 @@ export class TSense {
|
|
|
313
369
|
params.exclude_fields = options.omit.join(",");
|
|
314
370
|
}
|
|
315
371
|
const highlight = options.highlight;
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
if (typeof highlight === "object") {
|
|
319
|
-
highlightOpts = highlight;
|
|
372
|
+
const highlightOpts = typeof highlight === "object" ? highlight : undefined;
|
|
373
|
+
if (highlightOpts) {
|
|
320
374
|
if (highlightOpts.fields) {
|
|
321
375
|
params.highlight_fields = highlightOpts.fields.join(",");
|
|
322
376
|
}
|
|
@@ -335,7 +389,7 @@ export class TSense {
|
|
|
335
389
|
const data = [];
|
|
336
390
|
const scores = [];
|
|
337
391
|
for (const hit of res.hits ?? []) {
|
|
338
|
-
if (
|
|
392
|
+
if (highlight) {
|
|
339
393
|
const fieldsToHighlight = highlightOpts?.fields;
|
|
340
394
|
for (const [key, value] of Object.entries(hit.highlight ?? {})) {
|
|
341
395
|
if (!value?.snippet)
|
|
@@ -365,35 +419,22 @@ export class TSense {
|
|
|
365
419
|
};
|
|
366
420
|
}
|
|
367
421
|
async searchList(options) {
|
|
368
|
-
await this.ensureSynced();
|
|
369
|
-
const limit = Math.min(options.limit ?? 20, 100);
|
|
370
|
-
const field = options.sort.field;
|
|
371
422
|
const page = options.cursor ? Number(options.cursor) : 1;
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
423
|
+
const limit = Math.min(options.limit ?? 20, 100);
|
|
424
|
+
const result = await this.search({
|
|
425
|
+
query: options.query,
|
|
426
|
+
queryBy: options.queryBy,
|
|
427
|
+
filter: options.filter,
|
|
428
|
+
sortBy: [options.sortBy],
|
|
376
429
|
page,
|
|
377
|
-
|
|
378
|
-
};
|
|
379
|
-
const filterParts = this.buildFilter(options.filter);
|
|
380
|
-
const filterBy = filterParts.join("&&");
|
|
381
|
-
if (filterBy)
|
|
382
|
-
params.filter_by = filterBy;
|
|
383
|
-
const { data: res } = await this.axios({
|
|
384
|
-
method: "GET",
|
|
385
|
-
url: `/collections/${this.options.name}/documents/search`,
|
|
386
|
-
params,
|
|
430
|
+
limit,
|
|
387
431
|
});
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
const hasMore = page * limit < res.found;
|
|
395
|
-
const nextCursor = hasMore ? String(page + 1) : null;
|
|
396
|
-
return { data, nextCursor, total: res.found };
|
|
432
|
+
const hasMore = page * limit < result.count;
|
|
433
|
+
return {
|
|
434
|
+
data: result.data,
|
|
435
|
+
nextCursor: hasMore ? String(page + 1) : null,
|
|
436
|
+
total: result.count,
|
|
437
|
+
};
|
|
397
438
|
}
|
|
398
439
|
async count(filter) {
|
|
399
440
|
await this.ensureSynced();
|
|
@@ -405,15 +446,16 @@ export class TSense {
|
|
|
405
446
|
});
|
|
406
447
|
return data.num_documents;
|
|
407
448
|
}
|
|
449
|
+
const params = {
|
|
450
|
+
q: "*",
|
|
451
|
+
query_by: this.options.defaultSearchField,
|
|
452
|
+
per_page: 0,
|
|
453
|
+
filter_by: filterBy,
|
|
454
|
+
};
|
|
408
455
|
const { data } = await this.axios({
|
|
409
456
|
method: "GET",
|
|
410
457
|
url: `/collections/${this.options.name}/documents/search`,
|
|
411
|
-
params
|
|
412
|
-
q: "*",
|
|
413
|
-
query_by: this.options.defaultSearchField,
|
|
414
|
-
per_page: 0,
|
|
415
|
-
filter_by: filterBy,
|
|
416
|
-
},
|
|
458
|
+
params,
|
|
417
459
|
});
|
|
418
460
|
return data.found;
|
|
419
461
|
}
|
|
@@ -427,7 +469,9 @@ export class TSense {
|
|
|
427
469
|
this.options.schema.assert(item);
|
|
428
470
|
}
|
|
429
471
|
}
|
|
430
|
-
const payload = items
|
|
472
|
+
const payload = items
|
|
473
|
+
.map((item) => JSON.stringify(this.serializeDoc(item)))
|
|
474
|
+
.join("\n");
|
|
431
475
|
const params = { action: "upsert" };
|
|
432
476
|
if (this.options.batchSize) {
|
|
433
477
|
params.batch_size = this.options.batchSize;
|
|
@@ -492,4 +536,19 @@ export class TSense {
|
|
|
492
536
|
.filter((line) => line.length)
|
|
493
537
|
.map((line) => JSON.parse(line).id);
|
|
494
538
|
}
|
|
539
|
+
scoped(baseFilter) {
|
|
540
|
+
return {
|
|
541
|
+
search: (options) => this.search({
|
|
542
|
+
...options,
|
|
543
|
+
filter: { ...options.filter, ...baseFilter },
|
|
544
|
+
}),
|
|
545
|
+
searchList: (options) => this.searchList({
|
|
546
|
+
...options,
|
|
547
|
+
filter: { ...options.filter, ...baseFilter },
|
|
548
|
+
}),
|
|
549
|
+
count: (filter) => this.count({ ...filter, ...baseFilter }),
|
|
550
|
+
deleteMany: (filter) => this.deleteMany({ ...filter, ...baseFilter }),
|
|
551
|
+
updateMany: (filter, data) => this.updateMany({ ...filter, ...baseFilter }, data),
|
|
552
|
+
};
|
|
553
|
+
}
|
|
495
554
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ type BaseIfArray<T> = T extends (infer Q)[] ? Q : T;
|
|
|
4
4
|
export type FieldSchema = {
|
|
5
5
|
name: string;
|
|
6
6
|
type: string;
|
|
7
|
+
sourceExpression?: string;
|
|
7
8
|
facet?: boolean;
|
|
8
9
|
sort?: boolean;
|
|
9
10
|
index?: boolean;
|
|
10
11
|
optional?: boolean;
|
|
12
|
+
enumValues?: string[];
|
|
11
13
|
};
|
|
12
14
|
export type SearchHit<T> = {
|
|
13
15
|
document: T;
|
|
@@ -46,13 +48,29 @@ export type TsenseOptions<T extends Type> = {
|
|
|
46
48
|
transformers?: FieldTransformer[];
|
|
47
49
|
dataSync?: SyncConfig<T["infer"]>;
|
|
48
50
|
};
|
|
51
|
+
export type StringFilter = {
|
|
52
|
+
not?: string;
|
|
53
|
+
notIn?: string[];
|
|
54
|
+
};
|
|
55
|
+
export type NumberFilter = {
|
|
56
|
+
not?: number;
|
|
57
|
+
notIn?: number[];
|
|
58
|
+
gt?: number;
|
|
59
|
+
gte?: number;
|
|
60
|
+
lt?: number;
|
|
61
|
+
lte?: number;
|
|
62
|
+
};
|
|
63
|
+
type DateFilter = {
|
|
64
|
+
not?: Date;
|
|
65
|
+
notIn?: Date[];
|
|
66
|
+
gt?: Date;
|
|
67
|
+
gte?: Date;
|
|
68
|
+
lt?: Date;
|
|
69
|
+
lte?: Date;
|
|
70
|
+
};
|
|
71
|
+
type FilterValueFor<T> = [T] extends [boolean] ? boolean : [T] extends [Date] ? Date | Date[] | DateFilter : [T] extends [number] ? number | number[] | NumberFilter : [T] extends [string] ? T | T[] | StringFilter : never;
|
|
49
72
|
type SingleFilter<T> = Partial<{
|
|
50
|
-
[K in keyof T]:
|
|
51
|
-
not?: BaseIfArray<T[K]>;
|
|
52
|
-
} | (NonNullable<T[K]> extends number | Date ? NonNullable<T[K]> extends infer Type ? {
|
|
53
|
-
min?: Type;
|
|
54
|
-
max?: Type;
|
|
55
|
-
} : never : never);
|
|
73
|
+
[K in keyof T]: FilterValueFor<NonNullable<BaseIfArray<T[K]>>>;
|
|
56
74
|
}>;
|
|
57
75
|
export type FilterFor<T> = SingleFilter<T> & {
|
|
58
76
|
OR?: FilterFor<T>[];
|
|
@@ -108,15 +126,17 @@ export type UpsertResult = {
|
|
|
108
126
|
error?: string;
|
|
109
127
|
document?: unknown;
|
|
110
128
|
};
|
|
111
|
-
type
|
|
112
|
-
|
|
113
|
-
|
|
129
|
+
export type SearchInput<T> = {
|
|
130
|
+
query?: string;
|
|
131
|
+
filter?: FilterFor<T>;
|
|
132
|
+
page?: number;
|
|
133
|
+
limit?: number;
|
|
114
134
|
};
|
|
115
135
|
export type SearchListOptions<T> = {
|
|
116
136
|
query?: string;
|
|
117
137
|
queryBy?: (keyof T)[];
|
|
118
138
|
filter?: FilterFor<T>;
|
|
119
|
-
|
|
139
|
+
sortBy: `${Extract<keyof T, string>}:${"asc" | "desc"}`;
|
|
120
140
|
limit?: number;
|
|
121
141
|
cursor?: string;
|
|
122
142
|
};
|
|
@@ -125,6 +145,13 @@ export type SearchListResult<T> = {
|
|
|
125
145
|
nextCursor: string | null;
|
|
126
146
|
total: number;
|
|
127
147
|
};
|
|
148
|
+
export type ScopedCollection<T> = {
|
|
149
|
+
search: <const O extends SearchOptions<T> = SearchOptionsPlain<T>>(options: O) => Promise<SearchResult<ProjectSearch<T, O>>>;
|
|
150
|
+
searchList: (options: SearchListOptions<T>) => Promise<SearchListResult<T>>;
|
|
151
|
+
count: (filter?: FilterFor<T>) => Promise<number>;
|
|
152
|
+
deleteMany: (filter: FilterFor<T>) => Promise<DeleteResult>;
|
|
153
|
+
updateMany: (filter: FilterFor<T>, data: Partial<T>) => Promise<UpdateResult>;
|
|
154
|
+
};
|
|
128
155
|
export type SyncConfig<T> = {
|
|
129
156
|
getAllIds: () => Promise<string[]>;
|
|
130
157
|
getItems: (ids: string[]) => Promise<T[]>;
|
package/package.json
CHANGED
|
@@ -1,51 +1,70 @@
|
|
|
1
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
|
-
|
|
2
|
+
"name": "tsense",
|
|
3
|
+
"version": "0.2.0-next.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Opinionated, fully typed typesense client",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"typesense"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/lobomfz/tsense",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./filters": {
|
|
24
|
+
"types": "./dist/filters/index.d.ts",
|
|
25
|
+
"import": "./dist/filters/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./react": {
|
|
28
|
+
"types": "./dist/react/index.d.ts",
|
|
29
|
+
"import": "./dist/react/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsgo",
|
|
37
|
+
"check": "bun run scripts/check.ts",
|
|
38
|
+
"ci": "bun run build && bun run format && bun run check-exports",
|
|
39
|
+
"test": "bun test",
|
|
40
|
+
"format": "oxfmt check --write src tests",
|
|
41
|
+
"check-exports": "attw --pack . --ignore-rules cjs-resolves-to-esm no-resolution",
|
|
42
|
+
"local-release": "changeset version && changeset publish",
|
|
43
|
+
"prepublishOnly": "bun run ci"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"redaxios": "^0.5.1"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
50
|
+
"@changesets/cli": "^2.30.0",
|
|
51
|
+
"@types/bun": "latest",
|
|
52
|
+
"@types/node": "^25.5.0",
|
|
53
|
+
"@types/react": "^19.2.14",
|
|
54
|
+
"@typescript/native-preview": "^7.0.0-dev.20260324.1",
|
|
55
|
+
"arktype": "^2.2.0",
|
|
56
|
+
"jscpd": "^4.0.8",
|
|
57
|
+
"oxfmt": "^0.42.0",
|
|
58
|
+
"oxlint": "^1.57.0",
|
|
59
|
+
"react": "^19.2.4"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"arktype": "^2.1.29",
|
|
63
|
+
"react": ">=18"
|
|
64
|
+
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"react": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|