@nosto/search-js 0.1.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 +29 -0
- package/README.md +48 -0
- package/dist/currencies/getCurrencyFormatting.d.ts +11 -0
- package/dist/currencies/priceDecorator.d.ts +14 -0
- package/dist/currencies.cjs.js +1 -0
- package/dist/currencies.d.ts +2 -0
- package/dist/currencies.es.js +68 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es-Bcd5IQh9.js +20 -0
- package/dist/index.es-D_7T9vdv.cjs +1 -0
- package/dist/index.es.js +20 -0
- package/dist/search.d.ts +17 -0
- package/dist/thumbnails/generateThumbnailUrl.d.ts +8 -0
- package/dist/thumbnails/shopifyThumbnailDecorator.d.ts +11 -0
- package/dist/thumbnails/thumbnailDecorator.d.ts +10 -0
- package/dist/thumbnails/types.d.ts +33 -0
- package/dist/thumbnails.cjs.js +1 -0
- package/dist/thumbnails.d.ts +4 -0
- package/dist/thumbnails.es.js +80 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Nosto
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Search JS
|
|
2
|
+
|
|
3
|
+
Search JS is a wrapper for the Nosto Search functionality with some extended functionality such as
|
|
4
|
+
* Nosto currency formatting
|
|
5
|
+
* Nosto product thumbnails
|
|
6
|
+
* Retry logic
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
To install the package, use your preferred package manager:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
yarn add @nosto/search-js
|
|
14
|
+
# or
|
|
15
|
+
npm install @nosto/search-js --save
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Nosto stub
|
|
19
|
+
|
|
20
|
+
When using this library, it is not necessary to create the Nosto stub. It will be created automatically as soon as the library is imported for the first time.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
The main export of this library is the `search` function. It is compatible with the search function of the Nosto JS API and adds a couple of additional options
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { search } from "@nosto/search-js"
|
|
28
|
+
import { priceDecorator } from "@nosto/search-js/currencies"
|
|
29
|
+
|
|
30
|
+
const response = await search({
|
|
31
|
+
query: 'my search',
|
|
32
|
+
products: {
|
|
33
|
+
fields: [
|
|
34
|
+
"productId",
|
|
35
|
+
"name",
|
|
36
|
+
"price",
|
|
37
|
+
"listPrice",
|
|
38
|
+
"priceCurrencyCode"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}, {
|
|
42
|
+
track: 'serp',
|
|
43
|
+
hitDecorators: [
|
|
44
|
+
priceDecorator()
|
|
45
|
+
]
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CurrencySettingsDTO } from "@nosto/nosto-js/client";
|
|
2
|
+
type CurrencyFormats = Record<string, CurrencySettingsDTO>;
|
|
3
|
+
export interface CurrencyConfig {
|
|
4
|
+
defaultCurrency: string;
|
|
5
|
+
defaultLocale: string;
|
|
6
|
+
currencySettings: CurrencyFormats;
|
|
7
|
+
}
|
|
8
|
+
export declare function getCurrencyFormatting(overrides?: Partial<CurrencyConfig>): {
|
|
9
|
+
formatCurrency: (value: number, currency?: string) => string;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SearchProduct, SearchProductSku } from "@nosto/nosto-js/client";
|
|
2
|
+
import { CurrencyConfig } from "./getCurrencyFormatting";
|
|
3
|
+
type FormattedPrices = {
|
|
4
|
+
priceText?: string;
|
|
5
|
+
listPriceText?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Exposes currency formatting logic as a SearchProduct decorator
|
|
9
|
+
* Sets priceText and listPriceText fields on product and SKU level
|
|
10
|
+
*/
|
|
11
|
+
export declare function priceDecorator(config?: Partial<CurrencyConfig>): (hit: SearchProduct) => SearchProduct & FormattedPrices & {
|
|
12
|
+
skus?: (SearchProductSku & FormattedPrices)[];
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./index.es-D_7T9vdv.cjs"),g={defaultCurrency:"EUR",defaultLocale:"en-US",currencySettings:{}},p={EUR:"de-DE",GBP:"en-GB",USD:"en-US",AUD:"en-AU",CAD:"en-CA",INR:"en-IN",AFN:"en-IN",BDT:"en-IN",BTN:"en-IN",MMK:"en-IN",NPR:"en-IN",PKR:"en-IN"};function d(o={}){const u={...g,...o};o.currencySettings||y.s(c=>{u.currencySettings=c.internal.getSettings().currencySettings});function a(c,n){const{defaultCurrency:t,currencySettings:e,defaultLocale:i}=u,s=n??t,m=p[s]??i;if(s in e){const r=e[s],l=new Intl.NumberFormat(m,{useGrouping:!!r.groupingSeparator,minimumFractionDigits:r.decimalPlaces,maximumFractionDigits:r.decimalPlaces}).formatToParts(c).map(f=>f.type==="group"?r.groupingSeparator:f.type==="decimal"?r.decimalCharacter:f.value).join("");return r!=null&&r.currencyBeforeAmount?`${r.currencyToken}${l}`:`${l}${r==null?void 0:r.currencyToken}`}return new Intl.NumberFormat(m,{style:"currency",currency:s}).format(c)}return{formatCurrency:a}}function C(o){const{formatCurrency:u}=d(o);function a(n,t){const e={};return n.price!==void 0&&(e.priceText=u(n.price,t)),n.listPrice!==void 0&&(e.listPriceText=u(n.listPrice,t)),Object.assign({},n,e)}function c(n){return n.price!==void 0||n.listPrice!==void 0}return function(t){if(!c(t))return t;const e=a(t,t.priceCurrencyCode);return e.skus&&e.skus.some(c)&&(e.skus=e.skus.map(i=>c(i)?a(i,t.priceCurrencyCode):i)),e}}exports.getCurrencyFormatting=d;exports.priceDecorator=C;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { s as d } from "./index.es-Bcd5IQh9.js";
|
|
2
|
+
const y = {
|
|
3
|
+
defaultCurrency: "EUR",
|
|
4
|
+
defaultLocale: "en-US",
|
|
5
|
+
/** @hidden */
|
|
6
|
+
currencySettings: {}
|
|
7
|
+
}, p = {
|
|
8
|
+
EUR: "de-DE",
|
|
9
|
+
GBP: "en-GB",
|
|
10
|
+
USD: "en-US",
|
|
11
|
+
AUD: "en-AU",
|
|
12
|
+
CAD: "en-CA",
|
|
13
|
+
//India, Afghanistan, Bangladesh, Bhutan, Myanmar, Nepal, and Pakistan uses lakhs and crores notation
|
|
14
|
+
INR: "en-IN",
|
|
15
|
+
AFN: "en-IN",
|
|
16
|
+
BDT: "en-IN",
|
|
17
|
+
BTN: "en-IN",
|
|
18
|
+
MMK: "en-IN",
|
|
19
|
+
NPR: "en-IN",
|
|
20
|
+
PKR: "en-IN"
|
|
21
|
+
};
|
|
22
|
+
function g(o = {}) {
|
|
23
|
+
const u = {
|
|
24
|
+
...y,
|
|
25
|
+
...o
|
|
26
|
+
};
|
|
27
|
+
o.currencySettings || d((c) => {
|
|
28
|
+
u.currencySettings = c.internal.getSettings().currencySettings;
|
|
29
|
+
});
|
|
30
|
+
function a(c, n) {
|
|
31
|
+
const { defaultCurrency: t, currencySettings: e, defaultLocale: i } = u, s = n ?? t, m = p[s] ?? i;
|
|
32
|
+
if (s in e) {
|
|
33
|
+
const r = e[s], l = new Intl.NumberFormat(m, {
|
|
34
|
+
useGrouping: !!r.groupingSeparator,
|
|
35
|
+
minimumFractionDigits: r.decimalPlaces,
|
|
36
|
+
maximumFractionDigits: r.decimalPlaces
|
|
37
|
+
}).formatToParts(c).map((f) => f.type === "group" ? r.groupingSeparator : f.type === "decimal" ? r.decimalCharacter : f.value).join("");
|
|
38
|
+
return r != null && r.currencyBeforeAmount ? `${r.currencyToken}${l}` : `${l}${r == null ? void 0 : r.currencyToken}`;
|
|
39
|
+
}
|
|
40
|
+
return new Intl.NumberFormat(m, {
|
|
41
|
+
style: "currency",
|
|
42
|
+
currency: s
|
|
43
|
+
}).format(c);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
formatCurrency: a
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function S(o) {
|
|
50
|
+
const { formatCurrency: u } = g(o);
|
|
51
|
+
function a(n, t) {
|
|
52
|
+
const e = {};
|
|
53
|
+
return n.price !== void 0 && (e.priceText = u(n.price, t)), n.listPrice !== void 0 && (e.listPriceText = u(n.listPrice, t)), Object.assign({}, n, e);
|
|
54
|
+
}
|
|
55
|
+
function c(n) {
|
|
56
|
+
return n.price !== void 0 || n.listPrice !== void 0;
|
|
57
|
+
}
|
|
58
|
+
return function(t) {
|
|
59
|
+
if (!c(t))
|
|
60
|
+
return t;
|
|
61
|
+
const e = a(t, t.priceCurrencyCode);
|
|
62
|
+
return e.skus && e.skus.some(c) && (e.skus = e.skus.map((i) => c(i) ? a(i, t.priceCurrencyCode) : i)), e;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
g as getCurrencyFormatting,
|
|
67
|
+
S as priceDecorator
|
|
68
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index.es-D_7T9vdv.cjs");async function i(t,{hitDecorators:r,...u}={}){const c=await new Promise(a.s);return r!=null&&r.length?d(await c.search(t,u),r):await c.search(t,u)}function d(t,r){if(!t.products)return t;const u=c=>r.reduce((e,n)=>n(e),c);return{...t,products:{...t.products,hits:t.products.hits.map(u)}}}exports.search=i;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { search, type Options, type HitDecorator } from "./search";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function o() {
|
|
2
|
+
window.nostojs = window.nostojs ?? function(n) {
|
|
3
|
+
(window.nostojs.q = window.nostojs.q ?? []).push(n);
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
async function i(n) {
|
|
7
|
+
return window.nostojs(n);
|
|
8
|
+
}
|
|
9
|
+
let t = null;
|
|
10
|
+
typeof window < "u" && (o(), i((n) => {
|
|
11
|
+
t = n.internal.getSettings();
|
|
12
|
+
}));
|
|
13
|
+
function s() {
|
|
14
|
+
return t;
|
|
15
|
+
}
|
|
16
|
+
typeof window < "u" && o();
|
|
17
|
+
export {
|
|
18
|
+
s as i,
|
|
19
|
+
i as s
|
|
20
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function o(){window.nostojs=window.nostojs??function(n){(window.nostojs.q=window.nostojs.q??[]).push(n)}}async function t(n){return window.nostojs(n)}let s=null;typeof window<"u"&&(o(),t(n=>{s=n.internal.getSettings()}));function i(){return s}typeof window<"u"&&o();exports.i=i;exports.s=t;
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { s as d } from "./index.es-Bcd5IQh9.js";
|
|
2
|
+
async function p(r, { hitDecorators: t, ...u } = {}) {
|
|
3
|
+
const a = await new Promise(d);
|
|
4
|
+
return t != null && t.length ? i(await a.search(r, u), t) : await a.search(r, u);
|
|
5
|
+
}
|
|
6
|
+
function i(r, t) {
|
|
7
|
+
if (!r.products)
|
|
8
|
+
return r;
|
|
9
|
+
const u = (a) => t.reduce((c, n) => n(c), a);
|
|
10
|
+
return {
|
|
11
|
+
...r,
|
|
12
|
+
products: {
|
|
13
|
+
...r.products,
|
|
14
|
+
hits: r.products.hits.map(u)
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
p as search
|
|
20
|
+
};
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SearchOptions, SearchProduct, SearchQuery, SearchResult } from "@nosto/nosto-js/client";
|
|
2
|
+
export type Options = SearchOptions & {
|
|
3
|
+
/**
|
|
4
|
+
* Hit decorators to apply to the search results.
|
|
5
|
+
*/
|
|
6
|
+
hitDecorators?: HitDecorator[];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Performs a search operation using the provided query and options.
|
|
10
|
+
*
|
|
11
|
+
* @param query - The search query to be executed.
|
|
12
|
+
* @param options - An object containing optional parameters for the search.
|
|
13
|
+
* @param options.hitDecorators - An optional array of decorators to be applied to the search results.
|
|
14
|
+
* @returns A promise that resolves to the search result.
|
|
15
|
+
*/
|
|
16
|
+
export declare function search(query: SearchQuery, { hitDecorators, ...options }?: Options): Promise<SearchResult>;
|
|
17
|
+
export type HitDecorator = (hit: SearchProduct) => SearchProduct;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SearchProduct } from "@nosto/nosto-js/client";
|
|
2
|
+
import { ShopifySize } from "./types";
|
|
3
|
+
type Config = {
|
|
4
|
+
size: ShopifySize;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Replaces full size images with specified Shopify thumbnail size.
|
|
8
|
+
* This decorator will only affect the image URLs from Shopify CDN.
|
|
9
|
+
*/
|
|
10
|
+
export declare function shopifyThumbnailDecorator({ size }: Config): (hit: SearchProduct) => SearchProduct;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SearchProduct } from "@nosto/nosto-js/client";
|
|
2
|
+
import { ThumbnailSize } from "./types";
|
|
3
|
+
type Config = {
|
|
4
|
+
size: ThumbnailSize;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Replaces full size images with thumbnail sized versions.
|
|
8
|
+
*/
|
|
9
|
+
export declare function thumbnailDecorator({ size }: Config): (hit: SearchProduct) => SearchProduct;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nosto thumbnail size code.
|
|
3
|
+
*
|
|
4
|
+
* "1": 170x170 px
|
|
5
|
+
* "2": 100x100 px
|
|
6
|
+
* "3": 90x70 px
|
|
7
|
+
* "4": 50x50 px
|
|
8
|
+
* "5": 30x30 px
|
|
9
|
+
* "6": 100x140 px
|
|
10
|
+
* "7": 200x200 px
|
|
11
|
+
* "8": 400x400 px
|
|
12
|
+
* "9": 750x750 px
|
|
13
|
+
* "10": Original (Square)
|
|
14
|
+
* "11": 200x200 px (Square)
|
|
15
|
+
* "12": 400x400 px (Square)
|
|
16
|
+
* "13": 750x750 px (Square)
|
|
17
|
+
*/
|
|
18
|
+
export type ThumbnailSize = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "orig";
|
|
19
|
+
/**
|
|
20
|
+
* Shopify thumbnail size code.
|
|
21
|
+
*
|
|
22
|
+
* Pico (16×16 px)
|
|
23
|
+
* Icon (32×32 px)
|
|
24
|
+
* Thumb (50×50 px)
|
|
25
|
+
* Small (100×100 px)
|
|
26
|
+
* Compact (160×160 px)
|
|
27
|
+
* Medium (240×240 px)
|
|
28
|
+
* Large (480×480 px)
|
|
29
|
+
* Grande (600×600 px)
|
|
30
|
+
* Original (1024×1024 px)
|
|
31
|
+
* Master (full size)
|
|
32
|
+
*/
|
|
33
|
+
export type ShopifySize = "pico" | "icon" | "thumb" | "small" | "compact" | "medium" | "large" | "grande" | "original" | "master";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./index.es-D_7T9vdv.cjs");function i({size:o,productId:n,hash:t}){const u=c.i();if(!u)throw new Error("Client script settings are not yet available");return`https://${u.thumbnailHost}/${u.account}/${o}/${n}/${t}/A`}function s({size:o}){function n(a,r){if(r)return i({size:o,productId:a,hash:r})}function t(a,r){if(r)return r.map(e=>({...e,imageUrl:n(a,e.imageHash)??e.imageUrl}))}function u(a,r,e){if(!e)return r;if(r)return e.map(l=>i({size:o,productId:a,hash:l}))}return function(r){const e=r.productId;return e?{...r,imageUrl:n(e,r.imageHash)??r.imageUrl,thumbUrl:n(e,r.thumbHash)??r.thumbUrl,skus:t(e,r.skus),alternateImageUrls:u(e,r.alternateImageUrls,r.alternateImageHashes)}:r}}const m=/cdn\.shopify\.com/;function f({size:o}){function n(r){return r?new URL(r).hostname.match(m):!1}function t(r){return r?n(r)?r.replace(/(\.jpg|\.png|\.jpeg|\.gif|\.webp)/,`_${o}$1`):r:""}function u(r){if(r)return r.map(e=>({...e,imageUrl:t(e.imageUrl)}))}function a(r){if(r)return r.map(e=>t(e))}return function(e){return n(e.imageUrl)?{...e,imageUrl:t(e.imageUrl),thumbUrl:t(e.thumbUrl),skus:u(e.skus),alternateImageUrls:a(e.alternateImageUrls)}:e}}exports.generateThumbnailUrl=i;exports.shopifyThumbnailDecorator=f;exports.thumbnailDecorator=s;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { generateThumbnailUrl } from "./thumbnails/generateThumbnailUrl";
|
|
2
|
+
export { thumbnailDecorator } from "./thumbnails/thumbnailDecorator";
|
|
3
|
+
export { shopifyThumbnailDecorator } from "./thumbnails/shopifyThumbnailDecorator";
|
|
4
|
+
export type { ThumbnailSize, ShopifySize } from "./thumbnails/types";
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { i as m } from "./index.es-Bcd5IQh9.js";
|
|
2
|
+
function i({ size: o, productId: n, hash: t }) {
|
|
3
|
+
const u = m();
|
|
4
|
+
if (!u)
|
|
5
|
+
throw new Error("Client script settings are not yet available");
|
|
6
|
+
return `https://${u.thumbnailHost}/${u.account}/${o}/${n}/${t}/A`;
|
|
7
|
+
}
|
|
8
|
+
function s({ size: o }) {
|
|
9
|
+
function n(a, r) {
|
|
10
|
+
if (r)
|
|
11
|
+
return i({
|
|
12
|
+
size: o,
|
|
13
|
+
productId: a,
|
|
14
|
+
hash: r
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function t(a, r) {
|
|
18
|
+
if (r)
|
|
19
|
+
return r.map((e) => ({
|
|
20
|
+
...e,
|
|
21
|
+
imageUrl: n(a, e.imageHash) ?? e.imageUrl
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
function u(a, r, e) {
|
|
25
|
+
if (!e)
|
|
26
|
+
return r;
|
|
27
|
+
if (r)
|
|
28
|
+
return e.map(
|
|
29
|
+
(f) => i({
|
|
30
|
+
size: o,
|
|
31
|
+
productId: a,
|
|
32
|
+
hash: f
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return function(r) {
|
|
37
|
+
const e = r.productId;
|
|
38
|
+
return e ? {
|
|
39
|
+
...r,
|
|
40
|
+
imageUrl: n(e, r.imageHash) ?? r.imageUrl,
|
|
41
|
+
thumbUrl: n(e, r.thumbHash) ?? r.thumbUrl,
|
|
42
|
+
skus: t(e, r.skus),
|
|
43
|
+
alternateImageUrls: u(e, r.alternateImageUrls, r.alternateImageHashes)
|
|
44
|
+
} : r;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const l = /cdn\.shopify\.com/;
|
|
48
|
+
function g({ size: o }) {
|
|
49
|
+
function n(r) {
|
|
50
|
+
return r ? new URL(r).hostname.match(l) : !1;
|
|
51
|
+
}
|
|
52
|
+
function t(r) {
|
|
53
|
+
return r ? n(r) ? r.replace(/(\.jpg|\.png|\.jpeg|\.gif|\.webp)/, `_${o}$1`) : r : "";
|
|
54
|
+
}
|
|
55
|
+
function u(r) {
|
|
56
|
+
if (r)
|
|
57
|
+
return r.map((e) => ({
|
|
58
|
+
...e,
|
|
59
|
+
imageUrl: t(e.imageUrl)
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
function a(r) {
|
|
63
|
+
if (r)
|
|
64
|
+
return r.map((e) => t(e));
|
|
65
|
+
}
|
|
66
|
+
return function(e) {
|
|
67
|
+
return n(e.imageUrl) ? {
|
|
68
|
+
...e,
|
|
69
|
+
imageUrl: t(e.imageUrl),
|
|
70
|
+
thumbUrl: t(e.thumbUrl),
|
|
71
|
+
skus: u(e.skus),
|
|
72
|
+
alternateImageUrls: a(e.alternateImageUrls)
|
|
73
|
+
} : e;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
i as generateThumbnailUrl,
|
|
78
|
+
g as shopifyThumbnailDecorator,
|
|
79
|
+
s as thumbnailDecorator
|
|
80
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nosto/search-js",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "ISC",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/index.cjs.js",
|
|
10
|
+
"module": "./dist/index.es.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"directories": {
|
|
13
|
+
"doc": "docs",
|
|
14
|
+
"test": "test"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.es.js",
|
|
20
|
+
"require": "./dist/index.cjs.js"
|
|
21
|
+
},
|
|
22
|
+
"./currencies": {
|
|
23
|
+
"types": "./dist/currencies.d.ts",
|
|
24
|
+
"import": "./dist/currencies.es.js",
|
|
25
|
+
"require": "./dist/currencies.cjs.js"
|
|
26
|
+
},
|
|
27
|
+
"./thumbnails": {
|
|
28
|
+
"types": "./dist/thumbnails.d.ts",
|
|
29
|
+
"import": "./dist/thumbnails.es.js",
|
|
30
|
+
"require": "./dist/thumbnails.cjs.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"keywords": [],
|
|
34
|
+
"author": "Nosto",
|
|
35
|
+
"scripts": {
|
|
36
|
+
"dev": "vite",
|
|
37
|
+
"build": "tsc && vite build && npm run build-dts && npm run typedoc",
|
|
38
|
+
"build-dts": "tsc --noEmit false --emitDeclarationOnly",
|
|
39
|
+
"test": "vitest --run",
|
|
40
|
+
"lint": "eslint '{src,test}/**/*.ts'",
|
|
41
|
+
"preview": "vite preview",
|
|
42
|
+
"typedoc": "typedoc src/index.ts"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@nosto/nosto-js": "^1.4.4",
|
|
46
|
+
"@testing-library/dom": "^10.4.0",
|
|
47
|
+
"@types/eslint-config-prettier": "^6.11.3",
|
|
48
|
+
"@types/node": "^22.10.10",
|
|
49
|
+
"copyfiles": "^2.4.1",
|
|
50
|
+
"eslint": "^9.19.0",
|
|
51
|
+
"eslint-config-prettier": "^10.0.1",
|
|
52
|
+
"eslint-plugin-barrel-files": "^2.1.0",
|
|
53
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
54
|
+
"jsdom": "^26.0.0",
|
|
55
|
+
"prettier": "^3.3.3",
|
|
56
|
+
"typedoc": "^0.27.2",
|
|
57
|
+
"typescript": "^5.7.3",
|
|
58
|
+
"typescript-eslint": "^8.22.0",
|
|
59
|
+
"vite": "^6.0.11",
|
|
60
|
+
"vitest": "^3.0.4"
|
|
61
|
+
},
|
|
62
|
+
"publishConfig": {
|
|
63
|
+
"access": "public"
|
|
64
|
+
}
|
|
65
|
+
}
|