@infrab4a/connect-angular 5.8.19 → 5.8.21-beta.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 (296) hide show
  1. package/eslint.config.js +18 -0
  2. package/index.ts +1 -0
  3. package/karma.conf.js +32 -0
  4. package/ng-package.json +8 -0
  5. package/package.json +4 -24
  6. package/project.json +37 -0
  7. package/src/angular-connect.module.ts +266 -0
  8. package/src/angular-elastic-search.module.ts +23 -0
  9. package/src/angular-firebase-auth.module.ts +101 -0
  10. package/src/angular-firestore.module.ts +443 -0
  11. package/src/angular-hasura-graphql.module.ts +269 -0
  12. package/src/angular-vertex-search.module.ts +23 -0
  13. package/src/consts/backend-url.const.ts +1 -0
  14. package/src/consts/category-structure.ts +1 -0
  15. package/src/consts/default-shop.const.ts +1 -0
  16. package/src/consts/es-config.const.ts +1 -0
  17. package/src/consts/firebase-const.ts +5 -0
  18. package/src/consts/hasura-options.const.ts +1 -0
  19. package/src/consts/index.ts +8 -0
  20. package/src/consts/persistence.const.ts +1 -0
  21. package/src/consts/storage-base-url.const.ts +1 -0
  22. package/src/consts/vertex-config.const.ts +1 -0
  23. package/src/helpers/index.ts +1 -0
  24. package/src/helpers/mobile-operation-system-checker.helper.ts +10 -0
  25. package/src/index.ts +6 -0
  26. package/src/interfaces/catalog-strategies.interface.ts +36 -0
  27. package/src/interfaces/category-facades.interface.ts +7 -0
  28. package/src/interfaces/index.ts +2 -0
  29. package/src/persistence/cookie-data-persistence.ts +21 -0
  30. package/src/persistence/data-persistence.ts +7 -0
  31. package/src/persistence/index.ts +2 -0
  32. package/src/services/auth.service.ts +39 -0
  33. package/src/services/cart/cart-services.facade.ts +14 -0
  34. package/src/services/cart/index.ts +1 -0
  35. package/src/services/cart.service.ts +148 -0
  36. package/src/services/catalog/adapters/category-structure.adapter.ts +5 -0
  37. package/src/services/catalog/adapters/index.ts +3 -0
  38. package/src/services/catalog/adapters/new-category-structure.adapter.spec.ts +61 -0
  39. package/src/services/catalog/adapters/new-category-structure.adapter.ts +46 -0
  40. package/src/services/catalog/adapters/old-category-structure.adapter.ts +17 -0
  41. package/src/services/catalog/catalog.service.ts +153 -0
  42. package/src/services/catalog/category.service.ts +56 -0
  43. package/src/services/catalog/context/catalog-search.context.ts +59 -0
  44. package/src/services/catalog/enums/index.ts +1 -0
  45. package/src/services/catalog/enums/product-sorts.enum.ts +9 -0
  46. package/src/services/catalog/facades/catalog-service.facade.ts +32 -0
  47. package/src/services/catalog/facades/catalog-strategies.facade.ts +12 -0
  48. package/src/services/catalog/facades/category-repository.facade.ts +10 -0
  49. package/src/services/catalog/facades/category-service.facade.ts +25 -0
  50. package/{services/catalog/facades/index.d.ts → src/services/catalog/facades/index.ts} +5 -5
  51. package/src/services/catalog/facades/product-catalog.facade.ts +13 -0
  52. package/src/services/catalog/helpers/brand-manager.helper.ts +69 -0
  53. package/src/services/catalog/helpers/catalog-filter.helper.ts +50 -0
  54. package/src/services/catalog/helpers/catalog-sort.helper.ts +54 -0
  55. package/src/services/catalog/helpers/index.ts +4 -0
  56. package/src/services/catalog/helpers/product-fields.helper.ts +39 -0
  57. package/src/services/catalog/index.ts +7 -0
  58. package/src/services/catalog/models/category-with-tree.model.ts +7 -0
  59. package/src/services/catalog/models/index.ts +1 -0
  60. package/src/services/catalog/services/catalog-helpers.service.ts +35 -0
  61. package/src/services/catalog/services/catalog-operations.facade.ts +24 -0
  62. package/src/services/catalog/services/catalog-repository.service.ts +20 -0
  63. package/{services/catalog/services/index.d.ts → src/services/catalog/services/index.ts} +4 -4
  64. package/src/services/catalog/services/product-management.facade.ts +20 -0
  65. package/src/services/catalog/strategies/category-search.strategy.spec.ts +214 -0
  66. package/src/services/catalog/strategies/category-search.strategy.ts +207 -0
  67. package/src/services/catalog/strategies/index.ts +3 -0
  68. package/src/services/catalog/strategies/profile-search.strategy.ts +51 -0
  69. package/src/services/catalog/strategies/term-search.strategy.ts +163 -0
  70. package/src/services/catalog/strategies/types/strategy-params.type.ts +59 -0
  71. package/src/services/catalog/types/fetch-products-options.type.ts +10 -0
  72. package/src/services/catalog/types/fetch-products-params.type.ts +27 -0
  73. package/src/services/catalog/types/fetch-products-response.type.ts +11 -0
  74. package/src/services/catalog/types/index.ts +5 -0
  75. package/src/services/catalog/types/method-params.type.ts +21 -0
  76. package/src/services/catalog/types/product-sort.type.ts +3 -0
  77. package/src/services/catalog/wishlist.service.ts +364 -0
  78. package/src/services/checkout/checkout-dependencies.facade.ts +13 -0
  79. package/src/services/checkout/checkout-repositories.facade.ts +10 -0
  80. package/{services/checkout/index.d.ts → src/services/checkout/index.ts} +2 -2
  81. package/src/services/checkout.service.ts +236 -0
  82. package/src/services/coupon/coupon-repositories.facade.ts +11 -0
  83. package/{services/coupon/index.d.ts → src/services/coupon/index.ts} +1 -1
  84. package/src/services/coupon/types/coupon-params.type.ts +15 -0
  85. package/src/services/errors/group-invalid-coupon.error.ts +9 -0
  86. package/src/services/errors/index.ts +2 -0
  87. package/src/services/errors/invalid-coupon.error.ts +7 -0
  88. package/src/services/helpers/index.ts +1 -0
  89. package/src/services/helpers/util.helper.ts +17 -0
  90. package/src/services/home-shop/home-shop-repositories.facade.ts +11 -0
  91. package/{services/home-shop/index.d.ts → src/services/home-shop/index.ts} +1 -1
  92. package/src/services/home-shop.service.ts +210 -0
  93. package/src/services/index.ts +9 -0
  94. package/src/services/order-product-review.service.ts +135 -0
  95. package/src/services/order-recurrence.service.ts +121 -0
  96. package/src/services/order.service.ts +23 -0
  97. package/src/services/shared/configuration.facade.ts +21 -0
  98. package/src/services/shared/index.ts +1 -0
  99. package/src/services/types/index.ts +4 -0
  100. package/src/services/types/pending-product-review.type.ts +12 -0
  101. package/src/services/types/product-review-create.type.ts +15 -0
  102. package/src/services/types/required-checkout-data.type.ts +3 -0
  103. package/src/services/types/required-checkout-subscription-data.type.ts +3 -0
  104. package/src/test.ts +3 -0
  105. package/src/types/firebase-app-config.type.ts +1 -0
  106. package/src/types/index.ts +1 -0
  107. package/tsconfig.json +17 -0
  108. package/tsconfig.lib.json +13 -0
  109. package/tsconfig.lib.prod.json +13 -0
  110. package/tsconfig.spec.json +17 -0
  111. package/angular-connect.module.d.ts +0 -36
  112. package/angular-elastic-search.module.d.ts +0 -9
  113. package/angular-firebase-auth.module.d.ts +0 -11
  114. package/angular-firestore.module.d.ts +0 -17
  115. package/angular-hasura-graphql.module.d.ts +0 -14
  116. package/angular-vertex-search.module.d.ts +0 -9
  117. package/consts/backend-url.const.d.ts +0 -1
  118. package/consts/category-structure.d.ts +0 -1
  119. package/consts/default-shop.const.d.ts +0 -1
  120. package/consts/es-config.const.d.ts +0 -1
  121. package/consts/firebase-const.d.ts +0 -4
  122. package/consts/hasura-options.const.d.ts +0 -1
  123. package/consts/index.d.ts +0 -8
  124. package/consts/persistence.const.d.ts +0 -1
  125. package/consts/storage-base-url.const.d.ts +0 -1
  126. package/consts/vertex-config.const.d.ts +0 -1
  127. package/esm2020/angular-connect.module.mjs +0 -289
  128. package/esm2020/angular-elastic-search.module.mjs +0 -34
  129. package/esm2020/angular-firebase-auth.module.mjs +0 -141
  130. package/esm2020/angular-firestore.module.mjs +0 -653
  131. package/esm2020/angular-hasura-graphql.module.mjs +0 -421
  132. package/esm2020/angular-vertex-search.module.mjs +0 -34
  133. package/esm2020/consts/backend-url.const.mjs +0 -2
  134. package/esm2020/consts/category-structure.mjs +0 -2
  135. package/esm2020/consts/default-shop.const.mjs +0 -2
  136. package/esm2020/consts/es-config.const.mjs +0 -2
  137. package/esm2020/consts/firebase-const.mjs +0 -5
  138. package/esm2020/consts/hasura-options.const.mjs +0 -2
  139. package/esm2020/consts/index.mjs +0 -9
  140. package/esm2020/consts/persistence.const.mjs +0 -2
  141. package/esm2020/consts/storage-base-url.const.mjs +0 -2
  142. package/esm2020/consts/vertex-config.const.mjs +0 -2
  143. package/esm2020/helpers/index.mjs +0 -2
  144. package/esm2020/helpers/mobile-operation-system-checker.helper.mjs +0 -7
  145. package/esm2020/index.mjs +0 -7
  146. package/esm2020/infrab4a-connect-angular.mjs +0 -5
  147. package/esm2020/interfaces/catalog-strategies.interface.mjs +0 -2
  148. package/esm2020/interfaces/category-facades.interface.mjs +0 -2
  149. package/esm2020/interfaces/index.mjs +0 -3
  150. package/esm2020/persistence/cookie-data-persistence.mjs +0 -22
  151. package/esm2020/persistence/data-persistence.mjs +0 -2
  152. package/esm2020/persistence/index.mjs +0 -3
  153. package/esm2020/services/auth.service.mjs +0 -37
  154. package/esm2020/services/cart/cart-services.facade.mjs +0 -21
  155. package/esm2020/services/cart/index.mjs +0 -2
  156. package/esm2020/services/cart.service.mjs +0 -84
  157. package/esm2020/services/catalog/adapters/category-structure.adapter.mjs +0 -2
  158. package/esm2020/services/catalog/adapters/index.mjs +0 -4
  159. package/esm2020/services/catalog/adapters/new-category-structure.adapter.mjs +0 -43
  160. package/esm2020/services/catalog/adapters/old-category-structure.adapter.mjs +0 -23
  161. package/esm2020/services/catalog/catalog.service.mjs +0 -111
  162. package/esm2020/services/catalog/category.service.mjs +0 -42
  163. package/esm2020/services/catalog/context/catalog-search.context.mjs +0 -40
  164. package/esm2020/services/catalog/enums/index.mjs +0 -2
  165. package/esm2020/services/catalog/enums/product-sorts.enum.mjs +0 -11
  166. package/esm2020/services/catalog/facades/catalog-service.facade.mjs +0 -32
  167. package/esm2020/services/catalog/facades/catalog-strategies.facade.mjs +0 -17
  168. package/esm2020/services/catalog/facades/category-repository.facade.mjs +0 -20
  169. package/esm2020/services/catalog/facades/category-service.facade.mjs +0 -30
  170. package/esm2020/services/catalog/facades/index.mjs +0 -6
  171. package/esm2020/services/catalog/facades/product-catalog.facade.mjs +0 -21
  172. package/esm2020/services/catalog/helpers/brand-manager.helper.mjs +0 -62
  173. package/esm2020/services/catalog/helpers/catalog-filter.helper.mjs +0 -44
  174. package/esm2020/services/catalog/helpers/catalog-sort.helper.mjs +0 -52
  175. package/esm2020/services/catalog/helpers/index.mjs +0 -5
  176. package/esm2020/services/catalog/helpers/product-fields.helper.mjs +0 -43
  177. package/esm2020/services/catalog/index.mjs +0 -8
  178. package/esm2020/services/catalog/models/category-with-tree.model.mjs +0 -10
  179. package/esm2020/services/catalog/models/index.mjs +0 -2
  180. package/esm2020/services/catalog/services/catalog-helpers.service.mjs +0 -33
  181. package/esm2020/services/catalog/services/catalog-operations.facade.mjs +0 -26
  182. package/esm2020/services/catalog/services/catalog-repository.service.mjs +0 -25
  183. package/esm2020/services/catalog/services/index.mjs +0 -5
  184. package/esm2020/services/catalog/services/product-management.facade.mjs +0 -25
  185. package/esm2020/services/catalog/strategies/category-search.strategy.mjs +0 -133
  186. package/esm2020/services/catalog/strategies/index.mjs +0 -4
  187. package/esm2020/services/catalog/strategies/profile-search.strategy.mjs +0 -42
  188. package/esm2020/services/catalog/strategies/term-search.strategy.mjs +0 -126
  189. package/esm2020/services/catalog/strategies/types/strategy-params.type.mjs +0 -2
  190. package/esm2020/services/catalog/types/fetch-products-options.type.mjs +0 -2
  191. package/esm2020/services/catalog/types/fetch-products-params.type.mjs +0 -2
  192. package/esm2020/services/catalog/types/fetch-products-response.type.mjs +0 -2
  193. package/esm2020/services/catalog/types/index.mjs +0 -6
  194. package/esm2020/services/catalog/types/method-params.type.mjs +0 -2
  195. package/esm2020/services/catalog/types/product-sort.type.mjs +0 -2
  196. package/esm2020/services/catalog/wishlist.service.mjs +0 -258
  197. package/esm2020/services/checkout/checkout-dependencies.facade.mjs +0 -20
  198. package/esm2020/services/checkout/checkout-repositories.facade.mjs +0 -20
  199. package/esm2020/services/checkout/index.mjs +0 -3
  200. package/esm2020/services/checkout.service.mjs +0 -131
  201. package/esm2020/services/coupon/coupon-repositories.facade.mjs +0 -24
  202. package/esm2020/services/coupon/index.mjs +0 -2
  203. package/esm2020/services/helpers/index.mjs +0 -2
  204. package/esm2020/services/helpers/util.helper.mjs +0 -18
  205. package/esm2020/services/home-shop/home-shop-repositories.facade.mjs +0 -24
  206. package/esm2020/services/home-shop/index.mjs +0 -2
  207. package/esm2020/services/home-shop.service.mjs +0 -130
  208. package/esm2020/services/index.mjs +0 -10
  209. package/esm2020/services/order-product-review.service.mjs +0 -126
  210. package/esm2020/services/order-recurrence.service.mjs +0 -76
  211. package/esm2020/services/order.service.mjs +0 -30
  212. package/esm2020/services/shared/configuration.facade.mjs +0 -29
  213. package/esm2020/services/shared/index.mjs +0 -2
  214. package/esm2020/services/types/index.mjs +0 -5
  215. package/esm2020/services/types/pending-product-review.type.mjs +0 -2
  216. package/esm2020/services/types/product-review-create.type.mjs +0 -2
  217. package/esm2020/services/types/required-checkout-data.type.mjs +0 -2
  218. package/esm2020/services/types/required-checkout-subscription-data.type.mjs +0 -2
  219. package/esm2020/types/firebase-app-config.type.mjs +0 -2
  220. package/esm2020/types/index.mjs +0 -2
  221. package/fesm2015/infrab4a-connect-angular.mjs +0 -3504
  222. package/fesm2015/infrab4a-connect-angular.mjs.map +0 -1
  223. package/fesm2020/infrab4a-connect-angular.mjs +0 -3439
  224. package/fesm2020/infrab4a-connect-angular.mjs.map +0 -1
  225. package/helpers/index.d.ts +0 -1
  226. package/helpers/mobile-operation-system-checker.helper.d.ts +0 -3
  227. package/index.d.ts +0 -6
  228. package/interfaces/catalog-strategies.interface.d.ts +0 -31
  229. package/interfaces/category-facades.interface.d.ts +0 -6
  230. package/interfaces/index.d.ts +0 -2
  231. package/persistence/cookie-data-persistence.d.ts +0 -10
  232. package/persistence/data-persistence.d.ts +0 -6
  233. package/persistence/index.d.ts +0 -2
  234. package/services/auth.service.d.ts +0 -18
  235. package/services/cart/cart-services.facade.d.ts +0 -12
  236. package/services/cart/index.d.ts +0 -1
  237. package/services/cart.service.d.ts +0 -27
  238. package/services/catalog/adapters/category-structure.adapter.d.ts +0 -4
  239. package/services/catalog/adapters/index.d.ts +0 -3
  240. package/services/catalog/adapters/new-category-structure.adapter.d.ts +0 -12
  241. package/services/catalog/adapters/old-category-structure.adapter.d.ts +0 -10
  242. package/services/catalog/catalog.service.d.ts +0 -24
  243. package/services/catalog/category.service.d.ts +0 -23
  244. package/services/catalog/context/catalog-search.context.d.ts +0 -14
  245. package/services/catalog/enums/index.d.ts +0 -1
  246. package/services/catalog/enums/product-sorts.enum.d.ts +0 -9
  247. package/services/catalog/facades/catalog-service.facade.d.ts +0 -15
  248. package/services/catalog/facades/catalog-strategies.facade.d.ts +0 -10
  249. package/services/catalog/facades/category-repository.facade.d.ts +0 -9
  250. package/services/catalog/facades/category-service.facade.d.ts +0 -15
  251. package/services/catalog/facades/product-catalog.facade.d.ts +0 -10
  252. package/services/catalog/helpers/brand-manager.helper.d.ts +0 -14
  253. package/services/catalog/helpers/catalog-filter.helper.d.ts +0 -8
  254. package/services/catalog/helpers/catalog-sort.helper.d.ts +0 -7
  255. package/services/catalog/helpers/index.d.ts +0 -4
  256. package/services/catalog/helpers/product-fields.helper.d.ts +0 -7
  257. package/services/catalog/index.d.ts +0 -7
  258. package/services/catalog/models/category-with-tree.model.d.ts +0 -4
  259. package/services/catalog/models/index.d.ts +0 -1
  260. package/services/catalog/services/catalog-helpers.service.d.ts +0 -17
  261. package/services/catalog/services/catalog-operations.facade.d.ts +0 -13
  262. package/services/catalog/services/catalog-repository.service.d.ts +0 -12
  263. package/services/catalog/services/product-management.facade.d.ts +0 -12
  264. package/services/catalog/strategies/category-search.strategy.d.ts +0 -19
  265. package/services/catalog/strategies/index.d.ts +0 -3
  266. package/services/catalog/strategies/profile-search.strategy.d.ts +0 -14
  267. package/services/catalog/strategies/term-search.strategy.d.ts +0 -20
  268. package/services/catalog/strategies/types/strategy-params.type.d.ts +0 -59
  269. package/services/catalog/types/fetch-products-options.type.d.ts +0 -8
  270. package/services/catalog/types/fetch-products-params.type.d.ts +0 -25
  271. package/services/catalog/types/fetch-products-response.type.d.ts +0 -19
  272. package/services/catalog/types/index.d.ts +0 -5
  273. package/services/catalog/types/method-params.type.d.ts +0 -17
  274. package/services/catalog/types/product-sort.type.d.ts +0 -2
  275. package/services/catalog/wishlist.service.d.ts +0 -60
  276. package/services/checkout/checkout-dependencies.facade.d.ts +0 -10
  277. package/services/checkout/checkout-repositories.facade.d.ts +0 -9
  278. package/services/checkout.service.d.ts +0 -33
  279. package/services/coupon/coupon-repositories.facade.d.ts +0 -10
  280. package/services/helpers/index.d.ts +0 -1
  281. package/services/helpers/util.helper.d.ts +0 -3
  282. package/services/home-shop/home-shop-repositories.facade.d.ts +0 -10
  283. package/services/home-shop.service.d.ts +0 -34
  284. package/services/index.d.ts +0 -9
  285. package/services/order-product-review.service.d.ts +0 -18
  286. package/services/order-recurrence.service.d.ts +0 -25
  287. package/services/order.service.d.ts +0 -13
  288. package/services/shared/configuration.facade.d.ts +0 -12
  289. package/services/shared/index.d.ts +0 -1
  290. package/services/types/index.d.ts +0 -4
  291. package/services/types/pending-product-review.type.d.ts +0 -12
  292. package/services/types/product-review-create.type.d.ts +0 -14
  293. package/services/types/required-checkout-data.type.d.ts +0 -2
  294. package/services/types/required-checkout-subscription-data.type.d.ts +0 -2
  295. package/types/firebase-app-config.type.d.ts +0 -1
  296. package/types/index.d.ts +0 -1
