@unchainedshop/api 3.0.0-rc1 → 3.0.0-rc10

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 (233) hide show
  1. package/lib/api-index.d.ts +1 -1
  2. package/lib/api-index.d.ts.map +1 -1
  3. package/lib/api-index.js +1 -1
  4. package/lib/api-index.js.map +1 -1
  5. package/lib/context.d.ts +0 -1
  6. package/lib/context.d.ts.map +1 -1
  7. package/lib/context.js +4 -19
  8. package/lib/context.js.map +1 -1
  9. package/lib/errors.d.ts +1 -0
  10. package/lib/errors.d.ts.map +1 -1
  11. package/lib/errors.js +1 -0
  12. package/lib/errors.js.map +1 -1
  13. package/lib/express/createBulkImportMiddleware.d.ts +1 -2
  14. package/lib/express/createBulkImportMiddleware.d.ts.map +1 -1
  15. package/lib/express/createBulkImportMiddleware.js.map +1 -1
  16. package/lib/express/createERCMetadataMiddleware.js +1 -1
  17. package/lib/express/createERCMetadataMiddleware.js.map +1 -1
  18. package/lib/express/index.d.ts.map +1 -1
  19. package/lib/express/index.js.map +1 -1
  20. package/lib/fastify/index.d.ts.map +1 -1
  21. package/lib/fastify/index.js.map +1 -1
  22. package/lib/loaders/index.d.ts.map +1 -1
  23. package/lib/loaders/index.js +115 -87
  24. package/lib/loaders/index.js.map +1 -1
  25. package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.d.ts.map +1 -1
  26. package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.js +3 -0
  27. package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.js.map +1 -1
  28. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.d.ts +4 -1
  29. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.d.ts.map +1 -1
  30. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.d.ts +4 -1
  31. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.d.ts.map +1 -1
  32. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.js +2 -2
  33. package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.js.map +1 -1
  34. package/lib/resolvers/mutations/accounts/loginWithWebAuthn.d.ts.map +1 -1
  35. package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js +4 -1
  36. package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js.map +1 -1
  37. package/lib/resolvers/mutations/accounts/resetPassword.d.ts.map +1 -1
  38. package/lib/resolvers/mutations/accounts/resetPassword.js +12 -43
  39. package/lib/resolvers/mutations/accounts/resetPassword.js.map +1 -1
  40. package/lib/resolvers/mutations/accounts/verifyWeb3Address.d.ts.map +1 -1
  41. package/lib/resolvers/mutations/accounts/verifyWeb3Address.js +3 -1
  42. package/lib/resolvers/mutations/accounts/verifyWeb3Address.js.map +1 -1
  43. package/lib/resolvers/mutations/countries/updateCountry.d.ts +1 -3
  44. package/lib/resolvers/mutations/countries/updateCountry.d.ts.map +1 -1
  45. package/lib/resolvers/mutations/countries/updateCountry.js +1 -5
  46. package/lib/resolvers/mutations/countries/updateCountry.js.map +1 -1
  47. package/lib/resolvers/mutations/orders/addCartDiscount.d.ts.map +1 -1
  48. package/lib/resolvers/mutations/orders/addCartDiscount.js +8 -3
  49. package/lib/resolvers/mutations/orders/addCartDiscount.js.map +1 -1
  50. package/lib/resolvers/mutations/orders/addCartProduct.d.ts.map +1 -1
  51. package/lib/resolvers/mutations/orders/addCartProduct.js +8 -3
  52. package/lib/resolvers/mutations/orders/addCartProduct.js.map +1 -1
  53. package/lib/resolvers/mutations/orders/addCartQuotation.d.ts.map +1 -1
  54. package/lib/resolvers/mutations/orders/addCartQuotation.js +8 -3
  55. package/lib/resolvers/mutations/orders/addCartQuotation.js.map +1 -1
  56. package/lib/resolvers/mutations/orders/addMultipleCartProducts.d.ts.map +1 -1
  57. package/lib/resolvers/mutations/orders/addMultipleCartProducts.js +8 -3
  58. package/lib/resolvers/mutations/orders/addMultipleCartProducts.js.map +1 -1
  59. package/lib/resolvers/mutations/orders/checkoutCart.d.ts.map +1 -1
  60. package/lib/resolvers/mutations/orders/checkoutCart.js +10 -5
  61. package/lib/resolvers/mutations/orders/checkoutCart.js.map +1 -1
  62. package/lib/resolvers/mutations/orders/emptyCart.d.ts.map +1 -1
  63. package/lib/resolvers/mutations/orders/emptyCart.js +8 -3
  64. package/lib/resolvers/mutations/orders/emptyCart.js.map +1 -1
  65. package/lib/resolvers/mutations/orders/signPaymentProviderForCheckout.js +1 -1
  66. package/lib/resolvers/mutations/orders/signPaymentProviderForCheckout.js.map +1 -1
  67. package/lib/resolvers/mutations/orders/updateCart.d.ts.map +1 -1
  68. package/lib/resolvers/mutations/orders/updateCart.js +8 -3
  69. package/lib/resolvers/mutations/orders/updateCart.js.map +1 -1
  70. package/lib/resolvers/queries/users/validateResetPasswordToken.js +2 -2
  71. package/lib/resolvers/queries/users/validateResetPasswordToken.js.map +1 -1
  72. package/lib/resolvers/type/delivery-provider-types.d.ts +0 -1
  73. package/lib/resolvers/type/delivery-provider-types.d.ts.map +1 -1
  74. package/lib/resolvers/type/delivery-provider-types.js +0 -2
  75. package/lib/resolvers/type/delivery-provider-types.js.map +1 -1
  76. package/lib/resolvers/type/filter/loaded-filter-types.d.ts.map +1 -1
  77. package/lib/resolvers/type/filter/loaded-filter-types.js +1 -2
  78. package/lib/resolvers/type/filter/loaded-filter-types.js.map +1 -1
  79. package/lib/resolvers/type/index.d.ts +37 -46
  80. package/lib/resolvers/type/index.d.ts.map +1 -1
  81. package/lib/resolvers/type/index.js +0 -4
  82. package/lib/resolvers/type/index.js.map +1 -1
  83. package/lib/resolvers/type/order/order-delivery-discount-types.d.ts +2 -3
  84. package/lib/resolvers/type/order/order-delivery-discount-types.d.ts.map +1 -1
  85. package/lib/resolvers/type/order/order-delivery-discount-types.js +1 -3
  86. package/lib/resolvers/type/order/order-delivery-discount-types.js.map +1 -1
  87. package/lib/resolvers/type/order/order-global-discount-types.d.ts +2 -3
  88. package/lib/resolvers/type/order/order-global-discount-types.d.ts.map +1 -1
  89. package/lib/resolvers/type/order/order-global-discount-types.js +1 -3
  90. package/lib/resolvers/type/order/order-global-discount-types.js.map +1 -1
  91. package/lib/resolvers/type/order/order-item-discount-types.d.ts +2 -3
  92. package/lib/resolvers/type/order/order-item-discount-types.d.ts.map +1 -1
  93. package/lib/resolvers/type/order/order-item-discount-types.js +1 -3
  94. package/lib/resolvers/type/order/order-item-discount-types.js.map +1 -1
  95. package/lib/resolvers/type/order/order-item-types.d.ts.map +1 -1
  96. package/lib/resolvers/type/order/order-item-types.js +2 -11
  97. package/lib/resolvers/type/order/order-item-types.js.map +1 -1
  98. package/lib/resolvers/type/order/order-payment-discount-types.d.ts +2 -3
  99. package/lib/resolvers/type/order/order-payment-discount-types.d.ts.map +1 -1
  100. package/lib/resolvers/type/order/order-payment-discount-types.js +1 -7
  101. package/lib/resolvers/type/order/order-payment-discount-types.js.map +1 -1
  102. package/lib/resolvers/type/order/order-types.d.ts +1 -1
  103. package/lib/resolvers/type/order/order-types.d.ts.map +1 -1
  104. package/lib/resolvers/type/order/order-types.js +2 -7
  105. package/lib/resolvers/type/order/order-types.js.map +1 -1
  106. package/lib/resolvers/type/payment/payment-provider-types.d.ts +0 -1
  107. package/lib/resolvers/type/payment/payment-provider-types.d.ts.map +1 -1
  108. package/lib/resolvers/type/payment/payment-provider-types.js +0 -2
  109. package/lib/resolvers/type/payment/payment-provider-types.js.map +1 -1
  110. package/lib/resolvers/type/price-types.d.ts +0 -1
  111. package/lib/resolvers/type/price-types.d.ts.map +1 -1
  112. package/lib/resolvers/type/price-types.js.map +1 -1
  113. package/lib/resolvers/type/product/product-configurable-types.d.ts.map +1 -1
  114. package/lib/resolvers/type/product/product-configurable-types.js +5 -36
  115. package/lib/resolvers/type/product/product-configurable-types.js.map +1 -1
  116. package/lib/resolvers/type/product/product-discount.d.ts +2 -3
  117. package/lib/resolvers/type/product/product-discount.d.ts.map +1 -1
  118. package/lib/resolvers/type/product/product-discount.js +2 -4
  119. package/lib/resolvers/type/product/product-discount.js.map +1 -1
  120. package/lib/resolvers/type/product/product-plan-types.d.ts.map +1 -1
  121. package/lib/resolvers/type/product/product-plan-types.js +3 -7
  122. package/lib/resolvers/type/product/product-plan-types.js.map +1 -1
  123. package/lib/resolvers/type/product/product-simple-types.d.ts +0 -2
  124. package/lib/resolvers/type/product/product-simple-types.d.ts.map +1 -1
  125. package/lib/resolvers/type/product/product-simple-types.js +13 -50
  126. package/lib/resolvers/type/product/product-simple-types.js.map +1 -1
  127. package/lib/resolvers/type/product/product-tokenized-types.d.ts +0 -1
  128. package/lib/resolvers/type/product/product-tokenized-types.d.ts.map +1 -1
  129. package/lib/resolvers/type/product/product-tokenized-types.js +5 -23
  130. package/lib/resolvers/type/product/product-tokenized-types.js.map +1 -1
  131. package/lib/resolvers/type/user-types.d.ts +21 -2
  132. package/lib/resolvers/type/user-types.d.ts.map +1 -1
  133. package/lib/resolvers/type/user-types.js +2 -2
  134. package/lib/resolvers/type/user-types.js.map +1 -1
  135. package/lib/resolvers/type/webauthn-credentials-types.d.ts +26 -9
  136. package/lib/resolvers/type/webauthn-credentials-types.d.ts.map +1 -1
  137. package/lib/resolvers/type/webauthn-credentials-types.js.map +1 -1
  138. package/lib/schema/inputTypes.d.ts.map +1 -1
  139. package/lib/schema/inputTypes.js +0 -1
  140. package/lib/schema/inputTypes.js.map +1 -1
  141. package/lib/schema/mutation.js +2 -2
  142. package/lib/schema/types/dispatch.d.ts.map +1 -1
  143. package/lib/schema/types/dispatch.js +0 -1
  144. package/lib/schema/types/dispatch.js.map +1 -1
  145. package/lib/schema/types/price.d.ts.map +1 -1
  146. package/lib/schema/types/price.js +0 -2
  147. package/lib/schema/types/price.js.map +1 -1
  148. package/lib/schema/types/stock.d.ts.map +1 -1
  149. package/lib/schema/types/stock.js +0 -1
  150. package/lib/schema/types/stock.js.map +1 -1
  151. package/package.json +54 -17
  152. package/src/api-index.ts +1 -1
  153. package/src/context.ts +4 -20
  154. package/src/errors.ts +2 -0
  155. package/src/express/createBulkImportMiddleware.ts +1 -2
  156. package/src/express/createERCMetadataMiddleware.ts +1 -1
  157. package/src/express/index.ts +1 -2
  158. package/src/fastify/index.ts +2 -3
  159. package/src/loaders/index.ts +132 -105
  160. package/src/resolvers/mutations/accounts/addWebAuthnCredentials.ts +3 -0
  161. package/src/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.ts +2 -2
  162. package/src/resolvers/mutations/accounts/loginWithWebAuthn.ts +4 -1
  163. package/src/resolvers/mutations/accounts/resetPassword.ts +13 -46
  164. package/src/resolvers/mutations/accounts/verifyWeb3Address.ts +4 -1
  165. package/src/resolvers/mutations/countries/updateCountry.ts +2 -7
  166. package/src/resolvers/mutations/orders/addCartDiscount.ts +7 -2
  167. package/src/resolvers/mutations/orders/addCartProduct.ts +8 -2
  168. package/src/resolvers/mutations/orders/addCartQuotation.ts +7 -2
  169. package/src/resolvers/mutations/orders/addMultipleCartProducts.ts +7 -2
  170. package/src/resolvers/mutations/orders/checkoutCart.ts +9 -5
  171. package/src/resolvers/mutations/orders/emptyCart.ts +7 -3
  172. package/src/resolvers/mutations/orders/signPaymentProviderForCheckout.ts +1 -1
  173. package/src/resolvers/mutations/orders/updateCart.ts +7 -3
  174. package/src/resolvers/queries/users/validateResetPasswordToken.ts +2 -2
  175. package/src/resolvers/type/delivery-provider-types.ts +0 -3
  176. package/src/resolvers/type/filter/loaded-filter-types.ts +1 -2
  177. package/src/resolvers/type/index.ts +0 -4
  178. package/src/resolvers/type/order/order-delivery-discount-types.ts +1 -3
  179. package/src/resolvers/type/order/order-global-discount-types.ts +2 -3
  180. package/src/resolvers/type/order/order-item-discount-types.ts +1 -3
  181. package/src/resolvers/type/order/order-item-types.ts +3 -11
  182. package/src/resolvers/type/order/order-payment-discount-types.ts +2 -9
  183. package/src/resolvers/type/order/order-types.ts +3 -7
  184. package/src/resolvers/type/payment/payment-provider-types.ts +0 -2
  185. package/src/resolvers/type/price-types.ts +0 -1
  186. package/src/resolvers/type/product/product-configurable-types.ts +5 -49
  187. package/src/resolvers/type/product/product-discount.ts +2 -4
  188. package/src/resolvers/type/product/product-plan-types.ts +3 -11
  189. package/src/resolvers/type/product/product-simple-types.ts +14 -75
  190. package/src/resolvers/type/product/product-tokenized-types.ts +5 -35
  191. package/src/resolvers/type/user-types.ts +28 -12
  192. package/src/resolvers/type/webauthn-credentials-types.ts +29 -17
  193. package/src/schema/inputTypes.ts +0 -1
  194. package/src/schema/mutation.ts +2 -2
  195. package/src/schema/types/dispatch.ts +0 -1
  196. package/src/schema/types/price.ts +0 -2
  197. package/src/schema/types/stock.ts +0 -1
  198. package/tests/api-index.test.ts +4 -4
  199. package/lib/express/passport/access-token-strategy.d.ts +0 -10
  200. package/lib/express/passport/access-token-strategy.d.ts.map +0 -1
  201. package/lib/express/passport/access-token-strategy.js +0 -33
  202. package/lib/express/passport/access-token-strategy.js.map +0 -1
  203. package/lib/express/passport/setup.d.ts +0 -4
  204. package/lib/express/passport/setup.d.ts.map +0 -1
  205. package/lib/express/passport/setup.js +0 -30
  206. package/lib/express/passport/setup.js.map +0 -1
  207. package/lib/resolvers/mutations/products/deleteUserProductReviews.d.ts +0 -5
  208. package/lib/resolvers/mutations/products/deleteUserProductReviews.d.ts.map +0 -1
  209. package/lib/resolvers/mutations/products/deleteUserProductReviews.js +0 -15
  210. package/lib/resolvers/mutations/products/deleteUserProductReviews.js.map +0 -1
  211. package/lib/resolvers/mutations/users/deleteUser.d.ts +0 -6
  212. package/lib/resolvers/mutations/users/deleteUser.d.ts.map +0 -1
  213. package/lib/resolvers/mutations/users/deleteUser.js +0 -15
  214. package/lib/resolvers/mutations/users/deleteUser.js.map +0 -1
  215. package/lib/resolvers/mutations/users/deleteUserProductReviews.d.ts +0 -5
  216. package/lib/resolvers/mutations/users/deleteUserProductReviews.d.ts.map +0 -1
  217. package/lib/resolvers/mutations/users/deleteUserProductReviews.js +0 -15
  218. package/lib/resolvers/mutations/users/deleteUserProductReviews.js.map +0 -1
  219. package/lib/resolvers/mutations/utils/getOrderCart.d.ts +0 -7
  220. package/lib/resolvers/mutations/utils/getOrderCart.d.ts.map +0 -1
  221. package/lib/resolvers/mutations/utils/getOrderCart.js +0 -17
  222. package/lib/resolvers/mutations/utils/getOrderCart.js.map +0 -1
  223. package/lib/resolvers/type/dispatch-types.d.ts +0 -15
  224. package/lib/resolvers/type/dispatch-types.d.ts.map +0 -1
  225. package/lib/resolvers/type/dispatch-types.js +0 -13
  226. package/lib/resolvers/type/dispatch-types.js.map +0 -1
  227. package/lib/resolvers/type/stock-types.d.ts +0 -14
  228. package/lib/resolvers/type/stock-types.d.ts.map +0 -1
  229. package/lib/resolvers/type/stock-types.js +0 -12
  230. package/lib/resolvers/type/stock-types.js.map +0 -1
  231. package/src/resolvers/mutations/utils/getOrderCart.ts +0 -20
  232. package/src/resolvers/type/dispatch-types.ts +0 -27
  233. package/src/resolvers/type/stock-types.ts +0 -25
