@stacksjs/search-engine 0.75.72 → 0.75.74
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.
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SearchOptions } from '@stacksjs/types';
|
|
2
|
+
import type { Settings } from 'meilisearch';
|
|
3
|
+
/**
|
|
4
|
+
* The index settings a model's `useSearch` trait declares, and only those.
|
|
5
|
+
*
|
|
6
|
+
* Every list used to be sent, with `[]` standing in for one the model did not
|
|
7
|
+
* declare. To Meilisearch an empty list is not "unset": `displayedAttributes:
|
|
8
|
+
* []` returns every hit with no fields, and `searchableAttributes: []` makes
|
|
9
|
+
* nothing searchable. So a model declaring only `searchable` imported cleanly
|
|
10
|
+
* and then came back as empty objects, and one declaring only `filterable`
|
|
11
|
+
* matched no query at all. An undeclared list is now left out, so the engine
|
|
12
|
+
* keeps its default (every attribute) for it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function settingsFromSearchTrait(useSearch: Partial<Pick<SearchOptions, 'searchable' | 'filterable' | 'sortable' | 'displayable'>>, options?: { displayed?: boolean }): Settings;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var lt=Object.defineProperty;var gt=(e)=>e;function dt(e,t){this[e]=gt.bind(null,t)}var E=(e,t)=>{for(var n in t)lt(e,n,{get:t[n],enumerable:!0,configurable:!0,set:dt.bind(t,n)})};var R=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(r){n=[r]}if(n)throw n[0];return t};var Ue={};E(Ue,{algolia:()=>Ne,browse:()=>Ce,clearObjects:()=>we,clearRules:()=>Me,clearSynonyms:()=>ve,configure:()=>de,copyIndex:()=>Re,default:()=>Le,deleteBy:()=>Te,deleteIndex:()=>De,deleteObject:()=>he,deleteObjects:()=>Ae,getObject:()=>Pe,getObjects:()=>Se,getSettings:()=>xe,indexExists:()=>Ie,listIndices:()=>Ee,moveIndex:()=>$e,multiSearch:()=>ye,partialUpdateObject:()=>be,saveObject:()=>fe,saveObjects:()=>me,saveRule:()=>je,saveSynonym:()=>qe,search:()=>pe,searchRules:()=>Fe,searchSynonyms:()=>_e,setSettings:()=>ke,waitTask:()=>Oe});import{searchEngine as le}from"@stacksjs/config";import{log as Ft}from"@stacksjs/logging";function ge(){if(!I){let e=le.algolia?.appId||process.env.ALGOLIA_APP_ID||"",t=le.algolia?.apiKey||process.env.ALGOLIA_API_KEY||"";if(!e||!t)throw Ft.error("Algolia credentials not configured. Set ALGOLIA_APP_ID and ALGOLIA_API_KEY."),Error("Algolia credentials not configured. Set ALGOLIA_APP_ID and ALGOLIA_API_KEY.");I={appId:e,apiKey:t}}return I}function Mt(){let{appId:e}=ge();return`https://${e}.algolia.net`}function Ct(){let{appId:e,apiKey:t}=ge();return{"X-Algolia-Application-Id":e,"X-Algolia-API-Key":t,"Content-Type":"application/json"}}async function u(e,t,n){let r=await fetch(`${Mt()}${t}`,{method:e,headers:Ct(),body:n?JSON.stringify(n):void 0});if(!r.ok){let i=await r.json().catch(()=>({message:r.statusText}));throw Error(`Algolia API error: ${i.message||r.statusText}`)}return r.json()}function de(e){I=e}async function pe(e,t={}){return u("POST",`/1/indexes/${e}/query`,{query:t.query||"",page:t.page||0,hitsPerPage:t.hitsPerPage||20,filters:t.filters,facets:t.facets,attributesToRetrieve:t.attributesToRetrieve,attributesToHighlight:t.attributesToHighlight,attributesToSnippet:t.attributesToSnippet})}async function ye(e){return u("POST","/1/indexes/*/queries",{requests:e.map((t)=>({indexName:t.indexName,params:new URLSearchParams({query:t.params?.query||"",page:String(t.params?.page||0),hitsPerPage:String(t.params?.hitsPerPage||20),...t.params?.filters&&{filters:t.params.filters}}).toString()}))})}async function fe(e,t,n){if(n)return u("PUT",`/1/indexes/${e}/${n}`,t);return u("POST",`/1/indexes/${e}`,t)}async function me(e,t){return u("POST",`/1/indexes/${e}/batch`,{requests:t.map((n)=>({action:n.objectID?"updateObject":"addObject",body:n}))})}async function be(e,t,n,r=!0){return u("POST",`/1/indexes/${e}/${t}/partial${r?"":"?createIfNotExists=false"}`,n)}async function he(e,t){return u("DELETE",`/1/indexes/${e}/${t}`)}async function Ae(e,t){return u("POST",`/1/indexes/${e}/batch`,{requests:t.map((n)=>({action:"deleteObject",body:{objectID:n}}))})}async function Te(e,t){return u("POST",`/1/indexes/${e}/deleteByQuery`,{filters:t})}async function Pe(e,t,n){let r=n?`?attributesToRetrieve=${n.join(",")}`:"";return u("GET",`/1/indexes/${e}/${t}${r}`)}async function Se(e,t,n){return u("POST","/1/indexes/*/objects",{requests:t.map((r)=>({indexName:e,objectID:r,attributesToRetrieve:n}))})}async function we(e){return u("POST",`/1/indexes/${e}/clear`)}async function xe(e){return u("GET",`/1/indexes/${e}/settings`)}async function ke(e,t,n=!1){return u("PUT",`/1/indexes/${e}/settings${n?"?forwardToReplicas=true":""}`,t)}async function Ee(){return u("GET","/1/indexes")}async function Re(e,t,n){return u("POST",`/1/indexes/${e}/operation`,{operation:"copy",destination:t,scope:n})}async function $e(e,t){return u("POST",`/1/indexes/${e}/operation`,{operation:"move",destination:t})}async function De(e){return u("DELETE",`/1/indexes/${e}`)}async function Ie(e){try{return await u("GET",`/1/indexes/${e}/settings`),!0}catch{return!1}}async function Oe(e,t,n=1e4,r=100){let i=Date.now();while(Date.now()-i<n){let o=await u("GET",`/1/indexes/${e}/task/${t}`);if(o.status==="published")return o;await new Promise((a)=>setTimeout(a,r))}throw Error(`Task ${t} timed out after ${n}ms`)}async function qe(e,t,n=!1){return u("PUT",`/1/indexes/${e}/synonyms/${t.objectID}${n?"?forwardToReplicas=true":""}`,t)}async function _e(e,t="",n,r=0,i=20){return u("POST",`/1/indexes/${e}/synonyms/search`,{query:t,type:n,page:r,hitsPerPage:i})}async function ve(e,t=!1){return u("POST",`/1/indexes/${e}/synonyms/clear${t?"?forwardToReplicas=true":""}`)}async function je(e,t,n=!1){return u("PUT",`/1/indexes/${e}/rules/${t.objectID}${n?"?forwardToReplicas=true":""}`,t)}async function Fe(e,t="",n,r,i=0,o=20){return u("POST",`/1/indexes/${e}/rules/search`,{query:t,anchoring:n,context:r,page:i,hitsPerPage:o})}async function Me(e,t=!1){return u("POST",`/1/indexes/${e}/rules/clear${t?"?forwardToReplicas=true":""}`)}async function*Ce(e,t={}){let n;do{let r=await u("POST",`/1/indexes/${e}/browse`,{...t,cursor:n});for(let i of r.hits)yield i;n=r.cursor}while(n)}var I=null,Ne,Le;var U=R(()=>{Ne={configure:de,search:pe,multiSearch:ye,saveObject:fe,saveObjects:me,partialUpdateObject:be,deleteObject:he,deleteObjects:Ae,deleteBy:Te,getObject:Pe,getObjects:Se,clearObjects:we,getSettings:xe,setSettings:ke,listIndices:Ee,copyIndex:Re,moveIndex:$e,deleteIndex:De,indexExists:Ie,waitTask:Oe,saveSynonym:qe,searchSynonyms:_e,clearSynonyms:ve,saveRule:je,searchRules:Fe,clearRules:Me,browse:Ce},Le=Ne});var Ke={};E(Ke,{default:()=>ze});import{searchEngine as Nt}from"@stacksjs/config";function V(){let e=Nt.opensearch,t=String(e?.host||"localhost").replace(/\/+$/,""),n=/^https?:\/\//i.test(t),r=String(e?.protocol||"http").replace(/:$/,""),i=Number(e?.port||9200),o=`${r}://${t}${i?`:${i}`:""}`;if(n){let a=new URL(t);if(!a.port&&e?.port)a.port=String(e.port);o=a.toString().replace(/\/+$/,"")}return{baseUrl:o,auth:String(e?.auth||"")}}function Ut(e="application/json"){let{auth:t}=V();return{"Content-Type":e,...t?{Authorization:`Basic ${btoa(t)}`}:{}}}async function f(e,t,n,r){let{baseUrl:i}=V(),o=await fetch(`${i}${t}`,{method:e,headers:Ut(r),body:n===void 0?void 0:typeof n==="string"?n:JSON.stringify(n)});if(!o.ok){let d=await o.text();throw new q(o.status,e,t,d||o.statusText)}let a=await o.text();return a?JSON.parse(a):{}}function m(e){return`/${encodeURIComponent(e)}`}function T(e,t){return{taskUid:Date.now(),indexUid:e,status:"succeeded",type:t,enqueuedAt:new Date().toISOString()}}async function Z(e){return(await f("GET",`${m(e)}/_mapping`))[e]?.mappings?._meta?.stacks||{}}async function O(e,t){let n;try{n=await Z(e)}catch(r){if(!(r instanceof q)||r.status!==404)throw r;await f("PUT",m(e)),n={}}return await f("PUT",`${m(e)}/_mapping`,{_meta:{stacks:{...n,...t}}}),T(e,"settingsUpdate")}async function Lt(e,t={}){if(typeof t==="string")t={q:t};let n=String(t.q??t.query??""),r=Math.max(1,Number(t.limit??t.perPage??20)),i=Math.max(0,Number(t.offset??(Number(t.page||1)-1)*r)),o=Array.isArray(t.filter)?t.filter:t.filter?[t.filter]:[],a=n?{multi_match:{query:n,fields:t.attributesToSearchOn||["*"]}}:{match_all:{}},d=o.length>0?{bool:{must:[a],filter:o.map((y)=>({query_string:{query:typeof y==="string"?y:JSON.stringify(y)}}))}}:a,l=await f("POST",`${m(e)}/_search`,{query:d,from:i,size:r,...t.sort?{sort:t.sort}:{},...t.attributesToRetrieve?{_source:t.attributesToRetrieve}:{}}),c=typeof l.hits?.total==="number"?l.hits.total:Number(l.hits?.total?.value||0);return{hits:(l.hits?.hits||[]).map((y)=>({id:y._source?.id??y._id,...y._source})),estimatedTotalHits:c,processingTimeMs:Number(l.took||0),query:n,limit:r,offset:i}}async function Ht(e,t={}){return await f("PUT",m(e),t),T(e,"indexCreation")}async function Bt(e){return await f("GET",m(e))}async function Gt(e,t){return await f("PUT",`${m(e)}/_settings`,t),T(e,"indexUpdate")}async function Kt(e){try{await f("DELETE",m(e))}catch(t){if(!(t instanceof q)||t.status!==404)throw t}return T(e,"indexDeletion")}async function He(){let t=(await f("GET","/_cat/indices?format=json")).map((n)=>({uid:n.index,primaryKey:null,createdAt:null,updatedAt:null}));return{results:t,total:t.length,limit:t.length,offset:0}}async function Be(e,t){let n=t?.id??t?.objectID,r=n===void 0||n===null?`${m(e)}/_doc?refresh=wait_for`:`${m(e)}/_doc/${encodeURIComponent(String(n))}?refresh=wait_for`;return await f(n===void 0||n===null?"POST":"PUT",r,t),T(e,"documentAdditionOrUpdate")}async function Ge(e,t){if(!Array.isArray(t))throw TypeError("[search/opensearch] addDocuments requires an array of documents");if(t.length===0)return T(e,"documentAdditionOrUpdate");let n=t.flatMap((i)=>{let o=i?.id??i?.objectID;return[JSON.stringify({index:{_index:e,...o===void 0||o===null?{}:{_id:o}}}),JSON.stringify(i)]}),r=await f("POST","/_bulk?refresh=wait_for",`${n.join(`
|
|
2
|
+
var rn=Object.defineProperty;var sn=(e)=>e;function on(e,t){this[e]=sn.bind(null,t)}var z=(e,t)=>{for(var n in t)rn(e,n,{get:t[n],enumerable:!0,configurable:!0,set:on.bind(t,n)})};var L=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(r){n=[r]}if(n)throw n[0];return t};function ie(e,t){let n=Number(t);if(!Number.isInteger(n)||n<0)throw TypeError(`[search] \`${e}\` must be a non-negative integer, got ${JSON.stringify(t)}`);return n}function F(e,t=20){let n=typeof e==="string"?{q:e}:e??{},r=n.q??n.query,s=r==null?"":String(r),i=n.limit??n.perPage,o=i==null?t:ie(n.limit!=null?"limit":"perPage",i),a=0;if(n.offset!=null)a=ie("offset",n.offset);else if(n.page!=null){let c=ie("page",n.page);if(c<1)throw TypeError("[search] `page` is 1-based and must be at least 1");a=(c-1)*o}return{query:s,limit:o,offset:a,filter:n.filter,sort:n.sort}}function R(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function D(e,t){if(!Fn.test(t))throw Error(`[search/${e}] Refusing to build filter with unsafe field name: ${t}`)}function U(e,t){if(t==null)return[];if(typeof t==="string")return t?[t]:[];if(Array.isArray(t))return t.filter(Boolean);let n=[];for(let[r,s]of Object.entries(t))D(e,r),n.push(`${r}:${String(s).toLowerCase()==="desc"?"desc":"asc"}`);return n}var q=20,Fn;var H=L(()=>{Fn=/^[a-z_]\w*(?:\.[a-z_]\w*)*$/i});var $t={};z($t,{AlgoliaRequestError:()=>N,algolia:()=>vn,browse:()=>xt,clearObjects:()=>Te,clearRules:()=>kt,clearSynonyms:()=>Ee,configure:()=>be,copyIndex:()=>bt,default:()=>It,deleteBy:()=>Se,deleteIndex:()=>ke,deleteObject:()=>he,deleteObjects:()=>ft,getObject:()=>Ae,getObjects:()=>mt,getSettings:()=>we,indexExists:()=>St,listIndices:()=>Y,moveIndex:()=>ht,multiSearch:()=>gt,partialUpdateObject:()=>yt,saveObject:()=>V,saveObjects:()=>pt,saveRule:()=>wt,saveSynonym:()=>Tt,search:()=>dt,searchRules:()=>Pt,searchSynonyms:()=>xe,setSettings:()=>Pe,waitTask:()=>At});import{searchEngine as fe}from"@stacksjs/config";import{log as ut}from"@stacksjs/logging";function ct(){if(!B){let e=fe.algolia?.appId||process.env.ALGOLIA_APP_ID||"",t=fe.algolia?.apiKey||process.env.ALGOLIA_API_KEY||"";if(!e||!t)throw ut.error("Algolia credentials not configured. Set ALGOLIA_APP_ID and ALGOLIA_API_KEY."),Error("Algolia credentials not configured. Set ALGOLIA_APP_ID and ALGOLIA_API_KEY.");B={appId:e,apiKey:t}}return B}function jn(){let{appId:e}=ct();return`https://${e}.algolia.net`}function _n(){let{appId:e,apiKey:t}=ct();return{"X-Algolia-Application-Id":e,"X-Algolia-API-Key":t,"Content-Type":"application/json"}}async function d(e,t,n){let r=await fetch(`${jn()}${t}`,{method:e,headers:_n(),body:n?JSON.stringify(n):void 0});if(!r.ok){let s=await r.json().catch(()=>({message:r.statusText}));throw new N(r.status,s.message||r.statusText)}return r.json()}function lt(e){return e instanceof N&&e.status===404}function be(e){B=e}async function dt(e,t={}){return d("POST",`/1/indexes/${e}/query`,{query:t.query||"",page:t.page||0,hitsPerPage:t.hitsPerPage||20,filters:t.filters,facets:t.facets,attributesToRetrieve:t.attributesToRetrieve,attributesToHighlight:t.attributesToHighlight,attributesToSnippet:t.attributesToSnippet})}async function gt(e){return d("POST","/1/indexes/*/queries",{requests:e.map((t)=>({indexName:t.indexName,params:new URLSearchParams({query:t.params?.query||"",page:String(t.params?.page||0),hitsPerPage:String(t.params?.hitsPerPage||20),...t.params?.filters&&{filters:t.params.filters}}).toString()}))})}async function V(e,t,n){if(n)return d("PUT",`/1/indexes/${e}/${n}`,t);return d("POST",`/1/indexes/${e}`,t)}async function pt(e,t){return d("POST",`/1/indexes/${e}/batch`,{requests:t.map((n)=>({action:n.objectID?"updateObject":"addObject",body:n}))})}async function yt(e,t,n,r=!0){return d("POST",`/1/indexes/${e}/${t}/partial${r?"":"?createIfNotExists=false"}`,n)}async function he(e,t){return d("DELETE",`/1/indexes/${e}/${t}`)}async function ft(e,t){return d("POST",`/1/indexes/${e}/batch`,{requests:t.map((n)=>({action:"deleteObject",body:{objectID:n}}))})}async function Se(e,t){return d("POST",`/1/indexes/${e}/deleteByQuery`,{filters:t})}async function Ae(e,t,n){let r=n?`?attributesToRetrieve=${n.join(",")}`:"";return d("GET",`/1/indexes/${e}/${t}${r}`)}async function mt(e,t,n){return d("POST","/1/indexes/*/objects",{requests:t.map((r)=>({indexName:e,objectID:r,attributesToRetrieve:n}))})}async function Te(e){return d("POST",`/1/indexes/${e}/clear`)}async function we(e){return d("GET",`/1/indexes/${e}/settings`)}async function Pe(e,t,n=!1){return d("PUT",`/1/indexes/${e}/settings${n?"?forwardToReplicas=true":""}`,t)}async function Y(){return d("GET","/1/indexes")}async function bt(e,t,n){return d("POST",`/1/indexes/${e}/operation`,{operation:"copy",destination:t,scope:n})}async function ht(e,t){return d("POST",`/1/indexes/${e}/operation`,{operation:"move",destination:t})}async function ke(e){return d("DELETE",`/1/indexes/${e}`)}async function St(e){try{return await d("GET",`/1/indexes/${e}/settings`),!0}catch{return!1}}async function At(e,t,n=1e4,r=100){let s=Date.now();while(Date.now()-s<n){let i=await d("GET",`/1/indexes/${e}/task/${t}`);if(i.status==="published")return i;await new Promise((o)=>setTimeout(o,r))}throw Error(`Task ${t} timed out after ${n}ms`)}async function Tt(e,t,n=!1){return d("PUT",`/1/indexes/${e}/synonyms/${t.objectID}${n?"?forwardToReplicas=true":""}`,t)}async function xe(e,t="",n,r=0,s=20){return d("POST",`/1/indexes/${e}/synonyms/search`,{query:t,type:n,page:r,hitsPerPage:s})}async function Ee(e,t=!1){return d("POST",`/1/indexes/${e}/synonyms/clear${t?"?forwardToReplicas=true":""}`)}async function wt(e,t,n=!1){return d("PUT",`/1/indexes/${e}/rules/${t.objectID}${n?"?forwardToReplicas=true":""}`,t)}async function Pt(e,t="",n,r,s=0,i=20){return d("POST",`/1/indexes/${e}/rules/search`,{query:t,anchoring:n,context:r,page:s,hitsPerPage:i})}async function kt(e,t=!1){return d("POST",`/1/indexes/${e}/rules/clear${t?"?forwardToReplicas=true":""}`)}async function*xt(e,t={}){let n;do{let r=await d("POST",`/1/indexes/${e}/browse`,{...t,cursor:n});for(let s of r.hits)yield s;n=r.cursor}while(n)}function I(e,t){throw Error(`[search/algolia] ${e} is not supported by Algolia. ${t}`)}function A(e,t,n){return{taskUid:Number(n?.taskID??0),indexUid:e,status:"enqueued",type:t,enqueuedAt:n?.createdAt??n?.updatedAt??new Date().toISOString()}}function Re(e){let t=e.objectID??e.id;return t==null?{...e}:{...e,objectID:String(t)}}async function Et(e,t){let n;for(let r=0;r<t.length;r+=nt)n=await d("POST",`/1/indexes/${e}/batch`,{requests:t.slice(r,r+nt)});return n}function Cn(e){return`"${String(e).replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function rt(e,t){if(typeof t==="number")return`${e} = ${t}`;if(typeof t==="boolean")return`${e}:${t}`;return`${e}:${Cn(t)}`}function Rt(e){if(e==null||e==="")return;if(typeof e==="string")return e;if(Array.isArray(e)){let n=e.filter(Boolean).map((r)=>Array.isArray(r)?`(${r.join(" OR ")})`:`(${r})`);return n.length>0?n.join(" AND "):void 0}if(!R(e))throw TypeError(`[search/algolia] Unsupported filter: ${JSON.stringify(e)}`);let t=[];for(let[n,r]of Object.entries(e)){if(D("algolia",n),r===void 0)continue;if(r===null)throw TypeError(`[search/algolia] Algolia cannot filter on a missing value (${n}: null)`);t.push(Array.isArray(r)?`(${r.map((s)=>rt(n,s)).join(" OR ")})`:rt(n,r))}return t.length>0?t.join(" AND "):void 0}async function Mn(e,t={}){let{query:n,limit:r,offset:s,filter:i,sort:o}=F(t,fe.perPage??q);if(U("algolia",o).length>0)I("Sorting at query time","Algolia sorts through replica indices: create a replica ranked by the attribute (e.g. `products_price_asc`) and search that index instead.");let a={query:n};if(r>0&&s%r===0)a.page=s/r,a.hitsPerPage=r;else a.offset=s,a.length=r;let c=t.filters||Rt(i);if(c)a.filters=c;for(let p of Un)if(t[p]!==void 0)a[p]=t[p];let l=await d("POST",`/1/indexes/${e}/query`,a);return{hits:l.hits??[],query:l.query??n,processingTimeMs:l.processingTimeMS??0,limit:r,offset:s,estimatedTotalHits:l.nbHits??l.hits?.length??0,...l.facets?{facetDistribution:l.facets}:{}}}function st(e){let t=/^\w+\((.+)\)$/.exec(e);return t?t[1]:e}function Ln(e){if(e==null)return null;return e.flatMap((t)=>typeof t==="string"?[t]:t.attributePatterns)}function it(e){if(e==null||e.length===0||e.length===1&&e[0]==="*")return null;return e}function Hn(e){return e.flatMap((t)=>{let n=/^([\w.]+):(asc|desc)$/.exec(t);if(n)return[`${n[2]}(${n[1]})`];if(t==="exactness")return["exact"];if(t==="sort")return[];return[t]})}function Bn(e){return e.map((t)=>{let n=/^(asc|desc)\(([\w.]+)\)$/.exec(t);if(n)return`${n[2]}:${n[1]}`;return t==="exact"?"exactness":t})}function Nn(e){if(e==null)return{typoTolerance:null,minWordSizefor1Typo:null,minWordSizefor2Typos:null,disableTypoToleranceOnAttributes:null,disableTypoToleranceOnWords:null};let t={};if(e.enabled!=null)t.typoTolerance=e.enabled;if(e.minWordSizeForTypos?.oneTypo!=null)t.minWordSizefor1Typo=e.minWordSizeForTypos.oneTypo;if(e.minWordSizeForTypos?.twoTypos!=null)t.minWordSizefor2Typos=e.minWordSizeForTypos.twoTypos;if(e.disableOnAttributes!==void 0)t.disableTypoToleranceOnAttributes=e.disableOnAttributes;if(e.disableOnWords!==void 0)t.disableTypoToleranceOnWords=e.disableOnWords;if(e.disableOnNumbers!=null)t.allowTyposOnNumericTokens=!e.disableOnNumbers;return t}function Wn(e){let t={},n=[];for(let[r,s]of Object.entries(e)){if(s===void 0)continue;switch(r){case"searchableAttributes":t.searchableAttributes=it(s);break;case"filterableAttributes":t.attributesForFaceting=Ln(s);break;case"displayedAttributes":t.attributesToRetrieve=it(s);break;case"rankingRules":t.ranking=s==null?null:Hn(s);break;case"distinctAttribute":t.attributeForDistinct=s,t.distinct=s==null?null:!0;break;case"pagination":t.paginationLimitedTo=s?.maxTotalHits??null;break;case"faceting":{let i=s;t.maxValuesPerFacet=i?.maxValuesPerFacet??null;let o=i?.sortFacetValuesBy?.["*"];if(o!==void 0||i==null)t.sortFacetValuesBy=o??null;break}case"typoTolerance":Object.assign(t,Nn(s));break;case"synonyms":break;default:n.push(r)}}if(n.length>0)ut.warn(`[search/algolia] Skipped settings with no Algolia equivalent: ${n.join(", ")}. Algolia sorts through replica indices.`);return t}function Kn(e){return{searchableAttributes:(e.searchableAttributes??["*"]).map(st),filterableAttributes:(e.attributesForFaceting??[]).map(st),sortableAttributes:[],displayedAttributes:e.attributesToRetrieve??["*"],rankingRules:Bn(e.ranking??[]),distinctAttribute:e.distinct?e.attributeForDistinct??null:null,pagination:{maxTotalHits:e.paginationLimitedTo??null},faceting:{maxValuesPerFacet:e.maxValuesPerFacet??null,...e.sortFacetValuesBy?{sortFacetValuesBy:{"*":e.sortFacetValuesBy}}:{}},typoTolerance:{enabled:e.typoTolerance===void 0?!0:e.typoTolerance!==!1,minWordSizeForTypos:{oneTypo:e.minWordSizefor1Typo??null,twoTypos:e.minWordSizefor2Typos??null},disableOnAttributes:e.disableTypoToleranceOnAttributes??[],disableOnWords:e.disableTypoToleranceOnWords??[]}}}async function me(e){return Kn(await we(e))}async function v(e,t,n="settingsUpdate"){let r=Wn(t),s=await Pe(e,r);return A(e,n,s)}function C(e,t){return{get:async(n)=>(await me(n))[e],update:(n,r)=>v(n,{[e]:r}),reset:(n)=>v(n,{[e]:t})}}async function Gn(e,t){if(t==null)return Dt(e);let n=Object.entries(t).map(([s,i])=>({objectID:`stacks-${s}`,type:"oneWaySynonym",input:s,synonyms:i})),r=await d("POST",`/1/indexes/${e}/synonyms/batch?replaceExistingSynonyms=true`,n);return A(e,"settingsUpdate",r)}async function Dt(e){return A(e,"settingsUpdate",await Ee(e))}async function zn(e){let t={},n=0;while(!0){let{hits:r,nbHits:s}=await xe(e,"",void 0,n,100);for(let i of r)if(i.type==="oneWaySynonym"&&i.input)t[i.input]=[...t[i.input]??[],...i.synonyms??[]];else if(i.type==="synonym")for(let o of i.synonyms??[])t[o]=[...t[o]??[],...(i.synonyms??[]).filter((a)=>a!==o)];if(n++,r.length===0||n*100>=s)break}return t}async function Jn(e,t){if(t?.primaryKey&&t.primaryKey!=="id"&&t.primaryKey!=="objectID")I(`A primary key other than \`id\` (${t.primaryKey})`,"Algolia keys every record by `objectID`, which the driver takes from `id`.");return await v(e,t?.settings??{},"indexCreation")}async function Vn(e){let{items:t}=await Y(),n=t.find((r)=>r.name===e);if(!n)throw new N(404,`Index ${e} does not exist`);return{uid:n.name,primaryKey:"objectID",createdAt:n.createdAt,updatedAt:n.updatedAt}}async function ot(){let{items:e}=await Y(),t=e.map((n)=>({uid:n.name,primaryKey:"objectID",createdAt:n.createdAt,updatedAt:n.updatedAt}));return{results:t,offset:0,limit:t.length,total:t.length}}async function Yn(e){try{return A(e,"indexDeletion",await ke(e))}catch(t){if(!lt(t))throw t;return A(e,"indexDeletion")}}async function Qn(e,t){let n=Re(t),r=n.objectID==null?await V(e,n):await V(e,n,encodeURIComponent(String(n.objectID)));return A(e,"documentAdditionOrUpdate",r)}async function Xn(e,t){if(!Array.isArray(t))throw TypeError("[search/algolia] addDocuments requires an array of documents");let n=t.map((r)=>{let s=Re(r);return{action:s.objectID==null?"addObject":"updateObject",body:s}});return A(e,"documentAdditionOrUpdate",await Et(e,n))}async function at(e,t){let n=t.map((r)=>{let s=Re(r);if(s.objectID==null)throw Error("[search/algolia] updateDocuments needs an `id` (or `objectID`) on every document");return{action:"partialUpdateObject",body:s}});return A(e,"documentAdditionOrUpdate",await Et(e,n))}async function Zn(e,t,n){let r=Array.isArray(n)?n:Array.isArray(n?.fields)?n.fields:void 0;return await Ae(e,encodeURIComponent(String(t)),r)}async function er(e,t){return A(e,"documentDeletion",await he(e,encodeURIComponent(String(t))))}async function tr(e,t){let n=Rt(t);if(!n)throw Error(`[search/algolia] deleteDocuments on "${e}" needs a filter. Use deleteAllDocuments to empty the index.`);return A(e,"documentDeletion",await Se(e,n))}async function nr(e){try{return A(e,"documentDeletion",await Te(e))}catch(t){if(!lt(t))throw t;return A(e,"documentDeletion")}}async function rr(e){return await v(e,{searchableAttributes:null,filterableAttributes:null,displayedAttributes:null,rankingRules:null,distinctAttribute:null,pagination:null,faceting:null,typoTolerance:null})}var B=null,N,vn,nt=1000,Un,oe,ae,ue,ce,le,de,ge,pe="Algolia sorts through replica indices: create a replica ranked by the attribute and search that index instead.",ye="Use Algolia's dictionaries API (stop words, plurals, compounds) from the Algolia dashboard instead.",sr,It;var De=L(()=>{H();N=class N extends Error{status;constructor(e,t){super(`Algolia API error: ${t}`);this.status=e}};vn={configure:be,search:dt,multiSearch:gt,saveObject:V,saveObjects:pt,partialUpdateObject:yt,deleteObject:he,deleteObjects:ft,deleteBy:Se,getObject:Ae,getObjects:mt,clearObjects:Te,getSettings:we,setSettings:Pe,listIndices:Y,copyIndex:bt,moveIndex:ht,deleteIndex:ke,indexExists:St,waitTask:At,saveSynonym:Tt,searchSynonyms:xe,clearSynonyms:Ee,saveRule:wt,searchRules:Pt,clearRules:kt,browse:xt};Un=["facets","attributesToRetrieve","attributesToHighlight","attributesToSnippet","restrictSearchableAttributes"];oe=C("filterableAttributes",null),ae=C("searchableAttributes",null),ue=C("displayedAttributes",null),ce=C("rankingRules",null),le=C("pagination",null),de=C("faceting",null),ge=C("typoTolerance",null);sr={client:()=>({request:d,configure:be}),resetClient:()=>{B=null},search:Mn,createIndex:Jn,getIndex:Vn,updateIndex:(e,t)=>I("Changing an index's primary key","Algolia keys every record by `objectID`, which the driver takes from `id`."),deleteIndex:Yn,listAllIndexes:ot,listAllIndices:ot,addDocument:Qn,addDocuments:Xn,updateDocument:(e,t)=>at(e,[t]),updateDocuments:at,getDocument:Zn,deleteDocument:er,deleteDocuments:tr,deleteAllDocuments:nr,getFilterableAttributes:async(e)=>(await oe.get(e)).filter((t)=>typeof t==="string"),updateFilterableAttributes:oe.update,resetFilterableAttributes:oe.reset,getSearchableAttributes:ae.get,updateSearchableAttributes:ae.update,resetSearchableAttributes:ae.reset,getSortableAttributes:async()=>I("Sortable attributes",pe),updateSortableAttributes:async()=>I("Sortable attributes",pe),resetSortableAttributes:async()=>I("Sortable attributes",pe),getDisplayedAttributes:ue.get,updateDisplayedAttributes:ue.update,resetDisplayedAttributes:ue.reset,getSettings:me,updateSettings:(e,t)=>v(e,t),resetSettings:rr,getPagination:le.get,updatePagination:le.update,resetPagination:le.reset,getSynonyms:zn,updateSynonyms:Gn,resetSynonyms:Dt,getRankingRules:ce.get,updateRankingRules:ce.update,resetRankingRules:ce.reset,getDistinctAttribute:async(e)=>(await me(e)).distinctAttribute??null,updateDistinctAttribute:(e,t)=>v(e,{distinctAttribute:t}),resetDistinctAttribute:(e)=>v(e,{distinctAttribute:null}),getFaceting:de.get,updateFaceting:de.update,resetFaceting:de.reset,getTypoTolerance:ge.get,updateTypoTolerance:ge.update,resetTypoTolerance:ge.reset,getDictionary:async()=>I("A custom dictionary",ye),updateDictionary:async()=>I("A custom dictionary",ye),resetDictionary:async()=>I("A custom dictionary",ye)},It=sr});var _t={};z(_t,{default:()=>vt});import{searchEngine as jt}from"@stacksjs/config";function Le(){let e=jt.opensearch,t=String(e?.host||"localhost").replace(/\/+$/,""),n=/^https?:\/\//i.test(t),r=String(e?.protocol||"http").replace(/:$/,""),s=Number(e?.port||9200),i=`${r}://${t}${s?`:${s}`:""}`;if(n){let o=new URL(t);if(!o.port&&e?.port)o.port=String(e.port);i=o.toString().replace(/\/+$/,"")}return{baseUrl:i,auth:String(e?.auth||"")}}function ir(e="application/json"){let{auth:t}=Le();return{"Content-Type":e,...t?{Authorization:`Basic ${btoa(t)}`}:{}}}async function b(e,t,n,r){let{baseUrl:s}=Le(),i=await fetch(`${s}${t}`,{method:e,headers:ir(r),body:n===void 0?void 0:typeof n==="string"?n:JSON.stringify(n)});if(!i.ok){let a=await i.text();throw new W(i.status,e,t,a||i.statusText)}let o=await i.text();return o?JSON.parse(o):{}}function S(e){return`/${encodeURIComponent(e)}`}function E(e,t){return{taskUid:Date.now(),indexUid:e,status:"succeeded",type:t,enqueuedAt:new Date().toISOString()}}async function He(e){return(await b("GET",`${S(e)}/_mapping`))[e]?.mappings?._meta?.stacks||{}}async function Q(e,t){let n;try{n=await He(e)}catch(r){if(!(r instanceof W)||r.status!==404)throw r;await b("PUT",S(e)),n={}}return await b("PUT",`${S(e)}/_mapping`,{_meta:{stacks:{...n,...t}}}),E(e,"settingsUpdate")}function or(e){if(e==null||e==="")return[];if(typeof e==="string")return[{query_string:{query:e}}];if(Array.isArray(e))return e.filter(Boolean).map((n)=>({query_string:{query:Array.isArray(n)?n.map((r)=>`(${r})`).join(" OR "):n}}));if(!R(e))throw TypeError(`[search/opensearch] Unsupported filter: ${JSON.stringify(e)}`);let t=[];for(let[n,r]of Object.entries(e)){if(D("opensearch",n),r===void 0)continue;if(r===null)t.push({bool:{must_not:{exists:{field:n}}}});else if(Array.isArray(r))t.push({bool:{should:r.map((s)=>({match_phrase:{[n]:s}})),minimum_should_match:1}});else t.push({match_phrase:{[n]:r}})}return t}async function ar(e,t={}){let{query:n,limit:r,offset:s,filter:i,sort:o}=F(t,jt.perPage??q),a=typeof t==="string"?{}:t,c=or(i),l=n?{multi_match:{query:n,fields:a.attributesToSearchOn||["*"]}}:{match_all:{}},p=c.length>0?{bool:{must:[l],filter:c}}:l,f=await b("POST",`${S(e)}/_search`,{query:p,from:s,size:r,...o?{sort:R(o)?Object.entries(o).map(([k,M])=>({[k]:{order:String(M).toLowerCase()==="desc"?"desc":"asc"}})):o}:{},...a.attributesToRetrieve?{_source:a.attributesToRetrieve}:{}}),T=typeof f.hits?.total==="number"?f.hits.total:Number(f.hits?.total?.value||0);return{hits:(f.hits?.hits||[]).map((k)=>({id:k._source?.id??k._id,...k._source})),estimatedTotalHits:T,processingTimeMs:Number(f.took||0),query:n,limit:r,offset:s}}async function ur(e,t={}){return await b("PUT",S(e),t),E(e,"indexCreation")}async function cr(e){return await b("GET",S(e))}async function lr(e,t){return await b("PUT",`${S(e)}/_settings`,t),E(e,"indexUpdate")}async function dr(e){try{await b("DELETE",S(e))}catch(t){if(!(t instanceof W)||t.status!==404)throw t}return E(e,"indexDeletion")}async function Ot(){let t=(await b("GET","/_cat/indices?format=json")).map((n)=>({uid:n.index,primaryKey:null,createdAt:null,updatedAt:null}));return{results:t,total:t.length,limit:t.length,offset:0}}async function qt(e,t){let n=t?.id??t?.objectID,r=n===void 0||n===null?`${S(e)}/_doc?refresh=wait_for`:`${S(e)}/_doc/${encodeURIComponent(String(n))}?refresh=wait_for`;return await b(n===void 0||n===null?"POST":"PUT",r,t),E(e,"documentAdditionOrUpdate")}async function Ft(e,t){if(!Array.isArray(t))throw TypeError("[search/opensearch] addDocuments requires an array of documents");if(t.length===0)return E(e,"documentAdditionOrUpdate");let n=t.flatMap((s)=>{let i=s?.id??s?.objectID;return[JSON.stringify({index:{_index:e,...i===void 0||i===null?{}:{_id:i}}}),JSON.stringify(s)]}),r=await b("POST","/_bulk?refresh=wait_for",`${n.join(`
|
|
3
3
|
`)}
|
|
4
|
-
`,"application/x-ndjson");if(r.errors){let
|
|
5
|
-
`),i=await fetch(`${Xe()}/collections/${e}/documents/import?action=upsert`,{method:"POST",headers:{...Ve(),"Content-Type":"text/plain"},body:r});if(!i.ok){let o=await i.text().catch(()=>"");throw Error(`[search/typesense] bulk import failed (${i.status}): ${o}`)}return P(e)}async function sn(e,t){return await A("DELETE",`/collections/${e}/documents/${String(t)}`),P(e)}async function Je(e){try{await A("DELETE",`/collections/${e}`)}catch(t){Zt.debug(`[search/typesense] deleteIndex ${e}: ${t.message}`)}return P(e)}async function on(e,t){let n=t?.sampleDocument;return await j(e,n?te(n):void 0,t?.settings),P(e)}async function an(e){return await A("GET",`/collections/${e}`)}async function cn(e,t){return await j(e,void 0,t),P(e)}async function ne(e){return((await A("GET",`/collections/${e}`)).fields??[]).map((n)=>n.name).filter((n)=>n!=="id")}async function et(e){return((await A("GET",`/collections/${e}`)).fields??[]).filter((n)=>n.facet).map((n)=>n.name)}async function tt(e){return((await A("GET",`/collections/${e}`)).fields??[]).map((n)=>n.name)}async function nt(e){return ne(e)}async function un(e){return{searchableAttributes:await ne(e),filterableAttributes:await et(e),sortableAttributes:await tt(e),displayedAttributes:await nt(e)}}function g(e,t){return Promise.resolve(P("typesense"))}var v=null,Ze,ln,it;var re=R(()=>{Ze=/^[a-z_][\w]*(?:\.[a-z_][\w]*)*$/i;ln={client:()=>({}),resetClient:()=>{v=null},search:rn,getIndex:an,createIndex:on,deleteIndex:Je,updateIndex:g,listAllIndexes:async()=>({results:[]}),listAllIndices:async()=>({results:[]}),addDocument:We,addDocuments:Ye,updateDocument:(e,t)=>We(e,t),updateDocuments:(e,t)=>Ye(e,t),deleteDocument:sn,deleteDocuments:async(e)=>Je(e),getDocument:async()=>P("typesense"),getFilterableAttributes:et,updateFilterableAttributes:g,resetFilterableAttributes:g,updateDisplayedAttributes:g,resetDisplayedAttributes:g,getDisplayedAttributes:nt,updateSearchableAttributes:g,resetSearchableAttributes:g,getSearchableAttributes:ne,updateSortableAttributes:g,resetSortableAttributes:g,getSortableAttributes:tt,getSettings:un,updateSettings:cn,resetSettings:g,getPagination:async()=>({}),updatePagination:g,resetPagination:g,getSynonyms:async()=>({}),updateSynonyms:g,resetSynonyms:g,getRankingRules:async()=>[],updateRankingRules:g,resetRankingRules:g,getDistinctAttribute:async()=>null,updateDistinctAttribute:g,resetDistinctAttribute:g,getFaceting:async()=>({}),updateFaceting:g,resetFaceting:g,getTypoTolerance:async()=>({}),updateTypoTolerance:g,resetTypoTolerance:g,getDictionary:async()=>({}),updateDictionary:g,resetDictionary:g},it=ln});var at={};E(at,{default:()=>ct});import{searchEngine as st}from"@stacksjs/config";function s(){if(!ie)throw Error("The `meilisearch` search driver is selected but the `meilisearch` package is not installed. It is an opt-in dependency - run `bun add meilisearch` to enable it, or switch drivers in `config/search-engine.ts`.");if(!F){let e=st.meilisearch?.host||"http://127.0.0.1:7700",t=st.meilisearch?.apiKey||"";if(!e)throw Error("Meilisearch host is not configured. Please specify a search engine host.");F=new ie({host:e,apiKey:t})}return F}function gn(){F=null}async function dn(e,t){let n=Number(t.page)||1,r=Number(t.perPage)||20,i=(n-1)*r,o=ar(t.filter),a=cr(t.sort);return await s().index(e).search(t.query,{limit:r,filter:o,sort:a,offset:i})}async function pn(e,t){return await s().index(e).addDocuments([t])}async function yn(e,t){if(!Array.isArray(t))throw TypeError("[search/meilisearch] addDocuments requires an array of documents");if(t.length<=1000)return await s().index(e).addDocuments(t);let r;for(let i=0;i<t.length;i+=1000){let o=t.slice(i,i+1000),a=await s().index(e).addDocuments(o);if(!r)r=a}return r}async function fn(e){return await s().getIndex(e)}async function mn(e,t){return await s().createIndex(e,t)}async function bn(e,t){return await s().updateIndex(e,t)}async function hn(e,t){return await s().index(e).updateDocuments([t])}async function An(e,t){return await s().index(e).updateDocuments(t)}async function Tn(e,t){return await s().index(e).deleteDocument(t)}async function Pn(e,t){return await s().index(e).deleteDocuments({filter:t})}async function Sn(e,t,n){return await s().index(e).getDocument(t,n)}async function wn(e){return await s().deleteIndex(e)}async function ot(){return await s().getIndexes()}async function xn(e){return(await s().index(e).getFilterableAttributes()??[]).filter((n)=>typeof n==="string")}async function kn(e,t){return s().index(e).updateFilterableAttributes(t)}async function En(e){return s().index(e).resetFilterableAttributes()}async function Rn(e,t){return s().index(e).updateSearchableAttributes(t)}async function $n(e){return s().index(e).resetSearchableAttributes()}async function Dn(e){return s().index(e).getSearchableAttributes()}async function In(e,t){return s().index(e).updateSortableAttributes(t)}async function On(e){return s().index(e).resetSortableAttributes()}async function qn(e){return s().index(e).getSortableAttributes()}async function _n(e,t){return s().index(e).updateDisplayedAttributes(t)}async function vn(e){return s().index(e).getDisplayedAttributes()}async function jn(e){return s().index(e).resetDisplayedAttributes()}async function Fn(e){return s().index(e).getSettings()}async function Mn(e,t){return s().index(e).updateSettings(t)}async function Cn(e){return s().index(e).resetSettings()}async function Nn(e){return s().index(e).getPagination()}async function Un(e,t){return s().index(e).updatePagination(t)}async function Ln(e){return s().index(e).resetPagination()}async function Hn(e){return s().index(e).getSynonyms()}async function Bn(e,t){return s().index(e).updateSynonyms(t)}async function Gn(e){return s().index(e).resetSynonyms()}async function Kn(e){return s().index(e).getRankingRules()}async function zn(e,t){return s().index(e).updateRankingRules(t)}async function Wn(e){return s().index(e).resetRankingRules()}async function Yn(e){return s().index(e).getDistinctAttribute()}async function Jn(e,t){return s().index(e).updateDistinctAttribute(t)}async function Qn(e){return s().index(e).resetDistinctAttribute()}async function Xn(e){return s().index(e).getFaceting()}async function Vn(e,t){return s().index(e).updateFaceting(t)}async function Zn(e){return s().index(e).resetFaceting()}async function er(e){return s().index(e).getTypoTolerance()}async function tr(e,t){return s().index(e).updateTypoTolerance(t)}async function nr(e){return s().index(e).resetTypoTolerance()}async function rr(e){return s().index(e).getDictionary()}async function ir(e,t){return s().index(e).updateDictionary(t)}async function sr(e){return s().index(e).resetDictionary()}function ar(e){if(!e)return[];let t=[];for(let n in e){if(!Object.prototype.hasOwnProperty.call(e,n))continue;if(!or.test(n))throw Error(`[search/meilisearch] Refusing to build filter with unsafe field name: ${n}`);let r=e[n],i=String(r).replace(/'/g,"\\'");t.push(`${n}='${i}'`)}return t}function cr(e){if(!e)return[];let t=[];for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)){let i=String(e[n]).toLowerCase()==="desc"?"desc":"asc";t.push(`${n}:${i}`)}return t}var ie,F=null,or,ur,ct;var se=R(async()=>{try{({Meilisearch:ie}=await import("meilisearch"))}catch{}or=/^[a-z_][\w]*(?:\.[a-z_][\w]*)*$/i;ur={client:s,resetClient:gn,search:dn,getIndex:fn,createIndex:mn,deleteIndex:wn,updateIndex:bn,listAllIndexes:ot,listAllIndices:ot,addDocument:pn,addDocuments:yn,updateDocument:hn,updateDocuments:An,deleteDocument:Tn,deleteDocuments:Pn,getDocument:Sn,getFilterableAttributes:xn,updateFilterableAttributes:kn,resetFilterableAttributes:En,updateDisplayedAttributes:_n,resetDisplayedAttributes:jn,getDisplayedAttributes:vn,updateSearchableAttributes:Rn,resetSearchableAttributes:$n,getSearchableAttributes:Dn,updateSortableAttributes:In,resetSortableAttributes:On,getSortableAttributes:qn,getSettings:Fn,updateSettings:Mn,resetSettings:Cn,getPagination:Nn,updatePagination:Un,resetPagination:Ln,getSynonyms:Hn,updateSynonyms:Bn,resetSynonyms:Gn,getRankingRules:Kn,updateRankingRules:zn,resetRankingRules:Wn,getDistinctAttribute:Yn,updateDistinctAttribute:Jn,resetDistinctAttribute:Qn,getFaceting:Xn,updateFaceting:Vn,resetFaceting:Zn,getTypoTolerance:er,updateTypoTolerance:tr,resetTypoTolerance:nr,getDictionary:rr,updateDictionary:ir,resetDictionary:sr},ct=ur});import{overridesReady as lr,searchEngine as gr}from"@stacksjs/config";import{err as pt,ok as yt}from"@stacksjs/error-handling";import{log as w}from"@stacksjs/logging";import{getModelName as ft,getTableName as mt}from"@stacksjs/orm";import{path as ae}from"@stacksjs/path";import{useSearchEngine as bt}from"@stacksjs/search-engine";import{globSync as ht}from"@stacksjs/storage";import{snakeCase as D}from"@stacksjs/strings";async function Pr(e){try{let t=ht([ae.userModelsPath("*.ts"),ae.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{addDocument:n,updateSettings:r}=bt();for(let i of t){let o=(await import(i)).default,a=o.traits?.useSearch,d=mt(o,i),l=ft(o,i);if(e&&l!==e)continue;if(a&&(typeof a==="boolean"||typeof a==="object")){if(typeof a==="object")await r(d,{searchableAttributes:(a.searchable??[]).map((p)=>D(p)),filterableAttributes:(a.filterable??[]).map((p)=>D(p)),sortableAttributes:(a.sortable??[]).map((p)=>D(p)),displayedAttributes:(a.displayable??[]).map((p)=>D(p))});let c=o;if(typeof c.all!=="function"){w.warn(`[search] ${l}: model has no .all() - define it with defineModel`);continue}let b=c.makeAllSearchable;if(typeof b==="function"){let p=await b.call(c);w.info(`[search] ${l}: imported ${p}, skipped 0`);continue}let y=typeof a==="object"?a.denormalize:void 0,S=y?Array.from(new Set(Object.values(y).map((p)=>p.split(".")[0]).filter((p)=>Boolean(p)))):[],x;if(S.length>0&&typeof c.query==="function")try{x=await c.query().with(...S).get()}catch(p){w.warn(`[search] ${l}: eager-load of [${S.join(", ")}] failed - falling back to .all(); denormalized fields will be null. (${p.message})`),x=await c.all()}else x=await c.all();let oe=0,C=0;for(let p of x)try{let k=p.toSearchableObject?.();if(k==null){C++;continue}await n(d,k),oe++}catch(k){C++,w.warn(`[search] Skipped ${l}#${p.id??"?"}: ${k.message}`)}w.info(`[search] ${l}: imported ${oe}, skipped ${C}`)}}return w.info(e),yt("Successfully imported models to search engine!")}catch(t){return w.error(t),pt(t?.message||String(t))}}import{ok as At}from"@stacksjs/error-handling";import{log as Tt}from"@stacksjs/logging";import{getModelName as Pt,getTableName as St}from"@stacksjs/orm";import{path as ce}from"@stacksjs/path";import{useSearchEngine as wt}from"@stacksjs/search-engine";import{globSync as xt}from"@stacksjs/storage";async function Dr(e){try{let t=xt([ce.userModelsPath("*.ts"),ce.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{deleteIndex:n}=wt();for(let r of t){let i=(await import(r)).default,o=i.traits?.useSearch,a=St(i,r),d=Pt(i,r);if(e&&d!==e)continue;if(o&&(typeof o==="boolean"||typeof o==="object"))await n(a)}return At("Successfully flushed all model data from search engine!")}catch(t){return Tt.error(t),t(t)}}import{ok as kt}from"@stacksjs/error-handling";import{log as Et}from"@stacksjs/logging";import{getTableName as Rt}from"@stacksjs/orm";import{path as $t}from"@stacksjs/path";import{useSearchEngine as Dt}from"@stacksjs/search-engine";async function Fr(e){try{let t=$t.userModelsPath(`${e}.ts`),n=(await import(t)).default,{getFilterableAttributes:r,getSortableAttributes:i,getSearchableAttributes:o,getDisplayedAttributes:a}=Dt(),d=n.traits?.useSearch,l=Rt(n,t);if(d&&typeof d==="object"){let c=await a(l),b=await r(l),y=await i(l),S=await o(l);console.table({displayedAttributes:c,filterableAttributes:b,sortableAttributes:y,searchableAttributes:S})}return kt("Successfully update index settings!")}catch(t){return Et.error(t),t(t)}}import{err as It,ok as Ot}from"@stacksjs/error-handling";import{log as qt}from"@stacksjs/logging";import{getTableName as _t}from"@stacksjs/orm";import{path as ue}from"@stacksjs/path";import{useSearchEngine as vt}from"@stacksjs/search-engine";import{globSync as jt}from"@stacksjs/storage";import{snakeCase as N}from"@stacksjs/strings";async function Kr(){try{let e=jt([ue.userModelsPath("*.ts"),ue.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{updateSettings:t}=vt();for(let n of e){let r=(await import(n)).default,i=r.traits?.useSearch,o=_t(r,n);if(i&&typeof i==="object"){let a=(typeof r.traits?.useSearch==="object"&&r.traits?.useSearch.filterable||[]).map((c)=>N(c)),d=(typeof r.traits?.useSearch==="object"&&r.traits?.useSearch.sortable||[]).map((c)=>N(c)),l=(typeof r.traits?.useSearch==="object"&&r.traits?.useSearch.searchable||[]).map((c)=>N(c));await t(o,{filterableAttributes:a,sortableAttributes:d,searchableAttributes:l})}}return Ot("Successfully update index settings!")}catch(e){return qt.error(e),It(e?.message||String(e))}}function dr(e){if(e==="algolia")return Promise.resolve().then(() => (U(),Ue));if(e==="opensearch")return Promise.resolve().then(() => (ee(),Ke));if(e==="typesense")return Promise.resolve().then(() => (re(),rt));return se().then(() => at)}var M,ut=(async()=>(await lr,M=(await dr(gr.driver)).default,M))();function ei(){return new Proxy({},{get(e,t){if(M)return Reflect.get(M,t);return(...n)=>ut.then((r)=>{let i=Reflect.get(r,t);return typeof i==="function"?i.apply(r,n):i})}})}function ti(){return ut}function ni(){return Promise.resolve().then(() => (U(),{})).then((e)=>Le)}function ri(){return se().then(() => ({})).then((e)=>ct)}function ii(){return Promise.resolve().then(() => (ee(),{})).then((e)=>ze)}function si(){return Promise.resolve().then(() => (re(),{})).then((e)=>it)}export{Dr as flushModelDocuments,Pr as importModelDocuments,Fr as listIndexSettings,ti as searchEngineReady,Kr as updateIndexSettings,ni as useAlgolia,ri as useMeilisearch,ii as useOpensearch,ei as useSearchEngine,si as useTypesense};
|
|
4
|
+
`,"application/x-ndjson");if(r.errors){let s=r.items?.filter((i)=>Number(i.index?.status||0)>=400)||[];throw Error(`[search/opensearch] Bulk indexing failed for ${s.length} document(s)`)}return E(e,"documentAdditionOrUpdate")}async function gr(e,t,n){let r=n?`?_source=${encodeURIComponent(Array.isArray(n)?n.join(","):String(n))}`:"",s=await b("GET",`${S(e)}/_doc/${encodeURIComponent(String(t))}${r}`);return{id:s._source?.id??s._id,...s._source}}async function pr(e,t){return await b("DELETE",`${S(e)}/_doc/${encodeURIComponent(String(t))}?refresh=wait_for`),E(e,"documentDeletion")}async function yr(e,t){let n=(Array.isArray(t)?t:[t]).filter(Boolean);if(n.length===0)throw Error(`[search/opensearch] deleteDocuments on "${e}" needs a filter. Use deleteAllDocuments to empty the index.`);return await b("POST",`${S(e)}/_delete_by_query?refresh=true`,{query:{bool:{filter:n.map((r)=>({query_string:{query:r}}))}}}),E(e,"documentDeletion")}async function fr(e){try{await b("POST",`${S(e)}/_delete_by_query?refresh=true`,{query:{match_all:{}}})}catch(t){if(!(t instanceof W)||t.status!==404)throw t}return E(e,"documentDeletion")}function w(e,t){return{get:async(n)=>(await He(n))[e]??t,update:async(n,r)=>Q(n,{[e]:r}),reset:async(n)=>Q(n,{[e]:t})}}async function mr(e){let t=await He(e);return{filterableAttributes:t.filterableAttributes||[],searchableAttributes:t.searchableAttributes||[],sortableAttributes:t.sortableAttributes||[],displayedAttributes:t.displayedAttributes||[],pagination:t.pagination||{},synonyms:t.synonyms||{},rankingRules:t.rankingRules||[],distinctAttribute:t.distinctAttribute??null,faceting:t.faceting||{},typoTolerance:t.typoTolerance||{},dictionary:t.dictionary||[]}}async function br(e,t){let r=Object.fromEntries(["filterableAttributes","searchableAttributes","sortableAttributes","displayedAttributes","pagination","synonyms","rankingRules","distinctAttribute","faceting","typoTolerance","dictionary"].filter((s)=>(s in t)).map((s)=>[s,t[s]]));return await Q(e,r)}async function hr(e){return await Q(e,{filterableAttributes:[],searchableAttributes:[],sortableAttributes:[],displayedAttributes:[],pagination:{},synonyms:{},rankingRules:[],distinctAttribute:null,faceting:{},typoTolerance:{},dictionary:[]})}var W,$e,Ie,Oe,qe,Fe,je,_e,ve,Ce,Ue,Me,Sr,vt;var Be=L(()=>{H();W=class W extends Error{status;constructor(e,t,n,r){super(`[search/opensearch] ${t} ${n} failed (${e}): ${r}`);this.status=e}};$e=w("filterableAttributes",[]),Ie=w("searchableAttributes",[]),Oe=w("sortableAttributes",[]),qe=w("displayedAttributes",[]),Fe=w("pagination",{}),je=w("synonyms",{}),_e=w("rankingRules",[]),ve=w("distinctAttribute",null),Ce=w("faceting",{}),Ue=w("typoTolerance",{}),Me=w("dictionary",[]);Sr={client:()=>({request:b,configuration:Le}),search:ar,createIndex:ur,getIndex:cr,updateIndex:lr,deleteIndex:dr,listAllIndexes:Ot,listAllIndices:Ot,addDocument:qt,addDocuments:Ft,updateDocument:qt,updateDocuments:Ft,getDocument:gr,deleteDocument:pr,deleteDocuments:yr,deleteAllDocuments:fr,getFilterableAttributes:$e.get,updateFilterableAttributes:$e.update,resetFilterableAttributes:$e.reset,getSearchableAttributes:Ie.get,updateSearchableAttributes:Ie.update,resetSearchableAttributes:Ie.reset,getSortableAttributes:Oe.get,updateSortableAttributes:Oe.update,resetSortableAttributes:Oe.reset,getDisplayedAttributes:qe.get,updateDisplayedAttributes:qe.update,resetDisplayedAttributes:qe.reset,getSettings:mr,updateSettings:br,resetSettings:hr,getPagination:Fe.get,updatePagination:Fe.update,resetPagination:Fe.reset,getSynonyms:je.get,updateSynonyms:je.update,resetSynonyms:je.reset,getRankingRules:_e.get,updateRankingRules:_e.update,resetRankingRules:_e.reset,getDistinctAttribute:ve.get,updateDistinctAttribute:ve.update,resetDistinctAttribute:ve.reset,getFaceting:Ce.get,updateFaceting:Ce.update,resetFaceting:Ce.reset,getTypoTolerance:Ue.get,updateTypoTolerance:Ue.update,resetTypoTolerance:Ue.reset,getDictionary:Me.get,updateDictionary:Me.update,resetDictionary:Me.reset},vt=Sr});var Vt={};z(Vt,{TypesenseImportError:()=>ze,default:()=>Yt});import{searchEngine as K}from"@stacksjs/config";import{log as Ar}from"@stacksjs/logging";function Lt(){if(!ee){let e=K.typesense?.host||process.env.TYPESENSE_HOST||"127.0.0.1",t=K.typesense?.port||Number(process.env.TYPESENSE_PORT||8108),n=K.typesense?.protocol||process.env.TYPESENSE_PROTOCOL||"http",r=K.typesense?.apiKey||process.env.TYPESENSE_API_KEY||"xyz";ee={host:e,port:t,protocol:n,apiKey:r}}return ee}function Ht(){let{protocol:e,host:t,port:n}=Lt();return`${e}://${t}:${n}`}function Bt(){return{"Content-Type":"application/json","X-TYPESENSE-API-KEY":Lt().apiKey}}function P(e){return{taskUid:0,indexUid:e,status:"succeeded",type:"documentAddition",enqueuedAt:new Date}}function Ke(e){return e instanceof We&&e.status===404}async function y(e,t,n){let r=await fetch(`${Ht()}${t}`,{method:e,headers:Bt(),body:n==null?void 0:JSON.stringify(n)});if(!r.ok){let s=await r.text().catch(()=>"");throw new We(r.status,e,t,s)}if(r.status===204)return;return await r.json()}function m(e){return`/collections/${encodeURIComponent(e)}`}function Nt(e){if(e==null||e==="")return;if(typeof e==="string")return e;if(Array.isArray(e))return e.map((r)=>Array.isArray(r)?`(${r.join(" || ")})`:r).filter(Boolean).join(" && ")||void 0;if(!R(e))throw TypeError(`[search/typesense] Unsupported filter: ${JSON.stringify(e)}`);let t=(r)=>`\`${String(r).replace(/`/g,"\\`")}\``,n=[];for(let[r,s]of Object.entries(e)){if(D("typesense",r),s==null||s==="")continue;n.push(Array.isArray(s)?`${r}:=[${s.map(t).join(",")}]`:`${r}:=${t(s)}`)}return n.length?n.join(" && "):void 0}function Tr(e){if(typeof e==="boolean")return"bool";if(typeof e==="number")return Number.isInteger(e)?"int64":"float";if(Array.isArray(e)){let t=e[0];if(typeof t==="boolean")return"bool[]";if(typeof t==="number")return Number.isInteger(t)?"int64[]":"float[]";return"string[]"}return"string"}function wr(e,t){let n={...te.get(e)};for(let[r,s]of Object.entries(t??{}))if(s!==void 0)n[r]=s;return te.set(e,n),n}function j(e){let t=[];for(let n of e??[])if(typeof n==="string")t.push(n);else t.push(...n.attributePatterns);return t}function Pr(e){let t={};for(let n of e)for(let[r,s]of Object.entries(n)){if(s==null)continue;let i=t[r];if(i===void 0||Array.isArray(i)&&i.length===0&&Array.isArray(s)&&s.length>0)t[r]=s}return t}function Wt(e,t,n){let r={name:e,type:e==="id"?"string":Tr(t??""),facet:j(n.filterableAttributes).includes(e),optional:e!=="id"};if(j(n.sortableAttributes).includes(e))r.sort=!0;return r}async function kr(e){try{return await y("GET",m(e))}catch(t){if(Ke(t))return;throw t}}function xr(e,t,n){let r={name:e.name,type:e.type,facet:t,optional:e.optional??!0};if(n!==void 0)r.sort=n;if(e.index===!1)r.index=!1;if(e.infix===!0)r.infix=!0;if(typeof e.locale==="string"&&e.locale!=="")r.locale=e.locale;return r}function Er(e,t,n){let r=[],s=new Set(e.map((c)=>c.name)),i=n.filterableAttributes!=null,o=j(n.filterableAttributes),a=j(n.sortableAttributes);for(let c of e){if(c.name==="id"||c.name.includes("*"))continue;let l=i?o.includes(c.name):Boolean(c.facet),p=a.includes(c.name)?!0:c.sort;if(l!==Boolean(c.facet)||p!==c.sort)r.push({name:c.name,drop:!0},xr(c,l,p))}for(let[c,l]of Object.entries(t)){if(c==="id"||s.has(c))continue;r.push(Wt(c,l,n))}return r}async function ne(e,t,n){let r=wr(e,n),s=Pr(t??[]),i=await kr(e);if(i){let a=Er(i.fields??[],s,r);if(a.length>0)await y("PATCH",m(e),{fields:a});return}if(!t||t.length===0)return;let o=new Set(["id"]);for(let a of[...j(r.searchableAttributes),...j(r.filterableAttributes),...j(r.sortableAttributes),...j(r.displayedAttributes),...Object.keys(s)])o.add(a);await y("POST","/collections",{name:e,fields:[...o].map((a)=>Wt(a,s[a],r))})}function Ge(e){let t={};for(let[n,r]of Object.entries(e)){if(r==null)continue;if(n==="id"||typeof r==="bigint")t[n]=String(r);else t[n]=r}if(e.id!=null&&t.id==null)t.id=String(e.id);return t}function Rr(e){let t=e.queryBy??e.query_by;if(t==null)return;return(Array.isArray(t)?t.join(","):String(t))||void 0}async function Dr(e,t={}){let{query:n,limit:r,offset:s,filter:i,sort:o}=F(t,K.perPage??q),a=t.filter_by||Nt(i),c=t.sort_by||U("typesense",o).join(","),l=Rr(t);if(!l)throw Error(`[search/typesense] search on "${e}" needs fields to search by. Pass \`query_by\`, or declare \`searchable\` on the model's \`useSearch\` trait so it can be supplied for you.`);let p=n===""?"*":n,f=new URLSearchParams({q:p,query_by:l});if(r>0&&s%r===0)f.set("per_page",String(r)),f.set("page",String(s/r+1));else f.set("offset",String(s)),f.set("limit",String(r));if(a)f.set("filter_by",a);if(c)f.set("sort_by",c);let T=await y("GET",`${m(e)}/documents/search?${f}`),O=(T.hits??[]).map((k)=>k.document);return{hits:O,query:p,processingTimeMs:T.search_time_ms??0,limit:r,offset:s,estimatedTotalHits:T.found??O.length}}async function Ct(e,t){let n=Ge(t);return await ne(e,[n]),await y("POST",`${m(e)}/documents?action=upsert`,n),P(e)}async function Ut(e,t){if(!Array.isArray(t))throw TypeError("[search/typesense] addDocuments requires an array of documents");if(t.length===0)return P(e);let n=t.map(Ge);await ne(e,n);let r=n.map((a)=>JSON.stringify(a)).join(`
|
|
5
|
+
`),s=await fetch(`${Ht()}${m(e)}/documents/import?action=upsert`,{method:"POST",headers:{...Bt(),"Content-Type":"text/plain"},body:r}),i=await s.text().catch(()=>"");if(!s.ok)throw Error(`[search/typesense] bulk import failed (${s.status}): ${i}`);let o=[];if(i.split(`
|
|
6
|
+
`).filter((a)=>a.trim()!=="").forEach((a,c)=>{let l;try{l=JSON.parse(a)}catch{l={success:!1,error:a}}if(l.success!==!0)o.push({id:n[c]?.id,error:l.error??"not written"})}),o.length>0)throw new ze(e,o,n.length);return P(e)}async function $r(e,t){return await y("DELETE",`${m(e)}/documents/${encodeURIComponent(String(t))}`),P(e)}async function Ir(e,t){let n=Nt(t);if(!n)throw Error(`[search/typesense] deleteDocuments on "${e}" needs a filter. Use deleteAllDocuments to empty the collection.`);return await y("DELETE",`${m(e)}/documents?${new URLSearchParams({filter_by:n})}`),P(e)}async function Or(e){try{await y("DELETE",`${m(e)}/documents?truncate=true`)}catch(t){if(!Ke(t))throw t}return P(e)}async function qr(e){try{await y("DELETE",m(e))}catch(t){if(!Ke(t))throw t;Ar.debug(`[search/typesense] deleteIndex ${e}: already absent`)}return te.delete(e),P(e)}async function Fr(e,t){let n=t?.sampleDocument;return await ne(e,n?[Ge(n)]:void 0,t?.settings),P(e)}async function jr(e){return await y("GET",m(e))}async function Ne(e,t){return await ne(e,void 0,t),P(e)}function X(e){return(t,n)=>Ne(t,{[e]:n??[]})}async function Je(e){return((await y("GET",m(e))).fields??[]).map((n)=>n.name).filter((n)=>n!=="id")}async function Kt(e){return((await y("GET",m(e))).fields??[]).filter((n)=>n.facet).map((n)=>n.name)}async function Gt(e){return((await y("GET",m(e))).fields??[]).filter((n)=>n.sort).map((n)=>n.name)}async function zt(e){return Je(e)}async function _r(e){return{searchableAttributes:await Je(e),filterableAttributes:await Kt(e),sortableAttributes:await Gt(e),displayedAttributes:await zt(e)}}function g(e,t){throw Error(`[search/typesense] ${e} is not supported by Typesense. ${t}`)}async function Mt(){let t=(await y("GET","/collections")).map((n)=>({...n,uid:n.name,primaryKey:"id"}));return{results:t,offset:0,limit:t.length,total:t.length}}async function vr(e,t){return await y("GET",`${m(e)}/documents/${encodeURIComponent(String(t))}`)}async function Cr(e){let t=await y("GET",`${m(e)}/synonyms`),n={};for(let r of t.synonyms??[]){if(r.root){n[r.root]=[...n[r.root]??[],...r.synonyms];continue}for(let s of r.synonyms)n[s]=[...n[s]??[],...r.synonyms.filter((i)=>i!==s)]}return n}async function Ur(e,t){await Jt(e);for(let[n,r]of Object.entries(t??{})){if(!r?.length)continue;await y("PUT",`${m(e)}/synonyms/${encodeURIComponent(`stacks-${n}`)}`,{root:n,synonyms:r})}return P(e)}async function Jt(e){let t=await y("GET",`${m(e)}/synonyms`);for(let n of t.synonyms??[])await y("DELETE",`${m(e)}/synonyms/${encodeURIComponent(n.id)}`);return P(e)}var ee=null,We,te,ze,h="Typesense takes it per search request, not as an index setting.",Z="Typesense derives it from the collection schema: declare it in the model's useSearch trait.",Mr,Yt;var Ve=L(()=>{H();We=class We extends Error{status;constructor(e,t,n,r){super(`[search/typesense] ${t} ${n} failed (${e}): ${r}`);this.status=e}};te=new Map;ze=class ze extends Error{indexName;failures;total;constructor(e,t,n){let r=t.slice(0,5).map((i)=>`#${String(i.id??"?")}: ${i.error}`).join("; "),s=t.length>5?`; and ${t.length-5} more`:"";super(`[search/typesense] import into "${e}" rejected ${t.length} of ${n} document(s): ${r}${s}`);this.indexName=e;this.failures=t;this.total=n}};Mr={client:()=>({}),resetClient:()=>{ee=null,te.clear()},search:Dr,getIndex:jr,createIndex:Fr,deleteIndex:qr,updateIndex:()=>g("updateIndex (changing the primary key)","A Typesense collection's key is always `id`."),listAllIndexes:Mt,listAllIndices:Mt,addDocument:Ct,addDocuments:Ut,updateDocument:(e,t)=>Ct(e,t),updateDocuments:(e,t)=>Ut(e,t),deleteDocument:$r,deleteDocuments:Ir,deleteAllDocuments:Or,getDocument:vr,getFilterableAttributes:Kt,updateFilterableAttributes:X("filterableAttributes"),resetFilterableAttributes:(e)=>Ne(e,{filterableAttributes:[]}),updateDisplayedAttributes:X("displayedAttributes"),resetDisplayedAttributes:()=>g("resetDisplayedAttributes",Z),getDisplayedAttributes:zt,updateSearchableAttributes:X("searchableAttributes"),resetSearchableAttributes:()=>g("resetSearchableAttributes",Z),getSearchableAttributes:Je,updateSortableAttributes:X("sortableAttributes"),resetSortableAttributes:()=>g("resetSortableAttributes",Z),getSortableAttributes:Gt,getSettings:_r,updateSettings:Ne,resetSettings:()=>g("resetSettings",Z),getPagination:()=>g("Index pagination settings",h),updatePagination:()=>g("Index pagination settings",h),resetPagination:()=>g("Index pagination settings",h),getSynonyms:Cr,updateSynonyms:Ur,resetSynonyms:Jt,getRankingRules:()=>g("Ranking rules",h),updateRankingRules:()=>g("Ranking rules",h),resetRankingRules:()=>g("Ranking rules",h),getDistinctAttribute:()=>g("A distinct attribute",h),updateDistinctAttribute:()=>g("A distinct attribute",h),resetDistinctAttribute:()=>g("A distinct attribute",h),getFaceting:()=>g("Faceting settings",h),updateFaceting:()=>g("Faceting settings",h),resetFaceting:()=>g("Faceting settings",h),getTypoTolerance:()=>g("Typo tolerance settings",h),updateTypoTolerance:()=>g("Typo tolerance settings",h),resetTypoTolerance:()=>g("Typo tolerance settings",h),getDictionary:()=>g("Custom dictionaries","Typesense has no equivalent."),updateDictionary:()=>g("Custom dictionaries","Typesense has no equivalent."),resetDictionary:()=>g("Custom dictionaries","Typesense has no equivalent.")},Yt=Mr});var Zt={};z(Zt,{default:()=>en});import{searchEngine as Ye}from"@stacksjs/config";function u(){if(!Qe)throw Error("The `meilisearch` search driver is selected but the `meilisearch` package is not installed. It is an opt-in dependency - run `bun add meilisearch` to enable it, or switch drivers in `config/search-engine.ts`.");if(!re){let e=Ye.meilisearch?.host||"http://127.0.0.1:7700",t=Ye.meilisearch?.apiKey||"";if(!e)throw Error("Meilisearch host is not configured. Please specify a search engine host.");re=new Qe({host:e,apiKey:t})}return re}function Lr(){re=null}async function Br(e,t={}){let{query:n,limit:r,offset:s,filter:i,sort:o}=F(t,Ye.perPage??q),a={limit:r,offset:s},c=Cs(i);if(c!==void 0)a.filter=c;let l=U("meilisearch",o);if(l.length>0)a.sort=l;for(let p of Hr)if(t[p]!==void 0)a[p]=t[p];return await u().index(e).search(n,a)}async function Nr(e,t){return await u().index(e).addDocuments([t])}async function Wr(e,t){if(!Array.isArray(t))throw TypeError("[search/meilisearch] addDocuments requires an array of documents");if(t.length<=1000)return await u().index(e).addDocuments(t);let r;for(let s=0;s<t.length;s+=1000){let i=t.slice(s,s+1000),o=await u().index(e).addDocuments(i);if(!r)r=o}return r}async function Kr(e){return await u().getIndex(e)}async function Gr(e,t){return await u().createIndex(e,t)}async function zr(e,t){return await u().updateIndex(e,t)}async function Jr(e,t){return await u().index(e).updateDocuments([t])}async function Vr(e,t){return await u().index(e).updateDocuments(t)}async function Yr(e,t){return await u().index(e).deleteDocument(t)}async function Qr(e,t){return await u().index(e).deleteDocuments({filter:t})}async function Xr(e){return await u().index(e).deleteAllDocuments()}async function Zr(e,t,n){return await u().index(e).getDocument(t,n)}async function es(e){return await u().deleteIndex(e)}async function Qt(){return await u().getIndexes()}async function ts(e){return(await u().index(e).getFilterableAttributes()??[]).filter((n)=>typeof n==="string")}async function ns(e,t){return u().index(e).updateFilterableAttributes(t)}async function rs(e){return u().index(e).resetFilterableAttributes()}async function ss(e,t){return u().index(e).updateSearchableAttributes(t)}async function is(e){return u().index(e).resetSearchableAttributes()}async function os(e){return u().index(e).getSearchableAttributes()}async function as(e,t){return u().index(e).updateSortableAttributes(t)}async function us(e){return u().index(e).resetSortableAttributes()}async function cs(e){return u().index(e).getSortableAttributes()}async function ls(e,t){return u().index(e).updateDisplayedAttributes(t)}async function ds(e){return u().index(e).getDisplayedAttributes()}async function gs(e){return u().index(e).resetDisplayedAttributes()}async function ps(e){return u().index(e).getSettings()}async function ys(e,t){return u().index(e).updateSettings(t)}async function fs(e){return u().index(e).resetSettings()}async function ms(e){return u().index(e).getPagination()}async function bs(e,t){return u().index(e).updatePagination(t)}async function hs(e){return u().index(e).resetPagination()}async function Ss(e){return u().index(e).getSynonyms()}async function As(e,t){return u().index(e).updateSynonyms(t)}async function Ts(e){return u().index(e).resetSynonyms()}async function ws(e){return u().index(e).getRankingRules()}async function Ps(e,t){return u().index(e).updateRankingRules(t)}async function ks(e){return u().index(e).resetRankingRules()}async function xs(e){return u().index(e).getDistinctAttribute()}async function Es(e,t){return u().index(e).updateDistinctAttribute(t)}async function Rs(e){return u().index(e).resetDistinctAttribute()}async function Ds(e){return u().index(e).getFaceting()}async function $s(e,t){return u().index(e).updateFaceting(t)}async function Is(e){return u().index(e).resetFaceting()}async function Os(e){return u().index(e).getTypoTolerance()}async function qs(e,t){return u().index(e).updateTypoTolerance(t)}async function Fs(e){return u().index(e).resetTypoTolerance()}async function js(e){return u().index(e).getDictionary()}async function _s(e,t){return u().index(e).updateDictionary(t)}async function vs(e){return u().index(e).resetDictionary()}function Xt(e){return`'${String(e).replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`}function Cs(e){if(e==null||e==="")return;if(typeof e==="string"||Array.isArray(e))return e;if(!R(e))throw TypeError(`[search/meilisearch] Unsupported filter: ${JSON.stringify(e)}`);let t=[];for(let[n,r]of Object.entries(e)){if(D("meilisearch",n),r===void 0)continue;if(r===null)t.push(`${n} IS NULL`);else if(Array.isArray(r))t.push(`${n} IN [${r.map(Xt).join(", ")}]`);else t.push(`${n} = ${Xt(r)}`)}return t.length>0?t:void 0}var Qe,re=null,Hr,Us,en;var Xe=L(async()=>{H();try{({Meilisearch:Qe}=await import("meilisearch"))}catch{}Hr=["attributesToRetrieve","attributesToHighlight","attributesToCrop","attributesToSearchOn","cropLength","cropMarker","distinct","facets","highlightPreTag","highlightPostTag","matchingStrategy","showMatchesPosition","showRankingScore"];Us={client:u,resetClient:Lr,search:Br,getIndex:Kr,createIndex:Gr,deleteIndex:es,updateIndex:zr,listAllIndexes:Qt,listAllIndices:Qt,addDocument:Nr,addDocuments:Wr,updateDocument:Jr,updateDocuments:Vr,deleteDocument:Yr,deleteDocuments:Qr,deleteAllDocuments:Xr,getDocument:Zr,getFilterableAttributes:ts,updateFilterableAttributes:ns,resetFilterableAttributes:rs,updateDisplayedAttributes:ls,resetDisplayedAttributes:gs,getDisplayedAttributes:ds,updateSearchableAttributes:ss,resetSearchableAttributes:is,getSearchableAttributes:os,updateSortableAttributes:as,resetSortableAttributes:us,getSortableAttributes:cs,getSettings:ps,updateSettings:ys,resetSettings:fs,getPagination:ms,updatePagination:bs,resetPagination:hs,getSynonyms:Ss,updateSynonyms:As,resetSynonyms:Ts,getRankingRules:ws,updateRankingRules:Ps,resetRankingRules:ks,getDistinctAttribute:xs,updateDistinctAttribute:Es,resetDistinctAttribute:Rs,getFaceting:Ds,updateFaceting:$s,resetFaceting:Is,getTypoTolerance:Os,updateTypoTolerance:qs,resetTypoTolerance:Fs,getDictionary:js,updateDictionary:_s,resetDictionary:vs},en=Us});import{overridesReady as Ms,searchEngine as tn}from"@stacksjs/config";import{err as un,ok as cn}from"@stacksjs/error-handling";import{log as _}from"@stacksjs/logging";import{getModelName as ln,getTableName as dn}from"@stacksjs/orm";import{path as Ze}from"@stacksjs/path";import{useSearchEngine as gn}from"@stacksjs/search-engine";import{globSync as pn}from"@stacksjs/storage";import{snakeCase as an}from"@stacksjs/strings";function J(e,t={}){let n={},r=(c)=>Array.isArray(c)?c.map((l)=>an(l)):void 0,s=r(e.searchable),i=r(e.filterable),o=r(e.sortable),a=t.displayed===!1?void 0:r(e.displayable);if(s)n.searchableAttributes=s;if(i)n.filterableAttributes=i;if(o)n.sortableAttributes=o;if(a)n.displayedAttributes=a;return n}async function Qs(e){try{let t=pn([Ze.userModelsPath("*.ts"),Ze.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{addDocument:n,updateSettings:r}=gn();for(let s of t){let i=(await import(s)).default,o=i.traits?.useSearch,a=dn(i,s),c=ln(i,s);if(e&&c!==e)continue;if(o&&(typeof o==="boolean"||typeof o==="object")){if(typeof o==="object")await r(a,J(o));let l=i;if(typeof l.all!=="function"){_.warn(`[search] ${c}: model has no .all() - define it with defineModel`);continue}let p=l.makeAllSearchable;if(typeof p==="function"){let x=await p.call(l);_.info(`[search] ${c}: imported ${x}, skipped 0`);continue}let f=typeof o==="object"?o.denormalize:void 0,T=f?Array.from(new Set(Object.values(f).map((x)=>x.split(".")[0]).filter((x)=>Boolean(x)))):[],O;if(T.length>0&&typeof l.query==="function")try{O=await l.query().with(...T).get()}catch(x){_.warn(`[search] ${c}: eager-load of [${T.join(", ")}] failed - falling back to .all(); denormalized fields will be null. (${x.message})`),O=await l.all()}else O=await l.all();let k=0,M=0;for(let x of O)try{let G=x.toSearchableObject?.();if(G==null){M++;continue}await n(a,G),k++}catch(G){M++,_.warn(`[search] Skipped ${c}#${x.id??"?"}: ${G.message}`)}_.info(`[search] ${c}: imported ${k}, skipped ${M}`)}}return _.info(e),cn("Successfully imported models to search engine!")}catch(t){return _.error(t),un(t?.message||String(t))}}import{err as yn,ok as fn}from"@stacksjs/error-handling";import{log as mn}from"@stacksjs/logging";import{getModelName as bn,getTableName as hn}from"@stacksjs/orm";import{path as et}from"@stacksjs/path";import{useSearchEngine as Sn}from"@stacksjs/search-engine";import{globSync as An}from"@stacksjs/storage";async function ii(e){try{let t=An([et.userModelsPath("*.ts"),et.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{deleteIndex:n}=Sn();for(let r of t){let s=(await import(r)).default,i=s.traits?.useSearch,o=hn(s,r),a=bn(s,r);if(e&&a!==e)continue;if(i&&(typeof i==="boolean"||typeof i==="object"))await n(o)}return fn("Successfully flushed all model data from search engine!")}catch(t){return mn.error(t),yn(t instanceof Error?t.message:String(t))}}import{err as Tn,ok as wn}from"@stacksjs/error-handling";import{log as Pn}from"@stacksjs/logging";import{getTableName as kn}from"@stacksjs/orm";import{path as xn}from"@stacksjs/path";import{useSearchEngine as En}from"@stacksjs/search-engine";async function gi(e){try{let t=xn.userModelsPath(`${e}.ts`),n=(await import(t)).default,{getFilterableAttributes:r,getSortableAttributes:s,getSearchableAttributes:i,getDisplayedAttributes:o}=En(),a=n.traits?.useSearch,c=kn(n,t);if(a&&typeof a==="object"){let l=await o(c),p=await r(c),f=await s(c),T=await i(c);console.table({displayedAttributes:l,filterableAttributes:p,sortableAttributes:f,searchableAttributes:T})}return wn("Successfully update index settings!")}catch(t){return Pn.error(t),Tn(t instanceof Error?t.message:String(t))}}import{err as Rn,ok as Dn}from"@stacksjs/error-handling";import{log as $n}from"@stacksjs/logging";import{getTableName as In}from"@stacksjs/orm";import{path as tt}from"@stacksjs/path";import{useSearchEngine as On}from"@stacksjs/search-engine";import{globSync as qn}from"@stacksjs/storage";async function Ti(){try{let e=qn([tt.userModelsPath("*.ts"),tt.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),{updateSettings:t}=On();for(let n of e){let r=(await import(n)).default,s=r.traits?.useSearch,i=In(r,n);if(s&&typeof s==="object")await t(i,J(s,{displayed:!1}))}return Dn("Successfully update index settings!")}catch(e){return $n.error(e),Rn(e?.message||String(e))}}function Ls(e){if(e==="algolia")return Promise.resolve().then(() => (De(),$t));if(e==="opensearch")return Promise.resolve().then(() => (Be(),_t));if(e==="typesense")return Promise.resolve().then(() => (Ve(),Vt));return Xe().then(() => Zt)}var se,nn=(async()=>(await Ms,se=(await Ls(tn.driver)).default,se))();function _i(){return new Proxy({},{get(e,t){if(se)return Reflect.get(se,t);if(typeof t==="symbol"||t==="then")return;return(...n)=>nn.then((r)=>{let s=Reflect.get(r,t);if(typeof s!=="function")throw TypeError(`The ${tn.driver??"configured"} search engine driver has no method "${t}"`);return s.apply(r,n)})}})}function vi(){return nn}function Ci(){return Promise.resolve().then(() => (De(),{})).then((e)=>It)}function Ui(){return Xe().then(() => ({})).then((e)=>en)}function Mi(){return Promise.resolve().then(() => (Be(),{})).then((e)=>vt)}function Li(){return Promise.resolve().then(() => (Ve(),{})).then((e)=>Yt)}export{ii as flushModelDocuments,Qs as importModelDocuments,gi as listIndexSettings,vi as searchEngineReady,J as settingsFromSearchTrait,Ti as updateIndexSettings,Ci as useAlgolia,Ui as useMeilisearch,Mi as useOpensearch,_i as useSearchEngine,Li as useTypesense};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/search-engine",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.74",
|
|
6
6
|
"description": "The Stacks search engine integrations.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -64,13 +64,13 @@
|
|
|
64
64
|
"prepublishOnly": "bun run build"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@stacksjs/config": "0.75.
|
|
68
|
-
"@stacksjs/error-handling": "0.75.
|
|
69
|
-
"@stacksjs/logging": "0.75.
|
|
70
|
-
"@stacksjs/orm": "0.75.
|
|
71
|
-
"@stacksjs/path": "0.75.
|
|
72
|
-
"@stacksjs/storage": "0.75.
|
|
73
|
-
"@stacksjs/strings": "0.75.
|
|
67
|
+
"@stacksjs/config": "0.75.74",
|
|
68
|
+
"@stacksjs/error-handling": "0.75.74",
|
|
69
|
+
"@stacksjs/logging": "0.75.74",
|
|
70
|
+
"@stacksjs/orm": "0.75.74",
|
|
71
|
+
"@stacksjs/path": "0.75.74",
|
|
72
|
+
"@stacksjs/storage": "0.75.74",
|
|
73
|
+
"@stacksjs/strings": "0.75.74"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"meilisearch": "^0.62.0"
|