@unchainedshop/api 4.0.0-rc.2 → 4.0.0-rc.3

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 (417) hide show
  1. package/lib/api-index.d.ts.map +1 -1
  2. package/lib/api-index.js +4 -1
  3. package/lib/api-index.js.map +1 -1
  4. package/lib/errors.d.ts +1 -1
  5. package/lib/errors.d.ts.map +1 -1
  6. package/lib/errors.js +1 -1
  7. package/lib/errors.js.map +1 -1
  8. package/lib/express/chatRouter.d.ts +3 -0
  9. package/lib/express/chatRouter.d.ts.map +1 -0
  10. package/lib/express/chatRouter.js +86 -0
  11. package/lib/express/chatRouter.js.map +1 -0
  12. package/lib/express/createApolloMiddleware.d.ts +4 -0
  13. package/lib/express/createApolloMiddleware.d.ts.map +1 -0
  14. package/lib/express/createApolloMiddleware.js +36 -0
  15. package/lib/express/createApolloMiddleware.js.map +1 -0
  16. package/lib/express/createBulkImportMiddleware copy.d.ts +6 -0
  17. package/lib/express/createBulkImportMiddleware copy.d.ts.map +1 -0
  18. package/lib/express/createBulkImportMiddleware copy.js +49 -0
  19. package/lib/express/createBulkImportMiddleware copy.js.map +1 -0
  20. package/lib/express/createMCPMiddleware.d.ts +2 -6
  21. package/lib/express/createMCPMiddleware.d.ts.map +1 -1
  22. package/lib/express/createMCPMiddleware.js +73 -42
  23. package/lib/express/createMCPMiddleware.js.map +1 -1
  24. package/lib/express/createSingleSignOnMiddleware.d.ts +5 -0
  25. package/lib/express/createSingleSignOnMiddleware.d.ts.map +1 -0
  26. package/lib/express/createSingleSignOnMiddleware.js +71 -0
  27. package/lib/express/createSingleSignOnMiddleware.js.map +1 -0
  28. package/lib/express/createTempUploadMiddleware.d.ts +7 -0
  29. package/lib/express/createTempUploadMiddleware.d.ts.map +1 -0
  30. package/lib/express/createTempUploadMiddleware.js +48 -0
  31. package/lib/express/createTempUploadMiddleware.js.map +1 -0
  32. package/lib/express/index.d.ts.map +1 -1
  33. package/lib/express/index.js +17 -4
  34. package/lib/express/index.js.map +1 -1
  35. package/lib/express/setupMCPChatHandler.d.ts +3 -0
  36. package/lib/express/setupMCPChatHandler.d.ts.map +1 -0
  37. package/lib/express/setupMCPChatHandler.js +57 -0
  38. package/lib/express/setupMCPChatHandler.js.map +1 -0
  39. package/lib/fastify/index.d.ts.map +1 -1
  40. package/lib/fastify/index.js +24 -2
  41. package/lib/fastify/index.js.map +1 -1
  42. package/lib/fastify/mcpChatHandler.d.ts +3 -0
  43. package/lib/fastify/mcpChatHandler.d.ts.map +1 -0
  44. package/lib/fastify/mcpChatHandler.js +60 -0
  45. package/lib/fastify/mcpChatHandler.js.map +1 -0
  46. package/lib/fastify/mcpHandler copy.d.ts +4 -0
  47. package/lib/fastify/mcpHandler copy.d.ts.map +1 -0
  48. package/lib/fastify/mcpHandler copy.js +72 -0
  49. package/lib/fastify/mcpHandler copy.js.map +1 -0
  50. package/lib/fastify/mcpHandler.d.ts +3 -7
  51. package/lib/fastify/mcpHandler.d.ts.map +1 -1
  52. package/lib/fastify/mcpHandler.js +71 -39
  53. package/lib/fastify/mcpHandler.js.map +1 -1
  54. package/lib/fastify/tempUploadHandler.d.ts +4 -0
  55. package/lib/fastify/tempUploadHandler.d.ts.map +1 -0
  56. package/lib/fastify/tempUploadHandler.js +41 -0
  57. package/lib/fastify/tempUploadHandler.js.map +1 -0
  58. package/lib/hashPassword.d.ts +2 -0
  59. package/lib/hashPassword.d.ts.map +1 -0
  60. package/lib/hashPassword.js +5 -0
  61. package/lib/hashPassword.js.map +1 -0
  62. package/lib/loaders/assortmentMediaTextLoader.js +1 -1
  63. package/lib/loaders/assortmentMediaTextLoader.js.map +1 -1
  64. package/lib/loaders/assortmentTextLoader.js +1 -1
  65. package/lib/loaders/assortmentTextLoader.js.map +1 -1
  66. package/lib/loaders/buildLocaleMap.d.ts +6 -0
  67. package/lib/loaders/buildLocaleMap.d.ts.map +1 -0
  68. package/lib/loaders/buildLocaleMap.js +67 -0
  69. package/lib/loaders/buildLocaleMap.js.map +1 -0
  70. package/lib/loaders/buildTextMap.d.ts +1 -1
  71. package/lib/loaders/buildTextMap.d.ts.map +1 -1
  72. package/lib/loaders/buildTextMap.js +19 -6
  73. package/lib/loaders/buildTextMap.js.map +1 -1
  74. package/lib/loaders/filterTextLoader.js +1 -1
  75. package/lib/loaders/filterTextLoader.js.map +1 -1
  76. package/lib/loaders/productMediaTextLoader.d.ts.map +1 -1
  77. package/lib/loaders/productMediaTextLoader.js +1 -1
  78. package/lib/loaders/productMediaTextLoader.js.map +1 -1
  79. package/lib/loaders/productTextLoader.d.ts.map +1 -1
  80. package/lib/loaders/productTextLoader.js +1 -1
  81. package/lib/loaders/productTextLoader.js.map +1 -1
  82. package/lib/mcp/index.d.ts +3 -94
  83. package/lib/mcp/index.d.ts.map +1 -1
  84. package/lib/mcp/index.js +45 -135
  85. package/lib/mcp/index.js.map +1 -1
  86. package/lib/mcp/tools/addProductAssignmentHandler.d.ts +52 -0
  87. package/lib/mcp/tools/addProductAssignmentHandler.d.ts.map +1 -0
  88. package/lib/mcp/tools/addProductAssignmentHandler.js +97 -0
  89. package/lib/mcp/tools/addProductAssignmentHandler.js.map +1 -0
  90. package/lib/mcp/tools/addProductMediaUploadHandler.d.ts +28 -0
  91. package/lib/mcp/tools/addProductMediaUploadHandler.d.ts.map +1 -0
  92. package/lib/mcp/tools/addProductMediaUploadHandler.js +62 -0
  93. package/lib/mcp/tools/addProductMediaUploadHandler.js.map +1 -0
  94. package/lib/mcp/tools/countriesHandler.d.ts +60 -0
  95. package/lib/mcp/tools/countriesHandler.d.ts.map +1 -0
  96. package/lib/mcp/tools/countriesHandler.js +48 -0
  97. package/lib/mcp/tools/countriesHandler.js.map +1 -0
  98. package/lib/mcp/tools/countryHandler.d.ts +20 -0
  99. package/lib/mcp/tools/countryHandler.d.ts.map +1 -0
  100. package/lib/mcp/tools/countryHandler.js +34 -0
  101. package/lib/mcp/tools/countryHandler.js.map +1 -0
  102. package/lib/mcp/tools/createLanguageHandler.d.ts +36 -0
  103. package/lib/mcp/tools/createLanguageHandler.d.ts.map +1 -0
  104. package/lib/mcp/tools/createLanguageHandler.js +39 -0
  105. package/lib/mcp/tools/createLanguageHandler.js.map +1 -0
  106. package/lib/mcp/tools/createProduct.d.ts +138 -0
  107. package/lib/mcp/tools/createProduct.d.ts.map +1 -0
  108. package/lib/mcp/tools/createProduct.js +60 -0
  109. package/lib/mcp/tools/createProduct.js.map +1 -0
  110. package/lib/mcp/tools/createProductVariationHandler.d.ts +84 -0
  111. package/lib/mcp/tools/createProductVariationHandler.d.ts.map +1 -0
  112. package/lib/mcp/tools/createProductVariationHandler.js +73 -0
  113. package/lib/mcp/tools/createProductVariationHandler.js.map +1 -0
  114. package/lib/mcp/tools/createProductVariationOptionHandler.d.ts +60 -0
  115. package/lib/mcp/tools/createProductVariationOptionHandler.d.ts.map +1 -0
  116. package/lib/mcp/tools/createProductVariationOptionHandler.js +59 -0
  117. package/lib/mcp/tools/createProductVariationOptionHandler.js.map +1 -0
  118. package/lib/mcp/tools/currenciesHandler.d.ts +60 -0
  119. package/lib/mcp/tools/currenciesHandler.d.ts.map +1 -0
  120. package/lib/mcp/tools/currenciesHandler.js +50 -0
  121. package/lib/mcp/tools/currenciesHandler.js.map +1 -0
  122. package/lib/mcp/tools/currencyHandler.d.ts +20 -0
  123. package/lib/mcp/tools/currencyHandler.d.ts.map +1 -0
  124. package/lib/mcp/tools/currencyHandler.js +34 -0
  125. package/lib/mcp/tools/currencyHandler.js.map +1 -0
  126. package/lib/mcp/tools/getProduct.d.ts +48 -0
  127. package/lib/mcp/tools/getProduct.d.ts.map +1 -0
  128. package/lib/mcp/tools/getProduct.js +61 -0
  129. package/lib/mcp/tools/getProduct.js.map +1 -0
  130. package/lib/mcp/tools/index.d.ts +39 -0
  131. package/lib/mcp/tools/index.d.ts.map +1 -0
  132. package/lib/mcp/tools/index.js +39 -0
  133. package/lib/mcp/tools/index.js.map +1 -0
  134. package/lib/mcp/tools/languageHandler.d.ts +20 -0
  135. package/lib/mcp/tools/languageHandler.d.ts.map +1 -0
  136. package/lib/mcp/tools/languageHandler.js +31 -0
  137. package/lib/mcp/tools/languageHandler.js.map +1 -0
  138. package/lib/mcp/tools/languagesHandler.d.ts +60 -0
  139. package/lib/mcp/tools/languagesHandler.d.ts.map +1 -0
  140. package/lib/mcp/tools/languagesHandler.js +42 -0
  141. package/lib/mcp/tools/languagesHandler.js.map +1 -0
  142. package/lib/mcp/tools/listProducts.d.ts +112 -0
  143. package/lib/mcp/tools/listProducts.d.ts.map +1 -0
  144. package/lib/mcp/tools/listProducts.js +110 -0
  145. package/lib/mcp/tools/listProducts.js.map +1 -0
  146. package/lib/mcp/tools/normalizeMediaUrl.d.ts +3 -0
  147. package/lib/mcp/tools/normalizeMediaUrl.d.ts.map +1 -0
  148. package/lib/mcp/tools/normalizeMediaUrl.js +21 -0
  149. package/lib/mcp/tools/normalizeMediaUrl.js.map +1 -0
  150. package/lib/mcp/tools/productReviewsCountHandler.d.ts +20 -0
  151. package/lib/mcp/tools/productReviewsCountHandler.d.ts.map +1 -0
  152. package/lib/mcp/tools/productReviewsCountHandler.js +30 -0
  153. package/lib/mcp/tools/productReviewsCountHandler.js.map +1 -0
  154. package/lib/mcp/tools/productReviewsHandler.d.ts +56 -0
  155. package/lib/mcp/tools/productReviewsHandler.d.ts.map +1 -0
  156. package/lib/mcp/tools/productReviewsHandler.js +45 -0
  157. package/lib/mcp/tools/productReviewsHandler.js.map +1 -0
  158. package/lib/mcp/tools/productsCountHandler.d.ts +32 -0
  159. package/lib/mcp/tools/productsCountHandler.d.ts.map +1 -0
  160. package/lib/mcp/tools/productsCountHandler.js +33 -0
  161. package/lib/mcp/tools/productsCountHandler.js.map +1 -0
  162. package/lib/mcp/tools/publishProduct.d.ts +20 -0
  163. package/lib/mcp/tools/publishProduct.d.ts.map +1 -0
  164. package/lib/mcp/tools/publishProduct.js +40 -0
  165. package/lib/mcp/tools/publishProduct.js.map +1 -0
  166. package/lib/mcp/tools/removeLanguageHandler.d.ts +20 -0
  167. package/lib/mcp/tools/removeLanguageHandler.d.ts.map +1 -0
  168. package/lib/mcp/tools/removeLanguageHandler.js +35 -0
  169. package/lib/mcp/tools/removeLanguageHandler.js.map +1 -0
  170. package/lib/mcp/tools/removeProduct.d.ts +20 -0
  171. package/lib/mcp/tools/removeProduct.d.ts.map +1 -0
  172. package/lib/mcp/tools/removeProduct.js +34 -0
  173. package/lib/mcp/tools/removeProduct.js.map +1 -0
  174. package/lib/mcp/tools/removeProductAssignmentHandler.d.ts +48 -0
  175. package/lib/mcp/tools/removeProductAssignmentHandler.d.ts.map +1 -0
  176. package/lib/mcp/tools/removeProductAssignmentHandler.js +51 -0
  177. package/lib/mcp/tools/removeProductAssignmentHandler.js.map +1 -0
  178. package/lib/mcp/tools/removeProductHandler.d.ts +20 -0
  179. package/lib/mcp/tools/removeProductHandler.d.ts.map +1 -0
  180. package/lib/mcp/tools/removeProductHandler.js +34 -0
  181. package/lib/mcp/tools/removeProductHandler.js.map +1 -0
  182. package/lib/mcp/tools/removeProductMediaHandler.d.ts +20 -0
  183. package/lib/mcp/tools/removeProductMediaHandler.d.ts.map +1 -0
  184. package/lib/mcp/tools/removeProductMediaHandler.js +42 -0
  185. package/lib/mcp/tools/removeProductMediaHandler.js.map +1 -0
  186. package/lib/mcp/tools/removeProductVariationHandler.d.ts +20 -0
  187. package/lib/mcp/tools/removeProductVariationHandler.d.ts.map +1 -0
  188. package/lib/mcp/tools/removeProductVariationHandler.js +43 -0
  189. package/lib/mcp/tools/removeProductVariationHandler.js.map +1 -0
  190. package/lib/mcp/tools/removeProductVariationOptionHandler.d.ts +24 -0
  191. package/lib/mcp/tools/removeProductVariationOptionHandler.d.ts.map +1 -0
  192. package/lib/mcp/tools/removeProductVariationOptionHandler.js +47 -0
  193. package/lib/mcp/tools/removeProductVariationOptionHandler.js.map +1 -0
  194. package/lib/mcp/tools/reorderProductMediaHandler.d.ts +44 -0
  195. package/lib/mcp/tools/reorderProductMediaHandler.d.ts.map +1 -0
  196. package/lib/mcp/tools/reorderProductMediaHandler.js +39 -0
  197. package/lib/mcp/tools/reorderProductMediaHandler.js.map +1 -0
  198. package/lib/mcp/tools/unPublishProduct.d.ts +20 -0
  199. package/lib/mcp/tools/unPublishProduct.d.ts.map +1 -0
  200. package/lib/mcp/tools/unPublishProduct.js +40 -0
  201. package/lib/mcp/tools/unPublishProduct.js.map +1 -0
  202. package/lib/mcp/tools/updateLanguageHandler.d.ts +48 -0
  203. package/lib/mcp/tools/updateLanguageHandler.d.ts.map +1 -0
  204. package/lib/mcp/tools/updateLanguageHandler.js +40 -0
  205. package/lib/mcp/tools/updateLanguageHandler.js.map +1 -0
  206. package/lib/mcp/tools/updateProduct.d.ts +56 -0
  207. package/lib/mcp/tools/updateProduct.d.ts.map +1 -0
  208. package/lib/mcp/tools/updateProduct.js +44 -0
  209. package/lib/mcp/tools/updateProduct.js.map +1 -0
  210. package/lib/mcp/tools/updateProductCommerceHandler.d.ts +166 -0
  211. package/lib/mcp/tools/updateProductCommerceHandler.d.ts.map +1 -0
  212. package/lib/mcp/tools/updateProductCommerceHandler.js +64 -0
  213. package/lib/mcp/tools/updateProductCommerceHandler.js.map +1 -0
  214. package/lib/mcp/tools/updateProductMediaTextsHandler.d.ts +56 -0
  215. package/lib/mcp/tools/updateProductMediaTextsHandler.d.ts.map +1 -0
  216. package/lib/mcp/tools/updateProductMediaTextsHandler.js +45 -0
  217. package/lib/mcp/tools/updateProductMediaTextsHandler.js.map +1 -0
  218. package/lib/mcp/tools/updateProductPlanHandler.d.ts +72 -0
  219. package/lib/mcp/tools/updateProductPlanHandler.d.ts.map +1 -0
  220. package/lib/mcp/tools/updateProductPlanHandler.js +51 -0
  221. package/lib/mcp/tools/updateProductPlanHandler.js.map +1 -0
  222. package/lib/mcp/tools/updateProductSupplyHandler.d.ts +64 -0
  223. package/lib/mcp/tools/updateProductSupplyHandler.d.ts.map +1 -0
  224. package/lib/mcp/tools/updateProductSupplyHandler.js +52 -0
  225. package/lib/mcp/tools/updateProductSupplyHandler.js.map +1 -0
  226. package/lib/mcp/tools/updateProductTextsHandler.d.ts +114 -0
  227. package/lib/mcp/tools/updateProductTextsHandler.d.ts.map +1 -0
  228. package/lib/mcp/tools/updateProductTextsHandler.js +50 -0
  229. package/lib/mcp/tools/updateProductTextsHandler.js.map +1 -0
  230. package/lib/mcp/tools/updateProductTokenizationHandler.d.ts +72 -0
  231. package/lib/mcp/tools/updateProductTokenizationHandler.d.ts.map +1 -0
  232. package/lib/mcp/tools/updateProductTokenizationHandler.js +49 -0
  233. package/lib/mcp/tools/updateProductTokenizationHandler.js.map +1 -0
  234. package/lib/mcp/tools/updateProductWarehousingHandler.d.ts +48 -0
  235. package/lib/mcp/tools/updateProductWarehousingHandler.d.ts.map +1 -0
  236. package/lib/mcp/tools/updateProductWarehousingHandler.js +45 -0
  237. package/lib/mcp/tools/updateProductWarehousingHandler.js.map +1 -0
  238. package/lib/mcp/utils/getNormalizedProductDetails.d.ts +26 -0
  239. package/lib/mcp/utils/getNormalizedProductDetails.d.ts.map +1 -0
  240. package/lib/mcp/utils/getNormalizedProductDetails.js +38 -0
  241. package/lib/mcp/utils/getNormalizedProductDetails.js.map +1 -0
  242. package/lib/mcp/utils/normalizeMediaUrl.d.ts +3 -0
  243. package/lib/mcp/utils/normalizeMediaUrl.d.ts.map +1 -0
  244. package/lib/mcp/utils/normalizeMediaUrl.js +21 -0
  245. package/lib/mcp/utils/normalizeMediaUrl.js.map +1 -0
  246. package/lib/resolvers/mutations/accounts/buildSecretTOTPAuthURL.d.ts +3 -0
  247. package/lib/resolvers/mutations/accounts/buildSecretTOTPAuthURL.d.ts.map +1 -0
  248. package/lib/resolvers/mutations/accounts/buildSecretTOTPAuthURL.js +6 -0
  249. package/lib/resolvers/mutations/accounts/buildSecretTOTPAuthURL.js.map +1 -0
  250. package/lib/resolvers/mutations/accounts/disableTOTP.d.ts +6 -0
  251. package/lib/resolvers/mutations/accounts/disableTOTP.d.ts.map +1 -0
  252. package/lib/resolvers/mutations/accounts/disableTOTP.js +27 -0
  253. package/lib/resolvers/mutations/accounts/disableTOTP.js.map +1 -0
  254. package/lib/resolvers/mutations/accounts/enableTOTP.d.ts +6 -0
  255. package/lib/resolvers/mutations/accounts/enableTOTP.d.ts.map +1 -0
  256. package/lib/resolvers/mutations/accounts/enableTOTP.js +20 -0
  257. package/lib/resolvers/mutations/accounts/enableTOTP.js.map +1 -0
  258. package/lib/resolvers/mutations/accounts/linkOAuthAccount.d.ts +7 -0
  259. package/lib/resolvers/mutations/accounts/linkOAuthAccount.d.ts.map +1 -0
  260. package/lib/resolvers/mutations/accounts/linkOAuthAccount.js +30 -0
  261. package/lib/resolvers/mutations/accounts/linkOAuthAccount.js.map +1 -0
  262. package/lib/resolvers/mutations/accounts/loginWithOAuth.d.ts +8 -0
  263. package/lib/resolvers/mutations/accounts/loginWithOAuth.d.ts.map +1 -0
  264. package/lib/resolvers/mutations/accounts/loginWithOAuth.js +25 -0
  265. package/lib/resolvers/mutations/accounts/loginWithOAuth.js.map +1 -0
  266. package/lib/resolvers/mutations/accounts/logoutAllSessions.d.ts +5 -0
  267. package/lib/resolvers/mutations/accounts/logoutAllSessions.d.ts.map +1 -0
  268. package/lib/resolvers/mutations/accounts/logoutAllSessions.js +20 -0
  269. package/lib/resolvers/mutations/accounts/logoutAllSessions.js.map +1 -0
  270. package/lib/resolvers/mutations/accounts/unlinkOAuthAccount.d.ts +6 -0
  271. package/lib/resolvers/mutations/accounts/unlinkOAuthAccount.d.ts.map +1 -0
  272. package/lib/resolvers/mutations/accounts/unlinkOAuthAccount.js +13 -0
  273. package/lib/resolvers/mutations/accounts/unlinkOAuthAccount.js.map +1 -0
  274. package/lib/resolvers/mutations/assortments/addAssortmentMedia.d.ts +6 -0
  275. package/lib/resolvers/mutations/assortments/addAssortmentMedia.d.ts.map +1 -0
  276. package/lib/resolvers/mutations/assortments/addAssortmentMedia.js +18 -0
  277. package/lib/resolvers/mutations/assortments/addAssortmentMedia.js.map +1 -0
  278. package/lib/resolvers/mutations/products/addProductAssignment.d.ts.map +1 -1
  279. package/lib/resolvers/mutations/products/addProductAssignment.js +3 -1
  280. package/lib/resolvers/mutations/products/addProductAssignment.js.map +1 -1
  281. package/lib/resolvers/mutations/products/addProductMedia.d.ts +6 -0
  282. package/lib/resolvers/mutations/products/addProductMedia.d.ts.map +1 -0
  283. package/lib/resolvers/mutations/products/addProductMedia.js +18 -0
  284. package/lib/resolvers/mutations/products/addProductMedia.js.map +1 -0
  285. package/lib/resolvers/mutations/users/updateUserAvatar.d.ts +6 -0
  286. package/lib/resolvers/mutations/users/updateUserAvatar.d.ts.map +1 -0
  287. package/lib/resolvers/mutations/users/updateUserAvatar.js +22 -0
  288. package/lib/resolvers/mutations/users/updateUserAvatar.js.map +1 -0
  289. package/lib/resolvers/mutations/utils/getOrderCart.d.ts +7 -0
  290. package/lib/resolvers/mutations/utils/getOrderCart.d.ts.map +1 -0
  291. package/lib/resolvers/mutations/utils/getOrderCart.js +13 -0
  292. package/lib/resolvers/mutations/utils/getOrderCart.js.map +1 -0
  293. package/lib/resolvers/queries/filters/searchAssortments.d.ts.map +1 -1
  294. package/lib/resolvers/queries/filters/searchAssortments.js +0 -5
  295. package/lib/resolvers/queries/filters/searchAssortments.js.map +1 -1
  296. package/lib/resolvers/queries/filters/searchProducts.d.ts.map +1 -1
  297. package/lib/resolvers/queries/filters/searchProducts.js +2 -7
  298. package/lib/resolvers/queries/filters/searchProducts.js.map +1 -1
  299. package/lib/resolvers/type/dispatch-types.d.ts +15 -0
  300. package/lib/resolvers/type/dispatch-types.d.ts.map +1 -0
  301. package/lib/resolvers/type/dispatch-types.js +16 -0
  302. package/lib/resolvers/type/dispatch-types.js.map +1 -0
  303. package/lib/resolvers/type/oauth-account.d.ts +6 -0
  304. package/lib/resolvers/type/oauth-account.d.ts.map +1 -0
  305. package/lib/resolvers/type/oauth-account.js +7 -0
  306. package/lib/resolvers/type/oauth-account.js.map +1 -0
  307. package/lib/resolvers/type/oauth-provider.d.ts +6 -0
  308. package/lib/resolvers/type/oauth-provider.d.ts.map +1 -0
  309. package/lib/resolvers/type/oauth-provider.js +6 -0
  310. package/lib/resolvers/type/oauth-provider.js.map +1 -0
  311. package/lib/resolvers/type/stock-types.d.ts +14 -0
  312. package/lib/resolvers/type/stock-types.d.ts.map +1 -0
  313. package/lib/resolvers/type/stock-types.js +15 -0
  314. package/lib/resolvers/type/stock-types.js.map +1 -0
  315. package/lib/roles/all.d.ts.map +1 -1
  316. package/lib/roles/all.js +1 -0
  317. package/lib/roles/all.js.map +1 -1
  318. package/lib/roles/index.d.ts.map +1 -1
  319. package/lib/roles/index.js +1 -0
  320. package/lib/roles/index.js.map +1 -1
  321. package/lib/roles/loggedIn.d.ts.map +1 -1
  322. package/lib/roles/loggedIn.js +1 -0
  323. package/lib/roles/loggedIn.js.map +1 -1
  324. package/lib/user-context.d.ts +7 -0
  325. package/lib/user-context.d.ts.map +1 -0
  326. package/lib/user-context.js +76 -0
  327. package/lib/user-context.js.map +1 -0
  328. package/package.json +34 -18
  329. package/src/api-index.ts +4 -1
  330. package/src/errors.ts +5 -4
  331. package/src/express/createMCPMiddleware.ts +91 -0
  332. package/src/express/createTempUploadMiddleware.ts +60 -0
  333. package/src/express/index.ts +35 -6
  334. package/src/fastify/index.ts +32 -2
  335. package/src/fastify/mcpHandler.ts +97 -0
  336. package/src/fastify/tempUploadHandler.ts +52 -0
  337. package/src/loaders/assortmentMediaTextLoader.ts +1 -1
  338. package/src/loaders/assortmentTextLoader.ts +1 -1
  339. package/src/loaders/buildLocaleMap.test.ts +65 -0
  340. package/src/loaders/buildLocaleMap.ts +73 -0
  341. package/src/loaders/buildTextMap.test.ts +54 -0
  342. package/src/loaders/buildTextMap.ts +25 -6
  343. package/src/loaders/filterTextLoader.ts +1 -1
  344. package/src/loaders/productMediaTextLoader.ts +1 -1
  345. package/src/loaders/productTextLoader.ts +1 -1
  346. package/src/mcp/README.md +25 -0
  347. package/src/mcp/index.ts +313 -0
  348. package/src/mcp/tools/addProductAssignmentHandler.ts +118 -0
  349. package/src/mcp/tools/addProductMediaUploadHandler.ts +79 -0
  350. package/src/mcp/tools/countriesHandler.ts +60 -0
  351. package/src/mcp/tools/countryHandler.ts +40 -0
  352. package/src/mcp/tools/createLanguageHandler.ts +46 -0
  353. package/src/mcp/tools/createProduct.ts +75 -0
  354. package/src/mcp/tools/createProductVariationHandler.ts +93 -0
  355. package/src/mcp/tools/createProductVariationOptionHandler.ts +73 -0
  356. package/src/mcp/tools/currenciesHandler.ts +63 -0
  357. package/src/mcp/tools/currencyHandler.ts +40 -0
  358. package/src/mcp/tools/getProduct.ts +74 -0
  359. package/src/mcp/tools/index.ts +39 -0
  360. package/src/mcp/tools/languageHandler.ts +37 -0
  361. package/src/mcp/tools/languagesHandler.ts +54 -0
  362. package/src/mcp/tools/listProducts.ts +148 -0
  363. package/src/mcp/tools/productReviewsCountHandler.ts +36 -0
  364. package/src/mcp/tools/productReviewsHandler.ts +54 -0
  365. package/src/mcp/tools/productsCountHandler.ts +38 -0
  366. package/src/mcp/tools/publishProduct.ts +45 -0
  367. package/src/mcp/tools/removeLanguageHandler.ts +42 -0
  368. package/src/mcp/tools/removeProductAssignmentHandler.ts +61 -0
  369. package/src/mcp/tools/removeProductHandler.ts +40 -0
  370. package/src/mcp/tools/removeProductMediaHandler.ts +49 -0
  371. package/src/mcp/tools/removeProductVariationHandler.ts +51 -0
  372. package/src/mcp/tools/removeProductVariationOptionHandler.ts +58 -0
  373. package/src/mcp/tools/reorderProductMediaHandler.ts +48 -0
  374. package/src/mcp/tools/unPublishProduct.ts +46 -0
  375. package/src/mcp/tools/updateLanguageHandler.ts +47 -0
  376. package/src/mcp/tools/updateProduct.ts +51 -0
  377. package/src/mcp/tools/updateProductCommerceHandler.ts +79 -0
  378. package/src/mcp/tools/updateProductMediaTextsHandler.ts +56 -0
  379. package/src/mcp/tools/updateProductPlanHandler.ts +58 -0
  380. package/src/mcp/tools/updateProductSupplyHandler.ts +59 -0
  381. package/src/mcp/tools/updateProductTextsHandler.ts +59 -0
  382. package/src/mcp/tools/updateProductTokenizationHandler.ts +58 -0
  383. package/src/mcp/tools/updateProductWarehousingHandler.ts +54 -0
  384. package/src/mcp/utils/getNormalizedProductDetails.ts +42 -0
  385. package/src/mcp/utils/normalizeMediaUrl.ts +26 -0
  386. package/src/resolvers/mutations/products/addProductAssignment.ts +3 -0
  387. package/src/resolvers/queries/filters/searchAssortments.ts +0 -5
  388. package/src/resolvers/queries/filters/searchProducts.ts +2 -7
  389. package/src/roles/all.ts +1 -0
  390. package/src/roles/index.ts +1 -0
  391. package/src/roles/loggedIn.ts +1 -0
  392. package/lib/express/mcpHandler.d.ts.map +0 -1
  393. package/lib/express/mcpHandler.js +0 -68
  394. package/lib/express/mcpHandler.js.map +0 -1
  395. package/lib/fastify/index copy.d.ts.map +0 -1
  396. package/lib/fastify/index copy.js +0 -157
  397. package/lib/fastify/index copy.js.map +0 -1
  398. package/lib/mcp/server.d.ts +0 -4
  399. package/lib/mcp/server.d.ts.map +0 -1
  400. package/lib/mcp/server.js +0 -60
  401. package/lib/mcp/server.js.map +0 -1
  402. package/lib/mcp/types.d.ts +0 -28
  403. package/lib/mcp/types.d.ts.map +0 -1
  404. package/lib/mcp/types.js +0 -2
  405. package/lib/mcp/types.js.map +0 -1
  406. package/lib/middleware/accountLockout.d.ts.map +0 -1
  407. package/lib/middleware/accountLockout.js +0 -84
  408. package/lib/middleware/accountLockout.js.map +0 -1
  409. package/lib/middleware/rateLimiter.d.ts.map +0 -1
  410. package/lib/middleware/rateLimiter.js +0 -91
  411. package/lib/middleware/rateLimiter.js.map +0 -1
  412. package/lib/plugins/inputValidation.d.ts.map +0 -1
  413. package/lib/plugins/inputValidation.js +0 -95
  414. package/lib/plugins/inputValidation.js.map +0 -1
  415. package/lib/utils/inputValidation.d.ts.map +0 -1
  416. package/lib/utils/inputValidation.js +0 -51
  417. package/lib/utils/inputValidation.js.map +0 -1