@@ -12,6 +12,7 @@ import {
12
12
  AssortmentMediaText,
13
13
  } from '@unchainedshop/core-assortments';
14
14
  import { File } from '@unchainedshop/core-files';
15
+
15
16
  export interface UnchainedLoaders {
16
17
  loaders: {
17
18
  productLoader: InstanceType<typeof DataLoader<{ productId: string }, Product>>;
@@ -54,28 +55,16 @@ export interface UnchainedLoaders {
54
55
  };
55
56
  }
56
57
 
57
- function getLocaleStrings(localeObj: Intl.Locale) {
58
- return [localeObj.baseName, localeObj.language, systemLocale.baseName, systemLocale.language];
59
- }
60
-
61
- function findMatchingText(texts, localeStrings) {
62
- return localeStrings.reduce((acc, localeString) => {
63
- if (acc) return acc;
64
- return texts.find((p) => p.locale.toLowerCase() === localeString.toLowerCase());
65
- }, null);
66
- }
67
-
68
- function getFilteredQueries({ queries, texts, filterFn }) {
69
- return queries.map(({ locale, ...queryParams }) => {
70
- const localeObj = new Intl.Locale(locale);
71
-
72
- const filteredTexts = texts.filter(filterFn(queryParams));
73
- if (!filteredTexts.length) return null;
74
-
75
- const localeStrings = getLocaleStrings(localeObj);
76
- const filterText = findMatchingText(filteredTexts, localeStrings);
77
- return filterText || filteredTexts[0];
78
- });
58
+ function getLocaleStrings(locale: string) {
59
+ const localeObj = new Intl.Locale(locale);
60
+ return [
61
+ ...new Set([
62
+ localeObj.baseName.toLowerCase(),
63
+ localeObj.language.toLowerCase(),
64
+ systemLocale.baseName.toLowerCase(),
65
+ systemLocale.language.toLowerCase(),
66
+ ]),
67
+ ];
79
68
  }
80
69
 
81
70
  const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['loaders']> => {
@@ -89,12 +78,11 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
89
78
  includeLeaves: true,
90
79
  });
91
80
 
92
- return queries.map(({ assortmentId }) => {
93
- return assortments.find((assortment) => {
94
- if (assortment._id !== assortmentId) return false;
95
- return true;
96
- });
97
- });
81
+ const assortmentMap = {};
82
+ for (const assortment of assortments) {
83
+ assortmentMap[assortment._id] = assortment;
84
+ }
85
+ return queries.map((q) => assortmentMap[q.assortmentId]);
98
86
  }),
