@infrab4a/connect 1.0.0-beta.19 → 1.0.0-beta.21

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 (23) hide show
  1. package/bundles/infrab4a-connect.umd.js +356 -60
  2. package/bundles/infrab4a-connect.umd.js.map +1 -1
  3. package/domain/catalog/models/types/product-review.type.d.ts +10 -8
  4. package/domain/catalog/repositories/product.repository.d.ts +8 -1
  5. package/domain/generic/repository/types/repository-find-filters.type.d.ts +1 -1
  6. package/esm2015/domain/catalog/models/types/product-review.type.js +1 -1
  7. package/esm2015/domain/catalog/repositories/product.repository.js +1 -1
  8. package/esm2015/domain/generic/repository/types/repository-find-filters.type.js +1 -1
  9. package/esm2015/infra/firebase/firestore/repositories/catalog/product-firestore.repository.js +30 -2
  10. package/esm2015/infra/hasura-graphql/mixins/with-create-hasura-graphql.mixin.js +6 -2
  11. package/esm2015/infra/hasura-graphql/mixins/with-update-hasura-graphql.mixin.js +2 -2
  12. package/esm2015/infra/hasura-graphql/repositories/catalog/product-hasura-graphql.repository.js +190 -35
  13. package/esm2015/infra/hasura-graphql/types/graphql.repository.type.js +1 -1
  14. package/esm2015/infra/hasura-graphql/types/hasura-graphql-fields.type.js +1 -1
  15. package/fesm2015/infrab4a-connect.js +222 -35
  16. package/fesm2015/infrab4a-connect.js.map +1 -1
  17. package/infra/firebase/firestore/repositories/catalog/product-firestore.repository.d.ts +3 -1
  18. package/infra/hasura-graphql/mixins/with-find-hasura-graphql.mixin.d.ts +2 -2
  19. package/infra/hasura-graphql/mixins/with-get-hasura-graphql.mixin.d.ts +2 -2
  20. package/infra/hasura-graphql/repositories/catalog/product-hasura-graphql.repository.d.ts +11 -1
  21. package/infra/hasura-graphql/types/graphql.repository.type.d.ts +2 -2
  22. package/infra/hasura-graphql/types/hasura-graphql-fields.type.d.ts +1 -1
  23. package/package.json +1 -1
@@ -3,7 +3,7 @@ import { plainToInstance, instanceToPlain, Expose, Type } from 'class-transforme
3
3
  import { __decorate, __metadata, __awaiter, __rest } from 'tslib';
4
4
  import { parseISO } from 'date-fns';
5
5
  export { add, addBusinessDays, addDays, addMonths, addYears, endOfDay, format, formatISO9075, parseISO, startOfDay, sub } from 'date-fns';
6
- import { isString, isNil, isNumber, isDate, set, isObject, isEmpty, chunk, isBoolean, isInteger, isNaN as isNaN$1 } from 'lodash';
6
+ import { isString, isNil, isNumber, isDate, set, isObject, isEmpty, chunk, isBoolean, isInteger, isNaN as isNaN$1, omit } from 'lodash';
7
7
  export { chunk, isBoolean, isDate, isEmpty, isInteger, isNaN, isNil, isNumber, isObject, isString, now, omit, pick, set } from 'lodash';
8
8
  import { Md5 } from 'ts-md5';
9
9
  import axios from 'axios';