@@ -0,0 +1,60 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { checkAction } from '../acl.js';
3
+ import { actions } from '../roles/index.js';
4
+ import { Context } from '../context.js';
5
+ import { getFileAdapter } from '@unchainedshop/core-files';
6
+
7
+ const logger = createLogger('unchained:temp-upload');
8
+
9
+ const methodWrongHandler = (res) => {
10
+ logger.error('Method not supported, return 404');
11
+ res.writeHead(404);
12
+ res.end();
13
+ return;
14
+ };
15
+
16
+ export default async function tempUploadMiddleware(
17
+ req: Request & { query?: any; files: any; unchainedContext: Context },
18
+ res,
19
+ ) {
20
+ try {
21
+ const context = req.unchainedContext;
22
+
23
+ if (req.method !== 'POST') {
24
+ return methodWrongHandler(res);
25
+ }
26
+
27
+ await checkAction(context, (actions as any).uploadTempFile);
28
+
29
+ const [data] = req.files || [];
30
+
31
+ const file = await context.services.files.uploadFileFromStream({
32
+ directoryName: 'temp-uploads',
33
+ rawFile: {
34
+ filename: data.originalname,
35
+ buffer: data.buffer,
36
+ mimetype: data.mimetype,
37
+ },
38
+ meta: { fieldname: data.fieldname, encoding: data.encoding },
39
+ });
40
+
41
+ // Add an expiration date to this file manually!
42
+ const expires = new Date(Date.now() + 24 * 60 * 60 * 1000);
43
+ await context.modules.files.update(file._id, {
44
+ expires, // Default to 1 hour
45
+ });
46
+
47
+ const fileUploadAdapter = getFileAdapter();
48
+ const rawUrl = await fileUploadAdapter.createDownloadURL(file);
49
+ const url = context.modules.files.normalizeUrl(rawUrl, {});
50
+ const body = JSON.stringify({ fileId: file._id, url, expires: expires.toISOString() });
51
+
52
+ res.writeHead(200);
53
+ res.end(body);
54
+ } catch (e) {
55
+ logger.error(e.message);
56
+ res.writeHead(503);
57
+ res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
58
+ return;
59
+ }
60
+ }
@@ -1,17 +1,21 @@
1
1
  import e from 'express';