99
87
 
100
88
  assortmentTextLoader: new DataLoader(async (queries) => {
@@ -109,12 +97,18 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
109
97
  },
110
98
  );
111
99
 
112
- const filterFn =
113
- ({ assortmentId }) =>
114
- (text) =>
115
- text.assortmentId === assortmentId;
116
-
117
- return getFilteredQueries({ queries, texts, filterFn });
100
+ const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
101
+ const textsMap = {};
102
+ const localeMap = Object.fromEntries(
103
+ queryLocales.flatMap((queryLocale) => {
104
+ return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
105
+ }),
106
+ );
107
+ for (const text of texts) {
108
+ const locale = localeMap[text.locale.toLowerCase()];
109
+ textsMap[`${locale}:${text.assortmentId}`] = text;
110
+ }
111
+ return queries.map((q) => textsMap[`${q.locale.toLowerCase()}:${q.assortmentId}`]);
118
112
  }),
119
113
 
120
114
  assortmentMediaTextLoader: new DataLoader(async (queries) => {
@@ -129,12 +123,18 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
129
123
  },
130
124
  );
131
125
 
132
- const filterFn =
133
- ({ assortmentMediaId }) =>
134
- (text) =>
135
- text.assortmentMediaId === assortmentMediaId;
136
-
137
- return getFilteredQueries({ queries, texts, filterFn });
126
+ const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
127
+ const textsMap = {};
128
+ const localeMap = Object.fromEntries(
129
+ queryLocales.flatMap((queryLocale) => {
130
+ return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
131
+ }),
132
+ );
133
+ for (const text of texts) {
134
+ const locale = localeMap[text.locale.toLowerCase()];
135
+ textsMap[`${locale}:${text.assortmentMediaId}`] = text;
136
+ }
137
+ return queries.map((q) => textsMap[`${q.locale.toLowerCase()}:${q.assortmentMediaId}`]);
138
138
  }),
