@rubixstudios/payload-typesense 1.0.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/LICENSE +22 -0
- package/README.md +182 -0
- package/dist/components/HeadlessSearchInput.d.ts +86 -0
- package/dist/components/HeadlessSearchInput.d.ts.map +1 -0
- package/dist/components/HeadlessSearchInput.js +602 -0
- package/dist/components/ThemeProvider.d.ts +10 -0
- package/dist/components/ThemeProvider.d.ts.map +1 -0
- package/dist/components/ThemeProvider.js +17 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +3 -0
- package/dist/components/themes/hooks.d.ts +52 -0
- package/dist/components/themes/hooks.d.ts.map +1 -0
- package/dist/components/themes/hooks.js +177 -0
- package/dist/components/themes/index.d.ts +5 -0
- package/dist/components/themes/index.d.ts.map +1 -0
- package/dist/components/themes/index.js +4 -0
- package/dist/components/themes/themes.d.ts +6 -0
- package/dist/components/themes/themes.d.ts.map +1 -0
- package/dist/components/themes/themes.js +156 -0
- package/dist/components/themes/types.d.ts +147 -0
- package/dist/components/themes/types.d.ts.map +1 -0
- package/dist/components/themes/types.js +1 -0
- package/dist/components/themes/utils.d.ts +30 -0
- package/dist/components/themes/utils.d.ts.map +1 -0
- package/dist/components/themes/utils.js +397 -0
- package/dist/endpoints/customEndpointHandler.d.ts +3 -0
- package/dist/endpoints/customEndpointHandler.d.ts.map +1 -0
- package/dist/endpoints/customEndpointHandler.js +5 -0
- package/dist/endpoints/health.d.ts +12 -0
- package/dist/endpoints/health.d.ts.map +1 -0
- package/dist/endpoints/health.js +174 -0
- package/dist/endpoints/search.d.ts +13 -0
- package/dist/endpoints/search.d.ts.map +1 -0
- package/dist/endpoints/search.js +375 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +148 -0
- package/dist/lib/cache.d.ts +41 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/dist/lib/cache.js +96 -0
- package/dist/lib/config-validation.d.ts +75 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +174 -0
- package/dist/lib/hooks.d.ts +4 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +54 -0
- package/dist/lib/initialization.d.ts +5 -0
- package/dist/lib/initialization.d.ts.map +1 -0
- package/dist/lib/initialization.js +102 -0
- package/dist/lib/schema-mapper.d.ts +14 -0
- package/dist/lib/schema-mapper.d.ts.map +1 -0
- package/dist/lib/schema-mapper.js +137 -0
- package/dist/lib/types.d.ts +183 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/typesense-client.d.ts +5 -0
- package/dist/lib/typesense-client.d.ts.map +1 -0
- package/dist/lib/typesense-client.js +20 -0
- package/package.json +92 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { defaultTheme, themes } from './themes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get a theme by name or return the default theme
|
|
4
|
+
*/ export function getTheme(themeName) {
|
|
5
|
+
return themes[themeName] || defaultTheme;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Merge theme configurations with custom overrides
|
|
9
|
+
*/ export function mergeThemeConfig(config) {
|
|
10
|
+
const baseTheme = typeof config.theme === 'string' ? getTheme(config.theme) : config.theme;
|
|
11
|
+
return {
|
|
12
|
+
...baseTheme,
|
|
13
|
+
animations: {
|
|
14
|
+
...baseTheme.animations,
|
|
15
|
+
...config.animations
|
|
16
|
+
},
|
|
17
|
+
colors: {
|
|
18
|
+
...baseTheme.colors,
|
|
19
|
+
...config.colors
|
|
20
|
+
},
|
|
21
|
+
shadows: {
|
|
22
|
+
...baseTheme.shadows,
|
|
23
|
+
...config.shadows
|
|
24
|
+
},
|
|
25
|
+
spacing: {
|
|
26
|
+
...baseTheme.spacing,
|
|
27
|
+
...config.spacing
|
|
28
|
+
},
|
|
29
|
+
typography: {
|
|
30
|
+
...baseTheme.typography,
|
|
31
|
+
...config.typography
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generate CSS classes from theme configuration
|
|
37
|
+
*/ export function generateThemeClasses(theme, config = {}) {
|
|
38
|
+
const enableAnimations = config.enableAnimations !== false;
|
|
39
|
+
const enableShadows = config.enableShadows !== false;
|
|
40
|
+
const enableRoundedCorners = config.enableRoundedCorners !== false;
|
|
41
|
+
// Helper function to create CSS string
|
|
42
|
+
const css = (styles)=>{
|
|
43
|
+
return Object.entries(styles).map(([key, value])=>{
|
|
44
|
+
if (typeof value === 'object' && value !== null) {
|
|
45
|
+
// Handle nested objects like ':hover', '::placeholder'
|
|
46
|
+
const nested = Object.entries(value).map(([nestedKey, nestedValue])=>`${nestedKey.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${nestedValue}`).join('; ');
|
|
47
|
+
return `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: { ${nested} }`;
|
|
48
|
+
}
|
|
49
|
+
return `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value}`;
|
|
50
|
+
}).join('; ');
|
|
51
|
+
};
|
|
52
|
+
// Container styles
|
|
53
|
+
const containerStyles = css({
|
|
54
|
+
margin: '0 auto',
|
|
55
|
+
maxWidth: '600px',
|
|
56
|
+
position: 'relative',
|
|
57
|
+
width: '100%'
|
|
58
|
+
});
|
|
59
|
+
const inputContainerStyles = css({
|
|
60
|
+
position: 'relative',
|
|
61
|
+
width: '100%'
|
|
62
|
+
});
|
|
63
|
+
const resultsContainerStyles = css({
|
|
64
|
+
backgroundColor: theme.colors.resultsBackground,
|
|
65
|
+
border: `1px solid ${theme.colors.resultsBorder}`,
|
|
66
|
+
borderRadius: enableRoundedCorners ? theme.spacing.resultsBorderRadius : '0',
|
|
67
|
+
boxShadow: enableShadows ? theme.shadows.shadowLg : 'none',
|
|
68
|
+
left: '0',
|
|
69
|
+
marginTop: '4px',
|
|
70
|
+
maxHeight: theme.spacing.resultsMaxHeight,
|
|
71
|
+
overflowY: 'auto',
|
|
72
|
+
position: 'absolute',
|
|
73
|
+
right: '0',
|
|
74
|
+
top: '100%',
|
|
75
|
+
zIndex: '1000',
|
|
76
|
+
...enableAnimations && {
|
|
77
|
+
animation: 'slideDown 0.2s ease-out'
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// Input styles
|
|
81
|
+
const inputStyles = css({
|
|
82
|
+
'::placeholder': {
|
|
83
|
+
color: theme.colors.inputPlaceholder
|
|
84
|
+
},
|
|
85
|
+
':disabled': {
|
|
86
|
+
backgroundColor: theme.colors.inputBackground,
|
|
87
|
+
cursor: 'not-allowed',
|
|
88
|
+
opacity: '0.6'
|
|
89
|
+
},
|
|
90
|
+
':focus': {
|
|
91
|
+
borderColor: theme.colors.inputBorderFocus,
|
|
92
|
+
boxShadow: enableShadows ? `${theme.shadows.focusShadow} ${theme.shadows.focusShadowColor}` : 'none'
|
|
93
|
+
},
|
|
94
|
+
backgroundColor: theme.colors.inputBackground,
|
|
95
|
+
border: `2px solid ${theme.colors.inputBorder}`,
|
|
96
|
+
borderRadius: enableRoundedCorners ? theme.spacing.inputBorderRadius : '0',
|
|
97
|
+
boxShadow: 'none',
|
|
98
|
+
color: theme.colors.inputText,
|
|
99
|
+
fontFamily: theme.typography.fontFamily,
|
|
100
|
+
fontSize: theme.spacing.inputFontSize,
|
|
101
|
+
fontWeight: theme.typography.fontWeightNormal,
|
|
102
|
+
lineHeight: theme.typography.lineHeightNormal,
|
|
103
|
+
outline: 'none',
|
|
104
|
+
padding: theme.spacing.inputPadding,
|
|
105
|
+
transition: enableAnimations ? `all ${theme.animations.transitionNormal} ${theme.animations.easeInOut}` : 'none',
|
|
106
|
+
width: '100%'
|
|
107
|
+
});
|
|
108
|
+
// Results styles
|
|
109
|
+
const resultsStyles = css({
|
|
110
|
+
backgroundColor: theme.colors.resultsBackground,
|
|
111
|
+
border: `1px solid ${theme.colors.resultsBorder}`,
|
|
112
|
+
borderRadius: enableRoundedCorners ? theme.spacing.resultsBorderRadius : '0',
|
|
113
|
+
boxShadow: enableShadows ? theme.shadows.shadowLg : 'none',
|
|
114
|
+
left: '0',
|
|
115
|
+
maxHeight: theme.spacing.resultsMaxHeight,
|
|
116
|
+
overflowY: 'auto',
|
|
117
|
+
position: 'absolute',
|
|
118
|
+
right: '0',
|
|
119
|
+
top: '100%',
|
|
120
|
+
zIndex: '1000'
|
|
121
|
+
});
|
|
122
|
+
const resultsHeaderStyles = css({
|
|
123
|
+
alignItems: 'center',
|
|
124
|
+
backgroundColor: theme.colors.headerBackground,
|
|
125
|
+
borderBottom: `1px solid ${theme.colors.headerBorder}`,
|
|
126
|
+
color: theme.colors.headerText,
|
|
127
|
+
display: 'flex',
|
|
128
|
+
fontFamily: theme.typography.fontFamily,
|
|
129
|
+
fontSize: theme.spacing.headerFontSize,
|
|
130
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
131
|
+
justifyContent: 'space-between',
|
|
132
|
+
padding: theme.spacing.headerPadding
|
|
133
|
+
});
|
|
134
|
+
const resultsListStyles = css({
|
|
135
|
+
padding: '8px 0'
|
|
136
|
+
});
|
|
137
|
+
// Result item styles
|
|
138
|
+
const resultItemStyles = css({
|
|
139
|
+
':focus': {
|
|
140
|
+
backgroundColor: theme.colors.resultBackgroundFocus,
|
|
141
|
+
boxShadow: enableShadows ? `inset 0 0 0 2px ${theme.colors.inputBorderFocus}` : 'none'
|
|
142
|
+
},
|
|
143
|
+
':hover': {
|
|
144
|
+
backgroundColor: theme.colors.resultBackgroundHover,
|
|
145
|
+
transform: enableAnimations ? 'translateX(2px)' : 'none'
|
|
146
|
+
},
|
|
147
|
+
':last-child': {
|
|
148
|
+
borderBottom: 'none'
|
|
149
|
+
},
|
|
150
|
+
backgroundColor: theme.colors.resultBackground,
|
|
151
|
+
borderBottom: `1px solid ${theme.colors.resultBorder}`,
|
|
152
|
+
cursor: 'pointer',
|
|
153
|
+
outline: 'none',
|
|
154
|
+
padding: theme.spacing.itemPadding,
|
|
155
|
+
transition: enableAnimations ? `all ${theme.animations.transitionFast} ${theme.animations.easeInOut}` : 'none'
|
|
156
|
+
});
|
|
157
|
+
// Content styles
|
|
158
|
+
const resultTitleStyles = css({
|
|
159
|
+
color: theme.colors.titleText,
|
|
160
|
+
fontFamily: theme.typography.fontFamily,
|
|
161
|
+
fontSize: theme.typography.fontSizeLg,
|
|
162
|
+
fontWeight: theme.typography.fontWeightSemibold,
|
|
163
|
+
lineHeight: theme.typography.lineHeightTight,
|
|
164
|
+
marginBottom: '8px'
|
|
165
|
+
});
|
|
166
|
+
const resultDescriptionStyles = css({
|
|
167
|
+
color: theme.colors.descriptionText,
|
|
168
|
+
fontFamily: theme.typography.fontFamily,
|
|
169
|
+
fontSize: theme.typography.fontSizeSm,
|
|
170
|
+
lineHeight: theme.typography.lineHeightNormal,
|
|
171
|
+
marginBottom: '8px'
|
|
172
|
+
});
|
|
173
|
+
const resultHighlightStyles = css({
|
|
174
|
+
backgroundColor: theme.colors.highlightBackground,
|
|
175
|
+
borderRadius: enableRoundedCorners ? '6px' : '0',
|
|
176
|
+
color: theme.colors.descriptionText,
|
|
177
|
+
fontFamily: theme.typography.fontFamily,
|
|
178
|
+
fontSize: theme.typography.fontSizeSm,
|
|
179
|
+
lineHeight: theme.typography.lineHeightNormal,
|
|
180
|
+
marginBottom: '8px',
|
|
181
|
+
mark: {
|
|
182
|
+
backgroundColor: theme.colors.highlightBackground,
|
|
183
|
+
borderRadius: enableRoundedCorners ? '3px' : '0',
|
|
184
|
+
color: theme.colors.highlightText,
|
|
185
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
186
|
+
padding: '2px 4px'
|
|
187
|
+
},
|
|
188
|
+
padding: '8px 12px'
|
|
189
|
+
});
|
|
190
|
+
const resultMetaStyles = css({
|
|
191
|
+
alignItems: 'center',
|
|
192
|
+
color: theme.colors.metaText,
|
|
193
|
+
display: 'flex',
|
|
194
|
+
fontFamily: theme.typography.fontFamily,
|
|
195
|
+
fontSize: theme.typography.fontSizeXs,
|
|
196
|
+
justifyContent: 'space-between',
|
|
197
|
+
marginTop: '8px'
|
|
198
|
+
});
|
|
199
|
+
// Badge styles
|
|
200
|
+
const collectionBadgeStyles = css({
|
|
201
|
+
backgroundColor: theme.colors.collectionBadge,
|
|
202
|
+
borderRadius: enableRoundedCorners ? '12px' : '0',
|
|
203
|
+
color: theme.colors.collectionBadgeText,
|
|
204
|
+
display: 'inline-block',
|
|
205
|
+
fontFamily: theme.typography.fontFamily,
|
|
206
|
+
fontSize: theme.typography.fontSizeXs,
|
|
207
|
+
fontWeight: theme.typography.fontWeightSemibold,
|
|
208
|
+
letterSpacing: '0.5px',
|
|
209
|
+
padding: '4px 8px',
|
|
210
|
+
textTransform: 'uppercase'
|
|
211
|
+
});
|
|
212
|
+
const scoreBadgeStyles = css({
|
|
213
|
+
backgroundColor: theme.colors.scoreBadge,
|
|
214
|
+
borderRadius: enableRoundedCorners ? '4px' : '0',
|
|
215
|
+
color: theme.colors.scoreBadgeText,
|
|
216
|
+
display: 'inline-block',
|
|
217
|
+
fontFamily: theme.typography.fontFamily,
|
|
218
|
+
fontSize: theme.typography.fontSizeXs,
|
|
219
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
220
|
+
padding: '2px 6px'
|
|
221
|
+
});
|
|
222
|
+
// State styles
|
|
223
|
+
const loadingStyles = css({
|
|
224
|
+
alignItems: 'center',
|
|
225
|
+
color: theme.colors.loadingText,
|
|
226
|
+
display: 'flex',
|
|
227
|
+
fontFamily: theme.typography.fontFamily,
|
|
228
|
+
fontSize: theme.typography.fontSizeSm,
|
|
229
|
+
gap: '12px',
|
|
230
|
+
justifyContent: 'center',
|
|
231
|
+
padding: '24px'
|
|
232
|
+
});
|
|
233
|
+
const loadingSpinnerStyles = css({
|
|
234
|
+
animation: enableAnimations ? `spin 1s linear infinite` : 'none',
|
|
235
|
+
border: `2px solid ${theme.colors.inputBorder}`,
|
|
236
|
+
borderRadius: '50%',
|
|
237
|
+
borderTop: `2px solid ${theme.colors.inputBorderFocus}`,
|
|
238
|
+
height: '20px',
|
|
239
|
+
width: '20px'
|
|
240
|
+
});
|
|
241
|
+
const errorStyles = css({
|
|
242
|
+
alignItems: 'center',
|
|
243
|
+
backgroundColor: theme.colors.errorBackground,
|
|
244
|
+
borderBottom: `1px solid ${theme.colors.resultBorder}`,
|
|
245
|
+
color: theme.colors.errorText,
|
|
246
|
+
display: 'flex',
|
|
247
|
+
fontFamily: theme.typography.fontFamily,
|
|
248
|
+
fontSize: theme.typography.fontSizeSm,
|
|
249
|
+
gap: '8px',
|
|
250
|
+
padding: '16px'
|
|
251
|
+
});
|
|
252
|
+
const noResultsStyles = css({
|
|
253
|
+
color: theme.colors.noResultsText,
|
|
254
|
+
fontFamily: theme.typography.fontFamily,
|
|
255
|
+
fontSize: theme.typography.fontSizeSm,
|
|
256
|
+
padding: '40px 20px',
|
|
257
|
+
textAlign: 'center'
|
|
258
|
+
});
|
|
259
|
+
// Facet styles
|
|
260
|
+
const facetContainerStyles = css({
|
|
261
|
+
backgroundColor: theme.colors.headerBackground,
|
|
262
|
+
borderBottom: `1px solid ${theme.colors.headerBorder}`,
|
|
263
|
+
padding: '16px'
|
|
264
|
+
});
|
|
265
|
+
const facetItemStyles = css({
|
|
266
|
+
':hover': {
|
|
267
|
+
backgroundColor: theme.colors.facetActiveBackground,
|
|
268
|
+
borderColor: theme.colors.facetActiveBackground,
|
|
269
|
+
color: theme.colors.facetActiveText
|
|
270
|
+
},
|
|
271
|
+
backgroundColor: theme.colors.facetBackground,
|
|
272
|
+
border: `1px solid ${theme.colors.facetBorder}`,
|
|
273
|
+
borderRadius: enableRoundedCorners ? '16px' : '0',
|
|
274
|
+
color: theme.colors.facetText,
|
|
275
|
+
cursor: 'pointer',
|
|
276
|
+
display: 'inline-block',
|
|
277
|
+
fontFamily: theme.typography.fontFamily,
|
|
278
|
+
fontSize: theme.typography.fontSizeXs,
|
|
279
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
280
|
+
margin: '4px',
|
|
281
|
+
padding: '6px 12px',
|
|
282
|
+
transition: enableAnimations ? `all ${theme.animations.transitionFast} ${theme.animations.easeInOut}` : 'none'
|
|
283
|
+
});
|
|
284
|
+
const facetItemActiveStyles = css({
|
|
285
|
+
backgroundColor: theme.colors.facetActiveBackground,
|
|
286
|
+
borderColor: theme.colors.facetActiveBackground,
|
|
287
|
+
color: theme.colors.facetActiveText
|
|
288
|
+
});
|
|
289
|
+
// Utility styles
|
|
290
|
+
const hiddenStyles = css({
|
|
291
|
+
display: 'none'
|
|
292
|
+
});
|
|
293
|
+
const visibleStyles = css({
|
|
294
|
+
display: 'block'
|
|
295
|
+
});
|
|
296
|
+
const focusableStyles = css({
|
|
297
|
+
':focus': {
|
|
298
|
+
boxShadow: enableShadows ? `0 0 0 2px ${theme.colors.inputBorderFocus}` : 'none'
|
|
299
|
+
},
|
|
300
|
+
outline: 'none'
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
// Container classes
|
|
304
|
+
container: containerStyles,
|
|
305
|
+
inputContainer: inputContainerStyles,
|
|
306
|
+
resultsContainer: resultsContainerStyles,
|
|
307
|
+
// Input classes
|
|
308
|
+
input: inputStyles,
|
|
309
|
+
inputDisabled: '',
|
|
310
|
+
inputFocus: '',
|
|
311
|
+
// Results classes
|
|
312
|
+
results: resultsStyles,
|
|
313
|
+
resultsHeader: resultsHeaderStyles,
|
|
314
|
+
resultsList: resultsListStyles,
|
|
315
|
+
// Item classes
|
|
316
|
+
resultItem: resultItemStyles,
|
|
317
|
+
resultItemActive: '',
|
|
318
|
+
resultItemFocus: '',
|
|
319
|
+
resultItemHover: '',
|
|
320
|
+
// Content classes
|
|
321
|
+
resultDescription: resultDescriptionStyles,
|
|
322
|
+
resultHighlight: resultHighlightStyles,
|
|
323
|
+
resultMeta: resultMetaStyles,
|
|
324
|
+
resultTitle: resultTitleStyles,
|
|
325
|
+
// Badge classes
|
|
326
|
+
collectionBadge: collectionBadgeStyles,
|
|
327
|
+
scoreBadge: scoreBadgeStyles,
|
|
328
|
+
// State classes
|
|
329
|
+
error: errorStyles,
|
|
330
|
+
loading: loadingStyles,
|
|
331
|
+
loadingSpinner: loadingSpinnerStyles,
|
|
332
|
+
noResults: noResultsStyles,
|
|
333
|
+
// Facet classes
|
|
334
|
+
facetContainer: facetContainerStyles,
|
|
335
|
+
facetItem: facetItemStyles,
|
|
336
|
+
facetItemActive: facetItemActiveStyles,
|
|
337
|
+
// Utility classes
|
|
338
|
+
focusable: focusableStyles,
|
|
339
|
+
hidden: hiddenStyles,
|
|
340
|
+
visible: visibleStyles
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Apply theme to a CSS class with optional variant
|
|
345
|
+
*/ export function applyTheme(theme, element, variant) {
|
|
346
|
+
const classes = generateThemeClasses(theme);
|
|
347
|
+
if (variant) {
|
|
348
|
+
const variantKey = `${element}${variant.charAt(0).toUpperCase() + variant.slice(1)}`;
|
|
349
|
+
return `${classes[element] || ''} ${classes[variantKey] || ''}`;
|
|
350
|
+
}
|
|
351
|
+
return classes[element] || '';
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if theme is dark mode
|
|
355
|
+
*/ export function isDarkTheme(theme) {
|
|
356
|
+
return theme.name === 'dark' || theme.colors.inputBackground.includes('#1f') || theme.colors.inputBackground.includes('#0f');
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Check if theme is light mode
|
|
360
|
+
*/ export function isLightTheme(theme) {
|
|
361
|
+
return !isDarkTheme(theme);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Get theme-specific CSS variables
|
|
365
|
+
*/ export function getThemeVariables(theme) {
|
|
366
|
+
return {
|
|
367
|
+
'--search-collection-badge': theme.colors.collectionBadge,
|
|
368
|
+
'--search-collection-badge-text': theme.colors.collectionBadgeText,
|
|
369
|
+
'--search-description-text': theme.colors.descriptionText,
|
|
370
|
+
'--search-error-bg': theme.colors.errorBackground,
|
|
371
|
+
'--search-error-text': theme.colors.errorText,
|
|
372
|
+
'--search-facet-active-bg': theme.colors.facetActiveBackground,
|
|
373
|
+
'--search-facet-active-text': theme.colors.facetActiveText,
|
|
374
|
+
'--search-facet-bg': theme.colors.facetBackground,
|
|
375
|
+
'--search-facet-border': theme.colors.facetBorder,
|
|
376
|
+
'--search-facet-text': theme.colors.facetText,
|
|
377
|
+
'--search-header-bg': theme.colors.headerBackground,
|
|
378
|
+
'--search-header-text': theme.colors.headerText,
|
|
379
|
+
'--search-highlight-bg': theme.colors.highlightBackground,
|
|
380
|
+
'--search-highlight-text': theme.colors.highlightText,
|
|
381
|
+
'--search-input-bg': theme.colors.inputBackground,
|
|
382
|
+
'--search-input-border': theme.colors.inputBorder,
|
|
383
|
+
'--search-input-border-focus': theme.colors.inputBorderFocus,
|
|
384
|
+
'--search-input-placeholder': theme.colors.inputPlaceholder,
|
|
385
|
+
'--search-input-text': theme.colors.inputText,
|
|
386
|
+
'--search-loading-text': theme.colors.loadingText,
|
|
387
|
+
'--search-meta-text': theme.colors.metaText,
|
|
388
|
+
'--search-no-results-text': theme.colors.noResultsText,
|
|
389
|
+
'--search-result-bg': theme.colors.resultBackground,
|
|
390
|
+
'--search-result-bg-hover': theme.colors.resultBackgroundHover,
|
|
391
|
+
'--search-results-bg': theme.colors.resultsBackground,
|
|
392
|
+
'--search-results-border': theme.colors.resultsBorder,
|
|
393
|
+
'--search-score-badge': theme.colors.scoreBadge,
|
|
394
|
+
'--search-score-badge-text': theme.colors.scoreBadgeText,
|
|
395
|
+
'--search-title-text': theme.colors.titleText
|
|
396
|
+
};
|
|
397
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customEndpointHandler.d.ts","sourceRoot":"","sources":["../../src/endpoints/customEndpointHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,eAAO,MAAM,qBAAqB,EAAE,cAEnC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PayloadHandler } from 'payload';
|
|
2
|
+
import type Typesense from 'typesense';
|
|
3
|
+
import type { TypesenseSearchConfig } from '../index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create health check handler
|
|
6
|
+
*/
|
|
7
|
+
export declare const createHealthCheckHandler: (typesenseClient: Typesense.Client, pluginOptions: TypesenseSearchConfig, lastSyncTime?: number) => PayloadHandler;
|
|
8
|
+
/**
|
|
9
|
+
* Create detailed health check handler with more information
|
|
10
|
+
*/
|
|
11
|
+
export declare const createDetailedHealthCheckHandler: (typesenseClient: Typesense.Client, pluginOptions: TypesenseSearchConfig, lastSyncTime?: number) => PayloadHandler;
|
|
12
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/endpoints/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA2CxD;;GAEG;AACH,eAAO,MAAM,wBAAwB,GACnC,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,qBAAqB,EACpC,eAAe,MAAM,KACpB,cA4DF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gCAAgC,GAC3C,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,qBAAqB,EACpC,eAAe,MAAM,KACpB,cAuFF,CAAA"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { searchCache } from '../lib/cache.js';
|
|
2
|
+
/**
|
|
3
|
+
* Test Typesense connection
|
|
4
|
+
*/ const testTypesenseConnection = async (typesenseClient)=>{
|
|
5
|
+
try {
|
|
6
|
+
const health = await typesenseClient.health.retrieve();
|
|
7
|
+
return health.ok === true;
|
|
8
|
+
} catch (_error) {
|
|
9
|
+
// Handle health check error
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Get collection information
|
|
15
|
+
*/ const getCollectionInfo = async (typesenseClient)=>{
|
|
16
|
+
try {
|
|
17
|
+
const collections = await typesenseClient.collections().retrieve();
|
|
18
|
+
return collections.map((col)=>col.name);
|
|
19
|
+
} catch (_error) {
|
|
20
|
+
// Handle collections retrieval error
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Get cache statistics
|
|
26
|
+
*/ const getCacheStats = ()=>{
|
|
27
|
+
const stats = searchCache.getStats();
|
|
28
|
+
return {
|
|
29
|
+
hitRate: stats.hitRate || 0,
|
|
30
|
+
maxSize: stats.maxSize,
|
|
31
|
+
size: stats.size
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Create health check handler
|
|
36
|
+
*/ export const createHealthCheckHandler = (typesenseClient, pluginOptions, lastSyncTime)=>{
|
|
37
|
+
return async ()=>{
|
|
38
|
+
try {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
// Test Typesense connection
|
|
41
|
+
const isTypesenseHealthy = await testTypesenseConnection(typesenseClient);
|
|
42
|
+
const typesenseInfo = isTypesenseHealthy ? {
|
|
43
|
+
ok: true,
|
|
44
|
+
version: 'unknown'
|
|
45
|
+
} // Typesense doesn't expose version in health check
|
|
46
|
+
: {
|
|
47
|
+
ok: false
|
|
48
|
+
};
|
|
49
|
+
// Get collection information
|
|
50
|
+
const collections = isTypesenseHealthy ? await getCollectionInfo(typesenseClient) : [];
|
|
51
|
+
// Get cache statistics
|
|
52
|
+
const cacheStats = getCacheStats();
|
|
53
|
+
// Determine overall health status
|
|
54
|
+
const isHealthy = isTypesenseHealthy && collections.length > 0;
|
|
55
|
+
const response = {
|
|
56
|
+
cache: cacheStats,
|
|
57
|
+
collections,
|
|
58
|
+
...lastSyncTime !== undefined && {
|
|
59
|
+
lastSync: lastSyncTime
|
|
60
|
+
},
|
|
61
|
+
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
62
|
+
typesense: typesenseInfo
|
|
63
|
+
};
|
|
64
|
+
// Add error details if unhealthy
|
|
65
|
+
if (!isHealthy) {
|
|
66
|
+
const errors = [];
|
|
67
|
+
if (!isTypesenseHealthy) {
|
|
68
|
+
errors.push('Typesense connection failed');
|
|
69
|
+
}
|
|
70
|
+
if (collections.length === 0) {
|
|
71
|
+
errors.push('No collections available');
|
|
72
|
+
}
|
|
73
|
+
response.error = errors.join(', ');
|
|
74
|
+
}
|
|
75
|
+
const responseTime = Date.now() - startTime;
|
|
76
|
+
return Response.json({
|
|
77
|
+
...response,
|
|
78
|
+
responseTime,
|
|
79
|
+
timestamp: new Date().toISOString(),
|
|
80
|
+
version: '1.0.11'
|
|
81
|
+
});
|
|
82
|
+
} catch (_error) {
|
|
83
|
+
// Handle health check error
|
|
84
|
+
const errorResponse = {
|
|
85
|
+
cache: getCacheStats(),
|
|
86
|
+
error: _error instanceof Error ? _error.message : 'Unknown error',
|
|
87
|
+
status: 'unhealthy'
|
|
88
|
+
};
|
|
89
|
+
return Response.json(errorResponse, {
|
|
90
|
+
status: 500
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Create detailed health check handler with more information
|
|
97
|
+
*/ export const createDetailedHealthCheckHandler = (typesenseClient, pluginOptions, lastSyncTime)=>{
|
|
98
|
+
return async ()=>{
|
|
99
|
+
try {
|
|
100
|
+
const startTime = Date.now();
|
|
101
|
+
// Test Typesense connection
|
|
102
|
+
const isTypesenseHealthy = await testTypesenseConnection(typesenseClient);
|
|
103
|
+
// Get detailed collection information
|
|
104
|
+
let collections = [];
|
|
105
|
+
if (isTypesenseHealthy) {
|
|
106
|
+
try {
|
|
107
|
+
const collectionsData = await typesenseClient.collections().retrieve();
|
|
108
|
+
collections = collectionsData.map((col)=>({
|
|
109
|
+
name: col.name,
|
|
110
|
+
createdAt: col.created_at,
|
|
111
|
+
fields: col.fields?.length || 0,
|
|
112
|
+
numDocuments: col.num_documents
|
|
113
|
+
}));
|
|
114
|
+
} catch (_error) {
|
|
115
|
+
// Handle detailed collection info error
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Get cache statistics
|
|
119
|
+
const cacheStats = getCacheStats();
|
|
120
|
+
// Get plugin configuration info
|
|
121
|
+
const configInfo = {
|
|
122
|
+
enabledCollections: Object.entries(pluginOptions.collections || {}).filter(([_, config])=>config?.enabled).map(([name, config])=>({
|
|
123
|
+
name,
|
|
124
|
+
displayName: config?.displayName,
|
|
125
|
+
facetFields: config?.facetFields || [],
|
|
126
|
+
searchFields: config?.searchFields || []
|
|
127
|
+
})),
|
|
128
|
+
settings: pluginOptions.settings,
|
|
129
|
+
totalCollections: Object.keys(pluginOptions.collections || {}).length
|
|
130
|
+
};
|
|
131
|
+
// Determine overall health status
|
|
132
|
+
const isHealthy = isTypesenseHealthy && collections.length > 0;
|
|
133
|
+
const response = {
|
|
134
|
+
cache: cacheStats,
|
|
135
|
+
collectionDetails: collections,
|
|
136
|
+
collections: collections.map((col)=>col.name),
|
|
137
|
+
config: configInfo,
|
|
138
|
+
lastSync: lastSyncTime,
|
|
139
|
+
responseTime: Date.now() - startTime,
|
|
140
|
+
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
141
|
+
timestamp: new Date().toISOString(),
|
|
142
|
+
typesense: {
|
|
143
|
+
ok: isTypesenseHealthy,
|
|
144
|
+
version: 'unknown'
|
|
145
|
+
},
|
|
146
|
+
version: '1.0.11'
|
|
147
|
+
};
|
|
148
|
+
// Add error details if unhealthy
|
|
149
|
+
if (!isHealthy) {
|
|
150
|
+
const errors = [];
|
|
151
|
+
if (!isTypesenseHealthy) {
|
|
152
|
+
errors.push('Typesense connection failed');
|
|
153
|
+
}
|
|
154
|
+
if (collections.length === 0) {
|
|
155
|
+
errors.push('No collections available');
|
|
156
|
+
}
|
|
157
|
+
response.error = errors.join(', ');
|
|
158
|
+
}
|
|
159
|
+
return Response.json(response);
|
|
160
|
+
} catch (_error) {
|
|
161
|
+
// Handle detailed health check error
|
|
162
|
+
const errorResponse = {
|
|
163
|
+
cache: getCacheStats(),
|
|
164
|
+
error: _error instanceof Error ? _error.message : 'Unknown error',
|
|
165
|
+
status: 'unhealthy',
|
|
166
|
+
timestamp: new Date().toISOString(),
|
|
167
|
+
version: '1.0.11'
|
|
168
|
+
};
|
|
169
|
+
return Response.json(errorResponse, {
|
|
170
|
+
status: 500
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PayloadHandler } from 'payload';
|
|
2
|
+
import type Typesense from 'typesense';
|
|
3
|
+
import type { TypesenseSearchConfig } from '../index.js';
|
|
4
|
+
export declare const createSearchEndpoints: (typesenseClient: Typesense.Client, pluginOptions: TypesenseSearchConfig, lastSyncTime?: number) => ({
|
|
5
|
+
handler: PayloadHandler;
|
|
6
|
+
method: "get";
|
|
7
|
+
path: string;
|
|
8
|
+
} | {
|
|
9
|
+
handler: PayloadHandler;
|
|
10
|
+
method: "post";
|
|
11
|
+
path: string;
|
|
12
|
+
})[];
|
|
13
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/endpoints/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA4HxD,eAAO,MAAM,qBAAqB,GAChC,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,qBAAqB,EACpC,eAAe,MAAM;;;;;;;;IAuCtB,CAAA"}
|