2
- import { getCurrentContextResolver, LoginFn, LogoutFn } from '../context.js';
3
- import createBulkImportMiddleware from './createBulkImportMiddleware.js';
4
- import createERCMetadataMiddleware from './createERCMetadataMiddleware.js';
5
2
  import session from 'express-session';
3
+ import multer from 'multer';
6
4
  import MongoStore from 'connect-mongo';
7
5
  import { Passport } from 'passport';
8
6
  import { YogaServerInstance } from 'graphql-yoga';
9
7
  import { mongodb } from '@unchainedshop/mongodb';
10
8
  import { UnchainedCore } from '@unchainedshop/core';
11
9
  import { emit } from '@unchainedshop/events';
12
- import { API_EVENTS } from '../events.js';
13
10
  import { User } from '@unchainedshop/core-users';
14
11
 
12
+ import { getCurrentContextResolver, LoginFn, LogoutFn } from '../context.js';
13
+ import createBulkImportMiddleware from './createBulkImportMiddleware.js';
14
+ import createERCMetadataMiddleware from './createERCMetadataMiddleware.js';
15
+ import createTempUploadMiddleware from './createTempUploadMiddleware.js';
16
+ import createMCPMiddleware from './createMCPMiddleware.js';
17
+ import { API_EVENTS } from '../events.js';
18
+
15
19
  const resolveUserRemoteAddress = (req: e.Request) => {
16
20
  const remoteAddress =
17
21
  (req.headers['x-real-ip'] as string) ||
@@ -23,9 +27,14 @@ const resolveUserRemoteAddress = (req: e.Request) => {
23
27
  return { remoteAddress, remotePort };
24
28
  };
25
29
 
30
+ const storage = multer.memoryStorage();
31
+ const upload = multer({ storage: storage });
32
+
26
33
  const {
27
34
  BULK_IMPORT_API_PATH = '/bulk-import',
28
35
  ERC_METADATA_API_PATH = '/erc-metadata',
36
+ TEMP_UPLOAD_API_PATH = '/temp-upload',
37
+ MCP_API_PATH = '/mcp',
29
38
  GRAPHQL_API_PATH = '/graphql',
30
39
  UNCHAINED_COOKIE_NAME = 'unchained_token',
31
40
  UNCHAINED_COOKIE_PATH = '/',
@@ -126,10 +135,16 @@ export const connect = (
126
135
  {
127
136
  graphqlHandler,
128
137
  db,
129
- }: { graphqlHandler: YogaServerInstance<any, any>; db: mongodb.Db; unchainedAPI: UnchainedCore },
138
+ }: {
139
+ graphqlHandler: YogaServerInstance<any, any>;
140
+ db: mongodb.Db;
141
+ unchainedAPI: UnchainedCore;
142
+ },
130
143
  {
131
144
  allowRemoteToLocalhostSecureCookies = false,
132
- }: { allowRemoteToLocalhostSecureCookies?: boolean } = {},
145
+ }: {
146
+ allowRemoteToLocalhostSecureCookies?: boolean;
147
+ } = {},
133
148
  ) => {
134
149
  if (allowRemoteToLocalhostSecureCookies) {
135
150
  // Workaround: Allow to use sandbox with localhost
@@ -137,6 +152,16 @@ export const connect = (
137
152
  expressApp.use((req, res, next) => {
138
153
  req.headers['x-forwarded-proto'] = 'https';
139
154
  res.setHeader('Access-Control-Allow-Private-Network', 'true');
155
+ res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
156
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
157
+ res.setHeader(
158
+ 'Access-Control-Allow-Methods',
159
+ ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'].join(', '),
160
+ );
161
+ res.setHeader(
162
+ 'Access-Control-Allow-Headers',
163
+ req.headers['access-control-request-headers'] || '*',
164
+ );
140
165
  next();
141
166
  });
142
167
  }
@@ -189,4 +214,8 @@ export const connect = (
189
214
  expressApp.use(GRAPHQL_API_PATH, graphqlHandler.handle);
190
215
  expressApp.use(ERC_METADATA_API_PATH, createERCMetadataMiddleware);
191
216
  expressApp.use(BULK_IMPORT_API_PATH, createBulkImportMiddleware);
217
+ expressApp.use(TEMP_UPLOAD_API_PATH, upload.any(), createTempUploadMiddleware);
218
+
219
+ expressApp.use(MCP_API_PATH, e.json({ limit: '10mb' }));
220
+ expressApp.use(MCP_API_PATH, createMCPMiddleware);
192
221
  };
@@ -10,8 +10,11 @@ import { API_EVENTS } from '../events.js';
10
10
  import { User } from '@unchainedshop/core-users';
11
11
  import fastifySession from '@fastify/session';
12
12
  import fastifyCookie from '@fastify/cookie';
13
+ import fastifyMultipart from '@fastify/multipart';
13
14
  import { FastifyBaseLogger, FastifyInstance, FastifyRequest } from 'fastify';
14
15
  import { createLogger } from '@unchainedshop/logger';
16
+ import mcpHandler from './mcpHandler.js';
17
+ import tempUploadHandler from './tempUploadHandler.js';
15
18
 
16
19
  const resolveUserRemoteAddress = (req: FastifyRequest) => {
17
20
  const remoteAddress =
@@ -25,8 +28,10 @@ const resolveUserRemoteAddress = (req: FastifyRequest) => {
25
28
  };
26
29
 
27
30
  const {
31
+ MCP_API_PATH = '/mcp',
28
32
  GRAPHQL_API_PATH = '/graphql',
29
33
  BULK_IMPORT_API_PATH = '/bulk-import',
34
+ TEMP_UPLOAD_API_PATH = '/temp-upload',
30
35
  ERC_METADATA_API_PATH = '/erc-metadata/:productId/:localeOrTokenFilename/:tokenFileName?',
31
36
  UNCHAINED_COOKIE_NAME = 'unchained_token',
32
37
  UNCHAINED_COOKIE_PATH = '/',
@@ -112,7 +117,11 @@ export const connect = (
112
117
  {
113
118
  graphqlHandler,
114
119
  db,
115
- }: { graphqlHandler: YogaServerInstance<any, any>; db: mongodb.Db; unchainedAPI: UnchainedCore },
120
+ }: {
121
+ graphqlHandler: YogaServerInstance<any, any>;
122
+ db: mongodb.Db;
123
+ unchainedAPI: UnchainedCore;
124
+ },
116
125
  {
117
126
  allowRemoteToLocalhostSecureCookies = false,
118
127
  }: { allowRemoteToLocalhostSecureCookies?: boolean } = {},
@@ -123,9 +132,13 @@ export const connect = (
123
132
  fastify.addHook('preHandler', async function (request) {
124
133
  request.headers['x-forwarded-proto'] = 'https';
125
134
  });
126
- fastify.addHook('onSend', async function (_, reply) {
135
+ fastify.addHook('onSend', async function (req, reply) {
127
136
  reply.headers({
128
137
  'Access-Control-Allow-Private-Network': 'true',
138
+ 'Access-Control-Allow-Origin': req.headers.origin || '*',
139
+ 'Access-Control-Allow-Credentials': 'true',
140
+ 'Access-Control-Allow-Methods': ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'].join(', '),
141
+ 'Access-Control-Allow-Headers': req.headers['access-control-request-headers'] || '*',
129
142
  });
130
143
  });
131
144
  }
@@ -190,6 +203,23 @@ export const connect = (
190
203
  handler: ercMetadataHandler,
191
204
  });
192
205
 
206
+ fastify.route({
207
+ url: MCP_API_PATH,
208
+ method: ['GET', 'POST', 'DELETE'],
209
+ handler: mcpHandler,
210
+ });
211
+
212
+ fastify.register((s, opts, registered) => {
213
+ s.register(fastifyMultipart);
214
+ s.route({
215
+ url: TEMP_UPLOAD_API_PATH,
216
+ method: ['POST'],
217
+ bodyLimit: 1024 * 1024 * 35, // 35MB
218
+ handler: tempUploadHandler,
219
+ });
220
+ registered();
221
+ });
222
+
193
223
  fastify.register((s, opts, registered) => {
194
224
  s.removeAllContentTypeParsers();
195
225
  s.addContentTypeParser('*', function (req, payload, done) {
@@ -0,0 +1,97 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { Context } from '../context.js';
3
+ import { FastifyRequest, RouteHandlerMethod } from 'fastify';
4
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
6
+ import createMcpServer from '../mcp/index.js';
7
+
8
+ const logger = createLogger('unchained:mcp-handler');
9
+
10
+ const transports: Record<string, StreamableHTTPServerTransport> = {};
11
+
12
+ const mcpHandler: RouteHandlerMethod = async (
13
+ req: FastifyRequest & { unchainedContext: Context },
14
+ res,
15
+ ) => {
16
+ if (!req.unchainedContext.user) {
17
+ res.status(401);
18
+ res.header(
19
+ 'WWW-Authenticate',
20
+ `Bearer realm="Unchained MCP", error="invalid_token", resource="${process.env.ROOT_URL || 'http://localhost:4010'}",`,
21
+ );
22
+ return res.send(
23
+ JSON.stringify({
24
+ error: 'invalid_token',
25
+ resource_metadata: `${process.env.ROOT_URL || 'http://localhost:4010'}/.well-known/oauth-protected-resource`,
26
+ }),
27
+ );
28
+ }
29
+
30
+ try {
31
+ if (req.method === 'POST') {
32
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
33
+
34
+ let transport: StreamableHTTPServerTransport;
35
+
36
+ if (sessionId && transports[sessionId]) {
37
+ // Reuse existing transport
38
+ transport = transports[sessionId];
39
+ } else if (!sessionId && isInitializeRequest(req.body)) {
40
+ // New initialization request
41
+ transport = new StreamableHTTPServerTransport({
42
+ sessionIdGenerator: () => crypto.randomUUID(),
43
+ onsessioninitialized: (sessionId) => {
44
+ // Store the transport by session ID
45
+ transports[sessionId] = transport;
46
+ },
47
+ });
48
+
49
+ // Clean up transport when closed
50
+ transport.onclose = () => {
51
+ if (transport.sessionId) {
52
+ delete transports[transport.sessionId];
53
+ }
54
+ };
55
+
56
+ const roles = req.unchainedContext.user.roles || [];
57
+ const server = createMcpServer(req.unchainedContext, roles);
58
+ await server.connect(transport);
59
+ } else {
60
+ // Invalid request
61
+ res.status(400);
62
+ return res.send(
63
+ JSON.stringify({
64
+ jsonrpc: '2.0',
65
+ error: {
66
+ code: -32000,
67
+ message: 'Bad Request: No valid session ID provided',
68
+ },
69
+ id: null,
70
+ }),
71
+ );
72
+ }
73
+
74
+ await transport.handleRequest(req.raw, res.raw, req.body);
75
+ return res;
76
+ } else if (req.method === 'GET' || req.method === 'DELETE') {
77
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
78
+ if (!sessionId || !transports[sessionId]) {
79
+ res.status(400).send('Invalid or missing session ID');
80
+ return;
81
+ }
82
+
83
+ const transport = transports[sessionId];
84
+ await transport.handleRequest(req.raw, res.raw);
85
+ return res;
86
+ }
87
+
88
+ res.status(405);
89
+ return res.send('Method Not Allowed');
90
+ } catch (e) {
91
+ logger.error(e.message);
92
+ res.status(503);
93
+ return res.send(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
94
+ }
95
+ };
96
+
97
+ export default mcpHandler;
@@ -0,0 +1,52 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { getFileAdapter } from '@unchainedshop/core-files';
3
+ import { checkAction } from '../acl.js';
4
+ import { actions } from '../roles/index.js';
5
+ import { Context } from '../context.js';
6
+ import { FastifyRequest, RouteHandlerMethod } from 'fastify';
7
+
8
+ const logger = createLogger('unchained:temp-upload');
9
+
10
+ const tempUploadHandler: RouteHandlerMethod = async (
11
+ req: FastifyRequest & { file: any; unchainedContext: Context },
12
+ res,
13
+ ) => {
14
+ try {
15
+ const context = req.unchainedContext;
16
+
17
+ await checkAction(context, (actions as any).uploadTempFile);
18
+
19
+ const data = await req.file();
20
+
21
+ const file = await context.services.files.uploadFileFromStream({
22
+ directoryName: 'temp-uploads',
23
+ rawFile: Promise.resolve({
24
+ filename: data.filename,
25
+ createReadStream: () => data.file,
26
+ mimetype: data.mimetype,
27
+ }),
28
+ meta: { fieldname: data.fieldname, encoding: data.encoding },
29
+ });
30
+
31
+ // Add an expiration date to this file manually!
32
+ const expires = new Date(Date.now() + 24 * 60 * 60 * 1000);
33
+ await context.modules.files.update(file._id, {
34
+ expires, // Default to 1 hour
35
+ });
36
+
37
+ const fileUploadAdapter = getFileAdapter();
38
+ const rawUrl = await fileUploadAdapter.createDownloadURL(file);
39
+ const url = context.modules.files.normalizeUrl(rawUrl, {});
40
+ const body = JSON.stringify({ fileId: file._id, url, expires: expires.toISOString() });
41
+ res.status(200);
42
+ res.header('Content-Length', Buffer.byteLength(body));
43
+ res.header('Content-Type', 'application/json');
44
+ return res.send(body);
45
+ } catch (e) {
46
+ logger.error(e.message);
47
+ res.status(503);
48
+ return res.send(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
49
+ }
50
+ };
51
+
52
+ export default tempUploadHandler;
@@ -1,8 +1,8 @@
1
1
  import { UnchainedCore } from '@unchainedshop/core';
2
2
  import { AssortmentMediaText } from '@unchainedshop/core-assortments';
3
3
  import DataLoader from 'dataloader';
4
- import { buildLocaleMap } from './utils.js';
5
4
  import buildTextMap from './buildTextMap.js';
5
+ import buildLocaleMap from './buildLocaleMap.js';
6
6
 
7
7
  export default (unchainedAPI: UnchainedCore) =>
8
8
  new DataLoader<{ assortmentMediaId: string; locale: Intl.Locale }, AssortmentMediaText>(
@@ -1,8 +1,8 @@
1
1
  import { UnchainedCore } from '@unchainedshop/core';
2
2
  import { AssortmentText } from '@unchainedshop/core-assortments';
3
3
  import DataLoader from 'dataloader';
4
- import { buildLocaleMap } from './utils.js';
5
4
  import buildTextMap from './buildTextMap.js';
5
+ import buildLocaleMap from './buildLocaleMap.js';
6
6
 
7
7
  export default (unchainedAPI: UnchainedCore) =>
8
8
  new DataLoader<{ assortmentId: string; locale: Intl.Locale }, AssortmentText>(async (queries) => {
@@ -0,0 +1,65 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import buildLocaleMap from './buildLocaleMap.js';
4
+
5
+ const testTexts = [
6
+ // 1 has translations in French and German
7
+ { locale: 'fr', _id: '1', entityId: '1' },
8
+ { locale: 'de', _id: '2', entityId: '1' },
9
+
10
+ // 2 only has Ialien translations
11
+ { locale: 'it', _id: '3', entityId: '2' },
12
+
13
+ // 3 only has English translations
14
+ { locale: 'en', _id: '4', entityId: '3' },
15
+
16
+ // 4 only has German translations
17
+ { locale: 'de', _id: '5', entityId: '4' },
18
+ ];
19
+
20
+ describe('buildLocaleMap', () => {
21
+ it('Mixed usage of default locale and forced languages', () => {
22
+ const queries = [
23
+ { locale: new Intl.Locale('de-CH') },
24
+ { locale: new Intl.Locale('fr') },
25
+ { locale: new Intl.Locale('it') },
26
+ ];
27
+ const expected = {
28
+ de: ['de-CH', 'fr', 'it'],
29
+ fr: ['fr'],
30
+ it: ['it'],
31
+ };
32
+ const result = buildLocaleMap(queries, testTexts);
33
+ assert.deepStrictEqual(result, expected);
34
+ });
35
+
36
+ it('Mixed usage of forced languages', () => {
37
+ const queries = [{ locale: new Intl.Locale('fr') }, { locale: new Intl.Locale('it') }];
38
+ const expected = {
39
+ de: ['fr', 'it'],
40
+ fr: ['fr'],
41
+ it: ['it'],
42
+ };
43
+ const result = buildLocaleMap(queries, testTexts);
44
+ assert.deepStrictEqual(result, expected);
45
+ });
46
+
47
+ it('Only default locale', () => {
48
+ const queries = [{ locale: new Intl.Locale('de-CH') }];
49
+ const expected = {
50
+ de: ['de-CH'],
51
+ };
52
+ const result = buildLocaleMap(queries, testTexts);
53
+ assert.deepStrictEqual(result, expected);
54
+ });
55
+
56
+ it('Only one forced language locale', () => {
57
+ const queries = [{ locale: new Intl.Locale('fr') }];
58
+ const expected = {
59
+ fr: ['fr'],
60
+ de: ['fr'],
61
+ };
62
+ const result = buildLocaleMap(queries, testTexts);
63
+ assert.deepStrictEqual(result, expected);
64
+ });
65
+ });
@@ -0,0 +1,73 @@
1
+ import { systemLocale } from '@unchainedshop/utils';
2
+
3
+ function getLocaleStrings(locale: Intl.Locale): string[] {
4
+ try {
5
+ const locales = new Set<string>();
6
+ locales.add(locale.baseName);
7
+ locales.add(locale.language);
8
+ locales.add(systemLocale.baseName);
9
+ locales.add(systemLocale.language);
10
+ return Array.from(locales);
11
+ } catch {
12
+ // Optimized Set creation and spread
13
+ const locales = new Set<string>();
14
+ locales.add(systemLocale.baseName);
15
+ locales.add(systemLocale.language);
16
+ return Array.from(locales);
17
+ }
18
+ }
19
+ export default function buildLocaleMap(
20
+ queries: readonly { locale: Intl.Locale }[],
21
+ texts: readonly { locale?: string }[],
22
+ ): Record<string, string[]> {
23
+ // key = texts.locale
24
+ // value = input query locale
25
+ const queryLocales = new Set(queries.map((q) => q.locale));
26
+ const textLocales = new Set(texts.map((t) => t.locale));
27
+ const localeMap: Record<string, string[]> = {};
28
+ for (const queryLocale of queryLocales) {
29
+ const potentialMatches = getLocaleStrings(queryLocale);
30
+ const matches = potentialMatches.filter((l) => textLocales.has(l));
31
+ for (const match of matches) {
32
+ if (!localeMap[match]) localeMap[match] = [];
33
+ localeMap[match].push(queryLocale.toString());
34
+ }
35
+ }
36
+ return localeMap;
37
+ }
38
+
39
+ // import { systemLocale } from '@unchainedshop/utils';
40
+
41
+ // export function getLocaleStrings(locale: Intl.Locale) {
42
+ // try {
43
+ // return [
44
+ // ...new Set([locale.baseName, locale.language, systemLocale.baseName, systemLocale.language]),
45
+ // ];
46
+ // } catch {
47
+ // return [...new Set([systemLocale.baseName, systemLocale.language])];
48
+ // }
49
+ // }
50
+
51
+ // export function buildLocaleMap(
52
+ // queries: readonly { locale: Intl.Locale }[],
53
+ // texts: readonly { locale?: string }[],
54
+ // ): Record<string, string[]> {
55
+ // // key = texts.locale
56
+ // // value = input query locale
57
+
58
+ // const queryLocales = Object.values(
59
+ // Object.fromEntries(queries.map((q) => [q.locale.baseName, q.locale])),
60
+ // );
61
+
62
+ // const textLocales: string[] = [...new Set(texts.map((t) => t.locale))];
63
+ // const localeMap = {};
64
+ // for (const queryLocale of queryLocales) {
65
+ // const potentialMatches = getLocaleStrings(queryLocale);
66
+ // const matches = potentialMatches.filter((l) => textLocales.includes(l));
67
+ // for (const match of matches) {
68
+ // if (!localeMap[match]) localeMap[match] = [];
69
+ // localeMap[match].push(queryLocale);
70
+ // }
71
+ // }
72
+ // return localeMap;
73
+ // }
@@ -0,0 +1,54 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import buildTextMap from './buildTextMap.js';
4
+
5
+ const testTexts = [
6
+ // 1 has translations in French and German
7
+ { locale: 'fr', _id: 'french-1', entityId: '1' },
8
+ { locale: 'de', _id: 'german-1', entityId: '1' },
9
+
10
+ // 2 only has Ialien translations
11
+ { locale: 'it', _id: 'italian-2', entityId: '2' },
12
+
13
+ // 3 only has English translations
14
+ { locale: 'en', _id: 'english-3', entityId: '3' },
15
+
16
+ // 4 only has German translations
17
+ { locale: 'de', _id: 'german-4', entityId: '4' },
18
+ ];
19
+
20
+ describe('buildTextMap', () => {
21
+ it('Generate a correct text map for all fallbacks', () => {
22
+ const localeMap = {
23
+ de: ['de-CH', 'fr', 'it'],
24
+ fr: ['fr'],
25
+ it: ['it'],
26
+ };
27
+ const expected = {
28
+ 'de-CH1': {
29
+ _id: 'german-1',
30
+ },
31
+ fr1: {
32
+ _id: 'french-1',
33
+ },
34
+ it1: {
35
+ _id: 'german-1',
36
+ },
37
+ 'de-CH4': {
38
+ _id: 'german-4',
39
+ },
40
+ fr4: {
41
+ _id: 'german-4',
42
+ },
43
+ it4: {
44
+ _id: 'german-4',
45
+ },
46
+ it2: {
47
+ _id: 'italian-2',
48
+ },
49
+ };
50
+ const result = buildTextMap(localeMap, testTexts, (text) => text.entityId);
51
+
52
+ assert.partialDeepStrictEqual(result, expected);
53
+ });
54
+ });
@@ -1,17 +1,36 @@
1
1
  type ArrayElement<T> = T extends (infer U)[] ? U : never;
2
2
 
3
+ /* This file has been optimized for performance to the last drop. Don't refactor! */
4
+
3
5
  export default function buildTextMap<T extends { locale?: string }[]>(
4
6
  localeMap: Record<string, string[]>,
5
7
  texts: Readonly<T>,
6
8
  buildId: (item: ArrayElement<T>) => string,
7
9
  ) {
8
- const textsMap = {};
9
- for (const [originLocale, localesForText] of Object.entries(localeMap)) {
10
- for (const text of texts) {
10
+ const textsMap: Record<string, ArrayElement<T>> = {}; // Added type for textsMap
11
+ const localeMapKeys = Object.keys(localeMap);
12
+
13
+ // eslint-disable-next-line
14
+ for (let i = 0; i < localeMapKeys.length; i++) {
15
+ const originLocale = localeMapKeys[i];
16
+ const localesForText = localeMap[originLocale];
17
+
18
+ // eslint-disable-next-line
19
+ for (let j = 0; j < texts.length; j++) {
20
+ const text = texts[j];
11
21
  if (originLocale !== text.locale) continue;
12
- for (const locale of localesForText) {
13
- if (textsMap[locale + buildId(text as any)]) continue;
14
- textsMap[locale + buildId(text as any)] = text;
22
+
23
+ const idPart = buildId(text as ArrayElement<T>); // Ensured correct type for buildId argument
24
+
25
+ // eslint-disable-next-line
26
+ for (let k = 0; k < localesForText.length; k++) {
27
+ const locale = localesForText[k];
28
+ const key = locale + idPart;
29
+ if (textsMap[key] && locale !== text.locale) {
30
+ // If the key already exists and the locale is a fallback, skip this text
31
+ continue;
32
+ }
33
+ textsMap[key] = text as ArrayElement<T>; // Ensured correct type for assignment
15
34
  }
16
35
  }
17
36
  }
@@ -1,6 +1,6 @@
1
1
  import { UnchainedCore } from '@unchainedshop/core';
2
2
  import DataLoader from 'dataloader';
3
- import { buildLocaleMap } from './utils.js';
3
+ import buildLocaleMap from './buildLocaleMap.js';
4
4
  import { FilterText } from '@unchainedshop/core-filters';
5
5
  import buildTextMap from './buildTextMap.js';
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { UnchainedCore } from '@unchainedshop/core';
2
2
  import DataLoader from 'dataloader';
3
- import { buildLocaleMap } from './utils.js';
4
3
  import { ProductMediaText } from '@unchainedshop/core-products';
4
+ import buildLocaleMap from './buildLocaleMap.js';
5
5
  import buildTextMap from './buildTextMap.js';
6
6
 
7
7
  export default (unchainedAPI: UnchainedCore) =>
@@ -1,8 +1,8 @@
1
1
  import { UnchainedCore } from '@unchainedshop/core';
2
2
  import DataLoader from 'dataloader';
3
- import { buildLocaleMap } from './utils.js';
4
3
  import { ProductText } from '@unchainedshop/core-products';
5
4
  import buildTextMap from './buildTextMap.js';
5
+ import buildLocaleMap from './buildLocaleMap.js';
6
6
 
7
7
  export default (unchainedAPI: UnchainedCore) =>
8
8
  new DataLoader<{ productId: string; locale: Intl.Locale }, ProductText>(async (queries) => {