139
139
 
140
140
  assortmentMediasLoader: new DataLoader(async (queries) => {
@@ -143,11 +143,11 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
143
143
  assortmentId: { $in: assortmentIds },
144
144
  });
145
145
 
146
- return queries.map((q) => {
147
- return assortmentMediaItems.filter((i) => {
148
- return i.assortmentId === q.assortmentId;
149
- });
150
- });
146
+ const assortmentMediaMap = {};
147
+ for (const assortmentMedia of assortmentMediaItems) {
148
+ assortmentMediaMap[assortmentMedia._id] = assortmentMedia;
149
+ }
150
+ return queries.map((q) => assortmentMediaMap[q.assortmentId]);
151
151
  }),
152
152
 
153
153
  assortmentLinkLoader: new DataLoader(async (queries) => {
@@ -157,10 +157,11 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
157
157
  parentAssortmentIds,
158
158
  });
159
159
 
160
- return queries.map(({ parentAssortmentId, childAssortmentId }) => {
160
+ // TODO: Optimize
161
+ return queries.map((q) => {
161
162
  return links.find((link) => {
162
- if (link.parentAssortmentId !== parentAssortmentId) return false;
163
- if (childAssortmentId && link.childAssortmentId !== childAssortmentId) return false;
163
+ if (link.parentAssortmentId !== q.parentAssortmentId) return false;
164
+ if (q.childAssortmentId && link.childAssortmentId !== q.childAssortmentId) return false;
164
165
  return true;
165
166
  });
166
167
  });
@@ -183,16 +184,17 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
183
184
  assortmentIds,
184
185
  }));