@@ -0,0 +1,23 @@
1
+ import { ModuleWithProviders, NgModule } from '@angular/core'
2
+ import { ProductsVertexSearch, VertexAxiosAdapter, VertexSearchConfig } from '@infrab4a/connect'
3
+
4
+ import { VERTEX_CONFIG } from './consts'
5
+
6
+ @NgModule({
7
+ providers: [
8
+ {
9
+ provide: ProductsVertexSearch,
10
+ useFactory: (configuration: VertexSearchConfig): ProductsVertexSearch =>
11
+ new ProductsVertexSearch(new VertexAxiosAdapter(configuration)),
12
+ deps: [VERTEX_CONFIG],
13
+ },
14
+ ],
15
+ })
16
+ export class AngularVertexSeachModule {
17
+ static initializeApp(options: VertexSearchConfig): ModuleWithProviders<AngularVertexSeachModule> {
18
+ return {
19
+ ngModule: AngularVertexSeachModule,
20
+ providers: [{ provide: VERTEX_CONFIG, useValue: options }],
21
+ }
22
+ }
23
+ }
@@ -0,0 +1 @@
1
+ export const BACKEND_URL = 'BACKEND_URL'
@@ -0,0 +1 @@
1
+ export const CATEGORY_STRUCTURE = 'CATEGORY_STRUCTURE'
@@ -0,0 +1 @@
1
+ export const DEFAULT_SHOP = 'DEFAULT_SHOP'
@@ -0,0 +1 @@
1
+ export const ES_CONFIG = 'ES_CONFIG'
@@ -0,0 +1,5 @@
1
+ import { InjectionToken } from '@angular/core'
2
+
3
+ export const FIREBASE_APP_NAME = new InjectionToken('firebaseAppName')
4
+ export const FIREBASE_OPTIONS = new InjectionToken('firebaseOptions')
5
+ export const APP_CHECK_PROVIDER = new InjectionToken('appCheckProvider')
@@ -0,0 +1 @@
1
+ export const HASURA_OPTIONS = 'HASURA_OPTIONS'
@@ -0,0 +1,8 @@
1
+ export * from './backend-url.const'
2
+ export * from './category-structure'
3
+ export * from './default-shop.const'
4
+ export * from './es-config.const'
5
+ export * from './firebase-const'
6
+ export * from './hasura-options.const'
7
+ export * from './persistence.const'
8
+ export * from './vertex-config.const'
@@ -0,0 +1 @@
1
+ export const PERSISTENCE_PROVIDER = 'PERSISTENCE_PROVIDER'
@@ -0,0 +1 @@
1
+ export const STORAGE_BASE_URL = 'STORAGE_BASE_URL'
@@ -0,0 +1 @@
1
+ export const VERTEX_CONFIG = 'VERTEX_CONFIG'
@@ -0,0 +1 @@
1
+ export * from './mobile-operation-system-checker.helper'
@@ -0,0 +1,10 @@
1
+ export class MobileOperationSystemCheckerHelper {
2
+ static isAppleDevice() {
3
+ return (
4
+ ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(
5
+ navigator?.platform,
6
+ ) ||
7
+ (navigator?.userAgent?.includes?.('Mac') && 'ontouchend' in (document || {}))
8
+ )
9
+ }
10
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './angular-connect.module'
2
+ export * from './angular-firebase-auth.module'
3
+ export * from './angular-firestore.module'
4
+ export * from './angular-hasura-graphql.module'
5
+ export * from './persistence'
6
+ export * from './services'
@@ -0,0 +1,36 @@
1
+ import {
2
+ Category,
3
+ Product,
4
+ ProductGender,
5
+ RepositoryCacheOptions,
6
+ RepositoryFindResult,
7
+ Shops,
8
+ } from '@infrab4a/connect'
9
+
10
+ export interface CatalogSearchParams {
11
+ category?: Category
12
+ profile?: string[]
13
+ term?: string
14
+ filters?: CatalogFilters
15
+ mainGender?: ProductGender
16
+ limits: { limit?: number; offset?: number }
17
+ sort?: string
18
+ }
19
+
20
+ export interface CatalogFilters {
21
+ clubDiscount?: number[]
22
+ brands?: string[]
23
+ prices?: { min?: number; max?: number; subscriberPrice?: boolean }
24
+ gender?: ProductGender[]
25
+ rate?: number
26
+ customOptions?: string[]
27
+ tags?: string[]
28
+ }
29
+
30
+ export interface CatalogSearchStrategy {
31
+ search(
32
+ params: CatalogSearchParams,
33
+ shop: Shops,
34
+ optionsCache?: { cache?: RepositoryCacheOptions },
35
+ ): Promise<RepositoryFindResult<Product>>
36
+ }
@@ -0,0 +1,7 @@
1
+ import { CategoryRepository, ProductSearchIndex, ProductStockNotificationRepository } from '@infrab4a/connect'
2
+
3
+ export interface ProductServicesFacade {
4
+ productStockNotificationRepository: ProductStockNotificationRepository
5
+ categoryRepository: CategoryRepository
6
+ productSearch: ProductSearchIndex
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from './catalog-strategies.interface'
2
+ export * from './category-facades.interface'
@@ -0,0 +1,21 @@
1
+ import { Injectable } from '@angular/core'
2
+ import cookie from 'js-cookie'
3
+ import { Observable, from, of } from 'rxjs'
4
+ import { map } from 'rxjs/operators'
5
+
6
+ import { DataPersistence } from './data-persistence'
7
+
8
+ @Injectable()
9
+ export class CookieDataPersistence implements DataPersistence {
10
+ get(key: string): Observable<string> {
11
+ return of(cookie.get(key))
12
+ }
13
+
14
+ remove(key: string): Observable<void> {
15
+ return of(cookie.remove(key))
16
+ }
17
+
18
+ set(key: string, value: string): Observable<void> {
19
+ return from(cookie.set(key, value)).pipe(map(() => {}))
20
+ }
21
+ }
@@ -0,0 +1,7 @@
1
+ import { Observable } from 'rxjs'
2
+
3
+ export interface DataPersistence {
4
+ get(key: string): Observable<string>
5
+ remove(key: string): Observable<void>
6
+ set(key: string, value: string): Observable<void>
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from './cookie-data-persistence'
2
+ export * from './data-persistence'
@@ -0,0 +1,39 @@
1
+ import { Inject, Injectable } from '@angular/core'
2
+ import { Auth, User as FirebaseUser, authState, getIdToken } from '@angular/fire/auth'
3
+ import { User, UserRepository } from '@infrab4a/connect'
4
+ import { Observable, combineLatest, from, of } from 'rxjs'
5
+ import { catchError, map, mergeMap } from 'rxjs/operators'
6
+
7
+ @Injectable()
8
+ export class AuthService {
9
+ constructor(
10
+ private readonly angularFireAuth: Auth,
11
+ @Inject('UserRepository') private readonly userRepository: UserRepository,
12
+ ) {}
13
+
14
+ getAuthstate(): Observable<{ user: User; isAnonymous: boolean }> {
15
+ const observables: [Observable<FirebaseUser>, Observable<User>] = [this.getFireUser(), this.getUser()]
16
+
17
+ return combineLatest(observables).pipe(
18
+ map(([fireUser, user]) => ({
19
+ user,
20
+ isAnonymous: fireUser?.isAnonymous,
21
+ })),
22
+ )
23
+ }
24
+
25
+ getUser(): Observable<User> {
26
+ return this.getFireUser().pipe(
27
+ map((user) => user?.uid),
28
+ mergeMap((id) => (id ? from(this.userRepository.get({ id })).pipe(catchError(() => of(null))) : of(null))),
29
+ )
30
+ }
31
+
32
+ getTokenId(): Observable<string> {
33
+ return from(getIdToken(this.angularFireAuth.currentUser))
34
+ }
35
+
36
+ getFireUser(): Observable<FirebaseUser> {
37
+ return authState(this.angularFireAuth).pipe(catchError(() => of(null)))
38
+ }
39
+ }
@@ -0,0 +1,14 @@
1
+ import { HttpClient } from '@angular/common/http'
2
+ import { Injectable } from '@angular/core'
3
+
4
+ import { AuthService } from '../auth.service'
5
+ import { CheckoutService } from '../checkout.service'
6
+
7
+ @Injectable()
8
+ export class CartServicesFacade {
9
+ constructor(
10
+ public readonly authService: AuthService,
11
+ public readonly checkoutService: CheckoutService,
12
+ public readonly httpClient: HttpClient,
13
+ ) {}
14
+ }
@@ -0,0 +1 @@
1
+ export { CartServicesFacade } from './cart-services.facade'
@@ -0,0 +1,148 @@
1
+ /* eslint-disable max-params */
2
+ import { Injectable } from '@angular/core'
3
+ import { Checkout, LineItem, User } from '@infrab4a/connect'
4
+ import { Observable, of, Subject } from 'rxjs'
5
+ import { concatMap, map, tap } from 'rxjs/operators'
6
+
7
+ import { CartServicesFacade } from './cart'
8
+ import { ConfigurationFacade } from './shared'
9
+ import { RequiredCheckoutData } from './types'
10
+
11
+ export type Cart = {
12
+ [id: string]: LineItem
13
+ }
14
+
15
+ @Injectable()
16
+ export class CartService {
17
+ private cartSubject: Subject<Cart> = new Subject()
18
+ private checkoutUrl: string = null
19
+
20
+ constructor(
21
+ private readonly servicesFacade: CartServicesFacade,
22
+ private readonly configurationFacade: ConfigurationFacade,
23
+ ) {
24
+ this.checkoutUrl = this.configurationFacade.getCheckoutUrl()
25
+ }
26
+
27
+ addItem(
28
+ item: LineItem,
29
+ quantity: number = 1,
30
+ recurrence: boolean = false,
31
+ recurrenceCycle: string = null,
32
+ ): Observable<Cart> {
33
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
34
+ concatMap((checkout) =>
35
+ this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutAddItemToCart`, {
36
+ checkoutId: checkout.id,
37
+ productId: item.id,
38
+ quantity,
39
+ recurrence,
40
+ recurrenceCycle,
41
+ }),
42
+ ),
43
+ concatMap(() => this.servicesFacade.checkoutService.getCheckout()),
44
+ map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)),
45
+ tap((cart) => this.cartSubject.next(cart)),
46
+ )
47
+ }
48
+
49
+ updateItemRecurrence(item: LineItem, recurrence: boolean = false, recurrenceCycle: string = null): Observable<Cart> {
50
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
51
+ concatMap((checkout) =>
52
+ this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutUpdateItemRecurrence`, {
53
+ checkoutId: checkout.id,
54
+ productId: item.id,
55
+ recurrence,
56
+ recurrenceCycle,
57
+ }),
58
+ ),
59
+ concatMap(() => this.servicesFacade.checkoutService.getCheckout()),
60
+ map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)),
61
+ tap((cart) => this.cartSubject.next(cart)),
62
+ )
63
+ }
64
+
65
+ decreaseItem(item: LineItem): Observable<Cart> {
66
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
67
+ concatMap((checkout) =>
68
+ this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutDecreaseProductFromCart`, {
69
+ checkoutId: checkout.id,
70
+ productId: item.id,
71
+ quantity: 1,
72
+ }),
73
+ ),
74
+ concatMap(() => this.servicesFacade.checkoutService.getCheckout()),
75
+ map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)),
76
+ tap((cart) => this.cartSubject.next(cart)),
77
+ )
78
+ }
79
+
80
+ removeItem(item: LineItem): Observable<Cart> {
81
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
82
+ concatMap((checkout) =>
83
+ this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutRemoveProductFromCart`, {
84
+ checkoutId: checkout.id,
85
+ productId: item.id,
86
+ }),
87
+ ),
88
+ concatMap(() => this.servicesFacade.checkoutService.getCheckout()),
89
+ map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)),
90
+ tap((cart) => this.cartSubject.next(cart)),
91
+ )
92
+ }
93
+
94
+ updateUserCart(user: User): Observable<Cart> {
95
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
96
+ concatMap((checkout) =>
97
+ this.servicesFacade.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user })),
98
+ ),
99
+ concatMap((checkout) => {
100
+ return this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutUpdateUserCart`, {
101
+ checkoutId: checkout.id,
102
+ })
103
+ }),
104
+ concatMap(() => this.servicesFacade.checkoutService.getCheckout()),
105
+ map((updatedCheckout) => {
106
+ return this.generateCartObject(updatedCheckout.lineItems)
107
+ }),
108
+ tap((cart) => this.cartSubject.next(cart)),
109
+ )
110
+ }
111
+
112
+ getCart(checkout?: RequiredCheckoutData): Observable<Cart> {
113
+ this.buildCartFromCheckout(checkout).subscribe((cart) => this.cartSubject.next(cart))
114
+
115
+ return this.cartSubject
116
+ }
117
+
118
+ clearCart(): Observable<Cart> {
119
+ return this.servicesFacade.checkoutService.getCheckout().pipe(
120
+ map((checkout) => {
121
+ this.servicesFacade.checkoutService.clearCheckoutFromSession()
122
+
123
+ return checkout
124
+ }),
125
+ concatMap((oldCheckout) => this.buildCartFromCheckout(oldCheckout)),
126
+ tap((cart) => this.cartSubject.next(cart)),
127
+ )
128
+ }
129
+
130
+ private buildCartFromCheckout(checkoutData?: RequiredCheckoutData): Observable<Cart> {
131
+ return this.servicesFacade.checkoutService.getCheckout(checkoutData).pipe(
132
+ map((checkout) => checkout.lineItems),
133
+ concatMap((lineItems) => of(this.generateCartObject(lineItems))),
134
+ )
135
+ }
136
+
137
+ private generateCartObject = (items: LineItem[]): Cart =>
138
+ items?.reduce(
139
+ (cart, item) => ({
140
+ ...cart,
141
+ [item.id]: LineItem.toInstance({
142
+ ...(cart[item.id] || item),
143
+ quantity: (cart[item.id]?.quantity || 0) + (item.quantity ? item.quantity : 1),
144
+ }),
145
+ }),
146
+ {} as Record<string, LineItem>,
147
+ ) || {}
148
+ }
@@ -0,0 +1,5 @@
1
+ import { Category, Product, RepositoryFindFielters } from '@infrab4a/connect/'
2
+
3
+ export interface CategoryStructureAdapter {
4
+ buildProductFilterByCategory(category: Category): Promise<RepositoryFindFielters<Product>>
5
+ }
@@ -0,0 +1,3 @@
1
+ export * from './category-structure.adapter'
2
+ export * from './new-category-structure.adapter'
3
+ export * from './old-category-structure.adapter'
@@ -0,0 +1,61 @@
1
+ import { Category, CategoryRepository, Where } from '@infrab4a/connect'
2
+
3
+ import { NewCategoryStructureAdapter } from './new-category-structure.adapter'
4
+
5
+ describe('NewCategoryStructureAdapter', () => {
6
+ let categoryRepository: jasmine.SpyObj<CategoryRepository>
7
+ let adapter: NewCategoryStructureAdapter
8
+
9
+ beforeEach(() => {
10
+ categoryRepository = jasmine.createSpyObj<CategoryRepository>('CategoryRepository', ['get', 'getChildren'])
11
+ adapter = new NewCategoryStructureAdapter(categoryRepository)
12
+ })
13
+
14
+ it('should not get category when wishlist already has a products array', async () => {
15
+ const category = {
16
+ id: '10',
17
+ isWishlist: true,
18
+ isCollection: true,
19
+ products: ['1', '2'],
20
+ } as Category
21
+
22
+ const result = await adapter.buildProductFilterByCategory(category)
23
+
24
+ expect(categoryRepository.get).not.toHaveBeenCalled()
25
+ expect(result).toEqual({ id: { operator: Where.IN, value: ['1', '2'] } })
26
+ })
27
+
28
+ it('should not get category when collection already has an empty products array', async () => {
29
+ const category = {
30
+ id: '11',
31
+ isWishlist: false,
32
+ isCollection: true,
33
+ products: [],
34
+ } as Category
35
+
36
+ const result = await adapter.buildProductFilterByCategory(category)
37
+
38
+ expect(categoryRepository.get).not.toHaveBeenCalled()
39
+ expect(result).toEqual({ id: { operator: Where.IN, value: [] } })
40
+ })
41
+
42
+ it('should get category when wishlist products are not loaded', async () => {
43
+ const category = {
44
+ id: '12',
45
+ isWishlist: true,
46
+ isCollection: true,
47
+ } as Category
48
+
49
+ const loaded = {
50
+ ...category,
51
+ products: ['9'],
52
+ } as Category
53
+
54
+ categoryRepository.get.and.resolveTo(loaded)
55
+
56
+ const result = await adapter.buildProductFilterByCategory(category)
57
+
58
+ expect(categoryRepository.get).toHaveBeenCalledWith({ id: '12' })
59
+ expect(result).toEqual({ id: { operator: Where.IN, value: ['9'] } })
60
+ })
61
+ })
@@ -0,0 +1,46 @@
1
+ import { Inject, Injectable } from '@angular/core'
2
+ import { Category, CategoryRepository, isNil, Product, RepositoryFindFielters, Where } from '@infrab4a/connect'
3
+
4
+ import { CategoryStructureAdapter } from './category-structure.adapter'
5
+
6
+ @Injectable()
7
+ export class NewCategoryStructureAdapter implements CategoryStructureAdapter {
8
+ constructor(@Inject('CategoryRepository') private readonly categoryRepository: CategoryRepository) {}
9
+
10
+ async buildProductFilterByCategory(category: Category): Promise<RepositoryFindFielters<Product>> {
11
+ const loadedCategory = await this.getCategory(category)
12
+
13
+ if (loadedCategory.isCollection) return { id: { operator: Where.IN, value: loadedCategory.products } }
14
+
15
+ const categoryIds = [...(await this.getAllCategoriesIdFromCategory(category)), category.id.toString()]
16
+
17
+ return {
18
+ category: {
19
+ id: {
20
+ operator: Where.IN,
21
+ value: categoryIds,
22
+ },
23
+ },
24
+ }
25
+ }
26
+
27
+ private async getAllCategoriesIdFromCategory(category: Category): Promise<string[]> {
28
+ return this.categoryRepository
29
+ .getChildren(+category.id)
30
+ .then((categories) => categories.map((category) => category.id.toString()))
31
+ }
32
+
33
+ private async getCategory(category: Category): Promise<Category> {
34
+ if ((category.isWishlist || category.isCollection) && Array.isArray(category.products)) {
35
+ return category
36
+ }
37
+
38
+ const collectionCategory =
39
+ category.isCollection ||
40
+ (isNil(category.isCollection) && !category.products?.length) ||
41
+ category.isWishlist ||
42
+ category.brandCategory
43
+
44
+ return collectionCategory ? this.categoryRepository.get({ id: category.id }) : category
45
+ }
46
+ }
@@ -0,0 +1,17 @@
1
+ import { Inject, Injectable } from '@angular/core'
2
+ import { Category, CategoryRepository, Product, RepositoryFindFielters, Where } from '@infrab4a/connect'
3
+
4
+ import { CategoryStructureAdapter } from './category-structure.adapter'
5
+
6
+ @Injectable()
7
+ export class OldCategoryStructureAdapter implements CategoryStructureAdapter {
8
+ constructor(@Inject('CategoryRepository') private readonly categoryRepository: CategoryRepository) {}
9
+
10
+ async buildProductFilterByCategory(category: Category): Promise<RepositoryFindFielters<Product>> {
11
+ const productsIds = category.products?.length
12
+ ? category.products
13
+ : await this.categoryRepository.get({ id: category.id }).then((categoryFound) => categoryFound.products)
14
+
15
+ return { id: { operator: Where.IN, value: productsIds } }
16
+ }
17
+ }
@@ -0,0 +1,153 @@
1
+ import { Inject, Injectable } from '@angular/core'
2
+ import {
3
+ Category,
4
+ InvalidArgumentError,
5
+ RepositoryCacheOptions,
6
+ RoundProductPricesHelper,
7
+ Shops,
8
+ } from '@infrab4a/connect'
9
+
10
+ import { DEFAULT_SHOP } from '../../consts'
11
+ import { CatalogFilters, CatalogSearchParams } from '../../interfaces'
12
+
13
+ import { CatalogSearchContext } from './context/catalog-search.context'
14
+ import { CatalogHelpersService } from './services'
15
+ import {
16
+ BuildResponseParams,
17
+ FetchProductsMainParams,
18
+ FetchProductsOptions,
19
+ FetchProductsParams,
20
+ FetchProductsResponse,
21
+ StockNotificationParams,
22
+ } from './types'
23
+
24
+ @Injectable()
25
+ export class CatalogService<T extends Category = Category> {
26
+ constructor(
27
+ private readonly searchContext: CatalogSearchContext,
28
+ private readonly helpersService: CatalogHelpersService,
29
+ @Inject(DEFAULT_SHOP) private readonly shop: Shops,
30
+ ) {}
31
+
32
+ async fetchProducts(
33
+ options: FetchProductsParams<T>,
34
+ optionsCache?: { cache?: RepositoryCacheOptions },
35
+ ): Promise<FetchProductsResponse> {
36
+ this.validateRequest(options)
37
+
38
+ const searchParams = this.buildSearchParams(options)
39
+ const {
40
+ data,
41
+ count: total,
42
+ maximum,
43
+ minimal,
44
+ distinct,
45
+ } = await this.searchContext.executeSearch(searchParams, this.shop, optionsCache)
46
+
47
+ await this.helpersService.getBrandManager().setBrandsList(searchParams, distinct?.brand)
48
+
49
+ return this.buildResponse({
50
+ data,
51
+ total,
52
+ maximum,
53
+ minimal,
54
+ searchParams,
55
+ options,
56
+ })
57
+ }
58
+
59
+ async addCustomerToStockNotification(params: StockNotificationParams): Promise<void> {
60
+ const { shop, productId, name, email } = params
61
+ const productServices = this.helpersService.getProductServices()
62
+
63
+ return productServices.productStockNotificationRepository.addCustomerEmail({
64
+ shop,
65
+ productId,
66
+ name,
67
+ email,
68
+ })
69
+ }
70
+
71
+ private validateRequest(options: FetchProductsParams<T>): void {
72
+ if (this.hasProfile(options) && options.filters?.customOptions) {
73
+ throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`)
74
+ }
75
+
76
+ if (this.hasProfile(options) && options.filters?.tags) {
77
+ throw new InvalidArgumentError(`It couldn't filled tags when profile is given`)
78
+ }
79
+
80
+ if (this.hasTerm(options) && options.filters?.customOptions) {
81
+ throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`)
82
+ }
83
+ }
84
+
85
+ private buildSearchParams(options: FetchProductsParams<T>): CatalogSearchParams {
86
+ const limits = this.buildLimitQuery(options)
87
+
88
+ return {
89
+ category: this.hasCategory(options) ? options.category : undefined,
90
+ profile: this.hasProfile(options) ? options.profile : undefined,
91
+ term: this.hasTerm(options) ? options.term : undefined,
92
+ filters: options.filters,
93
+ mainGender: options.mainGender,
94
+ sort: options.sort,
95
+ limits,
96
+ }
97
+ }
98
+
99
+ private buildResponse(params: BuildResponseParams<T>): FetchProductsResponse {
100
+ const { data, total, maximum, minimal, searchParams } = params
101
+ const limits = searchParams.limits
102
+ const indexKey = this.helpersService.getBrandManager().buildIndexBrands(searchParams)
103
+
104
+ return {
105
+ products: {
106
+ data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)),
107
+ total,
108
+ },
109
+ pages: Math.ceil(total / limits.limit),
110
+ prices: {
111
+ price: {
112
+ min: +(minimal?.price?.price?.toFixed(2) || 0),
113
+ max: +(maximum?.price?.price?.toFixed(2) || 0),
114
+ },
115
+ subscriberPrice: {
116
+ min: +(minimal?.price?.subscriberPrice?.toFixed(2) || 0),
117
+ max: +(maximum?.price?.subscriberPrice?.toFixed(2) || 0),
118
+ },
119
+ },
120
+ brands: this.helpersService.getBrandManager().getBrandsList(indexKey),
121
+ }
122
+ }
123
+
124
+ private buildLimitQuery(options: { page?: number; perPage?: number }): { limit: number; offset: number } {
125
+ const limit = options?.perPage || 20
126
+
127
+ return {
128
+ limit,
129
+ offset: ((options?.page || 1) - 1) * limit,
130
+ }
131
+ }
132
+
133
+ private hasProfile(options: Partial<FetchProductsParams<T>>): options is FetchProductsOptions & {
134
+ profile: FetchProductsMainParams<T>['profile']
135
+ filters?: CatalogFilters & { customOptions?: never; tags?: never }
136
+ } {
137
+ return 'profile' in options
138
+ }
139
+
140
+ private hasTerm(options: Partial<FetchProductsParams<T>>): options is FetchProductsOptions & {
141
+ term: FetchProductsMainParams<T>['term']
142
+ filters?: CatalogFilters & { customOptions?: never }
143
+ } {
144
+ return 'term' in options
145
+ }
146
+
147
+ private hasCategory(options: Partial<FetchProductsParams<T>>): options is FetchProductsOptions & {
148
+ category: FetchProductsMainParams<T>['category']
149
+ filters?: CatalogFilters & { customOptions?: never }
150
+ } {
151
+ return 'category' in options
152
+ }
153
+ }