@getlupa/vue 0.6.3 → 0.7.1

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.
@@ -1635,6 +1635,14 @@ const track$1 = (queryKey, event, environment, customBaseUrl) => __awaiter(void
1635
1635
  }
1636
1636
  return res.json();
1637
1637
  });
1638
+ const loadRedirectionRules = (queryKey, environment, customBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
1639
+ const res = yield fetch(`${getApiUrl$1(environment, customBaseUrl)}redirections/${queryKey}`, Object.assign(Object.assign({}, defaultConfig$1), { method: "GET" }));
1640
+ if (res.status < 400) {
1641
+ return res.json();
1642
+ }
1643
+ const errors = yield res.json();
1644
+ return { success: false, errors };
1645
+ });
1638
1646
  const LupaSearchSdk = {
1639
1647
  query: (queryKey, publicQuery, options = null) => {
1640
1648
  if (options === null || options === void 0 ? void 0 : options.customUrl) {
@@ -1656,6 +1664,9 @@ const LupaSearchSdk = {
1656
1664
  },
1657
1665
  queryByIds: (queryKey, ids, options = null) => {
1658
1666
  return queryByIds(queryKey, ids, (options === null || options === void 0 ? void 0 : options.environment) || "production", options === null || options === void 0 ? void 0 : options.customBaseUrl);
1667
+ },
1668
+ loadRedirectionRules: (queryKey, options = null) => {
1669
+ return loadRedirectionRules(queryKey, (options === null || options === void 0 ? void 0 : options.environment) || "production", options === null || options === void 0 ? void 0 : options.customBaseUrl);
1659
1670
  }
1660
1671
  };
1661
1672
  const getNormalizedString = (str) => {
@@ -1734,6 +1745,13 @@ const escapeHtml = (value) => {
1734
1745
  });
1735
1746
  return output;
1736
1747
  };
1748
+ const inputMatches = (input, possibleValues) => {
1749
+ if (!input) {
1750
+ return false;
1751
+ }
1752
+ const normalizedInput = getNormalizedString(input);
1753
+ return possibleValues.some((v) => getNormalizedString(v).startsWith(normalizedInput));
1754
+ };
1737
1755
  const initAnalyticsTracking = (analyticsOptions) => {
1738
1756
  try {
1739
1757
  if (analyticsOptions == null ? void 0 : analyticsOptions.enabled) {
@@ -2684,12 +2702,89 @@ const toggleHierarchyParam = (params = [], param = "", removeAllLevels = false)
2684
2702
  }
2685
2703
  return getMostSpecificHierarchyTerms([param, ...params]);
2686
2704
  };
2705
+ const CACHE_KEY = "lupasearch-client-redirections";
2706
+ const useRedirectionStore = defineStore("redirections", () => {
2707
+ const redirections = vue.ref({ rules: [] });
2708
+ const redirectionOptions = vue.ref({ enabled: false, queryKey: "" });
2709
+ const saveToLocalStorage = () => {
2710
+ try {
2711
+ localStorage.setItem(
2712
+ CACHE_KEY,
2713
+ JSON.stringify({ redirections: redirections.value, savedAt: Date.now() })
2714
+ );
2715
+ } catch (e) {
2716
+ }
2717
+ };
2718
+ const tryLoadFromLocalStorage = (config) => {
2719
+ var _a;
2720
+ if (!config.cacheSeconds)
2721
+ return false;
2722
+ try {
2723
+ const data = JSON.parse((_a = localStorage.getItem(CACHE_KEY)) != null ? _a : "");
2724
+ if ((data == null ? void 0 : data.redirections) && Date.now() - data.savedAt < 1e3 * config.cacheSeconds) {
2725
+ redirections.value = data.redirections;
2726
+ return true;
2727
+ }
2728
+ } catch (e) {
2729
+ }
2730
+ return false;
2731
+ };
2732
+ const initiate = (config, options) => __async(exports, null, function* () {
2733
+ var _a, _b, _c, _d;
2734
+ if ((_a = redirectionOptions.value) == null ? void 0 : _a.enabled) {
2735
+ return;
2736
+ }
2737
+ redirectionOptions.value = config;
2738
+ if (!(config == null ? void 0 : config.enabled)) {
2739
+ return;
2740
+ }
2741
+ const loaded = tryLoadFromLocalStorage(config);
2742
+ if (loaded || ((_c = (_b = redirections.value) == null ? void 0 : _b.rules) == null ? void 0 : _c.length) > 0) {
2743
+ return;
2744
+ }
2745
+ try {
2746
+ const result = yield LupaSearchSdk.loadRedirectionRules(config.queryKey, options);
2747
+ if (!((_d = result == null ? void 0 : result.rules) == null ? void 0 : _d.length)) {
2748
+ return;
2749
+ }
2750
+ redirections.value = result;
2751
+ saveToLocalStorage();
2752
+ } catch (e) {
2753
+ }
2754
+ });
2755
+ const redirectOnKeywordIfConfigured = (input, routingBehavior = "direct-link") => {
2756
+ var _a, _b, _c, _d;
2757
+ if (!((_b = (_a = redirections.value) == null ? void 0 : _a.rules) == null ? void 0 : _b.length)) {
2758
+ return false;
2759
+ }
2760
+ const redirectTo = redirections.value.rules.find((r) => inputMatches(input, r.sources));
2761
+ if (!redirectTo) {
2762
+ return false;
2763
+ }
2764
+ const url = ((_c = redirectionOptions.value) == null ? void 0 : _c.urlTransformer) ? (_d = redirectionOptions.value) == null ? void 0 : _d.urlTransformer(redirectTo == null ? void 0 : redirectTo.target) : redirectTo == null ? void 0 : redirectTo.target;
2765
+ if (url === void 0 || url === null || url === "") {
2766
+ return false;
2767
+ }
2768
+ if (routingBehavior === "event") {
2769
+ emitRoutingEvent(url);
2770
+ } else {
2771
+ window.location.assign(url);
2772
+ }
2773
+ return true;
2774
+ };
2775
+ return {
2776
+ redirections,
2777
+ redirectOnKeywordIfConfigured,
2778
+ initiate
2779
+ };
2780
+ });
2687
2781
  const useParamsStore = defineStore("params", () => {
2688
2782
  const params = vue.ref({});
2689
2783
  const defaultLimit = vue.ref(DEFAULT_PAGE_SIZE);
2690
2784
  const searchResultsLink = vue.ref("");
2691
2785
  const searchString = vue.ref("");
2692
2786
  const optionsStore = useOptionsStore();
2787
+ const redirectionStore = useRedirectionStore();
2693
2788
  const query = vue.computed(() => params.value[QUERY_PARAMS_PARSED.QUERY]);
2694
2789
  const page = vue.computed(() => {
2695
2790
  const page2 = Number(params.value[QUERY_PARAMS_PARSED.PAGE]) || 1;
@@ -2767,6 +2862,13 @@ const useParamsStore = defineStore("params", () => {
2767
2862
  facet
2768
2863
  }) => {
2769
2864
  var _a;
2865
+ const redirectionApplied = redirectionStore.redirectOnKeywordIfConfigured(
2866
+ searchText,
2867
+ optionsStore.boxRoutingBehavior
2868
+ );
2869
+ if (redirectionApplied) {
2870
+ return;
2871
+ }
2770
2872
  if (!searchResultsLink.value || linksMatch(searchResultsLink.value, window.location.pathname)) {
2771
2873
  const singleFacetParam = facet ? getFacetParam(facet.key, [facet.title]) : void 0;
2772
2874
  const facetParam = singleFacetParam ? [
@@ -4682,6 +4784,7 @@ const _sfc_main$_ = /* @__PURE__ */ vue.defineComponent({
4682
4784
  const searchBoxStore = useSearchBoxStore();
4683
4785
  const optionsStore = useOptionsStore();
4684
4786
  const trackingStore = useTrackingStore();
4787
+ const redirectionStore = useRedirectionStore();
4685
4788
  const inputValue = vue.ref("");
4686
4789
  const suggestedValue = vue.ref(defaultSuggestedValue);
4687
4790
  const opened = vue.ref(props.isSearchContainer);
@@ -4720,6 +4823,7 @@ const _sfc_main$_ = /* @__PURE__ */ vue.defineComponent({
4720
4823
  paramsStore.setSearchResultsLink(props.options.links.searchResults);
4721
4824
  searchBoxStore.saveOptions({ newOptions: props.options });
4722
4825
  optionsStore.setSearchBoxOptions({ options: props.options });
4826
+ redirectionStore.initiate(props.options.redirections, props.options.options);
4723
4827
  bindSearchTriggers(searchTriggers.value, handleCurrentValueSearch);
4724
4828
  if (props.isSearchContainer && searchBoxInput.value) {
4725
4829
  (_a2 = searchBoxInput.value) == null ? void 0 : _a2.focus();
@@ -9426,6 +9530,7 @@ const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
9426
9530
  const trackingStore = useTrackingStore();
9427
9531
  const dynamicDataStore = useDynamicDataStore();
9428
9532
  const screenStore = useScreenStore();
9533
+ const redirectionStore = useRedirectionStore();
9429
9534
  const initialFilters = vue.computed(() => {
9430
9535
  var _a;
9431
9536
  return (_a = props.initialFilters) != null ? _a : {};
@@ -9451,17 +9556,18 @@ const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
9451
9556
  const searchParams = getSearchParams((_a = props.options.ssr) == null ? void 0 : _a.url);
9452
9557
  paramStore.add(parseParams(searchParams));
9453
9558
  };
9454
- vue.onMounted(() => {
9559
+ vue.onMounted(() => __async(this, null, function* () {
9455
9560
  var _a, _b;
9456
9561
  window.addEventListener("popstate", handlePopState);
9457
9562
  window.addEventListener("resize", handleResize);
9563
+ yield redirectionStore.initiate(props.options.redirections, props.options.options);
9458
9564
  if (props.initialData) {
9459
9565
  searchResultStore.add(__spreadValues({}, props.initialData));
9460
9566
  }
9461
9567
  handleMounted();
9462
9568
  (_b = (_a = props.options.callbacks) == null ? void 0 : _a.onMounted) == null ? void 0 : _b.call(_a);
9463
9569
  mounted.value = true;
9464
- });
9570
+ }));
9465
9571
  vue.onBeforeUnmount(() => {
9466
9572
  window.removeEventListener("resize", handleResize);
9467
9573
  window.removeEventListener("popstate", handlePopState);
@@ -9505,6 +9611,13 @@ const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
9505
9611
  const context = getLupaTrackingContext();
9506
9612
  const limit = publicQuery.limit || defaultSearchResultPageSize.value;
9507
9613
  const query2 = __spreadProps(__spreadValues(__spreadValues({}, publicQuery), context), { limit });
9614
+ const redirectionApplied = redirectionStore.redirectOnKeywordIfConfigured(
9615
+ publicQuery.searchText,
9616
+ optionStore.searchResultsRoutingBehavior
9617
+ );
9618
+ if (redirectionApplied) {
9619
+ return;
9620
+ }
9508
9621
  if (!query2.searchText && props.options.disallowEmptyQuery) {
9509
9622
  return;
9510
9623
  }
@@ -1633,6 +1633,14 @@ const track$1 = (queryKey, event, environment, customBaseUrl) => __awaiter(void
1633
1633
  }
1634
1634
  return res.json();
1635
1635
  });
1636
+ const loadRedirectionRules = (queryKey, environment, customBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
1637
+ const res = yield fetch(`${getApiUrl$1(environment, customBaseUrl)}redirections/${queryKey}`, Object.assign(Object.assign({}, defaultConfig$1), { method: "GET" }));
1638
+ if (res.status < 400) {
1639
+ return res.json();
1640
+ }
1641
+ const errors = yield res.json();
1642
+ return { success: false, errors };
1643
+ });
1636
1644
  const LupaSearchSdk = {
1637
1645
  query: (queryKey, publicQuery, options = null) => {
1638
1646
  if (options === null || options === void 0 ? void 0 : options.customUrl) {
@@ -1654,6 +1662,9 @@ const LupaSearchSdk = {
1654
1662
  },
1655
1663
  queryByIds: (queryKey, ids, options = null) => {
1656
1664
  return queryByIds(queryKey, ids, (options === null || options === void 0 ? void 0 : options.environment) || "production", options === null || options === void 0 ? void 0 : options.customBaseUrl);
1665
+ },
1666
+ loadRedirectionRules: (queryKey, options = null) => {
1667
+ return loadRedirectionRules(queryKey, (options === null || options === void 0 ? void 0 : options.environment) || "production", options === null || options === void 0 ? void 0 : options.customBaseUrl);
1657
1668
  }
1658
1669
  };
1659
1670
  const getNormalizedString = (str) => {
@@ -1732,6 +1743,13 @@ const escapeHtml = (value) => {
1732
1743
  });
1733
1744
  return output;
1734
1745
  };
1746
+ const inputMatches = (input, possibleValues) => {
1747
+ if (!input) {
1748
+ return false;
1749
+ }
1750
+ const normalizedInput = getNormalizedString(input);
1751
+ return possibleValues.some((v) => getNormalizedString(v).startsWith(normalizedInput));
1752
+ };
1735
1753
  const initAnalyticsTracking = (analyticsOptions) => {
1736
1754
  try {
1737
1755
  if (analyticsOptions == null ? void 0 : analyticsOptions.enabled) {
@@ -2682,12 +2700,89 @@ const toggleHierarchyParam = (params = [], param = "", removeAllLevels = false)
2682
2700
  }
2683
2701
  return getMostSpecificHierarchyTerms([param, ...params]);
2684
2702
  };
2703
+ const CACHE_KEY = "lupasearch-client-redirections";
2704
+ const useRedirectionStore = defineStore("redirections", () => {
2705
+ const redirections = ref({ rules: [] });
2706
+ const redirectionOptions = ref({ enabled: false, queryKey: "" });
2707
+ const saveToLocalStorage = () => {
2708
+ try {
2709
+ localStorage.setItem(
2710
+ CACHE_KEY,
2711
+ JSON.stringify({ redirections: redirections.value, savedAt: Date.now() })
2712
+ );
2713
+ } catch (e) {
2714
+ }
2715
+ };
2716
+ const tryLoadFromLocalStorage = (config) => {
2717
+ var _a;
2718
+ if (!config.cacheSeconds)
2719
+ return false;
2720
+ try {
2721
+ const data = JSON.parse((_a = localStorage.getItem(CACHE_KEY)) != null ? _a : "");
2722
+ if ((data == null ? void 0 : data.redirections) && Date.now() - data.savedAt < 1e3 * config.cacheSeconds) {
2723
+ redirections.value = data.redirections;
2724
+ return true;
2725
+ }
2726
+ } catch (e) {
2727
+ }
2728
+ return false;
2729
+ };
2730
+ const initiate = (config, options) => __async(void 0, null, function* () {
2731
+ var _a, _b, _c, _d;
2732
+ if ((_a = redirectionOptions.value) == null ? void 0 : _a.enabled) {
2733
+ return;
2734
+ }
2735
+ redirectionOptions.value = config;
2736
+ if (!(config == null ? void 0 : config.enabled)) {
2737
+ return;
2738
+ }
2739
+ const loaded = tryLoadFromLocalStorage(config);
2740
+ if (loaded || ((_c = (_b = redirections.value) == null ? void 0 : _b.rules) == null ? void 0 : _c.length) > 0) {
2741
+ return;
2742
+ }
2743
+ try {
2744
+ const result = yield LupaSearchSdk.loadRedirectionRules(config.queryKey, options);
2745
+ if (!((_d = result == null ? void 0 : result.rules) == null ? void 0 : _d.length)) {
2746
+ return;
2747
+ }
2748
+ redirections.value = result;
2749
+ saveToLocalStorage();
2750
+ } catch (e) {
2751
+ }
2752
+ });
2753
+ const redirectOnKeywordIfConfigured = (input, routingBehavior = "direct-link") => {
2754
+ var _a, _b, _c, _d;
2755
+ if (!((_b = (_a = redirections.value) == null ? void 0 : _a.rules) == null ? void 0 : _b.length)) {
2756
+ return false;
2757
+ }
2758
+ const redirectTo = redirections.value.rules.find((r) => inputMatches(input, r.sources));
2759
+ if (!redirectTo) {
2760
+ return false;
2761
+ }
2762
+ const url = ((_c = redirectionOptions.value) == null ? void 0 : _c.urlTransformer) ? (_d = redirectionOptions.value) == null ? void 0 : _d.urlTransformer(redirectTo == null ? void 0 : redirectTo.target) : redirectTo == null ? void 0 : redirectTo.target;
2763
+ if (url === void 0 || url === null || url === "") {
2764
+ return false;
2765
+ }
2766
+ if (routingBehavior === "event") {
2767
+ emitRoutingEvent(url);
2768
+ } else {
2769
+ window.location.assign(url);
2770
+ }
2771
+ return true;
2772
+ };
2773
+ return {
2774
+ redirections,
2775
+ redirectOnKeywordIfConfigured,
2776
+ initiate
2777
+ };
2778
+ });
2685
2779
  const useParamsStore = defineStore("params", () => {
2686
2780
  const params = ref({});
2687
2781
  const defaultLimit = ref(DEFAULT_PAGE_SIZE);
2688
2782
  const searchResultsLink = ref("");
2689
2783
  const searchString = ref("");
2690
2784
  const optionsStore = useOptionsStore();
2785
+ const redirectionStore = useRedirectionStore();
2691
2786
  const query = computed(() => params.value[QUERY_PARAMS_PARSED.QUERY]);
2692
2787
  const page = computed(() => {
2693
2788
  const page2 = Number(params.value[QUERY_PARAMS_PARSED.PAGE]) || 1;
@@ -2765,6 +2860,13 @@ const useParamsStore = defineStore("params", () => {
2765
2860
  facet
2766
2861
  }) => {
2767
2862
  var _a;
2863
+ const redirectionApplied = redirectionStore.redirectOnKeywordIfConfigured(
2864
+ searchText,
2865
+ optionsStore.boxRoutingBehavior
2866
+ );
2867
+ if (redirectionApplied) {
2868
+ return;
2869
+ }
2768
2870
  if (!searchResultsLink.value || linksMatch(searchResultsLink.value, window.location.pathname)) {
2769
2871
  const singleFacetParam = facet ? getFacetParam(facet.key, [facet.title]) : void 0;
2770
2872
  const facetParam = singleFacetParam ? [
@@ -4680,6 +4782,7 @@ const _sfc_main$_ = /* @__PURE__ */ defineComponent({
4680
4782
  const searchBoxStore = useSearchBoxStore();
4681
4783
  const optionsStore = useOptionsStore();
4682
4784
  const trackingStore = useTrackingStore();
4785
+ const redirectionStore = useRedirectionStore();
4683
4786
  const inputValue = ref("");
4684
4787
  const suggestedValue = ref(defaultSuggestedValue);
4685
4788
  const opened = ref(props.isSearchContainer);
@@ -4718,6 +4821,7 @@ const _sfc_main$_ = /* @__PURE__ */ defineComponent({
4718
4821
  paramsStore.setSearchResultsLink(props.options.links.searchResults);
4719
4822
  searchBoxStore.saveOptions({ newOptions: props.options });
4720
4823
  optionsStore.setSearchBoxOptions({ options: props.options });
4824
+ redirectionStore.initiate(props.options.redirections, props.options.options);
4721
4825
  bindSearchTriggers(searchTriggers.value, handleCurrentValueSearch);
4722
4826
  if (props.isSearchContainer && searchBoxInput.value) {
4723
4827
  (_a2 = searchBoxInput.value) == null ? void 0 : _a2.focus();
@@ -9424,6 +9528,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
9424
9528
  const trackingStore = useTrackingStore();
9425
9529
  const dynamicDataStore = useDynamicDataStore();
9426
9530
  const screenStore = useScreenStore();
9531
+ const redirectionStore = useRedirectionStore();
9427
9532
  const initialFilters = computed(() => {
9428
9533
  var _a;
9429
9534
  return (_a = props.initialFilters) != null ? _a : {};
@@ -9449,17 +9554,18 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
9449
9554
  const searchParams = getSearchParams((_a = props.options.ssr) == null ? void 0 : _a.url);
9450
9555
  paramStore.add(parseParams(searchParams));
9451
9556
  };
9452
- onMounted(() => {
9557
+ onMounted(() => __async(this, null, function* () {
9453
9558
  var _a, _b;
9454
9559
  window.addEventListener("popstate", handlePopState);
9455
9560
  window.addEventListener("resize", handleResize);
9561
+ yield redirectionStore.initiate(props.options.redirections, props.options.options);
9456
9562
  if (props.initialData) {
9457
9563
  searchResultStore.add(__spreadValues({}, props.initialData));
9458
9564
  }
9459
9565
  handleMounted();
9460
9566
  (_b = (_a = props.options.callbacks) == null ? void 0 : _a.onMounted) == null ? void 0 : _b.call(_a);
9461
9567
  mounted.value = true;
9462
- });
9568
+ }));
9463
9569
  onBeforeUnmount(() => {
9464
9570
  window.removeEventListener("resize", handleResize);
9465
9571
  window.removeEventListener("popstate", handlePopState);
@@ -9503,6 +9609,13 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
9503
9609
  const context = getLupaTrackingContext();
9504
9610
  const limit = publicQuery.limit || defaultSearchResultPageSize.value;
9505
9611
  const query2 = __spreadProps(__spreadValues(__spreadValues({}, publicQuery), context), { limit });
9612
+ const redirectionApplied = redirectionStore.redirectOnKeywordIfConfigured(
9613
+ publicQuery.searchText,
9614
+ optionStore.searchResultsRoutingBehavior
9615
+ );
9616
+ if (redirectionApplied) {
9617
+ return;
9618
+ }
9506
9619
  if (!query2.searchText && props.options.disallowEmptyQuery) {
9507
9620
  return;
9508
9621
  }
@@ -22,10 +22,11 @@ import ChatContainer from './components/chat/ChatContainer.vue';
22
22
  import { getInitialSearchResults } from './utils/ssr.utils';
23
23
  import { ChatOptions, ChatSettings } from './types/chat/ChatOptions';
24
24
  import { QueryParams } from './types/search-results/QueryParams';
25
+ import { RedirectionOptions } from './types/redirections/RedirectionOptions';
25
26
  declare const initPinia: () => Pinia;
26
27
  declare const setupTracking: (options: TrackingOptions) => void;
27
28
  declare const LupaSearch: {
28
29
  install: (app: any) => void;
29
30
  };
30
31
  export { SearchBox, SearchResults, ProductList, Recommendations, SearchContainer, ChatContainer, DocumentElementType, SearchBoxPanelType, BadgeType, setupTracking, LupaSearch, initPinia, getInitialSearchResults };
31
- export type { TrackingOptions, SearchBoxOptions, SearchResultsOptions, ProductListOptions, SdkOptions, FacetStyle, Environment, RoutingBehavior, AnchorPosition, SortDirection, DocumentElement, ImageDocumentElement, TitleDocumentElement, DescriptionDocumentElement, CustomDocumentElement, PriceElement, RegularPriceDocumentElement, RatingElement, AddToCartElement, CustomHtmlElement, SortOptions, SearchResultsSortOptions, SearchResultEventCallbacks, CallbackContext, SortCallbackContext, ResultCallbackContext, FacetFilterQuery, CategoryFilterOptions, SearchResultsFilterOptions, SearchResultBadgeType, SearchResultBadgeElement, ResultFacetOptions, BadgeGenerateSeed, BadgeGenerateOptions, BadgeOptions, SearchContainerOptions, SearchContainerConfigOptions, SingleStarRatingElement, DynamicData, ProductRecommendationOptions, RecommendationABTestingOptions, SsrOptions, ChatOptions, ChatSettings, SearchBoxEventCallbacks, SearchBoxResultCallbackContext, QueryParams, SearchBoxResultsNavigateContext };
32
+ export type { TrackingOptions, SearchBoxOptions, SearchResultsOptions, ProductListOptions, SdkOptions, FacetStyle, Environment, RoutingBehavior, AnchorPosition, SortDirection, DocumentElement, ImageDocumentElement, TitleDocumentElement, DescriptionDocumentElement, CustomDocumentElement, PriceElement, RegularPriceDocumentElement, RatingElement, AddToCartElement, CustomHtmlElement, SortOptions, SearchResultsSortOptions, SearchResultEventCallbacks, CallbackContext, SortCallbackContext, ResultCallbackContext, FacetFilterQuery, CategoryFilterOptions, SearchResultsFilterOptions, SearchResultBadgeType, SearchResultBadgeElement, ResultFacetOptions, BadgeGenerateSeed, BadgeGenerateOptions, BadgeOptions, SearchContainerOptions, SearchContainerConfigOptions, SingleStarRatingElement, DynamicData, ProductRecommendationOptions, RecommendationABTestingOptions, SsrOptions, ChatOptions, ChatSettings, SearchBoxEventCallbacks, SearchBoxResultCallbackContext, QueryParams, SearchBoxResultsNavigateContext, RedirectionOptions };
@@ -0,0 +1,18 @@
1
+ import { RedirectionOptions } from '../types/redirections/RedirectionOptions';
2
+ import { RedirectionRules } from '@getlupa/client-sdk/Types';
3
+ import { type Ref } from 'vue';
4
+ import { SdkOptions } from '../types/General';
5
+ import { RoutingBehavior } from '../types/search-results/RoutingBehavior';
6
+ export declare const useRedirectionStore: import("pinia").StoreDefinition<"redirections", import("pinia")._UnwrapAll<Pick<{
7
+ redirections: Ref<RedirectionRules>;
8
+ redirectOnKeywordIfConfigured: (input: string, routingBehavior?: RoutingBehavior) => boolean;
9
+ initiate: (config?: RedirectionOptions, options?: SdkOptions) => Promise<void>;
10
+ }, "redirections">>, Pick<{
11
+ redirections: Ref<RedirectionRules>;
12
+ redirectOnKeywordIfConfigured: (input: string, routingBehavior?: RoutingBehavior) => boolean;
13
+ initiate: (config?: RedirectionOptions, options?: SdkOptions) => Promise<void>;
14
+ }, never>, Pick<{
15
+ redirections: Ref<RedirectionRules>;
16
+ redirectOnKeywordIfConfigured: (input: string, routingBehavior?: RoutingBehavior) => boolean;
17
+ initiate: (config?: RedirectionOptions, options?: SdkOptions) => Promise<void>;
18
+ }, "redirectOnKeywordIfConfigured" | "initiate">>;
@@ -0,0 +1,6 @@
1
+ export type RedirectionOptions = {
2
+ enabled: boolean;
3
+ queryKey: string;
4
+ cacheSeconds?: number;
5
+ urlTransformer?: (redirectTo: string) => string;
6
+ };
@@ -6,12 +6,14 @@ import type { SearchBoxHistory } from './SearchBoxHistory';
6
6
  import type { SearchBoxPanel } from './SearchBoxPanel';
7
7
  import { DisplaySuggestion } from './Common';
8
8
  import { QueryParams } from '../search-results/QueryParams';
9
+ import { RedirectionOptions } from '../redirections/RedirectionOptions';
9
10
  export type SearchBoxOptions = SearchBoxPanelOptions & {
10
11
  inputSelector: string;
11
12
  searchTriggers?: string[];
12
13
  routingBehavior?: RoutingBehavior;
13
14
  dynamicData?: DynamicData;
14
15
  callbacks?: SearchBoxEventCallbacks;
16
+ redirections?: RedirectionOptions;
15
17
  };
16
18
  export type SearchBoxOptionLabels = {
17
19
  placeholder: string;
@@ -3,6 +3,7 @@ import type { CategoryFilterOptions } from '../product-list/ProductListOptions';
3
3
  import type { SearchResultsAdditionalPanelOptions } from './SearchResultsAdditionalPanelOptions';
4
4
  import type { SearchResultsProductCardOptions } from './SearchResultsProductCardOptions';
5
5
  import type { SearchResultsSortOptions } from './SearchResultsSort';
6
+ import { RedirectionOptions } from '../redirections/RedirectionOptions';
6
7
  export type SearchResultsOptions = SearchResultsProductOptions & SearchResultsAdditionalPanels & {
7
8
  containerSelector: string;
8
9
  breadcrumbs: SearchResultsBreadcrumb[];
@@ -12,6 +13,7 @@ export type SearchResultsOptions = SearchResultsProductOptions & SearchResultsAd
12
13
  categories?: CategoryFilterOptions;
13
14
  dynamicData?: DynamicData;
14
15
  ssr?: SsrOptions;
16
+ redirections?: RedirectionOptions;
15
17
  };
16
18
  export type SsrOptions = {
17
19
  baseUrl?: string;
@@ -7,3 +7,4 @@ export declare const getDisplayValue: (value?: string | number) => string;
7
7
  export declare const getProductKey: (index: string, product: Document, idKey: string | undefined) => string;
8
8
  export declare const normalizeFloat: (value?: string) => number;
9
9
  export declare const escapeHtml: (value?: string) => string;
10
+ export declare const inputMatches: (input: string, possibleValues: string[]) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getlupa/vue",
3
- "version": "0.6.3",
3
+ "version": "0.7.1",
4
4
  "main": "dist/lupaSearch.js",
5
5
  "module": "dist/lupaSearch.mjs",
6
6
  "types": "dist/src/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "vue": "^3.0.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@getlupa/client-sdk": "^1.3.5",
26
+ "@getlupa/client-sdk": "^1.4.0",
27
27
  "@pinia/testing": "^0.1.2",
28
28
  "@rollup/plugin-babel": "5.3.0",
29
29
  "@rollup/plugin-commonjs": "^21.0.1",