185
186
 
186
- return queries.map(({ parentAssortmentId, assortmentId }) => {
187
- if (parentAssortmentId) {
187
+ // TODO: Optimize
188
+ return queries.map((q) => {
189
+ if (q.parentAssortmentId) {
188
190
  return linksByParentAssortmentId.filter(
189
- (link) => link.parentAssortmentId === parentAssortmentId,
191
+ (link) => link.parentAssortmentId === q.parentAssortmentId,
190
192
  );
191
193
  }
192
- if (assortmentId) {
194
+ if (q.assortmentId) {
193
195
  return linksByAssortmentId.filter(
194
196
  (link) =>
195
- link.parentAssortmentId === assortmentId || link.childAssortmentId === assortmentId,
197
+ link.parentAssortmentId === q.assortmentId || link.childAssortmentId === q.assortmentId,
196
198
  );
197
199
  }
198
200
  return [];
@@ -206,10 +208,11 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
206
208
  assortmentIds,
207
209
  });
208
210
 
209
- return queries.map(({ assortmentId, productId }) => {
211
+ // TODO: Optimize
212
+ return queries.map((q) => {
210
213
  return assortmentProducts.find((assortmentProduct) => {
211
- if (assortmentProduct.assortmentId !== assortmentId) return false;
212
- if (assortmentProduct.productId !== productId) return false;
214
+ if (assortmentProduct.assortmentId !== q.assortmentId) return false;
215
+ if (assortmentProduct.productId !== q.productId) return false;
213
216
  return true;
214
217
  });
215
218
  });
@@ -223,12 +226,12 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
223
226
  includeInactive: true,
224
227
  });
225
228
 
226
- return queries.map(({ filterId }) => {
227
- return filters.find((product) => {
228
- if (product._id !== filterId) return false;
229
- return true;
230
- });
231
- });
229
+ const filterMap = {};
230
+ for (const filter of filters) {
231
+ filterMap[filter._id] = filter;
232
+ }
233
+
234
+ return queries.map((q) => filterMap[q.filterId]);
232
235
  }),
233
236
 
234
237
  filterTextLoader: new DataLoader(async (queries) => {
@@ -243,11 +246,20 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
243
246
  },
244
247
  );
245
248
 
246
- const filterFn =
247
- ({ filterId, filterOptionValue }) =>
248
- (text) =>
249
- text.filterId === filterId && text.filterOptionValue === filterOptionValue;
250
- return getFilteredQueries({ queries, texts, filterFn });
249
+ const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
250
+ const textsMap = {};
251
+ const localeMap = Object.fromEntries(
252
+ queryLocales.flatMap((queryLocale) => {
253
+ return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
254
+ }),
255
+ );
256
+ for (const text of texts) {
257
+ const locale = localeMap[text.locale.toLowerCase()];
258
+ textsMap[`${locale}:${text.filterId}:${text.filterOptionValue}`] = text;
259
+ }
260
+ return queries.map(
261
+ (q) => textsMap[`${q.locale.toLowerCase()}:${q.filterId}:${q.filterOptionValue}`],
262
+ );
251
263
  }),
252
264
 
253
265
  productLoader: new DataLoader(async (queries) => {
@@ -260,12 +272,12 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
260
272
  },
261
273
  });
262
274
 
263
- return queries.map(({ productId }) => {
264
- return products.find((product) => {
265
- if (product._id !== productId) return false;
266
- return true;
267
- });
268
- });
275
+ const productMap = {};
276
+ for (const product of products) {
277
+ productMap[product._id] = product;
278
+ }
279
+
280
+ return queries.map((q) => productMap[q.productId]);
269
281
  }),
