Setting the file. One moment.
Search · Wix Headless Templates · wix/skills · Skills Docs
ContentsBack to the top of the page shared/capabilities/site-search/rest/ search.ts
TypeScript · 82 lines · 4 KB
10
import
{
11 GROUP_LIMIT,
12 MIN_SUGGEST_CHARS,
13 MAX_SUGGEST_QUERY,
14 SUGGEST_LIMIT,
15 clampQuery,
16 federatedBody,
17 productsOf,
18 resolveConfig,
19 searchBody,
20 storeFrontById,
21 suggestBody,
22 toPage,
23 toSearchAll,
24 toSuggestGroups,
25 type Raw,
26 } from "../app/wix/site-search/search-core.js" ;
27 import type { SearchAllResult, SearchOptions, SearchPage, SiteSearchConfig, SuggestGroup } from "../app/wix/site-search/types.js" ;
28
29 /** The plan's siteSearch entry resolved — types in order, routes, labels. */
30 export const config : SiteSearchConfig = resolveConfig (siteSearchPlan);
31
32 // The store-front pass only adds product slugs and media; when it fails the products render unlinked.
33 async function storeFrontPass ( run : () => Promise < Raw >) : Promise < Raw | null > {
34 try {
35 return await run ();
36 } catch {
37 return null ;
38 }
39 }
40
41 /**
42 * Every configured type at once, `limit` hits per type. Products are fetched twice (default format
43 * for title and highlights, store-front for the slug) and joined on id.
44 * POST /sitesearch/v1/search/federated { query, documentTypes, limit, fuzzy, highlight, properties? }
45 * → { results: [{ documentType, documents, total }] }
46 */
47 export async function searchAll ( q : string , { limit = GROUP_LIMIT } : { limit ?: number } = {}) : Promise < SearchAllResult > {
48 const query = clampQuery (q);
49 if ( ! query) return { groups: [], indexed: null };
50 const wantsProducts = config.types. includes ( "products" );
51 const [ res , sf ] = await Promise . all ([
52 wixRequest < Raw >( "/sitesearch/v1/search/federated" , { body: federatedBody (query, config, { limit }) }),
53 wantsProducts ? storeFrontPass (() => wixRequest < Raw >( "/sitesearch/v1/search/federated" , { body: federatedBody (query, config, { limit, types: [ "products" ], storeFront: true }) })) : null ,
54 ]);
55 return toSearchAll (res?.results, config, imgSrc, storeFrontById ( productsOf (sf?.results)));
56 }
57
58 /**
59 * One type with paging, ordering, filter and facets.
60 * POST /sitesearch/v1/search { query, documentType, paging: { limit, offset }, ordering?, filter?, facets?, fuzzy, highlight }
61 * → { documents, nextPage: { total, skip, limit }, facets }
62 */
63 export async function searchType ( o : SearchOptions ) : Promise < SearchPage > {
64 const query = clampQuery (o.q);
65 if ( ! query) return toPage ( null , o, config, imgSrc);
66 const [ res , sf ] = await Promise . all ([
67 wixRequest < Raw >( "/sitesearch/v1/search" , { body: searchBody ({ ... o, q: query }, config) }),
68 o.type === "products" ? storeFrontPass (() => wixRequest < Raw >( "/sitesearch/v1/search" , { body: searchBody ({ ... o, q: query }, config, { storeFront: true }) })) : null ,
69 ]);
70 return toPage (res, { ... o, q: query }, config, imgSrc, storeFrontById (sf?.documents));
71 }
72
73 /**
74 * Suggestions for a partial phrase (3 to 50 chars; fewer → [] without a request), `limit` per type.
75 * POST /sitesearch/v1/suggest/federated { query, documentTypes, limit } → { results: [{ documentType, documents }] }
76 */
77 export async function suggest ( q : string , { limit = SUGGEST_LIMIT } : { limit ?: number } = {}) : Promise < SuggestGroup []> {
78 const query = clampQuery (q, MAX_SUGGEST_QUERY );
79 if (query. length < MIN_SUGGEST_CHARS ) return [];
80 const res = await wixRequest < Raw >( "/sitesearch/v1/suggest/federated" , { body: suggestBody (query, config, limit) });
81 return toSuggestGroups (res?.results, config, imgSrc);
82 }