@@ -1570,6 +1570,7 @@ class ProductFirestoreRepository extends withCrudFirestore(withHelpers(withFires
1570
1570
  constructor(firestore) {
1571
1571
  super();
1572
1572
  this.firestore = firestore;
1573
+ this.reviews = {};
1573
1574
  this.collectionName = 'products';
1574
1575
  this.model = Product;
1575
1576
  }
@@ -1585,6 +1586,33 @@ class ProductFirestoreRepository extends withCrudFirestore(withHelpers(withFires
1585
1586
  return (_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.shift();
1586
1587
  });
1587
1588
  }
1589
+ fetchReviews(status) {
1590
+ return __awaiter(this, void 0, void 0, function* () {
1591
+ const { data: products } = yield this.find();
1592
+ products.forEach((product) => {
1593
+ var _a;
1594
+ if ([undefined, 0].includes((_a = product.reviews) === null || _a === void 0 ? void 0 : _a.length))
1595
+ return;
1596
+ const productInfo = {
1597
+ productId: product.id,
1598
+ productName: product.name,
1599
+ productSku: product.sku,
1600
+ };
1601
+ this.reviews.pending = [];
1602
+ this.reviews.approved = [];
1603
+ this.reviews.rejected = [];
1604
+ product.reviews.forEach((review) => {
1605
+ if ([null, undefined].includes(review.status))
1606
+ return this.reviews.pending.push(Object.assign(Object.assign({}, review), productInfo));
1607
+ if (review.status === false)
1608
+ return this.reviews.rejected.push(Object.assign(Object.assign({}, review), productInfo));
1609
+ if (!!review.status)
1610
+ return this.reviews.approved.push(Object.assign(Object.assign({}, review), productInfo));
1611
+ });
1612
+ });
1613
+ return this.reviews[status];
1614
+ });
1615
+ }
1588
1616
  }
1589
1617
 
1590
1618
  class ProductVariantFirestoreRepository extends withSubCollection(withCrudFirestore(withHelpers(withFirestore(Base))), Product) {
@@ -1967,7 +1995,11 @@ const withCreateHasuraGraphQL = (MixinBase) => {
1967
1995
  columnOptions.foreignKeyColumn && [
1968
1996
  ...Object.values(columnOptions.foreignKeyColumn),
1969
1997
  {
1970
- [columnOptions.columnName]: Object.keys(columnOptions.foreignKeyColumn),
1998
+ [columnOptions.columnName]: Object.keys(columnOptions.foreignKeyColumn).map((foreignKeyField) => {
1999
+ var _a;
2000
+ return ((_a = AttributeOptionHelper.FindByAttribute(foreignKeyField, columnOptions === null || columnOptions === void 0 ? void 0 : columnOptions.fields)) === null || _a === void 0 ? void 0 : _a.columnName) ||
2001
+ foreignKeyField;
2002
+ }),
1971
2003
  },
1972
2004
  ]);
1973
2005
  })
