@goatlab/typesense 0.1.2 → 0.1.4

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 (31) hide show
  1. package/dist/TypesenseApi.js +16 -16
  2. package/dist/actions/aliases/createOrUpdateAlias.js +1 -1
  3. package/dist/actions/collections/createCollection.js +2 -2
  4. package/dist/actions/collections/deleteCollection.js +1 -1
  5. package/dist/actions/collections/updateCollection.js +1 -1
  6. package/dist/actions/documents/clearCollection.js +1 -1
  7. package/dist/actions/documents/deleteByFilter.js +1 -1
  8. package/dist/actions/documents/deleteDocument.js +1 -1
  9. package/dist/actions/documents/exportDocuments.js +3 -3
  10. package/dist/actions/documents/importDocuments.js +2 -2
  11. package/dist/actions/documents/insertDocument.js +3 -3
  12. package/dist/actions/documents/updateDocument.js +1 -1
  13. package/dist/actions/documents/upsertDocument.js +1 -1
  14. package/dist/actions/overrides/upsertOverride.js +1 -1
  15. package/dist/actions/presets/listPresets.js +1 -1
  16. package/dist/actions/presets/upsertPreset.js +1 -1
  17. package/dist/actions/search/multiSearch.js +1 -1
  18. package/dist/actions/search/search.js +1 -1
  19. package/dist/actions/synonyms/upsertSynonym.js +1 -1
  20. package/dist/components/export-formatter.js +5 -5
  21. package/dist/components/http-client.js +8 -8
  22. package/dist/components/resilience-policy.js +4 -4
  23. package/dist/components/schema-manager.js +6 -6
  24. package/dist/examples/multitenancy-example.js +21 -21
  25. package/dist/index.d.ts +1 -1
  26. package/dist/tests/type-inference-example.js +9 -9
  27. package/dist/tests/typesense.js +2 -2
  28. package/dist/typesense.model.js +1 -1
  29. package/dist/utils/schema-typed-api.js +1 -1
  30. package/dist/utils/tenant.js +1 -1
  31. package/package.json +3 -3
@@ -170,7 +170,7 @@ class TypesenseApi {
170
170
  this.resilience = new resilience_policy_1.ResiliencePolicy({
171
171
  ...options.resilience,
172
172
  onStateChange: options.onCircuitBreakerStateChange,
173
- onRateLimitUpdate: options.onRateLimitUpdate
173
+ onRateLimitUpdate: options.onRateLimitUpdate,
174
174
  });
175
175
  // Create request/response interceptors for circuit breaker
176
176
  const beforeRequestHooks = [
@@ -184,7 +184,7 @@ class TypesenseApi {
184
184
  }
185
185
  return undefined;
186
186
  },
187
- ...(options.beforeRequest || [])
187
+ ...(options.beforeRequest || []),
188
188
  ];
189
189
  const afterResponseHooks = [
190
190
  async (_request, _options, response) => {
@@ -196,7 +196,7 @@ class TypesenseApi {
196
196
  this.resilience.updateRateLimit(response.headers);
197
197
  return response;
198
198
  },
199
- ...(options.afterResponse || [])
199
+ ...(options.afterResponse || []),
200
200
  ];
201
201
  const beforeErrorHooks = [
202
202
  (error) => {
@@ -211,7 +211,7 @@ class TypesenseApi {
211
211
  }
212
212
  // Re-throw the original error
213
213
  throw error;
214
- }
214
+ },
215
215
  ];
216
216
  // Initialize components with interceptors
217
217
  this.httpClient = new http_client_1.TypesenseHttpClient({
@@ -224,13 +224,13 @@ class TypesenseApi {
224
224
  afterResponse: afterResponseHooks,
225
225
  beforeError: beforeErrorHooks,
226
226
  kyInstance: options.kyInstance,
227
- enforceTLS: options.enforceTLS
227
+ enforceTLS: options.enforceTLS,
228
228
  });
229
229
  this.schemaManager = new schema_manager_1.CollectionSchemaManager({
230
230
  typesenseVersion: options.typesenseVersion,
231
231
  cacheSize: options.schemaCacheSize,
232
232
  cacheTtl: options.schemaCacheTtl,
233
- suppressLogs: options.suppressLogs
233
+ suppressLogs: options.suppressLogs,
234
234
  });
235
235
  // Validate and sanitize tenant ID if provided
236
236
  const sanitizedTenantId = options.tenantId
@@ -249,7 +249,7 @@ class TypesenseApi {
249
249
  fqcn: (baseCollectionName) => {
250
250
  const base = baseCollectionName || this.ctx.collectionName;
251
251
  return sanitizedTenantId ? (0, tenant_1.createFQCN)(sanitizedTenantId, base) : base;
252
- }
252
+ },
253
253
  };