270
282
 
271
283
  productLoaderBySKU: new DataLoader(async (queries) => {
@@ -278,17 +290,16 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
278
290
  },
279
291
  });
280
292
 
281
- return queries.map(({ sku }) => {
282
- return products.find((product) => {
283
- if (product.warehousing?.sku !== sku) return false;
284
- return true;
285
- });
286
- });
293
+ const productMap = {};
294
+ for (const product of products) {
295
+ productMap[product.warehousing!.sku!] = product;
296
+ }
297
+
298
+ return queries.map((q) => productMap[q.sku]);
287
299
  }),
288
300
 
289
301
  productTextLoader: new DataLoader(async (queries) => {
290
- const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
291
-
302
+ const productIds = [...new Set(queries.map((q) => q.productId))].filter(Boolean);
292
303
  const texts = await unchainedAPI.modules.products.texts.findTexts(
293
304
  { productId: { $in: productIds } },
294
305
  {
@@ -297,13 +308,18 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
297
308
  },
298
309
  },
299
310
  );
300
-
301
- const filterFn =
302
- ({ productId }) =>
303
- (text) =>
304
- text.productId === productId;
305
-
306
- return getFilteredQueries({ queries, texts, filterFn });
311
+ const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
312
+ const textsMap = {};
313
+ const localeMap = Object.fromEntries(
314
+ queryLocales.flatMap((queryLocale) => {
315
+ return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
316
+ }),
317
+ );
318
+ for (const text of texts) {
319
+ const locale = localeMap[text.locale.toLowerCase()];
320
+ textsMap[`${locale}:${text.productId}`] = text;
321
+ }
322
+ return queries.map((q) => textsMap[`${q.locale.toLowerCase()}:${q.productId}`]);
307
323
  }),
308
324
 
309
325
  productMediaTextLoader: new DataLoader(async (queries) => {
@@ -318,12 +334,18 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
318
334
  },
319
335
  );
320
336
 
321
- const filterFn =
322
- ({ productMediaId }) =>
323
- (text) =>
324
- text.productMediaId === productMediaId;
325
-
326
- return getFilteredQueries({ queries, texts, filterFn });
337
+ const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
338
+ const textsMap = {};
339
+ const localeMap = Object.fromEntries(
340
+ queryLocales.flatMap((queryLocale) => {
341
+ return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
342
+ }),
343
+ );
344
+ for (const text of texts) {
345
+ const locale = localeMap[text.locale.toLowerCase()];
346
+ textsMap[`${locale}:${text.productMediaId}`] = text;
347
+ }
348
+ return queries.map((q) => textsMap[`${q.locale.toLowerCase()}:${q.productMediaId}`]);
327
349
  }),
328
350
 
329
351
  productMediasLoader: new DataLoader(async (queries) => {
@@ -331,11 +353,16 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
331
353
  const productMediaItems = await unchainedAPI.modules.products.media.findProductMedias({
332
354
  productId: { $in: productIds },
333
355
  });
334
- return queries.map((q) => {
335
- return productMediaItems.filter((i) => {
336
- return i.productId === q.productId;
337
- });
338
- });
356
+
357
+ const productMediaMap = {};
358
+ for (const productMedia of productMediaItems) {
359
+ if (!productMediaMap[productMedia.productId]) {
360
+ productMediaMap[productMedia.productId] = [productMedia];
361
+ } else {
362
+ productMediaMap[productMedia.productId].push(productMedia);
363
+ }
364
+ }
365
+ return queries.map((q) => productMediaMap[q.productId] || []);
339
366
  }),
340
367
 
341
368
  fileLoader: new DataLoader(async (queries) => {
@@ -345,12 +372,12 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
345
372
  _id: { $in: fileIds },
346
373
  });
347
374
 
348
- return queries.map(({ fileId }) => {
349
- return files.find((file) => {
350
- if (file._id !== fileId) return false;
351
- return true;
352
- });
353
- });
375
+ const fileMap = {};
376
+ for (const file of files) {
377
+ fileMap[file._id] = file;
378
+ }
379
+
380
+ return queries.map((q) => fileMap[q.fileId]);
354
381
  }),
355
382
  };
356
383
  };
@@ -1,5 +1,6 @@
1
1
  import { log } from '@unchainedshop/logger';
2
2
  import { Context } from '../../../context.js';
3
+ import { WebAuthnDisabledError } from '../../../errors.js';
3
4
 
