@larkup/vector-stores 0.1.20 → 0.1.21

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/src/registry.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { IndexType, VectorStoreDescriptor, VectorStoreId } from "@larkup/core/types"
1
+ import type { IndexType, VectorStoreDescriptor, VectorStoreId } from '@larkup/core/types';
2
2
 
3
3
  /**
4
4
  * Declarative registry of supported vector stores.
@@ -14,360 +14,406 @@ import type { IndexType, VectorStoreDescriptor, VectorStoreId } from "@larkup/co
14
14
  */
15
15
  export const VECTOR_STORES: Record<VectorStoreId, VectorStoreDescriptor> = {
16
16
  lancedb: {
17
- id: "lancedb",
18
- label: "LanceDB",
17
+ id: 'lancedb',
18
+ label: 'LanceDB',
19
19
  description:
20
- "Embedded, file-based vector DB. Runs fully local for dev or against LanceDB Cloud for production.",
21
- runtime: "both",
22
- installStatus: "installed",
23
- docsUrl: "https://lancedb.github.io/lancedb/",
20
+ 'Embedded vector database for local development, LanceDB Cloud, or persistent S3-compatible storage such as Cloudflare R2.',
21
+ runtime: 'both',
22
+ installStatus: 'installed',
23
+ docsUrl: 'https://lancedb.github.io/lancedb/',
24
24
  serverDependencies: {
25
- "@lancedb/lancedb": "^0.30.0",
25
+ '@lancedb/lancedb': '^0.30.0',
26
26
  },
27
27
  fields: [
28
28
  {
29
- key: "mode",
30
- label: "Mode",
31
- type: "select",
29
+ key: 'mode',
30
+ label: 'Mode',
31
+ type: 'select',
32
32
  required: true,
33
- defaultValue: "local",
34
- help: "Local writes to disk on the toolkit host. Cloud connects to LanceDB Cloud.",
33
+ defaultValue: 'local',
34
+ help: 'Use a local disk, LanceDB Cloud, or an S3-compatible bucket for persistent serverless deployments.',
35
35
  options: [
36
- { label: "Local (on-disk)", value: "local" },
37
- { label: "Cloud", value: "cloud" },
36
+ { label: 'Local (on-disk)', value: 'local' },
37
+ { label: 'S3-compatible (Vercel / R2 / S3)', value: 's3' },
38
+ { label: 'Cloud', value: 'cloud' },
38
39
  ],
39
40
  },
40
41
  {
41
- key: "dbPath",
42
- label: "Database path",
43
- type: "path",
42
+ key: 'dbPath',
43
+ label: 'Database path',
44
+ type: 'path',
44
45
  required: true,
45
- defaultValue: "./.larkup/lancedb",
46
- placeholder: "./.larkup/lancedb",
47
- help: "Directory where the LanceDB tables are stored.",
48
- showWhen: { key: "mode", equals: ["local"] },
46
+ defaultValue: './.larkup/lancedb',
47
+ placeholder: './.larkup/lancedb',
48
+ help: 'Directory where the LanceDB tables are stored.',
49
+ showWhen: { key: 'mode', equals: ['local'] },
49
50
  },
50
51
  {
51
- key: "uri",
52
- label: "Cloud URI",
53
- type: "text",
52
+ key: 's3Uri',
53
+ label: 'Database URI',
54
+ type: 'text',
54
55
  required: true,
55
- placeholder: "db://my-database",
56
- help: "Your LanceDB Cloud database URI.",
57
- showWhen: { key: "mode", equals: ["cloud"] },
56
+ placeholder: 's3://my-bucket/larkup/my-server',
57
+ help: 'A dedicated, private bucket prefix for LanceDB table files. This is persistent across Vercel invocations.',
58
+ showWhen: { key: 'mode', equals: ['s3'] },
58
59
  },
59
60
  {
60
- key: "apiKey",
61
- label: "API key",
62
- type: "password",
61
+ key: 's3Endpoint',
62
+ label: 'S3 endpoint',
63
+ type: 'text',
64
+ required: false,
65
+ placeholder: 'https://<account-id>.r2.cloudflarestorage.com',
66
+ help: 'Required for Cloudflare R2 and other S3-compatible providers. Leave blank for AWS S3.',
67
+ showWhen: { key: 'mode', equals: ['s3'] },
68
+ },
69
+ {
70
+ key: 's3Region',
71
+ label: 'Region',
72
+ type: 'text',
73
+ required: true,
74
+ defaultValue: 'auto',
75
+ placeholder: 'auto',
76
+ help: 'Use “auto” for Cloudflare R2, or your bucket region for AWS S3.',
77
+ showWhen: { key: 'mode', equals: ['s3'] },
78
+ },
79
+ {
80
+ key: 's3AccessKeyId',
81
+ label: 'Access key ID',
82
+ type: 'password',
83
+ required: true,
84
+ secret: true,
85
+ help: 'Use an object read/write credential restricted to this bucket.',
86
+ showWhen: { key: 'mode', equals: ['s3'] },
87
+ },
88
+ {
89
+ key: 's3SecretAccessKey',
90
+ label: 'Secret access key',
91
+ type: 'password',
63
92
  required: true,
64
93
  secret: true,
65
- placeholder: "sk_...",
66
- help: "LanceDB Cloud API key. Stored as an env var in the generated server.",
67
- showWhen: { key: "mode", equals: ["cloud"] },
94
+ help: 'Stored as a deployment environment variable; never expose it in the browser.',
95
+ showWhen: { key: 'mode', equals: ['s3'] },
68
96
  },
69
97
  {
70
- key: "tableName",
71
- label: "Table name",
72
- type: "text",
98
+ key: 'uri',
99
+ label: 'Cloud URI',
100
+ type: 'text',
73
101
  required: true,
74
- defaultValue: "documents",
75
- help: "The table that holds your embedded chunks.",
102
+ placeholder: 'db://my-database',
103
+ help: 'Your LanceDB Cloud database URI.',
104
+ showWhen: { key: 'mode', equals: ['cloud'] },
105
+ },
106
+ {
107
+ key: 'apiKey',
108
+ label: 'API key',
109
+ type: 'password',
110
+ required: true,
111
+ secret: true,
112
+ placeholder: 'sk_...',
113
+ help: 'LanceDB Cloud API key. Stored as an env var in the generated server.',
114
+ showWhen: { key: 'mode', equals: ['cloud'] },
115
+ },
116
+ {
117
+ key: 'tableName',
118
+ label: 'Table name',
119
+ type: 'text',
120
+ required: true,
121
+ defaultValue: 'documents',
122
+ help: 'The table that holds your embedded chunks.',
76
123
  },
77
124
  ],
78
125
  },
79
126
 
80
127
  pinecone: {
81
- id: "pinecone",
82
- label: "Pinecone",
128
+ id: 'pinecone',
129
+ label: 'Pinecone',
83
130
  description:
84
- "Fully-managed cloud vector database. Cloud-only — requires an API key and an existing index.",
85
- runtime: "cloud",
86
- installStatus: "installed",
87
- docsUrl: "https://docs.pinecone.io/",
131
+ 'Fully-managed cloud vector database. Cloud-only — requires an API key and an existing index.',
132
+ runtime: 'cloud',
133
+ installStatus: 'installed',
134
+ docsUrl: 'https://docs.pinecone.io/',
88
135
  serverDependencies: {
89
- "@pinecone-database/pinecone": "^6.0.0",
136
+ '@pinecone-database/pinecone': '^6.0.0',
90
137
  },
91
138
  fields: [
92
139
  {
93
- key: "apiKey",
94
- label: "API key",
95
- type: "password",
140
+ key: 'apiKey',
141
+ label: 'API key',
142
+ type: 'password',
96
143
  required: true,
97
144
  secret: true,
98
- placeholder: "pcsk_...",
99
- help: "Pinecone API key. Stored as an env var in the generated server.",
145
+ placeholder: 'pcsk_...',
146
+ help: 'Pinecone API key. Stored as an env var in the generated server.',
100
147
  },
101
148
  {
102
- key: "indexName",
103
- label: "Index name",
104
- type: "text",
149
+ key: 'indexName',
150
+ label: 'Index name',
151
+ type: 'text',
105
152
  required: true,
106
- placeholder: "rag-index",
153
+ placeholder: 'rag-index',
107
154
  help: "Name of the Pinecone index to upsert into / query. For hybrid/lexical mode this index must use the 'dotproduct' metric.",
108
155
  },
109
156
  {
110
- key: "namespace",
111
- label: "Namespace",
112
- type: "text",
157
+ key: 'namespace',
158
+ label: 'Namespace',
159
+ type: 'text',
113
160
  required: false,
114
- placeholder: "default",
115
- help: "Optional namespace to isolate this dataset within the index.",
161
+ placeholder: 'default',
162
+ help: 'Optional namespace to isolate this dataset within the index.',
116
163
  },
117
164
  {
118
- key: "sparseModel",
119
- label: "Sparse model",
120
- type: "text",
165
+ key: 'sparseModel',
166
+ label: 'Sparse model',
167
+ type: 'text',
121
168
  required: true,
122
- defaultValue: "pinecone-sparse-english-v0",
123
- help: "Pinecone-hosted sparse model used to generate keyword vectors via the Inference API. Both dense and sparse vectors are stored in the same index.",
124
- showWhenIndexType: ["lexical", "hybrid"],
169
+ defaultValue: 'pinecone-sparse-english-v0',
170
+ help: 'Pinecone-hosted sparse model used to generate keyword vectors via the Inference API. Both dense and sparse vectors are stored in the same index.',
171
+ showWhenIndexType: ['lexical', 'hybrid'],
125
172
  },
126
173
  ],
127
174
  },
128
175
 
129
176
  weaviate: {
130
- id: "weaviate",
131
- label: "Weaviate",
177
+ id: 'weaviate',
178
+ label: 'Weaviate',
132
179
  description:
133
- "Open-source AI-native vector database with built-in hybrid search, BM25, and multi-tenancy.",
134
- runtime: "both",
135
- installStatus: "coming-soon",
136
- docsUrl: "https://weaviate.io/developers/weaviate",
180
+ 'Open-source AI-native vector database with built-in hybrid search, BM25, and multi-tenancy.',
181
+ runtime: 'both',
182
+ installStatus: 'coming-soon',
183
+ docsUrl: 'https://weaviate.io/developers/weaviate',
137
184
  serverDependencies: {
138
- weaviate: "^3.0.0",
185
+ weaviate: '^3.0.0',
139
186
  },
140
187
  fields: [
141
188
  {
142
- key: "host",
143
- label: "Host URL",
144
- type: "text",
189
+ key: 'host',
190
+ label: 'Host URL',
191
+ type: 'text',
145
192
  required: true,
146
- placeholder: "https://my-cluster.weaviate.network",
147
- help: "Weaviate Cloud URL or self-hosted host address.",
193
+ placeholder: 'https://my-cluster.weaviate.network',
194
+ help: 'Weaviate Cloud URL or self-hosted host address.',
148
195
  },
149
196
  {
150
- key: "apiKey",
151
- label: "API key",
152
- type: "password",
197
+ key: 'apiKey',
198
+ label: 'API key',
199
+ type: 'password',
153
200
  required: false,
154
201
  secret: true,
155
- placeholder: "weaviate-api-key",
156
- help: "Weaviate Cloud API key (optional for self-hosted).",
202
+ placeholder: 'weaviate-api-key',
203
+ help: 'Weaviate Cloud API key (optional for self-hosted).',
157
204
  },
158
205
  {
159
- key: "className",
160
- label: "Collection name",
161
- type: "text",
206
+ key: 'className',
207
+ label: 'Collection name',
208
+ type: 'text',
162
209
  required: true,
163
- defaultValue: "Documents",
164
- help: "The Weaviate collection (class) that holds your embedded chunks.",
210
+ defaultValue: 'Documents',
211
+ help: 'The Weaviate collection (class) that holds your embedded chunks.',
165
212
  },
166
213
  ],
167
214
  },
168
215
 
169
216
  qdrant: {
170
- id: "qdrant",
171
- label: "Qdrant",
217
+ id: 'qdrant',
218
+ label: 'Qdrant',
172
219
  description:
173
- "High-performance vector search engine with rich filtering, built for production-scale RAG.",
174
- runtime: "both",
175
- installStatus: "coming-soon",
176
- docsUrl: "https://qdrant.tech/documentation/",
220
+ 'High-performance vector search engine with rich filtering, built for production-scale RAG.',
221
+ runtime: 'both',
222
+ installStatus: 'coming-soon',
223
+ docsUrl: 'https://qdrant.tech/documentation/',
177
224
  serverDependencies: {
178
- "@qdrant/js-client-rest": "^1.9.0",
225
+ '@qdrant/js-client-rest': '^1.9.0',
179
226
  },
180
227
  fields: [
181
228
  {
182
- key: "url",
183
- label: "Host URL",
184
- type: "text",
229
+ key: 'url',
230
+ label: 'Host URL',
231
+ type: 'text',
185
232
  required: true,
186
- placeholder: "http://localhost:6333",
187
- help: "Qdrant server URL (local or Qdrant Cloud endpoint).",
233
+ placeholder: 'http://localhost:6333',
234
+ help: 'Qdrant server URL (local or Qdrant Cloud endpoint).',
188
235
  },
189
236
  {
190
- key: "apiKey",
191
- label: "API key",
192
- type: "password",
237
+ key: 'apiKey',
238
+ label: 'API key',
239
+ type: 'password',
193
240
  required: false,
194
241
  secret: true,
195
- placeholder: "qdrant-api-key",
196
- help: "Qdrant Cloud API key (leave blank for local).",
242
+ placeholder: 'qdrant-api-key',
243
+ help: 'Qdrant Cloud API key (leave blank for local).',
197
244
  },
198
245
  {
199
- key: "collectionName",
200
- label: "Collection name",
201
- type: "text",
246
+ key: 'collectionName',
247
+ label: 'Collection name',
248
+ type: 'text',
202
249
  required: true,
203
- defaultValue: "documents",
204
- help: "Qdrant collection to upsert into and query.",
250
+ defaultValue: 'documents',
251
+ help: 'Qdrant collection to upsert into and query.',
205
252
  },
206
253
  ],
207
254
  },
208
255
 
209
256
  chroma: {
210
- id: "chroma",
211
- label: "Chroma",
257
+ id: 'chroma',
258
+ label: 'Chroma',
212
259
  description:
213
- "Open-source, developer-friendly embedding database. Great for rapid local prototyping.",
214
- runtime: "both",
215
- installStatus: "installable",
216
- docsUrl: "https://docs.trychroma.com/",
260
+ 'Open-source, developer-friendly embedding database. Great for rapid local prototyping.',
261
+ runtime: 'both',
262
+ installStatus: 'installable',
263
+ docsUrl: 'https://docs.trychroma.com/',
217
264
  serverDependencies: {
218
- chromadb: "^1.9.0",
265
+ chromadb: '^1.9.0',
219
266
  },
220
267
  fields: [
221
268
  {
222
- key: "mode",
223
- label: "Mode",
224
- type: "select",
269
+ key: 'mode',
270
+ label: 'Mode',
271
+ type: 'select',
225
272
  required: true,
226
- defaultValue: "server",
227
- help: "Server connects to a self-hosted Chroma instance. Cloud connects to Chroma Cloud.",
273
+ defaultValue: 'server',
274
+ help: 'Server connects to a self-hosted Chroma instance. Cloud connects to Chroma Cloud.',
228
275
  options: [
229
- { label: "Server (Self-hosted)", value: "server" },
230
- { label: "Cloud (Chroma Cloud)", value: "cloud" },
276
+ { label: 'Server (Self-hosted)', value: 'server' },
277
+ { label: 'Cloud (Chroma Cloud)', value: 'cloud' },
231
278
  ],
232
279
  },
233
280
  {
234
- key: "host",
235
- label: "Server URL",
236
- type: "text",
281
+ key: 'host',
282
+ label: 'Server URL',
283
+ type: 'text',
237
284
  required: true,
238
- placeholder: "http://localhost:8000",
239
- defaultValue: "http://localhost:8000",
240
- help: "Chroma server URL (local Docker or remote).",
241
- showWhen: { key: "mode", equals: ["server"] },
285
+ placeholder: 'http://localhost:8000',
286
+ defaultValue: 'http://localhost:8000',
287
+ help: 'Chroma server URL (local Docker or remote).',
288
+ showWhen: { key: 'mode', equals: ['server'] },
242
289
  },
243
290
  {
244
- key: "authToken",
245
- label: "Auth Token",
246
- type: "password",
291
+ key: 'authToken',
292
+ label: 'Auth Token',
293
+ type: 'password',
247
294
  required: false,
248
295
  secret: true,
249
- placeholder: "chroma-token",
250
- help: "Optional static auth token for Chroma server.",
251
- showWhen: { key: "mode", equals: ["server"] },
296
+ placeholder: 'chroma-token',
297
+ help: 'Optional static auth token for Chroma server.',
298
+ showWhen: { key: 'mode', equals: ['server'] },
252
299
  },
253
300
  {
254
- key: "apiKey",
255
- label: "API Key",
256
- type: "password",
301
+ key: 'apiKey',
302
+ label: 'API Key',
303
+ type: 'password',
257
304
  required: true,
258
305
  secret: true,
259
- placeholder: "sk_...",
260
- help: "Chroma Cloud API Key.",
261
- showWhen: { key: "mode", equals: ["cloud"] },
306
+ placeholder: 'sk_...',
307
+ help: 'Chroma Cloud API Key.',
308
+ showWhen: { key: 'mode', equals: ['cloud'] },
262
309
  },
263
310
  {
264
- key: "tenant",
265
- label: "Tenant",
266
- type: "text",
311
+ key: 'tenant',
312
+ label: 'Tenant',
313
+ type: 'text',
267
314
  required: true,
268
- defaultValue: "default_tenant",
269
- help: "Tenant name for Chroma Cloud.",
270
- showWhen: { key: "mode", equals: ["cloud"] },
315
+ defaultValue: 'default_tenant',
316
+ help: 'Tenant name for Chroma Cloud.',
317
+ showWhen: { key: 'mode', equals: ['cloud'] },
271
318
  },
272
319
  {
273
- key: "database",
274
- label: "Database",
275
- type: "text",
320
+ key: 'database',
321
+ label: 'Database',
322
+ type: 'text',
276
323
  required: true,
277
- defaultValue: "default_database",
278
- help: "Database name for Chroma Cloud.",
279
- showWhen: { key: "mode", equals: ["cloud"] },
324
+ defaultValue: 'default_database',
325
+ help: 'Database name for Chroma Cloud.',
326
+ showWhen: { key: 'mode', equals: ['cloud'] },
280
327
  },
281
328
  {
282
- key: "collectionName",
283
- label: "Collection name",
284
- type: "text",
329
+ key: 'collectionName',
330
+ label: 'Collection name',
331
+ type: 'text',
285
332
  required: true,
286
- defaultValue: "documents",
287
- help: "Chroma collection to store and retrieve embeddings.",
333
+ defaultValue: 'documents',
334
+ help: 'Chroma collection to store and retrieve embeddings.',
288
335
  },
289
336
  ],
290
337
  },
291
338
 
292
339
  pgvector: {
293
- id: "pgvector",
294
- label: "pgvector",
340
+ id: 'pgvector',
341
+ label: 'pgvector',
295
342
  description:
296
- "PostgreSQL extension for vector similarity search. Self-host vectors alongside your relational data.",
297
- runtime: "both",
298
- installStatus: "coming-soon",
299
- docsUrl: "https://github.com/pgvector/pgvector",
343
+ 'PostgreSQL extension for vector similarity search. Self-host vectors alongside your relational data.',
344
+ runtime: 'both',
345
+ installStatus: 'coming-soon',
346
+ docsUrl: 'https://github.com/pgvector/pgvector',
300
347
  serverDependencies: {
301
- pg: "^8.11.0",
302
- pgvector: "^0.2.0",
348
+ pg: '^8.11.0',
349
+ pgvector: '^0.2.0',
303
350
  },
304
351
  fields: [
305
352
  {
306
- key: "connectionString",
307
- label: "Connection string",
308
- type: "password",
353
+ key: 'connectionString',
354
+ label: 'Connection string',
355
+ type: 'password',
309
356
  required: true,
310
357
  secret: true,
311
- placeholder: "postgresql://user:pass@localhost:5432/db",
312
- help: "Full PostgreSQL connection string.",
358
+ placeholder: 'postgresql://user:pass@localhost:5432/db',
359
+ help: 'Full PostgreSQL connection string.',
313
360
  },
314
361
  {
315
- key: "tableName",
316
- label: "Table name",
317
- type: "text",
362
+ key: 'tableName',
363
+ label: 'Table name',
364
+ type: 'text',
318
365
  required: true,
319
- defaultValue: "embeddings",
320
- help: "The table used to store vector embeddings. Created automatically if absent.",
366
+ defaultValue: 'embeddings',
367
+ help: 'The table used to store vector embeddings. Created automatically if absent.',
321
368
  },
322
369
  ],
323
370
  },
324
371
 
325
372
  supabase: {
326
- id: "supabase",
327
- label: "Supabase",
373
+ id: 'supabase',
374
+ label: 'Supabase',
328
375
  description:
329
376
  "Postgres-backed vector store via the pgvector extension with Supabase's managed infrastructure.",
330
- runtime: "cloud",
331
- installStatus: "coming-soon",
332
- docsUrl: "https://supabase.com/docs/guides/ai",
377
+ runtime: 'cloud',
378
+ installStatus: 'coming-soon',
379
+ docsUrl: 'https://supabase.com/docs/guides/ai',
333
380
  serverDependencies: {
334
- "@supabase/supabase-js": "^2.43.0",
381
+ '@supabase/supabase-js': '^2.43.0',
335
382
  },
336
383
  fields: [
337
384
  {
338
- key: "url",
339
- label: "Project URL",
340
- type: "text",
385
+ key: 'url',
386
+ label: 'Project URL',
387
+ type: 'text',
341
388
  required: true,
342
- placeholder: "https://xyz.supabase.co",
343
- help: "Your Supabase project URL.",
389
+ placeholder: 'https://xyz.supabase.co',
390
+ help: 'Your Supabase project URL.',
344
391
  },
345
392
  {
346
- key: "serviceKey",
347
- label: "Service role key",
348
- type: "password",
393
+ key: 'serviceKey',
394
+ label: 'Service role key',
395
+ type: 'password',
349
396
  required: true,
350
397
  secret: true,
351
- placeholder: "eyJhbGci...",
352
- help: "Supabase service_role key (not the anon key). Stored as an env var.",
398
+ placeholder: 'eyJhbGci...',
399
+ help: 'Supabase service_role key (not the anon key). Stored as an env var.',
353
400
  },
354
401
  {
355
- key: "tableName",
356
- label: "Table name",
357
- type: "text",
402
+ key: 'tableName',
403
+ label: 'Table name',
404
+ type: 'text',
358
405
  required: true,
359
- defaultValue: "documents",
360
- help: "Supabase table with a vector column for embeddings.",
406
+ defaultValue: 'documents',
407
+ help: 'Supabase table with a vector column for embeddings.',
361
408
  },
362
409
  ],
363
410
  },
364
- }
411
+ };
365
412
 
