nestjs-paginate 4.2.2 → 4.4.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.
@@ -27,17 +27,17 @@ describe('paginate', () => {
27
27
  catToyRepo = connection.getRepository(cat_toy_entity_1.CatToyEntity);
28
28
  catHomeRepo = connection.getRepository(cat_home_entity_1.CatHomeEntity);
29
29
  cats = await catRepo.save([
30
- catRepo.create({ name: 'Milo', color: 'brown', age: 6 }),
31
- catRepo.create({ name: 'Garfield', color: 'ginger', age: 5 }),
32
- catRepo.create({ name: 'Shadow', color: 'black', age: 4 }),
33
- catRepo.create({ name: 'George', color: 'white', age: 3 }),
34
- catRepo.create({ name: 'Leche', color: 'white', age: null }),
30
+ catRepo.create({ name: 'Milo', color: 'brown', age: 6, size: { height: 25, width: 10, length: 40 } }),
31
+ catRepo.create({ name: 'Garfield', color: 'ginger', age: 5, size: { height: 30, width: 15, length: 45 } }),
32
+ catRepo.create({ name: 'Shadow', color: 'black', age: 4, size: { height: 25, width: 10, length: 50 } }),
33
+ catRepo.create({ name: 'George', color: 'white', age: 3, size: { height: 35, width: 12, length: 40 } }),
34
+ catRepo.create({ name: 'Leche', color: 'white', age: null, size: { height: 10, width: 5, length: 15 } }),
35
35
  ]);
36
36
  catToys = await catToyRepo.save([
37
- catToyRepo.create({ name: 'Fuzzy Thing', cat: cats[0] }),
38
- catToyRepo.create({ name: 'Stuffed Mouse', cat: cats[0] }),
39
- catToyRepo.create({ name: 'Mouse', cat: cats[0] }),
40
- catToyRepo.create({ name: 'String', cat: cats[1] }),
37
+ catToyRepo.create({ name: 'Fuzzy Thing', cat: cats[0], size: { height: 10, width: 10, length: 10 } }),
38
+ catToyRepo.create({ name: 'Stuffed Mouse', cat: cats[0], size: { height: 5, width: 5, length: 12 } }),
39
+ catToyRepo.create({ name: 'Mouse', cat: cats[0], size: { height: 6, width: 4, length: 13 } }),
40
+ catToyRepo.create({ name: 'String', cat: cats[1], size: { height: 1, width: 1, length: 50 } }),
41
41
  ]);
42
42
  catHomes = await catHomeRepo.save([
43
43
  catHomeRepo.create({ name: 'Box', cat: cats[0] }),
@@ -130,6 +130,58 @@ describe('paginate', () => {
130
130
  expect(links.next).toBe('?page=3&limit=2&sortBy=id:ASC');
131
131
  expect(links.last).toBe('?page=3&limit=2&sortBy=id:ASC');
132
132
  });
133
+ it('should return a relative path', async () => {
134
+ const config = {
135
+ sortableColumns: ['id'],
136
+ relativePath: true,
137
+ };
138
+ const query = {
139
+ path: 'http://localhost/cats',
140
+ page: 2,
141
+ limit: 2,
142
+ };
143
+ const { links } = await (0, paginate_1.paginate)(query, catRepo, config);
144
+ expect(links.first).toBe('/cats?page=1&limit=2&sortBy=id:ASC');
145
+ expect(links.previous).toBe('/cats?page=1&limit=2&sortBy=id:ASC');
146
+ expect(links.current).toBe('/cats?page=2&limit=2&sortBy=id:ASC');
147
+ expect(links.next).toBe('/cats?page=3&limit=2&sortBy=id:ASC');
148
+ expect(links.last).toBe('/cats?page=3&limit=2&sortBy=id:ASC');
149
+ });
150
+ it('should return an absolute path', async () => {
151
+ const config = {
152
+ sortableColumns: ['id'],
153
+ relativePath: false,
154
+ };
155
+ const query = {
156
+ path: 'http://localhost/cats',
157
+ page: 2,
158
+ limit: 2,
159
+ };
160
+ const { links } = await (0, paginate_1.paginate)(query, catRepo, config);
161
+ expect(links.first).toBe('http://localhost/cats?page=1&limit=2&sortBy=id:ASC');
162
+ expect(links.previous).toBe('http://localhost/cats?page=1&limit=2&sortBy=id:ASC');
163
+ expect(links.current).toBe('http://localhost/cats?page=2&limit=2&sortBy=id:ASC');
164
+ expect(links.next).toBe('http://localhost/cats?page=3&limit=2&sortBy=id:ASC');
165
+ expect(links.last).toBe('http://localhost/cats?page=3&limit=2&sortBy=id:ASC');
166
+ });
167
+ it('should return an absolute path with new origin', async () => {
168
+ const config = {
169
+ sortableColumns: ['id'],
170
+ relativePath: false,
171
+ origin: 'http://cats.example',
172
+ };
173
+ const query = {
174
+ path: 'http://localhost/cats',
175
+ page: 2,
176
+ limit: 2,
177
+ };
178
+ const { links } = await (0, paginate_1.paginate)(query, catRepo, config);
179
+ expect(links.first).toBe('http://cats.example/cats?page=1&limit=2&sortBy=id:ASC');
180
+ expect(links.previous).toBe('http://cats.example/cats?page=1&limit=2&sortBy=id:ASC');
181
+ expect(links.current).toBe('http://cats.example/cats?page=2&limit=2&sortBy=id:ASC');
182
+ expect(links.next).toBe('http://cats.example/cats?page=3&limit=2&sortBy=id:ASC');
183
+ expect(links.last).toBe('http://cats.example/cats?page=3&limit=2&sortBy=id:ASC');
184
+ });
133
185
  it('should return only current link if zero results', async () => {
134
186
  const config = {
135
187
  sortableColumns: ['id'],
@@ -472,7 +524,7 @@ describe('paginate', () => {
472
524
  relations: ['cat'],
473
525
  sortableColumns: ['id', 'name'],
474
526
  filterableColumns: {
475
- createdAt: [paginate_1.FilterOperator.BTW],
527
+ 'cat.age': [paginate_1.FilterOperator.BTW],
476
528
  },
477
529
  };
478
530
  const query = {
@@ -485,9 +537,381 @@ describe('paginate', () => {
485
537
  expect(result.meta.filter).toStrictEqual({
486
538
  'cat.age': '$btw:6,10',
487
539
  });
488
- expect(result.data).toStrictEqual([catHomes[0], catHomes[1]]);
540
+ expect(result.data).toStrictEqual([catHomes[0]]);
489
541
  expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.age=$btw:6,10');
490
542
  });
543
+ it('should return result based on sort on embedded entity', async () => {
544
+ const config = {
545
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
546
+ searchableColumns: ['name'],
547
+ };
548
+ const query = {
549
+ path: '',
550
+ sortBy: [
551
+ ['size.height', 'ASC'],
552
+ ['size.length', 'ASC'],
553
+ ],
554
+ };
555
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
556
+ const orderedCats = [cats[4], cats[0], cats[2], cats[1], cats[3]];
557
+ expect(result.data).toStrictEqual(orderedCats);
558
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=size.height:ASC&sortBy=size.length:ASC');
559
+ });
560
+ it('should return result based on sort on embedded entity when other relations loaded', async () => {
561
+ const config = {
562
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
563
+ searchableColumns: ['name'],
564
+ relations: ['home', 'toys'],
565
+ };
566
+ const query = {
567
+ path: '',
568
+ sortBy: [
569
+ ['size.height', 'DESC'],
570
+ ['size.length', 'DESC'],
571
+ ],
572
+ };
573
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
574
+ const copyCats = cats.map((cat) => {
575
+ const copy = (0, lodash_1.clone)(cat);
576
+ copy.home = null;
577
+ copy.toys = [];
578
+ return copy;
579
+ });
580
+ const copyHomes = catHomes.map((home) => {
581
+ const copy = (0, lodash_1.clone)(home);
582
+ delete copy.cat;
583
+ return copy;
584
+ });
585
+ copyCats[0].home = copyHomes[0];
586
+ copyCats[1].home = copyHomes[1];
587
+ const copyToys = catToys.map((toy) => {
588
+ const copy = (0, lodash_1.clone)(toy);
589
+ delete copy.cat;
590
+ return copy;
591
+ });
592
+ copyCats[0].toys = [copyToys[0], copyToys[1], copyToys[2]];
593
+ copyCats[1].toys = [copyToys[3]];
594
+ const orderedCats = [copyCats[3], copyCats[1], copyCats[2], copyCats[0], copyCats[4]];
595
+ expect(result.data).toStrictEqual(orderedCats);
596
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=size.height:DESC&sortBy=size.length:DESC');
597
+ });
598
+ it('should return result based on sort on embedded entity on one-to-many relation', async () => {
599
+ const config = {
600
+ sortableColumns: ['id', 'name', 'toys.size.height', 'toys.size.length', 'toys.size.width'],
601
+ searchableColumns: ['name'],
602
+ relations: ['toys'],
603
+ };
604
+ const query = {
605
+ path: '',
606
+ sortBy: [
607
+ ['id', 'DESC'],
608
+ ['toys.size.height', 'ASC'],
609
+ ['toys.size.length', 'ASC'],
610
+ ],
611
+ };
612
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
613
+ const toy0 = (0, lodash_1.clone)(catToys[0]);
614
+ delete toy0.cat;
615
+ const toy1 = (0, lodash_1.clone)(catToys[1]);
616
+ delete toy1.cat;
617
+ const toy2 = (0, lodash_1.clone)(catToys[2]);
618
+ delete toy2.cat;
619
+ const toy3 = (0, lodash_1.clone)(catToys[3]);
620
+ delete toy3.cat;
621
+ const orderedCats = [
622
+ Object.assign((0, lodash_1.clone)(cats[4]), { toys: [] }),
623
+ Object.assign((0, lodash_1.clone)(cats[3]), { toys: [] }),
624
+ Object.assign((0, lodash_1.clone)(cats[2]), { toys: [] }),
625
+ Object.assign((0, lodash_1.clone)(cats[1]), { toys: [toy3] }),
626
+ Object.assign((0, lodash_1.clone)(cats[0]), { toys: [toy1, toy2, toy0] }),
627
+ ];
628
+ expect(result.data).toStrictEqual(orderedCats);
629
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:DESC&sortBy=toys.size.height:ASC&sortBy=toys.size.length:ASC');
630
+ });
631
+ it('should return result based on sort on embedded entity on many-to-one relation', async () => {
632
+ const config = {
633
+ sortableColumns: ['id', 'name', 'cat.size.height', 'cat.size.length', 'cat.size.width'],
634
+ searchableColumns: ['name'],
635
+ relations: ['cat'],
636
+ };
637
+ const query = {
638
+ path: '',
639
+ sortBy: [
640
+ ['cat.size.height', 'DESC'],
641
+ ['cat.size.length', 'DESC'],
642
+ ['name', 'ASC'],
643
+ ],
644
+ };
645
+ const result = await (0, paginate_1.paginate)(query, catToyRepo, config);
646
+ const orderedToys = [catToys[3], catToys[0], catToys[2], catToys[1]];
647
+ expect(result.data).toStrictEqual(orderedToys);
648
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=cat.size.height:DESC&sortBy=cat.size.length:DESC&sortBy=name:ASC');
649
+ });
650
+ it('should return result based on sort on embedded entity on one-to-one relation', async () => {
651
+ const config = {
652
+ sortableColumns: ['id', 'name', 'cat.size.height', 'cat.size.length', 'cat.size.width'],
653
+ searchableColumns: ['name'],
654
+ relations: ['cat'],
655
+ };
656
+ const query = {
657
+ path: '',
658
+ sortBy: [['cat.size.height', 'DESC']],
659
+ };
660
+ const result = await (0, paginate_1.paginate)(query, catHomeRepo, config);
661
+ const orderedHomes = [catHomes[1], catHomes[0]];
662
+ expect(result.data).toStrictEqual(orderedHomes);
663
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=cat.size.height:DESC');
664
+ });
665
+ it('should return result based on search on embedded entity', async () => {
666
+ const config = {
667
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
668
+ searchableColumns: ['size.height'],
669
+ };
670
+ const query = {
671
+ path: '',
672
+ search: '10',
673
+ };
674
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
675
+ expect(result.data).toStrictEqual([cats[4]]);
676
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=10');
677
+ });
678
+ it('should return result based on search term on embedded entity when other relations loaded', async () => {
679
+ const config = {
680
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
681
+ searchableColumns: ['size.height'],
682
+ relations: ['home', 'toys'],
683
+ };
684
+ const query = {
685
+ path: '',
686
+ search: '10',
687
+ };
688
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
689
+ expect(result.meta.search).toStrictEqual('10');
690
+ const copyCat = (0, lodash_1.clone)(cats[4]);
691
+ copyCat.home = null;
692
+ copyCat.toys = [];
693
+ expect(result.data).toStrictEqual([copyCat]);
694
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=10');
695
+ });
696
+ it('should return result based on search term on embedded entity on many-to-one relation', async () => {
697
+ const config = {
698
+ sortableColumns: ['id', 'name', 'cat.size.height', 'cat.size.length', 'cat.size.width'],
699
+ searchableColumns: ['cat.size.height'],
700
+ relations: ['cat'],
701
+ };
702
+ const query = {
703
+ path: '',
704
+ search: '30',
705
+ };
706
+ const result = await (0, paginate_1.paginate)(query, catToyRepo, config);
707
+ expect(result.meta.search).toStrictEqual('30');
708
+ expect(result.data).toStrictEqual([catToys[3]]);
709
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=30');
710
+ });
711
+ it('should return result based on search term on embedded entity on one-to-many relation', async () => {
712
+ const config = {
713
+ sortableColumns: ['id', 'name', 'toys.size.height', 'toys.size.length', 'toys.size.width'],
714
+ searchableColumns: ['toys.size.height'],
715
+ relations: ['toys'],
716
+ };
717
+ const query = {
718
+ path: '',
719
+ search: '1',
720
+ };
721
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
722
+ const toy0 = (0, lodash_1.clone)(catToys[0]);
723
+ delete toy0.cat;
724
+ const toy3 = (0, lodash_1.clone)(catToys[3]);
725
+ delete toy3.cat;
726
+ expect(result.data).toStrictEqual([
727
+ Object.assign((0, lodash_1.clone)(cats[0]), { toys: [toy0] }),
728
+ Object.assign((0, lodash_1.clone)(cats[1]), { toys: [toy3] }),
729
+ ]);
730
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=1');
731
+ });
732
+ it('should return result based on search term on embedded entity on one-to-one relation', async () => {
733
+ const config = {
734
+ sortableColumns: ['id', 'name', 'cat.size.height', 'cat.size.length', 'cat.size.width'],
735
+ searchableColumns: ['cat.size.height'],
736
+ relations: ['cat'],
737
+ };
738
+ const query = {
739
+ path: '',
740
+ search: '30',
741
+ };
742
+ const result = await (0, paginate_1.paginate)(query, catHomeRepo, config);
743
+ expect(result.data).toStrictEqual([catHomes[1]]);
744
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=30');
745
+ });
746
+ it('should return result based on sort and search on embedded many-to-one relation', async () => {
747
+ const config = {
748
+ sortableColumns: ['id', 'name', 'cat.size.height', 'cat.size.length', 'cat.size.width'],
749
+ searchableColumns: ['cat.size.width'],
750
+ relations: ['cat'],
751
+ };
752
+ const query = {
753
+ path: '',
754
+ search: '1',
755
+ sortBy: [['cat.size.height', 'DESC']],
756
+ };
757
+ const result = await (0, paginate_1.paginate)(query, catToyRepo, config);
758
+ expect(result.meta.search).toStrictEqual('1');
759
+ expect(result.data).toStrictEqual([catToys[3], catToys[0], catToys[1], catToys[2]]);
760
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=cat.size.height:DESC&search=1');
761
+ });
762
+ it('should return result based on filter on embedded entity', async () => {
763
+ const config = {
764
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
765
+ searchableColumns: ['size.height'],
766
+ filterableColumns: {
767
+ 'size.height': [paginate_1.FilterOperator.NOT],
768
+ },
769
+ };
770
+ const query = {
771
+ path: '',
772
+ filter: {
773
+ 'size.height': '$not:25',
774
+ },
775
+ };
776
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
777
+ expect(result.data).toStrictEqual([cats[1], cats[3], cats[4]]);
778
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.size.height=$not:25');
779
+ });
780
+ it('should return result based on filter on embedded entity when other relations loaded', async () => {
781
+ const config = {
782
+ sortableColumns: ['id', 'name', 'size.height', 'size.length', 'size.width'],
783
+ searchableColumns: ['size.height'],
784
+ filterableColumns: {
785
+ 'size.height': [paginate_1.FilterOperator.NOT],
786
+ },
787
+ relations: ['home'],
788
+ };
789
+ const query = {
790
+ path: '',
791
+ filter: {
792
+ 'size.height': '$not:25',
793
+ },
794
+ };
795
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
796
+ const home = (0, lodash_1.clone)(catHomes[1]);
797
+ delete home.cat;
798
+ const copyCats = [
799
+ Object.assign((0, lodash_1.clone)(cats[1]), { home: home }),
800
+ Object.assign((0, lodash_1.clone)(cats[3]), { home: null }),
801
+ Object.assign((0, lodash_1.clone)(cats[4]), { home: null }),
802
+ ];
803
+ expect(result.data).toStrictEqual(copyCats);
804
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.size.height=$not:25');
805
+ });
806
+ it('should return result based on filter on embedded on many-to-one relation', async () => {
807
+ const config = {
808
+ relations: ['cat'],
809
+ sortableColumns: ['id', 'name'],
810
+ filterableColumns: {
811
+ 'cat.size.height': [paginate_1.FilterOperator.NOT],
812
+ },
813
+ };
814
+ const query = {
815
+ path: '',
816
+ filter: {
817
+ 'cat.size.height': '$not:25',
818
+ },
819
+ };
820
+ const result = await (0, paginate_1.paginate)(query, catToyRepo, config);
821
+ expect(result.meta.filter).toStrictEqual({
822
+ 'cat.size.height': '$not:25',
823
+ });
824
+ expect(result.data).toStrictEqual([catToys[3]]);
825
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.size.height=$not:25');
826
+ });
827
+ it('should return result based on filter on embedded on one-to-many relation', async () => {
828
+ const config = {
829
+ relations: ['toys'],
830
+ sortableColumns: ['id', 'name'],
831
+ filterableColumns: {
832
+ 'toys.size.height': [paginate_1.FilterOperator.EQ],
833
+ },
834
+ };
835
+ const query = {
836
+ path: '',
837
+ filter: {
838
+ 'toys.size.height': '$eq:1',
839
+ },
840
+ };
841
+ const result = await (0, paginate_1.paginate)(query, catRepo, config);
842
+ const cat2 = (0, lodash_1.clone)(cats[1]);
843
+ const catToys3 = (0, lodash_1.clone)(catToys[3]);
844
+ delete catToys3.cat;
845
+ cat2.toys = [catToys3];
846
+ expect(result.meta.filter).toStrictEqual({
847
+ 'toys.size.height': '$eq:1',
848
+ });
849
+ expect(result.data).toStrictEqual([cat2]);
850
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.toys.size.height=$eq:1');
851
+ });
852
+ it('should return result based on filter on embedded on one-to-one relation', async () => {
853
+ const config = {
854
+ relations: ['cat'],
855
+ sortableColumns: ['id', 'name'],
856
+ filterableColumns: {
857
+ 'cat.size.height': [paginate_1.FilterOperator.EQ],
858
+ },
859
+ };
860
+ const query = {
861
+ path: '',
862
+ filter: {
863
+ 'cat.size.height': '$eq:30',
864
+ },
865
+ };
866
+ const result = await (0, paginate_1.paginate)(query, catHomeRepo, config);
867
+ expect(result.meta.filter).toStrictEqual({
868
+ 'cat.size.height': '$eq:30',
869
+ });
870
+ expect(result.data).toStrictEqual([catHomes[1]]);
871
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.size.height=$eq:30');
872
+ });
873
+ it('should return result based on $in filter on embedded on one-to-one relation', async () => {
874
+ const config = {
875
+ relations: ['cat'],
876
+ sortableColumns: ['id', 'name'],
877
+ filterableColumns: {
878
+ 'cat.size.height': [paginate_1.FilterOperator.IN],
879
+ },
880
+ };
881
+ const query = {
882
+ path: '',
883
+ filter: {
884
+ 'cat.size.height': '$in:10,30,35',
885
+ },
886
+ };
887
+ const result = await (0, paginate_1.paginate)(query, catHomeRepo, config);
888
+ expect(result.meta.filter).toStrictEqual({
889
+ 'cat.size.height': '$in:10,30,35',
890
+ });
891
+ expect(result.data).toStrictEqual([catHomes[1]]);
892
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.size.height=$in:10,30,35');
893
+ });
894
+ it('should return result based on $btw filter on embedded on one-to-one relation', async () => {
895
+ const config = {
896
+ relations: ['cat'],
897
+ sortableColumns: ['id', 'name'],
898
+ filterableColumns: {
899
+ 'cat.size.height': [paginate_1.FilterOperator.BTW],
900
+ },
901
+ };
902
+ const query = {
903
+ path: '',
904
+ filter: {
905
+ 'cat.size.height': '$btw:18,33',
906
+ },
907
+ };
908
+ const result = await (0, paginate_1.paginate)(query, catHomeRepo, config);
909
+ expect(result.meta.filter).toStrictEqual({
910
+ 'cat.size.height': '$btw:18,33',
911
+ });
912
+ expect(result.data).toStrictEqual([catHomes[0], catHomes[1]]);
913
+ expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.size.height=$btw:18,33');
914
+ });
491
915
  it('should return result based on where array and filter', async () => {
492
916
  const config = {
493
917
  sortableColumns: ['id'],