@skawr/search 0.1.0 → 0.2.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/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,13 +13,14 @@ interface SearchFilters {
|
|
|
13
13
|
}
|
|
14
14
|
type SortBy = 'relevance' | 'price_asc' | 'price_desc' | 'date_desc';
|
|
15
15
|
interface SearchOptions {
|
|
16
|
-
index?: string;
|
|
17
16
|
filters?: SearchFilters;
|
|
18
17
|
page?: number;
|
|
19
18
|
per_page?: number;
|
|
20
19
|
sort_by?: SortBy;
|
|
21
20
|
highlight_matches?: boolean;
|
|
22
21
|
result_format?: 'standard' | 'minimal' | 'detailed';
|
|
22
|
+
/** Anonymous shopper ID for personalization. Generated and persisted automatically by the SDK. */
|
|
23
|
+
anonymous_id?: string;
|
|
23
24
|
}
|
|
24
25
|
interface SearchResult {
|
|
25
26
|
id: string;
|
|
@@ -57,7 +58,6 @@ interface SearchResponse {
|
|
|
57
58
|
search_id: string;
|
|
58
59
|
}
|
|
59
60
|
interface SuggestOptions {
|
|
60
|
-
index?: string;
|
|
61
61
|
limit?: number;
|
|
62
62
|
include_trending?: boolean;
|
|
63
63
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
export{
|
|
1
|
+
var o=class extends Error{status;detail;constructor(t,e,r){super(t),this.name="SearchError",this.status=e,this.detail=r??t;}};var g="https://api.skawr.com",l=1e4,p="skawr_anon_id";function d(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return (n==="x"?t:t&3|8).toString(16)})}function m(){if(!(typeof window>"u"||typeof localStorage>"u"))try{let n=localStorage.getItem(p);return n||(n=d(),localStorage.setItem(p,n)),n}catch{return}}var c=class{baseUrl;publicKey;timeout;constructor(t){if(!t.publicKey)throw new Error("publicKey is required");this.baseUrl=(t.baseUrl??g).replace(/\/+$/,""),this.publicKey=t.publicKey,this.timeout=t.timeout??l;}async search(t,e){let r=e?.anonymous_id??m();return this.post("/api/v1/search",{query:t,filters:e?.filters,page:e?.page,per_page:e?.per_page,sort_by:e?.sort_by,highlight_matches:e?.highlight_matches??true,result_format:e?.result_format,enable_personalization:true,anonymous_id:r})}async suggest(t,e){let r={q:t};return e?.limit!==void 0&&(r.limit=String(e.limit)),e?.include_trending!==void 0&&(r.include_trending=String(e.include_trending)),this.get("/api/v1/search/suggestions",r)}async autocomplete(t,e){let r={q:t};return e?.limit!==void 0&&(r.limit=String(e.limit)),this.get("/api/v1/autocomplete",r)}async get(t,e){let r=`${this.baseUrl}${t}`;if(e){let s=new URLSearchParams(e).toString();s&&(r+=`?${s}`);}return this.request(r,{method:"GET"})}async post(t,e){return this.request(`${this.baseUrl}${t}`,{method:"POST",body:JSON.stringify(e)})}async request(t,e){let r={"X-API-Key":this.publicKey,Accept:"application/json"};e.body&&(r["Content-Type"]="application/json");let s;try{s=await fetch(t,{...e,headers:r,signal:AbortSignal.timeout(this.timeout)});}catch(i){throw i instanceof DOMException&&i.name==="TimeoutError"?new o("Request timed out",0,"Request timed out"):i}if(!s.ok){let i=await s.text(),a;try{let u=JSON.parse(i);a=typeof u.detail=="string"?u.detail:i;}catch{a=i||s.statusText;}throw new o(a,s.status,a)}return await s.json()}};
|
|
2
|
+
export{o as SearchError,c as SkawrSearch};//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":["SearchError","message","status","detail","DEFAULT_BASE_URL","DEFAULT_TIMEOUT","SkawrSearch","config","query","options","params","path","url","qs","body","init","headers","response","error","text","parsed"],"mappings":"AAAO,IAAMA,
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":["SearchError","message","status","detail","DEFAULT_BASE_URL","DEFAULT_TIMEOUT","ANON_ID_KEY","generateAnonId","c","r","getOrCreateAnonId","id","SkawrSearch","config","query","options","anonId","params","path","url","qs","body","init","headers","response","error","text","parsed"],"mappings":"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","file":"index.js","sourcesContent":["export class SearchError extends Error {\n readonly status: number;\n readonly detail: string;\n\n constructor(message: string, status: number, detail?: string) {\n super(message);\n this.name = 'SearchError';\n this.status = status;\n this.detail = detail ?? message;\n }\n}\n","import { SearchError } from './errors.js';\nimport type {\n SkawrSearchConfig,\n SearchOptions,\n SearchResponse,\n SuggestOptions,\n SuggestionsResponse,\n AutocompleteOptions,\n AutocompleteResponse,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.skawr.com';\nconst DEFAULT_TIMEOUT = 10_000;\nconst ANON_ID_KEY = 'skawr_anon_id';\n\n/** Generate a UUID v4 using crypto.randomUUID when available, fallback to Math.random. */\nfunction generateAnonId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID();\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/** Get or create a persistent anonymous ID for this browser/device. */\nfunction getOrCreateAnonId(): string | undefined {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') return undefined;\n try {\n let id = localStorage.getItem(ANON_ID_KEY);\n if (!id) {\n id = generateAnonId();\n localStorage.setItem(ANON_ID_KEY, id);\n }\n return id;\n } catch {\n // localStorage disabled (private mode, etc.)\n return undefined;\n }\n}\n\nexport class SkawrSearch {\n private readonly baseUrl: string;\n private readonly publicKey: string;\n private readonly timeout: number;\n\n constructor(config: SkawrSearchConfig) {\n if (!config.publicKey) {\n throw new Error('publicKey is required');\n }\n\n this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this.publicKey = config.publicKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n }\n\n async search(query: string, options?: SearchOptions): Promise<SearchResponse> {\n const anonId = options?.anonymous_id ?? getOrCreateAnonId();\n return this.post<SearchResponse>('/api/v1/search', {\n query,\n filters: options?.filters,\n page: options?.page,\n per_page: options?.per_page,\n sort_by: options?.sort_by,\n highlight_matches: options?.highlight_matches ?? true,\n result_format: options?.result_format,\n enable_personalization: true,\n anonymous_id: anonId,\n });\n }\n\n async suggest(query: string, options?: SuggestOptions): Promise<SuggestionsResponse> {\n const params: Record<string, string> = { q: query };\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.include_trending !== undefined) params.include_trending = String(options.include_trending);\n\n return this.get<SuggestionsResponse>('/api/v1/search/suggestions', params);\n }\n\n async autocomplete(query: string, options?: AutocompleteOptions): Promise<AutocompleteResponse> {\n const params: Record<string, string> = { q: query };\n if (options?.limit !== undefined) params.limit = String(options.limit);\n\n return this.get<AutocompleteResponse>('/api/v1/autocomplete', params);\n }\n\n private async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n let url = `${this.baseUrl}${path}`;\n if (params) {\n const qs = new URLSearchParams(params).toString();\n if (qs) url += `?${qs}`;\n }\n\n return this.request<T>(url, { method: 'GET' });\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(`${this.baseUrl}${path}`, {\n method: 'POST',\n body: JSON.stringify(body),\n });\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const headers: Record<string, string> = {\n 'X-API-Key': this.publicKey,\n 'Accept': 'application/json',\n };\n\n if (init.body) {\n headers['Content-Type'] = 'application/json';\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n ...init,\n headers,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === 'TimeoutError') {\n throw new SearchError('Request timed out', 0, 'Request timed out');\n }\n throw error;\n }\n\n if (!response.ok) {\n const text = await response.text();\n let detail: string;\n try {\n const parsed = JSON.parse(text);\n detail = typeof parsed.detail === 'string' ? parsed.detail : text;\n } catch {\n detail = text || response.statusText;\n }\n throw new SearchError(detail, response.status, detail);\n }\n\n return (await response.json()) as T;\n }\n}\n"]}
|