@teambit/pnpm 1.0.1295 → 1.0.1296

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.
@@ -663,6 +663,441 @@ describe('convertLockfileToGraph with directory packages missing from componentI
663
663
  }) => id.includes('@file:'))).to.equal(undefined);
664
664
  });
665
665
  });
666
+ describe('convertLockfileToGraph when the root importer or snapshot lacks the component', () => {
667
+ it('should fall back to the component importer when the root importer is missing the component entry', () => {
668
+ const lockfile = {
669
+ bit: {
670
+ depsRequiringBuild: []
671
+ },
672
+ importers: {
673
+ '.': {},
674
+ 'node_modules/.bit_roots/env': {
675
+ // dependencies is undefined (or missing comp1)
676
+ },
677
+ 'comps/comp1': {
678
+ dependencies: {
679
+ foo: {
680
+ version: '1.0.0',
681
+ specifier: '^1.0.0'
682
+ }
683
+ }
684
+ }
685
+ },
686
+ lockfileVersion: '9.0',
687
+ snapshots: {
688
+ 'foo@1.0.0': {}
689
+ },
690
+ packages: {
691
+ 'foo@1.0.0': {
692
+ resolution: {
693
+ integrity: 'sha512-aaa'
694
+ }
695
+ }
696
+ }
697
+ };
698
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
699
+ pkgName: 'comp1',
700
+ componentRelativeDir: 'comps/comp1',
701
+ componentRootDir: 'node_modules/.bit_roots/env',
702
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')]])
703
+ });
704
+ const rootEdge = graph.findRootEdge();
705
+ (0, _chai().expect)(rootEdge?.neighbours).to.eql([{
706
+ name: 'foo',
707
+ specifier: '^1.0.0',
708
+ id: 'foo@1.0.0',
709
+ lifecycle: 'runtime',
710
+ optional: false
711
+ }]);
712
+ });
713
+ it('should fall back to the component importer when the locked snapshot is missing from snapshots', () => {
714
+ const lockfile = {
715
+ bit: {
716
+ depsRequiringBuild: []
717
+ },
718
+ importers: {
719
+ '.': {},
720
+ 'node_modules/.bit_roots/env': {
721
+ dependencies: {
722
+ comp1: {
723
+ version: 'file:comps/comp1',
724
+ specifier: '*'
725
+ }
726
+ }
727
+ },
728
+ 'comps/comp1': {
729
+ dependencies: {
730
+ foo: {
731
+ version: '1.0.0',
732
+ specifier: '^1.0.0'
733
+ }
734
+ }
735
+ }
736
+ },
737
+ lockfileVersion: '9.0',
738
+ snapshots: {
739
+ 'foo@1.0.0': {}
740
+ },
741
+ packages: {
742
+ 'foo@1.0.0': {
743
+ resolution: {
744
+ integrity: 'sha512-aaa'
745
+ }
746
+ }
747
+ }
748
+ };
749
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
750
+ pkgName: 'comp1',
751
+ componentRelativeDir: 'comps/comp1',
752
+ componentRootDir: 'node_modules/.bit_roots/env',
753
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')]])
754
+ });
755
+ const rootEdge = graph.findRootEdge();
756
+ (0, _chai().expect)(rootEdge?.neighbours).to.eql([{
757
+ name: 'foo',
758
+ specifier: '^1.0.0',
759
+ id: 'foo@1.0.0',
760
+ lifecycle: 'runtime',
761
+ optional: false
762
+ }]);
763
+ });
764
+ it('should scrub the component itself and circular back-edges when falling back to the component importer', () => {
765
+ const lockfile = {
766
+ bit: {
767
+ depsRequiringBuild: []
768
+ },
769
+ importers: {
770
+ '.': {},
771
+ 'node_modules/.bit_roots/env': {},
772
+ 'comps/comp1': {
773
+ dependencies: {
774
+ comp2: {
775
+ version: 'file:comps/comp2',
776
+ specifier: '*'
777
+ }
778
+ }
779
+ },
780
+ 'comps/comp2': {
781
+ dependencies: {
782
+ comp1: {
783
+ version: 'file:comps/comp1',
784
+ specifier: '*'
785
+ }
786
+ }
787
+ }
788
+ },
789
+ lockfileVersion: '9.0',
790
+ snapshots: {
791
+ 'comp1@file:comps/comp1': {
792
+ dependencies: {
793
+ comp2: 'file:comps/comp2'
794
+ }
795
+ },
796
+ 'comp2@file:comps/comp2': {
797
+ dependencies: {
798
+ comp1: 'file:comps/comp1'
799
+ }
800
+ }
801
+ },
802
+ packages: {
803
+ 'comp1@file:comps/comp1': {
804
+ resolution: {
805
+ directory: 'comps/comp1',
806
+ type: 'directory'
807
+ }
808
+ },
809
+ 'comp2@file:comps/comp2': {
810
+ resolution: {
811
+ directory: 'comps/comp2',
812
+ type: 'directory'
813
+ }
814
+ }
815
+ }
816
+ };
817
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
818
+ pkgName: 'comp1',
819
+ componentRelativeDir: 'comps/comp1',
820
+ componentRootDir: 'node_modules/.bit_roots/env',
821
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')], ['comp2', _component().ComponentID.fromString('my-scope/comp2@1.0.0')]])
822
+ });
823
+ const referencingComp1 = graph.edges.filter(edge => edge.neighbours.some(n => n.id === 'comp1@1.0.0'));
824
+ (0, _chai().expect)(referencingComp1).to.eql([]);
825
+ (0, _chai().expect)(Array.from(graph.packages.keys())).to.not.include('comp1@1.0.0');
826
+ });
827
+ it('should scrub circular back-edges even when the component snapshot itself is missing', () => {
828
+ const lockfile = {
829
+ bit: {
830
+ depsRequiringBuild: []
831
+ },
832
+ importers: {
833
+ '.': {},
834
+ 'node_modules/.bit_roots/env': {
835
+ dependencies: {
836
+ comp1: {
837
+ version: 'file:comps/comp1',
838
+ specifier: '*'
839
+ }
840
+ }
841
+ },
842
+ 'comps/comp1': {
843
+ dependencies: {
844
+ comp2: {
845
+ version: 'file:comps/comp2',
846
+ specifier: '*'
847
+ }
848
+ }
849
+ }
850
+ },
851
+ lockfileVersion: '9.0',
852
+ snapshots: {
853
+ 'comp2@file:comps/comp2': {
854
+ dependencies: {
855
+ comp1: 'file:comps/comp1'
856
+ }
857
+ }
858
+ },
859
+ packages: {
860
+ 'comp2@file:comps/comp2': {
861
+ resolution: {
862
+ directory: 'comps/comp2',
863
+ type: 'directory'
864
+ }
865
+ }
866
+ }
867
+ };
868
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
869
+ pkgName: 'comp1',
870
+ componentRelativeDir: 'comps/comp1',
871
+ componentRootDir: 'node_modules/.bit_roots/env',
872
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')], ['comp2', _component().ComponentID.fromString('my-scope/comp2@1.0.0')]])
873
+ });
874
+ const referencingComp1 = graph.edges.filter(edge => edge.neighbours.some(n => n.id === 'comp1@1.0.0'));
875
+ (0, _chai().expect)(referencingComp1).to.eql([]);
876
+ (0, _chai().expect)(Array.from(graph.packages.keys())).to.not.include('comp1@1.0.0');
877
+ });
878
+ it('should not include packages reachable only from the root importer when falling back to the component importer', () => {
879
+ const lockfile = {
880
+ bit: {
881
+ depsRequiringBuild: []
882
+ },
883
+ importers: {
884
+ 'node_modules/.bit_roots/env': {
885
+ dependencies: {
886
+ 'root-only-pkg': {
887
+ version: '2.0.0',
888
+ specifier: '^2.0.0'
889
+ }
890
+ }
891
+ },
892
+ 'comps/comp1': {
893
+ dependencies: {
894
+ foo: {
895
+ version: '1.0.0',
896
+ specifier: '^1.0.0'
897
+ }
898
+ }
899
+ }
900
+ },
901
+ lockfileVersion: '9.0',
902
+ snapshots: {
903
+ 'foo@1.0.0': {},
904
+ 'root-only-pkg@2.0.0': {}
905
+ },
906
+ packages: {
907
+ 'foo@1.0.0': {
908
+ resolution: {
909
+ integrity: 'sha512-aaa'
910
+ }
911
+ },
912
+ 'root-only-pkg@2.0.0': {
913
+ resolution: {
914
+ integrity: 'sha512-bbb'
915
+ }
916
+ }
917
+ }
918
+ };
919
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
920
+ pkgName: 'comp1',
921
+ componentRelativeDir: 'comps/comp1',
922
+ componentRootDir: 'node_modules/.bit_roots/env',
923
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')]])
924
+ });
925
+ (0, _chai().expect)(Array.from(graph.packages.keys())).to.eql(['foo@1.0.0']);
926
+ });
927
+ it('should not mutate the caller lockfile when converting without a root importer', () => {
928
+ const lockfile = {
929
+ bit: {
930
+ depsRequiringBuild: []
931
+ },
932
+ importers: {
933
+ 'comps/comp1': {
934
+ dependencies: {
935
+ comp2: {
936
+ version: 'file:comps/comp2',
937
+ specifier: '*'
938
+ }
939
+ }
940
+ },
941
+ 'comps/comp2': {
942
+ dependencies: {
943
+ comp1: {
944
+ version: 'file:comps/comp1',
945
+ specifier: '*'
946
+ }
947
+ }
948
+ }
949
+ },
950
+ lockfileVersion: '9.0',
951
+ snapshots: {
952
+ 'comp1@file:comps/comp1': {
953
+ dependencies: {
954
+ comp2: 'file:comps/comp2'
955
+ }
956
+ },
957
+ 'comp2@file:comps/comp2': {
958
+ dependencies: {
959
+ comp1: 'file:comps/comp1'
960
+ }
961
+ }
962
+ },
963
+ packages: {
964
+ 'comp1@file:comps/comp1': {
965
+ resolution: {
966
+ directory: 'comps/comp1',
967
+ type: 'directory'
968
+ }
969
+ },
970
+ 'comp2@file:comps/comp2': {
971
+ resolution: {
972
+ directory: 'comps/comp2',
973
+ type: 'directory'
974
+ }
975
+ }
976
+ }
977
+ };
978
+ const componentIdByPkgName = new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')], ['comp2', _component().ComponentID.fromString('my-scope/comp2@1.0.0')]]);
979
+ (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
980
+ pkgName: 'comp1',
981
+ componentRelativeDir: 'comps/comp1',
982
+ componentIdByPkgName
983
+ });
984
+ const graph2 = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(lockfile, {
985
+ pkgName: 'comp2',
986
+ componentRelativeDir: 'comps/comp2',
987
+ componentIdByPkgName
988
+ });
989
+ (0, _chai().expect)(Array.from(graph2.packages.keys())).to.eql(['comp1@1.0.0']);
990
+ });
991
+ });
992
+ describe('filterLockfileByImporters', () => {
993
+ it('should narrow packages and snapshots to the transitive closure of the requested importers without mutating the source lockfile', () => {
994
+ const lockfile = {
995
+ lockfileVersion: '9.0',
996
+ importers: {
997
+ 'comps/comp1': {
998
+ dependencies: {
999
+ foo: {
1000
+ version: '1.0.0(bar@1.0.0)',
1001
+ specifier: '^1.0.0'
1002
+ }
1003
+ }
1004
+ },
1005
+ 'comps/comp2': {
1006
+ dependencies: {
1007
+ unreached: {
1008
+ version: '1.0.0',
1009
+ specifier: '^1.0.0'
1010
+ }
1011
+ }
1012
+ }
1013
+ },
1014
+ packages: {
1015
+ 'foo@1.0.0': {
1016
+ resolution: {
1017
+ integrity: 'sha512-foo'
1018
+ }
1019
+ },
1020
+ 'bar@1.0.0': {
1021
+ resolution: {
1022
+ integrity: 'sha512-bar'
1023
+ }
1024
+ },
1025
+ 'baz@1.0.0': {
1026
+ resolution: {
1027
+ integrity: 'sha512-baz'
1028
+ }
1029
+ },
1030
+ 'unreached@1.0.0': {
1031
+ resolution: {
1032
+ integrity: 'sha512-unreached'
1033
+ }
1034
+ }
1035
+ },
1036
+ snapshots: {
1037
+ 'foo@1.0.0(bar@1.0.0)': {
1038
+ dependencies: {
1039
+ bar: '1.0.0'
1040
+ },
1041
+ optionalDependencies: {
1042
+ baz: '1.0.0'
1043
+ }
1044
+ },
1045
+ 'bar@1.0.0': {},
1046
+ 'baz@1.0.0': {},
1047
+ 'unreached@1.0.0': {}
1048
+ }
1049
+ };
1050
+ const filtered = (0, _lockfileDepsGraphConverter().filterLockfileByImporters)(lockfile, ['comps/comp1']);
1051
+ (0, _chai().expect)(Object.keys(filtered.packages).sort()).to.eql(['bar@1.0.0', 'baz@1.0.0', 'foo@1.0.0']);
1052
+ (0, _chai().expect)(Object.keys(filtered.snapshots).sort()).to.eql(['bar@1.0.0', 'baz@1.0.0', 'foo@1.0.0(bar@1.0.0)']);
1053
+ (0, _chai().expect)(Object.keys(filtered.importers)).to.eql(['comps/comp1']);
1054
+
1055
+ // Mutating filtered snapshots/packages must not mutate the original lockfile
1056
+ delete filtered.snapshots['foo@1.0.0(bar@1.0.0)'].dependencies.bar;
1057
+ (0, _chai().expect)(lockfile.snapshots['foo@1.0.0(bar@1.0.0)'].dependencies.bar).to.equal('1.0.0');
1058
+ });
1059
+ it('should retain package metadata for a reached dependency even when its snapshot is absent', () => {
1060
+ const lockfile = {
1061
+ lockfileVersion: '9.0',
1062
+ importers: {
1063
+ 'comps/comp1': {
1064
+ dependencies: {
1065
+ foo: {
1066
+ version: '1.0.0',
1067
+ specifier: '^1.0.0'
1068
+ }
1069
+ }
1070
+ }
1071
+ },
1072
+ packages: {
1073
+ 'foo@1.0.0': {
1074
+ resolution: {
1075
+ integrity: 'sha512-foo'
1076
+ }
1077
+ }
1078
+ },
1079
+ snapshots: {}
1080
+ };
1081
+ const filtered = (0, _lockfileDepsGraphConverter().filterLockfileByImporters)(lockfile, ['comps/comp1']);
1082
+ (0, _chai().expect)(filtered.packages).to.eql({
1083
+ 'foo@1.0.0': {
1084
+ resolution: {
1085
+ integrity: 'sha512-foo'
1086
+ }
1087
+ }
1088
+ });
1089
+ const graph = (0, _lockfileDepsGraphConverter().convertLockfileToGraph)(filtered, {
1090
+ pkgName: 'comp1',
1091
+ componentRelativeDir: 'comps/comp1',
1092
+ componentIdByPkgName: new Map([['comp1', _component().ComponentID.fromString('my-scope/comp1@1.0.0')]])
1093
+ });
1094
+ (0, _chai().expect)(graph.packages.get('foo@1.0.0')).to.eql({
1095
+ resolution: {
1096
+ integrity: 'sha512-foo'
1097
+ }
1098
+ });
1099
+ });
1100
+ });
666
1101
  describe('convertLockfileToGraph benchmark', () => {
667
1102
  function generateLargeLockfile(numPackages, numComponents) {
668
1103
  const snapshots = {};