-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsearch-engine.zod.ts
More file actions
64 lines (53 loc) · 3.48 KB
/
search-engine.zod.ts
File metadata and controls
64 lines (53 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { z } from 'zod';
/**
* Full-text search protocol
* Supports Elasticsearch, Algolia, Meilisearch, Typesense
*/
export const SearchProviderSchema = z.enum([
'elasticsearch',
'algolia',
'meilisearch',
'typesense',
'opensearch',
]).describe('Supported full-text search engine provider');
export type SearchProvider = z.infer<typeof SearchProviderSchema>;
export const AnalyzerConfigSchema = z.object({
type: z.enum(['standard', 'simple', 'whitespace', 'keyword', 'pattern', 'language']).describe('Text analyzer type'),
language: z.string().optional().describe('Language for language-specific analysis'),
stopwords: z.array(z.string()).optional().describe('Custom stopwords to filter during analysis'),
customFilters: z.array(z.string()).optional().describe('Additional token filter names to apply'),
}).describe('Text analyzer configuration for index tokenization and normalization');
export type AnalyzerConfig = z.infer<typeof AnalyzerConfigSchema>;
export const SearchIndexConfigSchema = z.object({
indexName: z.string().describe('Name of the search index'),
objectName: z.string().describe('Source ObjectQL object'),
fields: z.array(z.object({
name: z.string().describe('Field name to index'),
type: z.enum(['text', 'keyword', 'number', 'date', 'boolean', 'geo']).describe('Index field data type'),
analyzer: z.string().optional().describe('Named analyzer to use for this field'),
searchable: z.boolean().default(true).describe('Include field in full-text search'),
filterable: z.boolean().default(false).describe('Allow filtering on this field'),
sortable: z.boolean().default(false).describe('Allow sorting by this field'),
boost: z.number().default(1).describe('Relevance boost factor for this field'),
})).describe('Fields to include in the search index'),
replicas: z.number().default(1).describe('Number of index replicas for availability'),
shards: z.number().default(1).describe('Number of index shards for distribution'),
}).describe('Search index definition mapping an ObjectQL object to a search engine index');
export type SearchIndexConfig = z.infer<typeof SearchIndexConfigSchema>;
export const FacetConfigSchema = z.object({
field: z.string().describe('Field name to generate facets from'),
maxValues: z.number().default(10).describe('Maximum number of facet values to return'),
sort: z.enum(['count', 'alpha']).default('count').describe('Facet value sort order'),
}).describe('Faceted search configuration for a single field');
export type FacetConfig = z.infer<typeof FacetConfigSchema>;
export const SearchConfigSchema = z.object({
provider: SearchProviderSchema.describe('Search engine backend provider'),
indexes: z.array(SearchIndexConfigSchema).describe('Search index definitions'),
analyzers: z.record(z.string(), AnalyzerConfigSchema).optional().describe('Named text analyzer configurations'),
facets: z.array(FacetConfigSchema).optional().describe('Faceted search configurations'),
typoTolerance: z.boolean().default(true).describe('Enable typo-tolerant search'),
synonyms: z.record(z.string(), z.array(z.string())).optional().describe('Synonym mappings for search expansion'),
ranking: z.array(z.enum(['typo', 'geo', 'words', 'filters', 'proximity', 'attribute', 'exact', 'custom'])).optional().describe('Custom ranking rule order'),
}).describe('Top-level full-text search engine configuration');
export type SearchConfig = z.infer<typeof SearchConfigSchema>;