4
5
  export default async function addWebAuthnCredentials(
5
6
  root: never,
@@ -15,6 +16,8 @@ export default async function addWebAuthnCredentials(
15
16
  credentials,
16
17
  );
17
18
 
19
+ if (!webAuthnService) throw new WebAuthnDisabledError();
20
+
18
21
  return modules.users.updateUser(
19
22
  { _id: userId },
20
23
  {
@@ -16,11 +16,11 @@ export default async function createWebAuthnCredentialRequestOptions(
16
16
  extensionOptions,
17
17
  );
18
18
 
19
- if (username) {
19
+ if (username && options) {
20
20
  const user = await modules.users.findUserByUsername(username);
21
21
  options.allowCredentials = user?.services?.webAuthn?.map(({ id, type }) => ({
22
22
  id,
23
- type: type || options.type || 'public-key',
23
+ type: type || 'public-key',
24
24
  }));
25
25
  }
26
26
 
@@ -1,5 +1,6 @@
1
1
  import { log } from '@unchainedshop/logger';
2
2
  import { Context } from '../../../context.js';
3
+ import { WebAuthnDisabledError } from '../../../errors.js';
3
4
 
4
5
  export default async function loginWithWebAuthn(
5
6
  root: never,
@@ -16,12 +17,14 @@ export default async function loginWithWebAuthn(
16
17
  let user = await context.modules.users.findUserByUsername(username);
17
18
  if (!user) throw new Error('User not found');
18
19
 
19
- await context.modules.users.webAuthn.verifyCredentialRequest(
20
+ const verification = await context.modules.users.webAuthn.verifyCredentialRequest(
20
21
  user.services?.webAuthn,
21
22
  user.username,
22
23
  params.webAuthnPublicKeyCredentials,
23
24
  );
24
25
 
26
+ if (!verification) throw new WebAuthnDisabledError();
27
+
25
28
  user = await context.modules.users.updateHeartbeat(user._id, {
26
29
  remoteAddress: context.remoteAddress,
27
30
  remotePort: context.remotePort,
@@ -14,55 +14,22 @@ export default async function resetPassword(
14
14
  if (!params.newPassword) {
15
15
  throw new Error('Password is required');
16
16
  }
17
- let user = await modules.users.findUserByResetToken(params.token);
18
-
19
- if (!user) throw new InvalidResetTokenError({});
20
17
 
21
18
  try {
22
- await modules.users.setPassword(user._id, params.newPassword);
23
-
24
- // TODO: Verify E-Mail after reset!
25
- // if (resetTicket.address) {
26
- // // Try verifying the E-Mail along the way
27
- // try {
28
- // const updatedUser = await modules.users.updateUser(
29
- // {
30
- // _id: userWithNewPassword.id,
31
- // emails: {
32
- // $elemMatch: {
33
- // address: emailRegexOperator(resetTicket.address),
34
- // verified: false,
35
- // },
36
- // },
37
- // },
38
- // {
39
- // $set: {
40
- // 'emails.$[email].verified': true,
41
- // },
42
- // },
43
- // {
44
- // arrayFilters: [{ 'email.address': resetTicket.address }],
45
- // },
46
- // );
47
- // if (updatedUser) {
48
- // await modules.accounts.emit('VerifyEmailSuccess', updatedUser);
49
- // }
50
- // } catch (e) {
51
- // /* */
52
- // }
53
- // }
19
+ let user = await modules.users.resetPassword(params.token, params.newPassword);
20
+ if (!user) throw new InvalidResetTokenError({});
21
+
22
+ user = await context.modules.users.updateHeartbeat(user._id, {
23
+ remoteAddress: context.remoteAddress,
24
+ remotePort: context.remotePort,
25
+ userAgent: context.userAgent,
26
+ locale: context.localeContext.baseName,
27
+ countryCode: context.countryContext,
28
+ });
29
+
30
+ return context.login(user);
54
31
  } catch (e) {
55
- if (e.cause === 'PASSWORD_INVALID') throw new PasswordInvalidError({ userId: user._id });
32
+ if (e.cause === 'PASSWORD_INVALID') throw new PasswordInvalidError({});
56
33
  else throw e;
57
34
  }
58
-
59
- user = await context.modules.users.updateHeartbeat(user._id, {
60
- remoteAddress: context.remoteAddress,
61
- remotePort: context.remotePort,
62
- userAgent: context.userAgent,
63
- locale: context.localeContext.baseName,
64
- countryCode: context.countryContext,
65
- });
66
-
67
- return context.login(user);
68
35
  }
@@ -1,5 +1,4 @@
1
1
  import { log } from '@unchainedshop/logger';
2
- import { recoverPersonalSignature } from '@metamask/eth-sig-util';
3
2
  import { UserWeb3AddressNotFoundError, UserWeb3AddressSignatureError } from '../../../errors.js';
4
3
  import { Context } from '../../../context.js';
5
4
 
@@ -21,6 +20,10 @@ export default async function verifyWeb3Address(
21
20
 
22
21
  const msg = `0x${Buffer.from(foundCredentials.nonce, 'utf8').toString('hex')}`;
23
22
 
23
+ // eslint-disable-next-line
24
+ // @ts-ignore
25
+ const { recoverPersonalSignature } = await import('@metamask/eth-sig-util');
26
+
24
27
  const recoveredAddr = recoverPersonalSignature({
25
28
  data: msg,
26
29
  signature: hash,
@@ -5,7 +5,7 @@ import { Context } from '../../../context.js';
5
5
 
6
6
  export default async function updateCountry(
7
7
  root: never,
8
- { country, countryId }: { country: Country & { defaultCurrencyId: string }; countryId: string },
8
+ { country, countryId }: { country: Country; countryId: string },
9
9
  { userId, modules }: Context,
10
10
  ) {
11
11
  log(`mutation updateCountry ${countryId}`, { userId });
@@ -15,12 +15,7 @@ export default async function updateCountry(
15
15
  if (!(await modules.countries.countryExists({ countryId })))
16
16
  throw new CountryNotFoundError({ countryId });
17
17
 
18
- const currencyObject = await modules.currencies.findCurrency({
19
- currencyId: country.defaultCurrencyId,
20
- });
21
- const defaultCurrencyCode = country?.defaultCurrencyCode || currencyObject?.isoCode;
22
-
23
- await modules.countries.update(countryId, { ...country, defaultCurrencyCode });
18
+ await modules.countries.update(countryId, country);
24
19
 
25
20
  return modules.countries.findCountry({ countryId });
26
21
  }
@@ -1,10 +1,10 @@
1
1
  import { Context } from '../../../context.js';
2
2
  import { log } from '@unchainedshop/logger';
3
- import { getOrderCart } from '../utils/getOrderCart.js';
4
3
  import {
5
4
  OrderWrongStatusError,
6
5
  OrderDiscountCodeAlreadyPresentError,
7
6
  OrderDiscountCodeNotValidError,
7
+ OrderNotFoundError,
8
8
  } from '../../../errors.js';
9
9
 
10
10
  export default async function addCartDiscount(
@@ -16,7 +16,12 @@ export default async function addCartDiscount(
16
16
 
17
17
  log(`mutation addCartDiscount ${code} ${orderId}`, { userId, orderId });
18
18
 
19
- const order = await getOrderCart({ orderId, user }, context);
19
+ const order = await services.orders.findOrInitCart({
20
+ orderId,
21
+ user,
22
+ countryCode: context.countryContext,
23
+ });
24
+ if (!order) throw new OrderNotFoundError({ orderId });
20
25
 
21
26
  if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
22
27
 
@@ -5,8 +5,8 @@ import {
5
5
  OrderQuantityTooLowError,
6
6
  InvalidIdError,
7
7
  OrderWrongStatusError,
8
+ OrderNotFoundError,
8
9
  } from '../../../errors.js';
9
- import { getOrderCart } from '../utils/getOrderCart.js';
10
10
  import { ordersSettings } from '@unchainedshop/core-orders';
11
11
 
12
12
  export default async function addCartProduct(
@@ -29,7 +29,13 @@ export default async function addCartProduct(
29
29
  const originalProduct = await modules.products.findProduct({ productId: originalProductId });
30
30
  if (!originalProduct) throw new ProductNotFoundError({ productId: originalProductId });
31
31
 
32
- const order = await getOrderCart({ orderId, user }, context);
32
+ const order = await services.orders.findOrInitCart({
33
+ orderId,
34
+ user,
35
+ countryCode: context.countryContext,
36
+ });
37
+ if (!order) throw new OrderNotFoundError({ orderId });
38
+
33
39
  if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
34
40
 
35
41
  const product = await modules.products.resolveOrderableProduct(originalProduct, { configuration });
@@ -8,8 +8,8 @@ import {
8
8
  InvalidIdError,
9
9
  OrderWrongStatusError,
10
10
  ProductNotFoundError,
11
+ OrderNotFoundError,
11
12
  } from '../../../errors.js';
12
- import { getOrderCart } from '../utils/getOrderCart.js';
13
13
  import { QuotationDirector } from '@unchainedshop/core';
14
14
 
15
15
  export default async function addCartQuotation(
@@ -43,7 +43,12 @@ export default async function addCartQuotation(
43
43
  throw new QuotationWrongStatusError({ status: quotation.status });
44
44
  }
45
45
 
46
- const order = await getOrderCart({ orderId, user }, context);
46
+ const order = await services.orders.findOrInitCart({
47
+ orderId,
48
+ user,
49
+ countryCode: context.countryContext,
50
+ });
51
+ if (!order) throw new OrderNotFoundError({ orderId });
47
52
  if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
48
53
 
49
54
  if (
@@ -4,8 +4,8 @@ import {
4
4
  ProductNotFoundError,
5
5
  OrderQuantityTooLowError,
6
6
  OrderWrongStatusError,
7
+ OrderNotFoundError,
7
8
  } from '../../../errors.js';
8
- import { getOrderCart } from '../utils/getOrderCart.js';
9
9
  import { ordersSettings } from '@unchainedshop/core-orders';
10
10
 
11
11
  export default async function addMultipleCartProducts(
@@ -41,7 +41,12 @@ export default async function addMultipleCartProducts(
41
41
  }),
42
42
  );
43
43
 
44
- const order = await getOrderCart({ orderId, user }, context);
44
+ const order = await services.orders.findOrInitCart({
45
+ orderId,
46
+ user,
47
+ countryCode: context.countryContext,
48
+ });
49
+ if (!order) throw new OrderNotFoundError({ orderId });
45
50
  if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
46
51
 
47
52
  // Reduce is used to wait for each product to be added before processing the next (sequential processing)
@@ -1,6 +1,5 @@
1
1
  import { Context } from '../../../context.js';
2
- import { OrderCheckoutError } from '../../../errors.js';
3
- import { getOrderCart } from '../utils/getOrderCart.js';
2
+ import { OrderCheckoutError, OrderNotFoundError } from '../../../errors.js';
4
3
  import { createLogger, log } from '@unchainedshop/logger';
5
4
 
6
5
  const logger = createLogger('unchained:api');
@@ -20,11 +19,16 @@ export default async function checkoutCart(
20
19
  log('mutation checkoutCart', { orderId: forceOrderId, userId });
21
20
 
22
21
  // Do not check for order status here! The checkout method will act accordingly
23
- let order = await getOrderCart({ orderId: forceOrderId, user }, context);
22
+ const order = await services.orders.findOrInitCart({
23
+ orderId: forceOrderId,
24
+ user,
25
+ countryCode: context.countryContext,
26
+ });
27
+ if (!order) throw new OrderNotFoundError({ orderId: forceOrderId });
24
28
 
25
29
  try {
26
- order = await services.orders.checkoutOrder(order._id, transactionContext);
27
- return order;
30
+ const checkedOutOrder = await services.orders.checkoutOrder(order._id, transactionContext);
31
+ return checkedOutOrder;
28
32
  } catch (error) {
29
33
  logger.error(error.message, { userId, orderId: order._id });
30
34
  throw new OrderCheckoutError({