@@ -2101,7 +2133,7 @@ const withUpdateHasuraGraphQL = (MixinBase) => {
2101
2133
  const getValueByAction = (options) => {
2102
2134
  if (options instanceof BaseModel)
2103
2135
  return options.toPlain();
2104
- if (isNil(options.action))
2136
+ if (isNil(options === null || options === void 0 ? void 0 : options.action))
2105
2137
  return options;
2106
2138
  if ([UpdateOptionActions.REMOVE_FIELD.toString(), UpdateOptionActions.NULL.toString()].includes(options.action))
2107
2139
  return null;
@@ -2432,6 +2464,15 @@ class CategoryHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGr
2432
2464
 
2433
2465
  class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGraphQL(Base)) {
2434
2466
  constructor(endpoint, authOptions) {
2467
+ super({
2468
+ tableName: 'product',
2469
+ model: ProductHasuraGraphQL,
2470
+ endpoint,
2471
+ authOptions,
2472
+ fields: [],
2473
+ });
2474
+ this.bindReviewToModel = (plain) => (Object.assign(Object.assign({}, omit(plain, ['product_id', 'created_at', 'updated_at', 'person_id', 'order_id'])), { createdAt: typeof plain.created_at === 'string' ? new Date(plain.created_at) : plain.created_at, updatedAt: typeof plain.updated_at === 'string' ? new Date(plain.updated_at) : plain.updated_at, personId: plain.person_id, orderId: plain.order_id }));
2475
+ this.bindReviewToHasura = (review) => (Object.assign(Object.assign({}, omit(review, ['productId', 'createdAt', 'updatedAt', 'personId', 'orderId'])), { person_id: review.personId, order_id: review.orderId }));
2435
2476
  const commonFields = [
2436
2477
  { id: { columnName: 'id', to: (value) => +value, from: (value) => value.toString() } },
2437
2478
  { firestoreId: { columnName: 'firestore_id' } },
@@ -2506,37 +2547,65 @@ class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGra
2506
2547
  { createdAt: { columnName: 'created_at' } },
2507
2548
  { updatedAt: { columnName: 'updated_at' } },
2508
2549
  ];
2509
- super({
2510
- tableName: 'product',
2511
- model: ProductHasuraGraphQL,
2512
- endpoint,
2513
- authOptions,
2514
- fields: [
2515
- ...commonFields,
2516
- {
2517
- categories: {
2518
- columnName: 'categories',
2519
- fields: ['category_id'],
2520
- bindPersistData: (value) => ({
2521
- categories: { data: value.map((category) => ({ category_id: +category })) },
2522
- }),
2523
- to: (categories) => categories.map((categoryId) => +categoryId),
2524
- from: (categories) => (categories === null || categories === void 0 ? void 0 : categories.map((category) => { var _a; return (_a = category === null || category === void 0 ? void 0 : category.category_id) === null || _a === void 0 ? void 0 : _a.toString(); })) || [],
2525
- },
2550
+ this.fields = [
2551
+ ...commonFields,
2552
+ {
2553
+ categories: {
2554
+ columnName: 'categories',
2555
+ fields: ['category_id'],
2556
+ bindPersistData: (value) => ({
2557
+ categories: { data: value.map((category) => ({ category_id: +category })) },
2558
+ }),
2559
+ to: (categories) => categories.map((categoryId) => +categoryId),
2560
+ from: (categories) => (categories === null || categories === void 0 ? void 0 : categories.map((category) => { var _a; return (_a = category === null || category === void 0 ? void 0 : category.category_id) === null || _a === void 0 ? void 0 : _a.toString(); })) || [],
2526
2561
  },
2527
- {
2528
- kitProducts: {
2529
- columnName: 'kit_products',
2530
- foreignKeyColumn: { productId: 'id' },
2531
- fields: [
2532
- { productId: { columnName: 'product_id' } },
2533
- { kitProductId: { columnName: 'kit_product_id' } },
2534
- 'quantity',
2535
- { product: { columnName: 'product', foreignKeyColumn: { id: 'product_id' }, fields: commonFields } },
2536
- ],
2537
- },
2562
+ },
2563
+ {
2564
+ kitProducts: {
2565
+ columnName: 'kit_products',
2566
+ foreignKeyColumn: { productId: 'id' },
2567
+ fields: [
2568
+ { productId: { columnName: 'product_id' } },
2569
+ { kitProductId: { columnName: 'kit_product_id' } },
2570
+ 'quantity',
2571
+ { product: { columnName: 'product', foreignKeyColumn: { id: 'product_id' }, fields: commonFields } },
2572
+ ],
2538
2573
  },
2539
- ],
2574
+ },
2575
+ ];
2576
+ }
2577
+ get reviewsFields() {
2578
+ return [
2579
+ 'id',
2580
+ 'shop',
2581
+ 'rate',
2582
+ 'author',
2583
+ 'email',
2584
+ 'location',
2585
+ 'review',
2586
+ 'status',
2587
+ 'title',
2588
+ 'person_id',
2589
+ 'points',
2590
+ 'order_id',
2591
+ 'created_at',
2592
+ 'updated_at',
2593
+ ];
2594
+ }
2595
+ create(data) {
2596
+ const _super = Object.create(null, {
2597
+ create: { get: () => super.create }
2598
+ });
2599
+ return __awaiter(this, void 0, void 0, function* () {
2600
+ const product = yield _super.create.call(this, omit(data, ['reviews']));
2601
+ try {
2602
+ product.reviews = yield this.updateReviews(+product.id, data);
2603
+ }
2604
+ catch (error) {
2605
+ yield this.delete({ id: product.id });
2606
+ throw error;
2607
+ }
2608
+ return product;
2540
2609
  });
2541
2610
  }
2542
2611
  get(identifiers) {
@@ -2545,9 +2614,11 @@ class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGra
2545
2614
  });
2546
2615
  var _a;
2547
2616
  return __awaiter(this, void 0, void 0, function* () {
2548
- return Number.isNaN(+identifiers.id)
2617
+ const product = Number.isNaN(+identifiers.id)
2549
2618
  ? (_a = (yield this.find({ filters: { firestoreId: identifiers.id } })).data) === null || _a === void 0 ? void 0 : _a[0]
2550
- : _super.get.call(this, identifiers);
2619
+ : yield _super.get.call(this, identifiers);
2620
+ product.reviews = yield this.findReviewsByProduct(+product.id);
2621
+ return product;
2551
2622
  });
2552
2623
  }
2553
2624
  getBySlug(slug, shop) {
@@ -2567,15 +2638,36 @@ class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGra
2567
2638
  update: { get: () => super.update }
2568
2639
  });
2569
2640
  return __awaiter(this, void 0, void 0, function* () {
2570
- const { categories, kitProducts, id: checkId } = params, data = __rest(params, ["categories", "kitProducts", "id"]);
2641
+ const { categories, kitProducts, reviews, id: checkId } = params, data = __rest(params, ["categories", "kitProducts", "reviews", "id"]);
2571
2642
  const plainData = this.paramsToPlain({ id: checkId });
2572
2643
  const id = yield this.getId(plainData.id);
2573
2644
  const product = yield _super.update.call(this, Object.assign({ id }, data));
2574
2645
  product.categories = categories && (yield this.updateCategories(+id, { categories }));
2575
2646
  product.kitProducts = kitProducts && (yield this.updateKitProducts(+id, { kitProducts }));
2647
+ product.reviews = reviews && (yield this.updateReviews(+id, { reviews }));
2576
2648
  return product;
2577
2649
  });
2578
2650
  }
2651
+ fetchReviews(status) {
2652
+ return __awaiter(this, void 0, void 0, function* () {
2653
+ const reviews = {
2654
+ status: status === 'pending'
2655
+ ? { [HasuraGraphQLWhere.ISNULL]: true }
2656
+ : { [HasuraGraphQLWhere.EQUALS]: status === 'approved' },
2657
+ };
2658
+ const { product: data } = yield this.query('product', ['id', 'name', 'sku', { reviews: { columnName: 'reviews', fields: this.reviewsFields } }], {
2659
+ where: { value: { reviews }, type: 'product_bool_exp', required: true },
2660
+ });
2661
+ return data.reduce((reviews, product) => [
2662
+ ...reviews,
2663
+ ...product.reviews
2664
+ .filter((review) => (status === 'pending' && [undefined, null].includes(review.status)) ||
2665
+ (status === 'approved' && review.status === true) ||
2666
+ (status === 'rejected' && review.status === false))
2667
+ .map((review) => (Object.assign(Object.assign({}, this.bindReviewToModel(review)), { productId: product.id, productName: product.name, productSku: product.sku }))),
2668
+ ], []);
2669
+ });
2670
+ }
2579
2671
  updateCategories(productId, { categories }) {
2580
2672
  return __awaiter(this, void 0, void 0, function* () {
2581
2673
  const plainData = this.paramsToPlain({ categories });
@@ -2620,6 +2712,44 @@ class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGra
2620
2712
  return plainData.kitProducts;
2621
2713
  });
2622
2714
  }
2715
+ updateReviews(productId, { reviews }) {
2716
+ return __awaiter(this, void 0, void 0, function* () {
2717
+ if ('action' in reviews && reviews.action === 'remove') {
2718
+ const reviewIds = yield Promise.all(reviews.value.map((reviewData) => __awaiter(this, void 0, void 0, function* () {
2719
+ const review = yield this.findReview(reviewData, productId);
2720
+ return review === null || review === void 0 ? void 0 : review.id;
2721
+ })));
2722
+ yield this.mutation('delete_product_review', ['affected_rows'], {
2723
+ where: { value: { id: { _in: reviewIds.filter(Boolean) } }, type: 'product_review_bool_exp', required: true },
2724
+ });
2725
+ return reviews.value.map((review, index) => !reviewIds[index] && review).filter(Boolean);
2726
+ }
2727
+ const plainData = this.paramsToPlain({ reviews });
2728
+ return Promise.all(plainData.reviews.map((reviewData) => __awaiter(this, void 0, void 0, function* () {
2729
+ const review = yield this.findReview(reviewData, productId);
2730
+ if (review)
2731
+ return this.bindReviewToModel((yield this.mutation('update_product_review_by_pk', this.reviewsFields, {
2732
+ pk_columns: {
2733
+ value: { id: review.id },
2734
+ type: 'product_review_pk_columns_input',
2735
+ required: true,
2736
+ },
2737
+ _set: {
2738
+ value: omit(this.bindReviewToHasura(reviewData), ['id', 'product_id']),
2739
+ type: 'product_review_set_input',
2740
+ required: true,
2741
+ },
2742
+ })).update_product_review_by_pk);
2743
+ return this.bindReviewToModel((yield this.mutation('insert_product_review_one', this.reviewsFields, {
2744
+ object: {
2745
+ value: omit(Object.assign(Object.assign({}, this.bindReviewToHasura(reviewData)), { product_id: productId }), ['id']),
2746
+ type: 'product_review_insert_input',
2747
+ required: true,
2748
+ },
2749
+ })).insert_product_review_one);
2750
+ })));
2751
+ });
2752
+ }
2623
2753
  getId(id) {
2624
2754
  var _a, _b;
2625
2755
  return __awaiter(this, void 0, void 0, function* () {
@@ -2631,6 +2761,63 @@ class ProductHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGra
2631
2761
  throw new NotFoundError(`Product with id ${id} not found`);
2632
2762
  });
2633
2763
  }
2764
+ findReviewsByProduct(productId) {
2765
+ return __awaiter(this, void 0, void 0, function* () {
2766
+ const { product_review: data } = yield this.query('product_review', this.reviewsFields, {
2767
+ where: {
2768
+ value: {
2769
+ product_id: { _eq: productId },
2770
+ },
2771
+ type: 'product_review_bool_exp',
2772
+ required: true,
2773
+ },
2774
+ });
2775
+ return data && data.map((review) => this.bindReviewToModel(review));
2776
+ });
2777
+ }
2778
+ findReview(review, productId) {
2779
+ return __awaiter(this, void 0, void 0, function* () {
2780
+ if (review.id)
2781
+ return review;
2782
+ let loadedReview;
2783
+ if (review.personId)
2784
+ loadedReview = yield this.getReviewByPersonId(review.personId, productId);
2785
+ if (!loadedReview && review.author && review.email)
2786
+ loadedReview = yield this.getReviewByAuthorAndEmail(review.author, review.email, productId);
2787
+ return loadedReview || review;
2788
+ });
2789
+ }
2790
+ getReviewByPersonId(personId, productId) {
2791
+ return __awaiter(this, void 0, void 0, function* () {
2792
+ const { product_review: data } = yield this.query('product_review', this.reviewsFields, {
2793
+ where: {
2794
+ value: {
2795
+ product_id: { _eq: productId },
2796
+ person_id: { _eq: personId },
2797
+ },
2798
+ type: `product_review_bool_exp`,
2799
+ required: true,
2800
+ },
2801
+ });
2802
+ return data && data[0] && this.bindReviewToModel(data[0]);
2803
+ });
2804
+ }
2805
+ getReviewByAuthorAndEmail(author, email, productId) {
2806
+ return __awaiter(this, void 0, void 0, function* () {
2807
+ const { product_review: data } = yield this.query('product_review', this.reviewsFields, {
2808
+ where: {
2809
+ value: {
2810
+ product_id: { _eq: productId },
2811
+ author: { _eq: author },
2812
+ email: { _eq: email },
2813
+ },
2814
+ type: `product_review_bool_exp`,
2815
+ required: true,
2816
+ },
2817
+ });
2818
+ return data && data[0] && this.bindReviewToModel(data[0]);
2819
+ });
2820
+ }
2634
2821
  }
2635
2822
 
2636
2823
  class VariantHasuraGraphQLRepository extends withCrudHasuraGraphQL(withHasuraGraphQL(Base)) {