366
- export const VECTOR_STORE_LIST: VectorStoreDescriptor[] =
367
- Object.values(VECTOR_STORES)
413
+ export const VECTOR_STORE_LIST: VectorStoreDescriptor[] = Object.values(VECTOR_STORES);
368
414
 
369
415
  export function getVectorStore(id: VectorStoreId): VectorStoreDescriptor {
370
- return VECTOR_STORES[id]
416
+ return VECTOR_STORES[id];
371
417
  }
372
418
 
373
419
  /**
@@ -380,19 +426,19 @@ export function visibleFields(
380
426
  store: VectorStoreDescriptor,
381
427
  values: Record<string, string>,
382
428
  indexType?: IndexType,
383
- ): import("@larkup/core/types").StoreField[] {
429
+ ): import('@larkup/core/types').StoreField[] {
384
430
  return store.fields.filter((field) => {
385
431
  // Sibling-field dependency (e.g. LanceDB mode → local/cloud fields)
386
432
  if (field.showWhen) {
387
- const current = values[field.showWhen.key] ?? ""
388
- if (!field.showWhen.equals.includes(current)) return false
433
+ const current = values[field.showWhen.key] ?? '';
434
+ if (!field.showWhen.equals.includes(current)) return false;
389
435
  }
390
436
  // Cross-concern dependency (e.g. indexType → sparse model)
391
437
  if (field.showWhenIndexType && indexType) {
392
- if (!field.showWhenIndexType.includes(indexType)) return false
438
+ if (!field.showWhenIndexType.includes(indexType)) return false;
393
439
  }
394
- return true
395
- })
440
+ return true;
441
+ });
396
442
  }
397
443
 
398
444
  /**
@@ -404,11 +450,11 @@ export function validateStoreConfig(
404
450
  values: Record<string, string>,
405
451
  indexType?: IndexType,
406
452
  ): Record<string, string> {
407
- const errors: Record<string, string> = {}
453
+ const errors: Record<string, string> = {};
408
454
  for (const field of visibleFields(store, values, indexType)) {
409
455
  if (field.required && !values[field.key]?.trim()) {
410
- errors[field.key] = `${field.label} is required`
456
+ errors[field.key] = `${field.label} is required`;
411
457
  }
412
458
  }
413
- return errors
459
+ return errors;
414
460
  }