@floxiz/medusa-plugin-meilisearch 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.
Files changed (133) hide show
  1. package/.medusa/server/src/admin/index.js +266 -0
  2. package/.medusa/server/src/admin/index.mjs +265 -0
  3. package/.medusa/server/src/api/admin/meilisearch/categories-hits/route.d.ts +32 -0
  4. package/.medusa/server/src/api/admin/meilisearch/categories-hits/route.d.ts.map +1 -0
  5. package/.medusa/server/src/api/admin/meilisearch/categories-hits/route.js +46 -0
  6. package/.medusa/server/src/api/admin/meilisearch/products-hits/route.d.ts +32 -0
  7. package/.medusa/server/src/api/admin/meilisearch/products-hits/route.d.ts.map +1 -0
  8. package/.medusa/server/src/api/admin/meilisearch/products-hits/route.js +49 -0
  9. package/.medusa/server/src/api/admin/meilisearch/sync/route.d.ts +6 -0
  10. package/.medusa/server/src/api/admin/meilisearch/sync/route.d.ts.map +1 -0
  11. package/.medusa/server/src/api/admin/meilisearch/sync/route.js +15 -0
  12. package/.medusa/server/src/api/admin/meilisearch/vector-status/route.d.ts +11 -0
  13. package/.medusa/server/src/api/admin/meilisearch/vector-status/route.d.ts.map +1 -0
  14. package/.medusa/server/src/api/admin/meilisearch/vector-status/route.js +11 -0
  15. package/.medusa/server/src/api/middlewares.d.ts +3 -0
  16. package/.medusa/server/src/api/middlewares.d.ts.map +1 -0
  17. package/.medusa/server/src/api/middlewares.js +44 -0
  18. package/.medusa/server/src/api/store/meilisearch/categories/route.d.ts +37 -0
  19. package/.medusa/server/src/api/store/meilisearch/categories/route.d.ts.map +1 -0
  20. package/.medusa/server/src/api/store/meilisearch/categories/route.js +105 -0
  21. package/.medusa/server/src/api/store/meilisearch/categories-hits/route.d.ts +32 -0
  22. package/.medusa/server/src/api/store/meilisearch/categories-hits/route.d.ts.map +1 -0
  23. package/.medusa/server/src/api/store/meilisearch/categories-hits/route.js +49 -0
  24. package/.medusa/server/src/api/store/meilisearch/products/route.d.ts +43 -0
  25. package/.medusa/server/src/api/store/meilisearch/products/route.d.ts.map +1 -0
  26. package/.medusa/server/src/api/store/meilisearch/products/route.js +118 -0
  27. package/.medusa/server/src/api/store/meilisearch/products-hits/route.d.ts +32 -0
  28. package/.medusa/server/src/api/store/meilisearch/products-hits/route.d.ts.map +1 -0
  29. package/.medusa/server/src/api/store/meilisearch/products-hits/route.js +49 -0
  30. package/.medusa/server/src/index.d.ts +3 -0
  31. package/.medusa/server/src/index.d.ts.map +1 -0
  32. package/.medusa/server/src/index.js +19 -0
  33. package/.medusa/server/src/jobs/meilisearch-categories-index.d.ts +5 -0
  34. package/.medusa/server/src/jobs/meilisearch-categories-index.d.ts.map +1 -0
  35. package/.medusa/server/src/jobs/meilisearch-categories-index.js +19 -0
  36. package/.medusa/server/src/jobs/meilisearch-products-index.d.ts +5 -0
  37. package/.medusa/server/src/jobs/meilisearch-products-index.d.ts.map +1 -0
  38. package/.medusa/server/src/jobs/meilisearch-products-index.js +19 -0
  39. package/.medusa/server/src/models/CronJobConfig.d.ts +7 -0
  40. package/.medusa/server/src/models/CronJobConfig.d.ts.map +1 -0
  41. package/.medusa/server/src/models/CronJobConfig.js +3 -0
  42. package/.medusa/server/src/modules/meilisearch/index.d.ts +9 -0
  43. package/.medusa/server/src/modules/meilisearch/index.d.ts.map +1 -0
  44. package/.medusa/server/src/modules/meilisearch/index.js +31 -0
  45. package/.medusa/server/src/modules/meilisearch/loaders/index.d.ts +5 -0
  46. package/.medusa/server/src/modules/meilisearch/loaders/index.d.ts.map +1 -0
  47. package/.medusa/server/src/modules/meilisearch/loaders/index.js +18 -0
  48. package/.medusa/server/src/modules/meilisearch/services/index.d.ts +2 -0
  49. package/.medusa/server/src/modules/meilisearch/services/index.d.ts.map +1 -0
  50. package/.medusa/server/src/modules/meilisearch/services/index.js +18 -0
  51. package/.medusa/server/src/modules/meilisearch/services/meilisearch.d.ts +52 -0
  52. package/.medusa/server/src/modules/meilisearch/services/meilisearch.d.ts.map +1 -0
  53. package/.medusa/server/src/modules/meilisearch/services/meilisearch.js +177 -0
  54. package/.medusa/server/src/modules/meilisearch/types/index.d.ts +3 -0
  55. package/.medusa/server/src/modules/meilisearch/types/index.d.ts.map +1 -0
  56. package/.medusa/server/src/modules/meilisearch/types/index.js +19 -0
  57. package/.medusa/server/src/modules/meilisearch/types/meilisearch.d.ts +127 -0
  58. package/.medusa/server/src/modules/meilisearch/types/meilisearch.d.ts.map +1 -0
  59. package/.medusa/server/src/modules/meilisearch/types/meilisearch.js +7 -0
  60. package/.medusa/server/src/modules/meilisearch/types/translation.d.ts +64 -0
  61. package/.medusa/server/src/modules/meilisearch/types/translation.d.ts.map +1 -0
  62. package/.medusa/server/src/modules/meilisearch/types/translation.js +36 -0
  63. package/.medusa/server/src/modules/meilisearch/utils/embedder.d.ts +54 -0
  64. package/.medusa/server/src/modules/meilisearch/utils/embedder.d.ts.map +1 -0
  65. package/.medusa/server/src/modules/meilisearch/utils/embedder.js +151 -0
  66. package/.medusa/server/src/modules/meilisearch/utils/transformer.d.ts +8 -0
  67. package/.medusa/server/src/modules/meilisearch/utils/transformer.d.ts.map +1 -0
  68. package/.medusa/server/src/modules/meilisearch/utils/transformer.js +121 -0
  69. package/.medusa/server/src/subscribers/meilisearch-category-created.d.ts +6 -0
  70. package/.medusa/server/src/subscribers/meilisearch-category-created.d.ts.map +1 -0
  71. package/.medusa/server/src/subscribers/meilisearch-category-created.js +14 -0
  72. package/.medusa/server/src/subscribers/meilisearch-category-deleted.d.ts +6 -0
  73. package/.medusa/server/src/subscribers/meilisearch-category-deleted.d.ts.map +1 -0
  74. package/.medusa/server/src/subscribers/meilisearch-category-deleted.js +14 -0
  75. package/.medusa/server/src/subscribers/meilisearch-category-updated.d.ts +6 -0
  76. package/.medusa/server/src/subscribers/meilisearch-category-updated.d.ts.map +1 -0
  77. package/.medusa/server/src/subscribers/meilisearch-category-updated.js +14 -0
  78. package/.medusa/server/src/subscribers/meilisearch-product-created.d.ts +6 -0
  79. package/.medusa/server/src/subscribers/meilisearch-product-created.d.ts.map +1 -0
  80. package/.medusa/server/src/subscribers/meilisearch-product-created.js +19 -0
  81. package/.medusa/server/src/subscribers/meilisearch-product-deleted.d.ts +6 -0
  82. package/.medusa/server/src/subscribers/meilisearch-product-deleted.d.ts.map +1 -0
  83. package/.medusa/server/src/subscribers/meilisearch-product-deleted.js +19 -0
  84. package/.medusa/server/src/subscribers/meilisearch-product-updated.d.ts +6 -0
  85. package/.medusa/server/src/subscribers/meilisearch-product-updated.d.ts.map +1 -0
  86. package/.medusa/server/src/subscribers/meilisearch-product-updated.js +19 -0
  87. package/.medusa/server/src/subscribers/meilisearch-sync.d.ts +4 -0
  88. package/.medusa/server/src/subscribers/meilisearch-sync.d.ts.map +1 -0
  89. package/.medusa/server/src/subscribers/meilisearch-sync.js +22 -0
  90. package/.medusa/server/src/workflows/category-created.d.ts +7 -0
  91. package/.medusa/server/src/workflows/category-created.d.ts.map +1 -0
  92. package/.medusa/server/src/workflows/category-created.js +10 -0
  93. package/.medusa/server/src/workflows/category-deleted.d.ts +7 -0
  94. package/.medusa/server/src/workflows/category-deleted.d.ts.map +1 -0
  95. package/.medusa/server/src/workflows/category-deleted.js +10 -0
  96. package/.medusa/server/src/workflows/category-updated.d.ts +7 -0
  97. package/.medusa/server/src/workflows/category-updated.d.ts.map +1 -0
  98. package/.medusa/server/src/workflows/category-updated.js +10 -0
  99. package/.medusa/server/src/workflows/product-created.d.ts +8 -0
  100. package/.medusa/server/src/workflows/product-created.d.ts.map +1 -0
  101. package/.medusa/server/src/workflows/product-created.js +12 -0
  102. package/.medusa/server/src/workflows/product-deleted.d.ts +6 -0
  103. package/.medusa/server/src/workflows/product-deleted.d.ts.map +1 -0
  104. package/.medusa/server/src/workflows/product-deleted.js +10 -0
  105. package/.medusa/server/src/workflows/product-updated.d.ts +8 -0
  106. package/.medusa/server/src/workflows/product-updated.d.ts.map +1 -0
  107. package/.medusa/server/src/workflows/product-updated.js +12 -0
  108. package/.medusa/server/src/workflows/steps/delete-category.d.ts +8 -0
  109. package/.medusa/server/src/workflows/steps/delete-category.d.ts.map +1 -0
  110. package/.medusa/server/src/workflows/steps/delete-category.js +14 -0
  111. package/.medusa/server/src/workflows/steps/delete-product.d.ts +6 -0
  112. package/.medusa/server/src/workflows/steps/delete-product.d.ts.map +1 -0
  113. package/.medusa/server/src/workflows/steps/delete-product.js +13 -0
  114. package/.medusa/server/src/workflows/steps/sync-categories.d.ts +10 -0
  115. package/.medusa/server/src/workflows/steps/sync-categories.d.ts.map +1 -0
  116. package/.medusa/server/src/workflows/steps/sync-categories.js +78 -0
  117. package/.medusa/server/src/workflows/steps/sync-products.d.ts +10 -0
  118. package/.medusa/server/src/workflows/steps/sync-products.d.ts.map +1 -0
  119. package/.medusa/server/src/workflows/steps/sync-products.js +79 -0
  120. package/.medusa/server/src/workflows/steps/upsert-category.d.ts +8 -0
  121. package/.medusa/server/src/workflows/steps/upsert-category.d.ts.map +1 -0
  122. package/.medusa/server/src/workflows/steps/upsert-category.js +28 -0
  123. package/.medusa/server/src/workflows/steps/upsert-product.d.ts +8 -0
  124. package/.medusa/server/src/workflows/steps/upsert-product.d.ts.map +1 -0
  125. package/.medusa/server/src/workflows/steps/upsert-product.js +29 -0
  126. package/.medusa/server/src/workflows/sync-categories.d.ts +10 -0
  127. package/.medusa/server/src/workflows/sync-categories.d.ts.map +1 -0
  128. package/.medusa/server/src/workflows/sync-categories.js +13 -0
  129. package/.medusa/server/src/workflows/sync-products.d.ts +11 -0
  130. package/.medusa/server/src/workflows/sync-products.d.ts.map +1 -0
  131. package/.medusa/server/src/workflows/sync-products.js +13 -0
  132. package/README.md +511 -0
  133. package/package.json +76 -0
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const react = require("react");
4
+ const ui = require("@medusajs/ui");
5
+ const reactQuery = require("@tanstack/react-query");
6
+ const adminSdk = require("@medusajs/admin-sdk");
7
+ const Medusa = require("@medusajs/js-sdk");
8
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
9
+ const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
10
+ const sdk = new Medusa__default.default({
11
+ baseUrl: __BACKEND_URL__ || "/",
12
+ auth: {
13
+ type: "session"
14
+ }
15
+ });
16
+ const SyncPage = () => {
17
+ const [semanticSearchEnabled, setSemanticSearchEnabled] = react.useState(false);
18
+ const [semanticRatio, setSemanticRatio] = react.useState(0.5);
19
+ const [searchQuery, setSearchQuery] = react.useState("jeans");
20
+ const {
21
+ data: vectorStatus,
22
+ isLoading: statusLoading,
23
+ error: statusError,
24
+ refetch: refetchStatus
25
+ } = reactQuery.useQuery({
26
+ queryKey: ["meilisearch-vector-status"],
27
+ queryFn: async () => sdk.client.fetch("/admin/meilisearch/vector-status"),
28
+ retry: 2,
29
+ staleTime: 3e4
30
+ // Consider data stale after 30 seconds
31
+ });
32
+ const { mutate: syncData, isPending: syncPending } = reactQuery.useMutation({
33
+ mutationFn: () => sdk.client.fetch("/admin/meilisearch/sync", {
34
+ method: "POST"
35
+ }),
36
+ onSuccess: () => {
37
+ ui.toast.success("Successfully triggered data sync to Meilisearch");
38
+ },
39
+ onError: (err) => {
40
+ console.error(err);
41
+ ui.toast.error("Failed to sync data to Meilisearch");
42
+ }
43
+ });
44
+ const { mutate: searchProducts, isPending: searchProductsPending } = reactQuery.useMutation({
45
+ mutationFn: async () => {
46
+ if (!searchQuery.trim()) {
47
+ throw new Error("Search query cannot be empty");
48
+ }
49
+ return sdk.client.fetch("/admin/meilisearch/products-hits", {
50
+ method: "POST",
51
+ body: {
52
+ query: searchQuery.trim(),
53
+ semanticSearch: semanticSearchEnabled,
54
+ semanticRatio,
55
+ limit: 5,
56
+ offset: 0
57
+ }
58
+ });
59
+ },
60
+ onSuccess: (data) => {
61
+ const hybridInfo = data.hybridSearch ? ` (hybrid search with ratio ${data.semanticRatio})` : "";
62
+ ui.toast.success(`Search successful. Found ${data.hits.length} products${hybridInfo}`);
63
+ },
64
+ onError: (err) => {
65
+ console.error("Search error:", err);
66
+ ui.toast.error(err.message || "Search failed");
67
+ }
68
+ });
69
+ const { mutate: searchCategories, isPending: searchCategoriesPending } = reactQuery.useMutation({
70
+ mutationFn: async () => {
71
+ if (!searchQuery.trim()) {
72
+ throw new Error("Search query cannot be empty");
73
+ }
74
+ return sdk.client.fetch("/admin/meilisearch/categories-hits", {
75
+ method: "POST",
76
+ body: {
77
+ query: searchQuery.trim(),
78
+ semanticSearch: semanticSearchEnabled,
79
+ semanticRatio,
80
+ limit: 5,
81
+ offset: 0
82
+ }
83
+ });
84
+ },
85
+ onSuccess: (data) => {
86
+ const hybridInfo = data.hybridSearch ? ` (hybrid search with ratio ${data.semanticRatio})` : "";
87
+ ui.toast.success(`Search successful. Found ${data.hits.length} categories${hybridInfo}`);
88
+ },
89
+ onError: (err) => {
90
+ console.error("Search error:", err);
91
+ ui.toast.error(err.message || "Search failed");
92
+ }
93
+ });
94
+ const handleSync = () => {
95
+ syncData();
96
+ };
97
+ const handleSearchProducts = () => {
98
+ searchProducts();
99
+ };
100
+ const handleSearchCategories = () => {
101
+ searchCategories();
102
+ };
103
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
104
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
105
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Meilisearch Configuration" }),
106
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-gray-500 mt-2", children: "Manage your Meilisearch index synchronization and AI-powered semantic search settings." })
107
+ ] }),
108
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
109
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
110
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
111
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "AI-Powered Semantic Search" }),
112
+ statusLoading ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: "Loading..." }) : statusError ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", children: "Error" }) : (vectorStatus == null ? void 0 : vectorStatus.enabled) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Enabled" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "grey", children: "Disabled" })
113
+ ] }),
114
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => refetchStatus(), isLoading: statusLoading, children: "Refresh Status" })
115
+ ] }),
116
+ statusError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 rounded-md", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-red-800 text-sm", children: [
117
+ "Failed to load vector search status: ",
118
+ statusError.message
119
+ ] }) }),
120
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 mb-4", children: [
121
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
122
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm font-medium text-gray-700", children: "Provider" }),
123
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-600", children: vectorStatus.provider || "Not specified" })
124
+ ] }),
125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
126
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm font-medium text-gray-700", children: "Model" }),
127
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-600", children: vectorStatus.model || "Not specified" })
128
+ ] }),
129
+ vectorStatus.dimensions && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
130
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm font-medium text-gray-700", children: "Vector Dimensions" }),
131
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-600", children: vectorStatus.dimensions })
132
+ ] }),
133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
134
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm font-medium text-gray-700", children: "Embedding Fields" }),
135
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-600", children: vectorStatus.embeddingFields.join(", ") })
136
+ ] })
137
+ ] }),
138
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
139
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
141
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: "Enable Semantic Search in Tests" }),
142
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-500", children: "Use AI-powered semantic search for better results" })
143
+ ] }),
144
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { checked: semanticSearchEnabled, onCheckedChange: setSemanticSearchEnabled })
145
+ ] }),
146
+ semanticSearchEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
147
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium mb-2", children: [
148
+ "Semantic Ratio: ",
149
+ semanticRatio
150
+ ] }),
151
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-500 mb-3", children: "0.0 = Pure keyword search, 1.0 = Pure semantic search, 0.5 = Balanced hybrid" }),
152
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
153
+ /* @__PURE__ */ jsxRuntime.jsx(
154
+ ui.Input,
155
+ {
156
+ type: "range",
157
+ min: "0",
158
+ max: "1",
159
+ step: "0.1",
160
+ value: semanticRatio,
161
+ onChange: (e) => setSemanticRatio(parseFloat(e.target.value)),
162
+ className: "flex-1",
163
+ "aria-label": "Semantic search ratio",
164
+ "aria-describedby": "semantic-ratio-description"
165
+ }
166
+ ),
167
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-700", children: semanticRatio.toFixed(1) })
168
+ ] }),
169
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id: "semantic-ratio-description", className: "sr-only", children: "Adjust the balance between keyword and semantic search from 0 to 1" })
170
+ ] })
171
+ ] }),
172
+ !(vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-gray-500", children: "Vector search is not configured. Add vectorSearch configuration to your plugin options to enable AI-powered semantic search." })
173
+ ] }),
174
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
175
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Data Synchronization" }) }),
176
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-gray-500 mb-4", children: [
177
+ "Manually trigger synchronization of your product catalog with Meilisearch.",
178
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && " This will also generate embeddings for semantic search."
179
+ ] }),
180
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSync, isLoading: syncPending, variant: "primary", children: "Sync Now" })
181
+ ] }),
182
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Search Testing" }) }),
184
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-gray-500 mb-4", children: [
185
+ "Test your products search configuration with a custom query.",
186
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && " You can test both traditional keyword search and AI-powered semantic search."
187
+ ] }),
188
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
189
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
190
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm font-medium text-gray-700 mb-2", children: "Search Query" }),
191
+ /* @__PURE__ */ jsxRuntime.jsx(
192
+ ui.Input,
193
+ {
194
+ value: searchQuery,
195
+ onChange: (e) => setSearchQuery(e.target.value),
196
+ placeholder: "Enter search query (e.g., 'blue shirt', 'comfortable clothing')",
197
+ className: "w-full",
198
+ "aria-label": "Search query input",
199
+ "aria-describedby": "search-query-help"
200
+ }
201
+ ),
202
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id: "search-query-help", className: "sr-only", children: "Enter a search term to test the search functionality" })
203
+ ] }),
204
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
205
+ /* @__PURE__ */ jsxRuntime.jsx(
206
+ ui.Button,
207
+ {
208
+ onClick: handleSearchProducts,
209
+ isLoading: searchProductsPending,
210
+ variant: "secondary",
211
+ disabled: !searchQuery.trim(),
212
+ children: "Search Products"
213
+ }
214
+ ),
215
+ /* @__PURE__ */ jsxRuntime.jsx(
216
+ ui.Button,
217
+ {
218
+ onClick: handleSearchCategories,
219
+ isLoading: searchCategoriesPending,
220
+ variant: "secondary",
221
+ disabled: !searchQuery.trim(),
222
+ children: "Search Categories"
223
+ }
224
+ ),
225
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-gray-500 self-center", children: semanticSearchEnabled ? `Using hybrid search (${Math.round(semanticRatio * 100)}% semantic)` : "Using keyword search only" })
226
+ ] })
227
+ ] })
228
+ ] })
229
+ ] }) });
230
+ };
231
+ const config = adminSdk.defineRouteConfig({
232
+ label: "Meilisearch"
233
+ });
234
+ const widgetModule = { widgets: [] };
235
+ const routeModule = {
236
+ routes: [
237
+ {
238
+ Component: SyncPage,
239
+ path: "/settings/meilisearch"
240
+ }
241
+ ]
242
+ };
243
+ const menuItemModule = {
244
+ menuItems: [
245
+ {
246
+ label: config.label,
247
+ icon: void 0,
248
+ path: "/settings/meilisearch",
249
+ nested: void 0
250
+ }
251
+ ]
252
+ };
253
+ const formModule = { customFields: {} };
254
+ const displayModule = {
255
+ displays: {}
256
+ };
257
+ const i18nModule = { resources: {} };
258
+ const plugin = {
259
+ widgetModule,
260
+ routeModule,
261
+ menuItemModule,
262
+ formModule,
263
+ displayModule,
264
+ i18nModule
265
+ };
266
+ module.exports = plugin;
@@ -0,0 +1,265 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { toast, Container, Heading, Text, Badge, Button, Switch, Input } from "@medusajs/ui";
4
+ import { useQuery, useMutation } from "@tanstack/react-query";
5
+ import { defineRouteConfig } from "@medusajs/admin-sdk";
6
+ import Medusa from "@medusajs/js-sdk";
7
+ const sdk = new Medusa({
8
+ baseUrl: __BACKEND_URL__ || "/",
9
+ auth: {
10
+ type: "session"
11
+ }
12
+ });
13
+ const SyncPage = () => {
14
+ const [semanticSearchEnabled, setSemanticSearchEnabled] = useState(false);
15
+ const [semanticRatio, setSemanticRatio] = useState(0.5);
16
+ const [searchQuery, setSearchQuery] = useState("jeans");
17
+ const {
18
+ data: vectorStatus,
19
+ isLoading: statusLoading,
20
+ error: statusError,
21
+ refetch: refetchStatus
22
+ } = useQuery({
23
+ queryKey: ["meilisearch-vector-status"],
24
+ queryFn: async () => sdk.client.fetch("/admin/meilisearch/vector-status"),
25
+ retry: 2,
26
+ staleTime: 3e4
27
+ // Consider data stale after 30 seconds
28
+ });
29
+ const { mutate: syncData, isPending: syncPending } = useMutation({
30
+ mutationFn: () => sdk.client.fetch("/admin/meilisearch/sync", {
31
+ method: "POST"
32
+ }),
33
+ onSuccess: () => {
34
+ toast.success("Successfully triggered data sync to Meilisearch");
35
+ },
36
+ onError: (err) => {
37
+ console.error(err);
38
+ toast.error("Failed to sync data to Meilisearch");
39
+ }
40
+ });
41
+ const { mutate: searchProducts, isPending: searchProductsPending } = useMutation({
42
+ mutationFn: async () => {
43
+ if (!searchQuery.trim()) {
44
+ throw new Error("Search query cannot be empty");
45
+ }
46
+ return sdk.client.fetch("/admin/meilisearch/products-hits", {
47
+ method: "POST",
48
+ body: {
49
+ query: searchQuery.trim(),
50
+ semanticSearch: semanticSearchEnabled,
51
+ semanticRatio,
52
+ limit: 5,
53
+ offset: 0
54
+ }
55
+ });
56
+ },
57
+ onSuccess: (data) => {
58
+ const hybridInfo = data.hybridSearch ? ` (hybrid search with ratio ${data.semanticRatio})` : "";
59
+ toast.success(`Search successful. Found ${data.hits.length} products${hybridInfo}`);
60
+ },
61
+ onError: (err) => {
62
+ console.error("Search error:", err);
63
+ toast.error(err.message || "Search failed");
64
+ }
65
+ });
66
+ const { mutate: searchCategories, isPending: searchCategoriesPending } = useMutation({
67
+ mutationFn: async () => {
68
+ if (!searchQuery.trim()) {
69
+ throw new Error("Search query cannot be empty");
70
+ }
71
+ return sdk.client.fetch("/admin/meilisearch/categories-hits", {
72
+ method: "POST",
73
+ body: {
74
+ query: searchQuery.trim(),
75
+ semanticSearch: semanticSearchEnabled,
76
+ semanticRatio,
77
+ limit: 5,
78
+ offset: 0
79
+ }
80
+ });
81
+ },
82
+ onSuccess: (data) => {
83
+ const hybridInfo = data.hybridSearch ? ` (hybrid search with ratio ${data.semanticRatio})` : "";
84
+ toast.success(`Search successful. Found ${data.hits.length} categories${hybridInfo}`);
85
+ },
86
+ onError: (err) => {
87
+ console.error("Search error:", err);
88
+ toast.error(err.message || "Search failed");
89
+ }
90
+ });
91
+ const handleSync = () => {
92
+ syncData();
93
+ };
94
+ const handleSearchProducts = () => {
95
+ searchProducts();
96
+ };
97
+ const handleSearchCategories = () => {
98
+ searchCategories();
99
+ };
100
+ return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
101
+ /* @__PURE__ */ jsxs("div", { children: [
102
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Meilisearch Configuration" }),
103
+ /* @__PURE__ */ jsx(Text, { className: "text-gray-500 mt-2", children: "Manage your Meilisearch index synchronization and AI-powered semantic search settings." })
104
+ ] }),
105
+ /* @__PURE__ */ jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
106
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
107
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
108
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: "AI-Powered Semantic Search" }),
109
+ statusLoading ? /* @__PURE__ */ jsx(Badge, { children: "Loading..." }) : statusError ? /* @__PURE__ */ jsx(Badge, { color: "red", children: "Error" }) : (vectorStatus == null ? void 0 : vectorStatus.enabled) ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Enabled" }) : /* @__PURE__ */ jsx(Badge, { color: "grey", children: "Disabled" })
110
+ ] }),
111
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => refetchStatus(), isLoading: statusLoading, children: "Refresh Status" })
112
+ ] }),
113
+ statusError && /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 rounded-md", children: /* @__PURE__ */ jsxs(Text, { className: "text-red-800 text-sm", children: [
114
+ "Failed to load vector search status: ",
115
+ statusError.message
116
+ ] }) }),
117
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 mb-4", children: [
118
+ /* @__PURE__ */ jsxs("div", { children: [
119
+ /* @__PURE__ */ jsx(Text, { className: "text-sm font-medium text-gray-700", children: "Provider" }),
120
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-600", children: vectorStatus.provider || "Not specified" })
121
+ ] }),
122
+ /* @__PURE__ */ jsxs("div", { children: [
123
+ /* @__PURE__ */ jsx(Text, { className: "text-sm font-medium text-gray-700", children: "Model" }),
124
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-600", children: vectorStatus.model || "Not specified" })
125
+ ] }),
126
+ vectorStatus.dimensions && /* @__PURE__ */ jsxs("div", { children: [
127
+ /* @__PURE__ */ jsx(Text, { className: "text-sm font-medium text-gray-700", children: "Vector Dimensions" }),
128
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-600", children: vectorStatus.dimensions })
129
+ ] }),
130
+ /* @__PURE__ */ jsxs("div", { children: [
131
+ /* @__PURE__ */ jsx(Text, { className: "text-sm font-medium text-gray-700", children: "Embedding Fields" }),
132
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-600", children: vectorStatus.embeddingFields.join(", ") })
133
+ ] })
134
+ ] }),
135
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
136
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
137
+ /* @__PURE__ */ jsxs("div", { children: [
138
+ /* @__PURE__ */ jsx(Text, { className: "font-medium", children: "Enable Semantic Search in Tests" }),
139
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-500", children: "Use AI-powered semantic search for better results" })
140
+ ] }),
141
+ /* @__PURE__ */ jsx(Switch, { checked: semanticSearchEnabled, onCheckedChange: setSemanticSearchEnabled })
142
+ ] }),
143
+ semanticSearchEnabled && /* @__PURE__ */ jsxs("div", { children: [
144
+ /* @__PURE__ */ jsxs(Text, { className: "font-medium mb-2", children: [
145
+ "Semantic Ratio: ",
146
+ semanticRatio
147
+ ] }),
148
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-500 mb-3", children: "0.0 = Pure keyword search, 1.0 = Pure semantic search, 0.5 = Balanced hybrid" }),
149
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
150
+ /* @__PURE__ */ jsx(
151
+ Input,
152
+ {
153
+ type: "range",
154
+ min: "0",
155
+ max: "1",
156
+ step: "0.1",
157
+ value: semanticRatio,
158
+ onChange: (e) => setSemanticRatio(parseFloat(e.target.value)),
159
+ className: "flex-1",
160
+ "aria-label": "Semantic search ratio",
161
+ "aria-describedby": "semantic-ratio-description"
162
+ }
163
+ ),
164
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-700", children: semanticRatio.toFixed(1) })
165
+ ] }),
166
+ /* @__PURE__ */ jsx("div", { id: "semantic-ratio-description", className: "sr-only", children: "Adjust the balance between keyword and semantic search from 0 to 1" })
167
+ ] })
168
+ ] }),
169
+ !(vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsx(Text, { className: "text-gray-500", children: "Vector search is not configured. Add vectorSearch configuration to your plugin options to enable AI-powered semantic search." })
170
+ ] }),
171
+ /* @__PURE__ */ jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
172
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 mb-4", children: /* @__PURE__ */ jsx(Heading, { level: "h2", children: "Data Synchronization" }) }),
173
+ /* @__PURE__ */ jsxs(Text, { className: "text-gray-500 mb-4", children: [
174
+ "Manually trigger synchronization of your product catalog with Meilisearch.",
175
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && " This will also generate embeddings for semantic search."
176
+ ] }),
177
+ /* @__PURE__ */ jsx(Button, { onClick: handleSync, isLoading: syncPending, variant: "primary", children: "Sync Now" })
178
+ ] }),
179
+ /* @__PURE__ */ jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [
180
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 mb-4", children: /* @__PURE__ */ jsx(Heading, { level: "h2", children: "Search Testing" }) }),
181
+ /* @__PURE__ */ jsxs(Text, { className: "text-gray-500 mb-4", children: [
182
+ "Test your products search configuration with a custom query.",
183
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && " You can test both traditional keyword search and AI-powered semantic search."
184
+ ] }),
185
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
186
+ /* @__PURE__ */ jsxs("div", { children: [
187
+ /* @__PURE__ */ jsx(Text, { className: "text-sm font-medium text-gray-700 mb-2", children: "Search Query" }),
188
+ /* @__PURE__ */ jsx(
189
+ Input,
190
+ {
191
+ value: searchQuery,
192
+ onChange: (e) => setSearchQuery(e.target.value),
193
+ placeholder: "Enter search query (e.g., 'blue shirt', 'comfortable clothing')",
194
+ className: "w-full",
195
+ "aria-label": "Search query input",
196
+ "aria-describedby": "search-query-help"
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx("div", { id: "search-query-help", className: "sr-only", children: "Enter a search term to test the search functionality" })
200
+ ] }),
201
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
202
+ /* @__PURE__ */ jsx(
203
+ Button,
204
+ {
205
+ onClick: handleSearchProducts,
206
+ isLoading: searchProductsPending,
207
+ variant: "secondary",
208
+ disabled: !searchQuery.trim(),
209
+ children: "Search Products"
210
+ }
211
+ ),
212
+ /* @__PURE__ */ jsx(
213
+ Button,
214
+ {
215
+ onClick: handleSearchCategories,
216
+ isLoading: searchCategoriesPending,
217
+ variant: "secondary",
218
+ disabled: !searchQuery.trim(),
219
+ children: "Search Categories"
220
+ }
221
+ ),
222
+ (vectorStatus == null ? void 0 : vectorStatus.enabled) && /* @__PURE__ */ jsx(Text, { className: "text-sm text-gray-500 self-center", children: semanticSearchEnabled ? `Using hybrid search (${Math.round(semanticRatio * 100)}% semantic)` : "Using keyword search only" })
223
+ ] })
224
+ ] })
225
+ ] })
226
+ ] }) });
227
+ };
228
+ const config = defineRouteConfig({
229
+ label: "Meilisearch"
230
+ });
231
+ const widgetModule = { widgets: [] };
232
+ const routeModule = {
233
+ routes: [
234
+ {
235
+ Component: SyncPage,
236
+ path: "/settings/meilisearch"
237
+ }
238
+ ]
239
+ };
240
+ const menuItemModule = {
241
+ menuItems: [
242
+ {
243
+ label: config.label,
244
+ icon: void 0,
245
+ path: "/settings/meilisearch",
246
+ nested: void 0
247
+ }
248
+ ]
249
+ };
250
+ const formModule = { customFields: {} };
251
+ const displayModule = {
252
+ displays: {}
253
+ };
254
+ const i18nModule = { resources: {} };
255
+ const plugin = {
256
+ widgetModule,
257
+ routeModule,
258
+ menuItemModule,
259
+ formModule,
260
+ displayModule,
261
+ i18nModule
262
+ };
263
+ export {
264
+ plugin as default
265
+ };
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ import { SearchResponse } from 'meilisearch';
3
+ import { MedusaRequest, MedusaResponse } from '@medusajs/framework';
4
+ export declare const AdminSearchCategoriesSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ limit: z.ZodDefault<z.ZodNumber>;
7
+ offset: z.ZodDefault<z.ZodNumber>;
8
+ language: z.ZodOptional<z.ZodString>;
9
+ semanticSearch: z.ZodDefault<z.ZodBoolean>;
10
+ semanticRatio: z.ZodDefault<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ offset: number;
13
+ limit: number;
14
+ semanticSearch: boolean;
15
+ semanticRatio: number;
16
+ query: string;
17
+ language?: string | undefined;
18
+ }, {
19
+ query: string;
20
+ language?: string | undefined;
21
+ offset?: number | undefined;
22
+ limit?: number | undefined;
23
+ semanticSearch?: boolean | undefined;
24
+ semanticRatio?: number | undefined;
25
+ }>;
26
+ export type AdminSearchCategoriesParams = z.infer<typeof AdminSearchCategoriesSchema>;
27
+ export type AdminCategoriesHitsResponse = SearchResponse & {
28
+ hybridSearch?: boolean;
29
+ semanticRatio?: number;
30
+ };
31
+ export declare function POST(req: MedusaRequest<any, AdminSearchCategoriesParams>, res: MedusaResponse<AdminCategoriesHitsResponse>): Promise<void>;
32
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/meilisearch/categories-hits/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGnE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;EAOtC,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAErF,MAAM,MAAM,2BAA2B,GAAG,cAAc,GAAG;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7G,wBAAsB,IAAI,CACxB,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,2BAA2B,CAAC,EACpD,GAAG,EAAE,cAAc,CAAC,2BAA2B,CAAC,iBAuCjD"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AdminSearchCategoriesSchema = void 0;
4
+ exports.POST = POST;
5
+ const zod_1 = require("zod");
6
+ const meilisearch_1 = require("../../../../modules/meilisearch");
7
+ exports.AdminSearchCategoriesSchema = zod_1.z.object({
8
+ query: zod_1.z.string(),
9
+ limit: zod_1.z.coerce.number().default(10),
10
+ offset: zod_1.z.coerce.number().default(0),
11
+ language: zod_1.z.string().optional(),
12
+ semanticSearch: zod_1.z.coerce.boolean().default(false),
13
+ semanticRatio: zod_1.z.coerce.number().min(0).max(1).default(0.5),
14
+ });
15
+ async function POST(req, res) {
16
+ const { query, language, limit, offset, semanticSearch, semanticRatio } = req.validatedBody;
17
+ const meilisearchService = req.scope.resolve(meilisearch_1.MEILISEARCH_MODULE);
18
+ const indexes = await meilisearchService.getIndexesByType('categories');
19
+ const results = await Promise.all(indexes.map(async (indexKey) => {
20
+ return await meilisearchService.search(indexKey, query, {
21
+ language,
22
+ paginationOptions: {
23
+ limit,
24
+ offset,
25
+ },
26
+ semanticSearch,
27
+ semanticRatio,
28
+ });
29
+ }));
30
+ // Merge results from all indexes
31
+ const mergedResults = results.reduce((acc, result) => {
32
+ return {
33
+ hits: [...acc.hits, ...result.hits],
34
+ estimatedTotalHits: (acc.estimatedTotalHits || 0) + (result.estimatedTotalHits || 0),
35
+ processingTimeMs: Math.max(acc.processingTimeMs, result.processingTimeMs),
36
+ query: result.query,
37
+ // Include vector search metadata if available
38
+ ...(semanticSearch && {
39
+ hybridSearch: true,
40
+ semanticRatio,
41
+ }),
42
+ };
43
+ }, { hits: [], estimatedTotalHits: 0, processingTimeMs: 0, query });
44
+ res.json(mergedResults);
45
+ }
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL21laWxpc2VhcmNoL2NhdGVnb3JpZXMtaGl0cy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFrQkEsb0JBeUNDO0FBM0RELDZCQUF1QjtBQUd2QixpRUFBd0Y7QUFFM0UsUUFBQSwyQkFBMkIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ2xELEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2pCLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7SUFDcEMsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNwQyxRQUFRLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixjQUFjLEVBQUUsT0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQ2pELGFBQWEsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztDQUM1RCxDQUFDLENBQUE7QUFNSyxLQUFLLFVBQVUsSUFBSSxDQUN4QixHQUFvRCxFQUNwRCxHQUFnRDtJQUVoRCxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFBO0lBQzNGLE1BQU0sa0JBQWtCLEdBQXVCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGdDQUFrQixDQUFDLENBQUE7SUFFcEYsTUFBTSxPQUFPLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUN2RSxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFO1FBQzdCLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRTtZQUN0RCxRQUFRO1lBQ1IsaUJBQWlCLEVBQUU7Z0JBQ2pCLEtBQUs7Z0JBQ0wsTUFBTTthQUNQO1lBQ0QsY0FBYztZQUNkLGFBQWE7U0FDZCxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FDSCxDQUFBO0lBRUQsaUNBQWlDO0lBQ2pDLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQ2xDLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ2QsT0FBTztZQUNMLElBQUksRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDbkMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLElBQUksQ0FBQyxDQUFDO1lBQ3BGLGdCQUFnQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztZQUN6RSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7WUFDbkIsOENBQThDO1lBQzlDLEdBQUcsQ0FBQyxjQUFjLElBQUk7Z0JBQ3BCLFlBQVksRUFBRSxJQUFJO2dCQUNsQixhQUFhO2FBQ2QsQ0FBQztTQUNILENBQUE7SUFDSCxDQUFDLEVBQ0QsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLGtCQUFrQixFQUFFLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQ2hFLENBQUE7SUFFRCxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ3pCLENBQUMifQ==
@@ -0,0 +1,32 @@
1
+ import z from 'zod';
2
+ import { SearchResponse } from 'meilisearch';
3
+ import { MedusaRequest, MedusaResponse } from '@medusajs/framework';
4
+ export declare const AdminSearchProductsSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ limit: z.ZodDefault<z.ZodNumber>;
7
+ offset: z.ZodDefault<z.ZodNumber>;
8
+ language: z.ZodOptional<z.ZodString>;
9
+ semanticSearch: z.ZodDefault<z.ZodBoolean>;
10
+ semanticRatio: z.ZodDefault<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ offset: number;
13
+ limit: number;
14
+ semanticSearch: boolean;
15
+ semanticRatio: number;
16
+ query: string;
17
+ language?: string | undefined;
18
+ }, {
19
+ query: string;
20
+ language?: string | undefined;
21
+ offset?: number | undefined;
22
+ limit?: number | undefined;
23
+ semanticSearch?: boolean | undefined;
24
+ semanticRatio?: number | undefined;
25
+ }>;
26
+ export type AdminSearchProductsParams = z.infer<typeof AdminSearchProductsSchema>;
27
+ export type AdminProductsHitsResponse = SearchResponse & {
28
+ hybridSearch?: boolean;
29
+ semanticRatio?: number;
30
+ };
31
+ export declare function POST(req: MedusaRequest<any, AdminSearchProductsParams>, res: MedusaResponse<AdminProductsHitsResponse>): Promise<void>;
32
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/meilisearch/products-hits/route.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGnE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;EAOpC,CAAA;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEjF,MAAM,MAAM,yBAAyB,GAAG,cAAc,GAAG;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3G,wBAAsB,IAAI,CACxB,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,yBAAyB,CAAC,EAClD,GAAG,EAAE,cAAc,CAAC,yBAAyB,CAAC,iBAuC/C"}