254
254
  this.withCtx = bindCtx(this.ctx);
255
255
  // Check version if enabled
@@ -282,7 +282,7 @@ class TypesenseApi {
282
282
  update: this.withCtx(updateCollection_1.updateCollection),
283
283
  delete: this.withCtx(deleteCollection_1.deleteCollection),
284
284
  list: this.withCtx(listCollections_1.listCollections),
285
- getOrCreate: this.withCtx(getOrCreateCollection_1.getOrCreateCollection)
285
+ getOrCreate: this.withCtx(getOrCreateCollection_1.getOrCreateCollection),
286
286
  };
287
287
  }
288
288
  /**
@@ -304,7 +304,7 @@ class TypesenseApi {
304
304
  // Search operations
305
305
  search: this.withCtx(search_1.search),
306
306
  searchText: this.withCtx(search_1.searchText),
307
- searchVector: this.withCtx(search_1.searchVector)
307
+ searchVector: this.withCtx(search_1.searchVector),
308
308
  };
309
309
  }
310
310
  /**
@@ -315,7 +315,7 @@ class TypesenseApi {
315
315
  query: this.withCtx(search_1.search),
316
316
  text: this.withCtx(search_1.searchText),
317
317
  vector: this.withCtx(search_1.searchVector),
318
- multi: this.withCtx(multiSearch_1.multiSearch)
318
+ multi: this.withCtx(multiSearch_1.multiSearch),
319
319
  };
320
320
  }
321
321
  /**
@@ -327,7 +327,7 @@ class TypesenseApi {
327
327
  waitForHealth: this.withCtx(health_1.waitForHealth),
328
328
  getMetrics: this.withCtx(metrics_1.getMetrics),
329
329
  getStats: this.withCtx(metrics_1.getStats),
330
- getCollectionStats: this.withCtx(getCollectionStats_1.getCollectionStats)
330
+ getCollectionStats: this.withCtx(getCollectionStats_1.getCollectionStats),
331
331
  };
332
332
  }
333
333
  /**
@@ -338,7 +338,7 @@ class TypesenseApi {
338
338
  createOrUpdate: this.withCtx(createOrUpdateAlias_1.createOrUpdateAlias),
339
339
  get: this.withCtx(getAlias_1.getAlias),
340
340
  list: this.withCtx(listAliases_1.listAliases),
341
- delete: this.withCtx(deleteAlias_1.deleteAlias)
341
+ delete: this.withCtx(deleteAlias_1.deleteAlias),
342
342
  };
343
343
  }
344
344
  /**
@@ -349,7 +349,7 @@ class TypesenseApi {
349
349
  upsert: this.withCtx(upsertSynonym_1.upsertSynonym),
350
350
  get: this.withCtx(getSynonym_1.getSynonym),
351
351
  list: this.withCtx(listSynonyms_1.listSynonyms),
352
- delete: this.withCtx(deleteSynonym_1.deleteSynonym)
352
+ delete: this.withCtx(deleteSynonym_1.deleteSynonym),
353
353
  };
354
354
  }
355
355
  /**
@@ -360,7 +360,7 @@ class TypesenseApi {
360
360
  upsert: this.withCtx(upsertOverride_1.upsertOverride),
361
361
  get: this.withCtx(getOverride_1.getOverride),
362
362
  list: this.withCtx(listOverrides_1.listOverrides),
363
- delete: this.withCtx(deleteOverride_1.deleteOverride)
363
+ delete: this.withCtx(deleteOverride_1.deleteOverride),
364
364
  };
365
365
  }
366
366
  /**
@@ -371,7 +371,7 @@ class TypesenseApi {
371
371
  upsert: this.withCtx(upsertPreset_1.upsertPreset),
372
372
  get: this.withCtx(getPreset_1.getPreset),
373
373
  list: this.withCtx(listPresets_1.listPresets),
374
- delete: this.withCtx(deletePreset_1.deletePreset)
374
+ delete: this.withCtx(deletePreset_1.deletePreset),
375
375
  };
376
376
  }
377
377
  /**
@@ -438,7 +438,7 @@ class TypesenseApi {
438
438
  const tenantCollections = await this.listTenantCollections();
439
439
  for (const collectionName of tenantCollections) {
440
440
  await this.httpClient.request(`/collections/${collectionName}`, {
441
- method: 'DELETE'
441
+ method: 'DELETE',
442
442
  });
443
443
  }
444
444
  }
@@ -9,7 +9,7 @@ async function createOrUpdateAlias(ctx, aliasName, collectionName) {
9
9
  const qualifiedCollectionName = ctx.fqcn(collectionName);
10
10
  return await ctx.httpClient.request(`/aliases/${qualifiedAliasName}`, {
11
11
  method: 'PUT',
12
- body: { collection_name: qualifiedCollectionName }
12
+ body: { collection_name: qualifiedCollectionName },
13
13
  });
14
14
  }
15
15
  //# sourceMappingURL=createOrUpdateAlias.js.map
@@ -5,11 +5,11 @@ async function createCollection(ctx, collection) {
5
5
  // Use fqcn for the collection name if tenant is configured
6
6
  const collectionWithFqcn = {
7
7
  ...collection,
8
- name: ctx.fqcn(collection.name)
8
+ name: ctx.fqcn(collection.name),
9
9
  };
10
10
  const result = await ctx.httpClient.request('/collections', {
11
11
  method: 'POST',
12
- body: collectionWithFqcn
12
+ body: collectionWithFqcn,
13
13
  });
14
14
  // Cache the schema with the fully qualified name
15
15
  ctx.schemaManager.setCachedSchema(collectionWithFqcn.name, collectionWithFqcn);
@@ -4,7 +4,7 @@ exports.deleteCollection = deleteCollection;
4
4
  async function deleteCollection(ctx, collectionName) {
5
5
  const collection = collectionName || ctx.fqcn();
6
6
  const result = await ctx.httpClient.request(`/collections/${collection}`, {
7
- method: 'DELETE'
7
+ method: 'DELETE',
8
8
  });
9
9
  // Remove from cache
10
10
  ctx.schemaManager.deleteCachedSchema(collection);
@@ -5,7 +5,7 @@ async function updateCollection(ctx, collection, options) {
5
5
  const collectionName = options?.collection || collection.name || ctx.fqcn();
6
6
  const result = await ctx.httpClient.request(`/collections/${collectionName}`, {
7
7
  method: 'PATCH',
8
- body: collection
8
+ body: collection,
9
9
  });
10
10
  // Update cache
11
11
  ctx.schemaManager.setCachedSchema(collectionName, result);
@@ -5,7 +5,7 @@ async function clearCollection(ctx, options) {
5
5
  const collectionName = options?.collection || ctx.fqcn();
6
6
  return await ctx.httpClient.request(`/collections/${collectionName}/documents`, {
7
7
  method: 'DELETE',
8
- searchParams: { filter_by: '*' }
8
+ searchParams: { filter_by: '*' },
9
9
  });
10
10
  }
11
11
  //# sourceMappingURL=clearCollection.js.map
@@ -9,7 +9,7 @@ async function deleteByFilter(ctx, filter, options) {
9
9
  }
10
10
  return await ctx.httpClient.request(`/collections/${collectionName}/documents`, {
11
11
  method: 'DELETE',
12
- searchParams: params
12
+ searchParams: params,
13
13
  });
14
14
  }
15
15
  //# sourceMappingURL=deleteByFilter.js.map
@@ -8,7 +8,7 @@ async function deleteDocument(ctx, id, options) {
8
8
  }
9
9
  const collectionName = options?.collection || ctx.fqcn();
10
10
  return await ctx.httpClient.request(`/collections/${collectionName}/documents/${id}`, {
11
- method: 'DELETE'
11
+ method: 'DELETE',
12
12
  });
13
13
  }
14
14
  //# sourceMappingURL=deleteDocument.js.map
@@ -14,7 +14,7 @@ async function exportDocuments(ctx, format = 'jsonl', options) {
14
14
  const collectionName = options?.collection || ctx.fqcn();
15
15
  const { collection: _, ...exportOptions } = options || {};
16
16
  const searchParams = {
17
- ...exportOptions
17
+ ...exportOptions,
18
18
  // Note: Typesense export always returns JSONL regardless of format param
19
19
  };
20
20
  // Get response as text (JSONL format)
@@ -40,11 +40,11 @@ async function exportDocumentsStream(ctx, options) {
40
40
  const collectionName = options?.collection || ctx.fqcn();
41
41
  const { collection: _, ...exportOptions } = options || {};
42
42
  const searchParams = {
43
- ...exportOptions
43
+ ...exportOptions,
44
44
  };
45
45
  return ctx.httpClient
46
46
  .stream(`/collections/${collectionName}/documents/export`, {
47
- searchParams
47
+ searchParams,
48
48
  })
49
49
  .then(stream => node_stream_1.Readable.fromWeb(stream));
50
50
  }
@@ -42,14 +42,14 @@ async function importDocuments(ctx, documents, format = 'jsonl', importOptions,
42
42
  }
43
43
  const searchParams = {
44
44
  ...importOptions,
45
- action: importOptions?.action || 'create'
45
+ action: importOptions?.action || 'create',
46
46
  };
47
47
  // Stream directly to HTTP body for large files
48
48
  const response = await ctx.httpClient.requestTextWithRawBody(`/collections/${collectionName}/documents/import`, {
49
49
  method: 'POST',
50
50
  body: bodyStream,
51
51
  searchParams,
52
- timeout: ctx.httpClient.importTimeout
52
+ timeout: ctx.httpClient.importTimeout,
53
53
  });
54
54
  // Parse JSONL response to array
55
55
  return response
@@ -11,7 +11,7 @@ async function insertDocument(ctx, document, options) {
11
11
  try {
12
12
  return await ctx.httpClient.request(`/collections/${collectionName}/documents`, {
13
13
  method: 'POST',
14
- body: document
14
+ body: document,
15
15
  });
16
16
  }
17
17
  catch (error) {
@@ -23,12 +23,12 @@ async function insertDocument(ctx, document, options) {
23
23
  // Create collection
24
24
  await (0, getOrCreateCollection_1.getOrCreateCollection)(ctx, {
25
25
  ...inferredSchema,
26
- name: collectionName
26
+ name: collectionName,
27
27
  });
28
28
  // Retry insert
29
29
  return await ctx.httpClient.request(`/collections/${collectionName}/documents`, {
30
30
  method: 'POST',
31
- body: document
31
+ body: document,
32
32
  });
33
33
  }
34
34
  throw error;
@@ -9,7 +9,7 @@ async function updateDocument(ctx, document, options) {
9
9
  const collectionName = options?.collection || ctx.fqcn();
10
10
  return await ctx.httpClient.request(`/collections/${collectionName}/documents/${document.id}`, {
11
11
  method: 'PATCH',
12
- body: document
12
+ body: document,
13
13
  });
14
14
  }
15
15
  //# sourceMappingURL=updateDocument.js.map
@@ -10,7 +10,7 @@ async function upsertDocument(ctx, document, options) {
10
10
  return await ctx.httpClient.request(`/collections/${collectionName}/documents`, {
11
11
  method: 'POST',
12
12
  body: document,
13
- searchParams: { action: 'upsert' }
13
+ searchParams: { action: 'upsert' },
14
14
  });
15
15
  }
16
16
  //# sourceMappingURL=upsertDocument.js.map
@@ -5,7 +5,7 @@ async function upsertOverride(ctx, override, options) {
5
5
  const collectionName = options?.collection || ctx.fqcn();
6
6
  return await ctx.httpClient.request(`/collections/${collectionName}/overrides/${override.id}`, {
7
7
  method: 'PUT',
8
- body: override
8
+ body: override,
9
9
  });
10
10
  }
11
11
  //# sourceMappingURL=upsertOverride.js.map
@@ -10,7 +10,7 @@ async function listPresets(ctx) {
10
10
  // Remove tenant prefix from names for clean API response
11
11
  const cleanedPresets = filteredPresets.map(preset => ({
12
12
  ...preset,
13
- name: preset.name.substring(tenantPrefix.length)
13
+ name: preset.name.substring(tenantPrefix.length),
14
14
  }));
15
15
  return { presets: cleanedPresets };
16
16
  }
@@ -8,7 +8,7 @@ async function upsertPreset(ctx, preset) {
8
8
  const qualifiedPreset = { ...preset, name: qualifiedName };
9
9
  return await ctx.httpClient.request(`/presets/${qualifiedName}`, {
10
10
  method: 'PUT',
11
- body: qualifiedPreset
11
+ body: qualifiedPreset,
12
12
  });
13
13
  }
14
14
  //# sourceMappingURL=upsertPreset.js.map
@@ -4,7 +4,7 @@ exports.multiSearch = multiSearch;
4
4
  async function multiSearch(ctx, request) {
5
5
  return await ctx.httpClient.request('/multi_search', {
6
6
  method: 'POST',
7
- body: request
7
+ body: request,
8
8
  });
9
9
  }
10
10
  //# sourceMappingURL=multiSearch.js.map
@@ -7,7 +7,7 @@ async function search(ctx, query, options) {
7
7
  const collectionName = options?.collection || ctx.fqcn();
8
8
  return await ctx.httpClient.request(`/collections/${collectionName}/documents/search`, {
9
9
  searchParams: query,
10
- timeout: ctx.httpClient.getOptions().searchTimeout
10
+ timeout: ctx.httpClient.getOptions().searchTimeout,
11
11
  });
12
12
  }
13
13
  async function searchVector(ctx, query, options) {
@@ -5,7 +5,7 @@ async function upsertSynonym(ctx, synonym, options) {
5
5
  const collectionName = options?.collection || ctx.fqcn();
6
6
  return await ctx.httpClient.request(`/collections/${collectionName}/synonyms/${synonym.id}`, {
7
7
  method: 'PUT',
8
- body: synonym
8
+ body: synonym,
9
9
  });
10
10
  }
11
11
  //# sourceMappingURL=upsertSynonym.js.map
@@ -61,7 +61,7 @@ class ExportFormatter {
61
61
  catch (error) {
62
62
  callback(error);
63
63
  }
64
- }
64
+ },
65
65
  });
66
66
  }
67
67
  static createStreamingJSONLTransform() {
@@ -75,7 +75,7 @@ class ExportFormatter {
75
75
  catch (error) {
76
76
  callback(error);
77
77
  }
78
- }
78
+ },
79
79
  });
80
80
  }
81
81
  static createGzipStream() {
@@ -124,7 +124,7 @@ class ExportFormatter {
124
124
  }
125
125
  }
126
126
  callback();
127
- }
127
+ },
128
128
  });
129
129
  }
130
130
  static createJSONParser() {
@@ -149,7 +149,7 @@ class ExportFormatter {
149
149
  return callback(new Error(`Invalid JSON: ${error.message}`));
150
150
  }
151
151
  callback();
152
- }
152
+ },
153
153
  });
154
154
  }
155
155
  static escapeCsvValue(value) {
@@ -218,7 +218,7 @@ class ExportFormatter {
218
218
  else {
219
219
  this.push(null); // End stream
220
220
  }
221
- }
221
+ },
222
222
  });
223
223
  }
224
224
  }
@@ -27,7 +27,7 @@ class TypesenseHttpClient {
27
27
  timeout: options.defaultTimeout || 10000,
28
28
  headers: {
29
29
  'X-TYPESENSE-API-KEY': options.token,
30
- 'Content-Type': 'application/json'
30
+ 'Content-Type': 'application/json',
31
31
  },
32
32
  hooks: {
33
33
  beforeRequest: options.beforeRequest || [],
@@ -49,9 +49,9 @@ class TypesenseHttpClient {
49
49
  }
50
50
  }
51
51
  throw error;
52
- }
53
- ]
54
- }
52
+ },
53
+ ],
54
+ },
55
55
  });
56
56
  }
57
57
  sanitizeHeaders(headers) {
@@ -77,7 +77,7 @@ class TypesenseHttpClient {
77
77
  const requestOptions = {
78
78
  method,
79
79
  timeout: timeout || 10000,
80
- signal
80
+ signal,
81
81
  };
82
82
  if (body) {
83
83
  requestOptions.json = body;
@@ -97,7 +97,7 @@ class TypesenseHttpClient {
97
97
  const requestOptions = {
98
98
  method,
99
99
  timeout: timeout || 10000,
100
- signal
100
+ signal,
101
101
  };
102
102
  if (body) {
103
103
  requestOptions.json = body;
@@ -117,7 +117,7 @@ class TypesenseHttpClient {
117
117
  const requestOptions = {
118
118
  method,
119
119
  timeout: timeout || 10000,
120
- signal
120
+ signal,
121
121
  };
122
122
  if (body) {
123
123
  // Use raw body instead of JSON encoding
@@ -137,7 +137,7 @@ class TypesenseHttpClient {
137
137
  : endpoint;
138
138
  const requestOptions = {
139
139
  method,
140
- signal
140
+ signal,
141
141
  };
142
142
  if (body) {
143
143
  requestOptions.body = body;
@@ -15,7 +15,7 @@ class ResiliencePolicy {
15
15
  retryDelay: 1000,
16
16
  maxRetries: 3,
17
17
  enabled: true, // Enabled by default
18
- ...options
18
+ ...options,
19
19
  };
20
20
  }
21
21
  isCircuitOpen() {
@@ -75,7 +75,7 @@ class ResiliencePolicy {
75
75
  this.options.onStateChange('open', {
76
76
  failures: this.failures,
77
77
  openUntil: new Date(this.circuitOpenUntil),
78
- resetTimeout: this.options.resetTimeout || 60000
78
+ resetTimeout: this.options.resetTimeout || 60000,
79
79
  });
80
80
  }
81
81
  }
@@ -89,7 +89,7 @@ class ResiliencePolicy {
89
89
  limit: limit ? Number.parseInt(limit, 10) : undefined,
90
90
  remaining: remaining ? Number.parseInt(remaining, 10) : undefined,
91
91
  resetMs: resetMs ? Number.parseInt(resetMs, 10) : undefined,
92
- retryAfter: retryAfter ? Number.parseInt(retryAfter, 10) : undefined
92
+ retryAfter: retryAfter ? Number.parseInt(retryAfter, 10) : undefined,
93
93
  };
94
94
  // Set retry-after period if present
95
95
  if (retryAfter) {
@@ -128,7 +128,7 @@ class ResiliencePolicy {
128
128
  circuitOpenUntil: this.circuitOpenUntil,
129
129
  rateLimited: this.isRateLimited(),
130
130
  retryAfterUntil: this.retryAfterUntil,
131
- rateLimit: this.rateLimitInfo
131
+ rateLimit: this.rateLimitInfo,
132
132
  };
133
133
  }
134
134
  }
@@ -49,7 +49,7 @@ class CollectionSchemaManager {
49
49
  cacheTtl: options.cacheTtl || 300000, // 5 minutes
50
50
  enableNestedFields: options.enableNestedFields ?? false,
51
51
  typesenseVersion: options.typesenseVersion || '0.24.0',
52
- suppressLogs: options.suppressLogs ?? false
52
+ suppressLogs: options.suppressLogs ?? false,
53
53
  };
54
54
  this.schemaCache = new LRUCache(this.options.cacheSize);
55
55
  }
@@ -87,7 +87,7 @@ class CollectionSchemaManager {
87
87
  const cacheKey = `schema:${collectionName}`;
88
88
  this.schemaCache.set(cacheKey, {
89
89
  schema,
90
- timestamp: Date.now()
90
+ timestamp: Date.now(),
91
91
  });
92
92
  }
93
93
  deleteCachedSchema(collectionName) {
@@ -175,7 +175,7 @@ class CollectionSchemaManager {
175
175
  }
176
176
  const collection = {
177
177
  name: collectionName,
178
- fields
178
+ fields,
179
179
  };
180
180
  // Add version-gated features
181
181
  if (this.isVersionSupported('nested_fields', '0.25.0') &&
@@ -213,7 +213,7 @@ class CollectionSchemaManager {
213
213
  'object',
214
214
  'object[]',
215
215
  'auto',
216
- 'image'
216
+ 'image',
217
217
  ];
218
218
  schema.fields?.forEach(field => {
219
219
  if (!validTypes.includes(field.type)) {
@@ -227,7 +227,7 @@ class CollectionSchemaManager {
227
227
  }
228
228
  return {
229
229
  valid: errors.length === 0,
230
- errors
230
+ errors,
231
231
  };
232
232
  }
233
233
  clearCache() {
@@ -236,7 +236,7 @@ class CollectionSchemaManager {
236
236
  getCacheStats() {
237
237
  return {
238
238
  size: this.schemaCache.size(),
239
- maxSize: this.options.cacheSize
239
+ maxSize: this.options.cacheSize,
240
240
  };
241
241
  }
242
242
  setTypesenseVersion(version) {
@@ -12,14 +12,14 @@ async function _example1() {
12
12
  prefixUrl: 'http://localhost:8108',
13
13
  token: 'xyz',
14
14
  tenantId: 'acme',
15
- collectionName: 'products'
15
+ collectionName: 'products',
16
16
  });
17
17
  // API instance for tenant "globex"
18
18
  const globexApi = new TypesenseApi_1.TypesenseApi({
19
19
  prefixUrl: 'http://localhost:8108',
20
20
  token: 'xyz',
21
21
  tenantId: 'globex',
22
- collectionName: 'products'
22
+ collectionName: 'products',
23
23
  });
24
24
  // Define schema
25
25
  const productSchema = {
@@ -27,8 +27,8 @@ async function _example1() {
27
27
  fields: [
28
28
  { name: 'name', type: 'string' },
29
29
  { name: 'price', type: 'float' },
30
- { name: 'category', type: 'string', facet: true }
31
- ]
30
+ { name: 'category', type: 'string', facet: true },
31
+ ],
32
32
  };
33
33
  // Create collections - each tenant gets their own prefixed collection
34
34
  // This creates "acme__products" collection
@@ -40,23 +40,23 @@ async function _example1() {
40
40
  id: '1',
41
41
  name: 'Acme Widget',
42
42
  price: 19.99,
43
- category: 'widgets'
43
+ category: 'widgets',
44
44
  });
45
45
  await globexApi.documents.insert({
46
46
  id: '1', // Same ID is fine - different collection
47
47
  name: 'Globex Gadget',
48
48
  price: 29.99,
49
- category: 'gadgets'
49
+ category: 'gadgets',
50
50
  });
51
51
  // Search - each tenant only sees their own data
52
52
  const acmeResults = await acmeApi.search.text({
53
53
  q: '*',
54
- query_by: 'name'
54
+ query_by: 'name',
55
55
  });
56
56
  console.log('Acme products:', acmeResults.hits); // Only Acme Widget
57
57
  const globexResults = await globexApi.search.text({
58
58
  q: '*',
59
- query_by: 'name'
59
+ query_by: 'name',
60
60
  });
61
61
  console.log('Globex products:', globexResults.hits); // Only Globex Gadget
62
62
  }
@@ -65,7 +65,7 @@ async function _example2() {
65
65
  const adminApi = new TypesenseApi_1.TypesenseApi({
66
66
  prefixUrl: 'http://localhost:8108',
67
67
  token: 'xyz',
68
- tenantId: 'acme'
68
+ tenantId: 'acme',
69
69
  });
70
70
  // List all collections for the tenant
71
71
  const tenantCollections = await adminApi.listTenantCollections();
@@ -86,48 +86,48 @@ async function _example3() {
86
86
  const api = new TypesenseApi_1.TypesenseApi({
87
87
  prefixUrl: 'http://localhost:8108',
88
88
  token: 'xyz',
89
- tenantId: 'acme'
89
+ tenantId: 'acme',
90
90
  });
91
91
  // Create multiple collections for the tenant
92
92
  await api.collections.create({
93
93
  name: 'users',
94
94
  fields: [
95
95
  { name: 'email', type: 'string' },
96
- { name: 'name', type: 'string' }
97
- ]
96
+ { name: 'name', type: 'string' },
97
+ ],
98
98
  });
99
99
  await api.collections.create({
100
100
  name: 'orders',
101
101
  fields: [
102
102
  { name: 'order_id', type: 'string' },
103
103
  { name: 'user_email', type: 'string' },
104
- { name: 'total', type: 'float' }
105
- ]
104
+ { name: 'total', type: 'float' },
105
+ ],
106
106
  });
107
107
  // Work with different collections by changing the context
108
108
  const userApi = new TypesenseApi_1.TypesenseApi({
109
109
  prefixUrl: 'http://localhost:8108',
110
110
  token: 'xyz',
111
111
  tenantId: 'acme',
112
- collectionName: 'users'
112
+ collectionName: 'users',
113
113
  });
114
114
  const orderApi = new TypesenseApi_1.TypesenseApi({
115
115
  prefixUrl: 'http://localhost:8108',
116
116
  token: 'xyz',
117
117
  tenantId: 'acme',
118
- collectionName: 'orders'
118
+ collectionName: 'orders',
119
119
  });
120
120
  // Insert data into different collections
121
121
  await userApi.documents.insert({
122
122
  id: 'user-1',
123
123
  email: 'john@acme.com',
124
- name: 'John Doe'
124
+ name: 'John Doe',
125
125
  });
126
126
  await orderApi.documents.insert({
127
127
  id: 'ORD-001',
128
128
  order_id: 'ORD-001',
129
129
  user_email: 'john@acme.com',
130
- total: 99.99
130
+ total: 99.99,
131
131
  });
132
132
  }
133
133
  // Example 4: Migrating existing non-tenant data
@@ -136,14 +136,14 @@ async function _example4() {
136
136
  const legacyApi = new TypesenseApi_1.TypesenseApi({
137
137
  prefixUrl: 'http://localhost:8108',
138
138
  token: 'xyz',
139
- collectionName: 'products'
139
+ collectionName: 'products',
140
140
  });
141
141
  // API with tenant
142
142
  const tenantApi = new TypesenseApi_1.TypesenseApi({
143
143
  prefixUrl: 'http://localhost:8108',
144
144
  token: 'xyz',
145
145
  tenantId: 'legacy',
146
- collectionName: 'products'
146
+ collectionName: 'products',
147
147
  });
148
148
  // Export from legacy collection
149
149
  const legacyData = await legacyApi.documents.export();
@@ -174,7 +174,7 @@ async function _example5() {
174
174
  'acme__products',
175
175
  'acme__users',
176
176
  'globex__products',
177
- 'legacy_collection'
177
+ 'legacy_collection',
178
178
  ];
179
179
  const acmeCollections = (0, tenant_1.filterCollectionsByTenant)(allCollections, 'acme');
180
180
  console.log('Acme collections:', acmeCollections); // ['acme__products', 'acme__users']
package/dist/index.d.ts CHANGED
@@ -8,5 +8,5 @@ export { TypesenseApi } from './TypesenseApi';
8
8
  export * from './types';
9
9
  export type * from './typesense.model';
10
10
  export * from './typesense.model';
11
- export { defineCollection, type InferDocumentType, type InferFromCollection } from './utils/schema-to-types';
11
+ export { defineCollection, type InferDocumentType, type InferFromCollection, } from './utils/schema-to-types';
12
12
  export { createSchemaTypedApi } from './utils/schema-typed-api';
@@ -15,26 +15,26 @@ const index_1 = require("../index");
15
15
  { name: 'description', type: 'string', optional: true },
16
16
  { name: 'price', type: 'float' },
17
17
  { name: 'inStock', type: 'bool' },
18
- { name: 'tags', type: 'string[]', optional: true }
19
- ]
18
+ { name: 'tags', type: 'string[]', optional: true },
19
+ ],
20
20
  });
21
21
  // These should compile without errors
22
22
  const _validDoc1 = {
23
23
  title: 'Laptop',
24
24
  price: 999.99,
25
- inStock: true
25
+ inStock: true,
26
26
  };
27
27
  const _validDoc2 = {
28
28
  title: 'Gaming Laptop',
29
29
  description: 'High-performance laptop',
30
30
  price: 1999.99,
31
31
  inStock: true,
32
- tags: ['gaming', 'performance']
32
+ tags: ['gaming', 'performance'],
33
33
  };
34
34
  // Create typed API
35
35
  const api = (0, index_1.createSchemaTypedApi)(ProductCollection)({
36
36
  prefixUrl: 'http://localhost:8108',
37
- token: 'xyz'
37
+ token: 'xyz',
38
38
  });
39
39
  // Verify API structure
40
40
  (0, vitest_1.expect)(api).toBeDefined();
@@ -69,20 +69,20 @@ const index_1 = require("../index");
69
69
  { name: 'timestamp', type: 'int64' },
70
70
  { name: 'location', type: 'geopoint' },
71
71
  { name: 'attendees', type: 'int32[]', optional: true },
72
- { name: 'metadata', type: 'object', optional: true }
73
- ]
72
+ { name: 'metadata', type: 'object', optional: true },
73
+ ],
74
74
  });
75
75
  const validEvent = {
76
76
  name: 'Tech Conference',
77
77
  timestamp: Date.now(),
78
- location: [37.7749, -122.4194]
78
+ location: [37.7749, -122.4194],
79
79
  };
80
80
  const validEventWithOptionals = {
81
81
  name: 'Meetup',
82
82
  timestamp: Date.now(),
83
83
  location: [40.7128, -74.006],
84
84
  attendees: [10, 20, 30],
85
- metadata: { organizer: 'John', venue: 'Tech Hub' }
85
+ metadata: { organizer: 'John', venue: 'Tech Hub' },
86
86
  };
87
87
  (0, vitest_1.expect)(validEvent).toBeDefined();
88
88
  (0, vitest_1.expect)(validEventWithOptionals).toBeDefined();
@@ -4,7 +4,7 @@ exports.typesenseContainer = void 0;
4
4
  const testcontainers_1 = require("testcontainers");
5
5
  exports.typesenseContainer = new testcontainers_1.GenericContainer('typesense/typesense:29.0')
6
6
  .withEnvironment({
7
- TYPESENSE_API_KEY: 'MY_API_KEY'
7
+ TYPESENSE_API_KEY: 'MY_API_KEY',
8
8
  })
9
9
  .withCommand([
10
10
  '--data-dir',
@@ -18,7 +18,7 @@ exports.typesenseContainer = new testcontainers_1.GenericContainer('typesense/ty
18
18
  '--analytics-dir',
19
19
  '/path/to/analytics-data',
20
20
  '--analytics-flush-interval',
21
- '300'
21
+ '300',
22
22
  ])
23
23
  .withExposedPorts(8108);
24
24
  //# sourceMappingURL=typesense.js.map
@@ -90,7 +90,7 @@ function validateVectorQuery(query) {
90
90
  }
91
91
  return {
92
92
  valid: errors.length === 0,
93
- errors
93
+ errors,
94
94
  };
95
95
  }
96
96
  /**
@@ -35,7 +35,7 @@ function createSchemaTypedApi(collection) {
35
35
  return (options) => {
36
36
  return new TypesenseApi_1.TypesenseApi({
37
37
  ...options,
38
- collectionName: collection.name
38
+ collectionName: collection.name,
39
39
  });
40
40
  };
41
41
  }
@@ -64,7 +64,7 @@ function parseFQCN(fqcn) {
64
64
  }
65
65
  return {
66
66
  tenantId: fqcn.substring(0, separatorIndex),
67
- baseCollectionName: fqcn.substring(separatorIndex + 2)
67
+ baseCollectionName: fqcn.substring(separatorIndex + 2),
68
68
  };
69
69
  }
70
70
  /**
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "@goatlab/typesense",
5
5
  "description": "Modern TypeScript wrapper for Typesense search engine API",
6
6
  "author": "ignacio.cabrera@goatlab.io",
7
- "version": "0.1.2",
7
+ "version": "0.1.4",
8
8
  "private": false,
9
9
  "publishConfig": {
10
10
  "access": "public"
@@ -12,7 +12,7 @@
12
12
  "types": "./dist/index.d.ts",
13
13
  "dependencies": {
14
14
  "zod": "^4.0.10",
15
- "@goatlab/js-utils": "0.10.1",
15
+ "@goatlab/js-utils": "0.10.3",
16
16
  "@goatlab/tsconfig": "0.1.0"
17
17
  },
18
18
  "devDependencies": {
@@ -29,7 +29,7 @@
29
29
  "turbo": "^1.1.10",
30
30
  "typescript": "^5.0.2",
31
31
  "vitest": "^3.2.4",
32
- "@goatlab/biome": "0.1.0"
32
+ "@goatlab/biome": "0.1.1"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=14.16.0"