@@ -1156,6 +1156,10 @@ def parse(cls, location, package_only=False):
1156
1156
yield models .PackageData .from_data (package_data , package_only )
1157
1157
1158
1158
1159
+ class UnknownPnpmLockFormat (Exception ):
1160
+ pass
1161
+
1162
+
1159
1163
class BasePnpmLockHandler (BaseNpmHandler ):
1160
1164
1161
1165
@classmethod
@@ -1182,31 +1186,62 @@ def parse(cls, location, package_only=False):
1182
1186
}
1183
1187
major_v , minor_v = lockfile_version .split ("." )
1184
1188
1185
- resolved_packages = lock_data .get ("packages" , [])
1189
+ resolved_packages = lock_data .get ("packages" , {})
1190
+ dependency_relations = lock_data .get ("snapshots" , {})
1191
+ dependency_relations_by_purl = {}
1192
+ if dependency_relations :
1193
+ for purl_fields , relations in dependency_relations .items ():
1194
+ clean_purl_fields = purl_fields .split ("(" )[0 ]
1195
+ sections = clean_purl_fields .split ("/" )
1196
+ namespace = None
1197
+ if len (sections ) == 2 :
1198
+ namespace , name_version = sections
1199
+ elif len (sections ) == 1 :
1200
+ name_version , = sections
1201
+ name , version = name_version .split ("@" )
1202
+
1203
+ purl = PackageURL (
1204
+ type = cls .default_package_type ,
1205
+ name = name ,
1206
+ namespace = namespace ,
1207
+ version = version ,
1208
+ ).to_string ()
1209
+ dependency_relations_by_purl [purl ] = relations
1210
+
1186
1211
dependencies_by_purl = {}
1187
1212
1188
1213
for purl_fields , data in resolved_packages .items ():
1189
1214
if major_v == "6" :
1190
1215
clean_purl_fields = purl_fields .split ("(" )[0 ]
1191
1216
elif major_v == "5" or is_shrinkwrap :
1192
1217
clean_purl_fields = purl_fields .split ("_" )[0 ]
1193
- else :
1218
+ elif major_v == "9" :
1194
1219
clean_purl_fields = purl_fields
1195
- raise Exception (lockfile_version , purl_fields )
1220
+ else :
1221
+ message = f"Unknown pnpm lockfile format: { lockfile_version } "
1222
+ raise UnknownPnpmLockFormat (message , purl_fields )
1196
1223
1197
1224
sections = clean_purl_fields .split ("/" )
1198
- name_version = None
1225
+ name_version = None
1226
+ namespace = None
1199
1227
if major_v == "6" :
1200
1228
if len (sections ) == 2 :
1201
- namespace = None
1202
1229
_ , name_version = sections
1203
1230
elif len (sections ) == 3 :
1204
1231
_ , namespace , name_version = sections
1232
+ elif len (sections ) == 1 :
1233
+ name_version , = sections
1234
+
1235
+ name , version = name_version .split ("@" )
1236
+ elif major_v == "9" :
1237
+ if len (sections ) == 2 :
1238
+ namespace , name_version = sections
1239
+ elif len (sections ) == 1 :
1240
+ name_version , = sections
1205
1241
1206
1242
name , version = name_version .split ("@" )
1207
1243
elif major_v == "5" or is_shrinkwrap :
1208
1244
if len (sections ) == 3 :
1209
- namespace = None
1210
1245
_ , name , version = sections
1211
1246
elif len (sections ) == 4 :
1212
1247
_ , namespace , name , version = sections
@@ -1224,7 +1259,21 @@ def parse(cls, location, package_only=False):
1224
1259
1225
1260
dependencies = data .get ('dependencies' ) or {}
1226
1261
optional_dependencies = data .get ('optionalDependencies' ) or {}
1227
- transitive_peer_dependencies = data .get ('transitivePeerDependencies' ) or {}
1262
+ transitive_peer_dependencies = data .get ('transitivePeerDependencies' ) or []
1263
+
1264
+ if purl in dependency_relations_by_purl :
1265
+ dependency_relations = dependency_relations_by_purl .get (purl )
1266
+ if dependency_relations :
1267
+ deps = dependency_relations .get ('dependencies' )
1268
+ if deps :
1269
+ dependencies .update (deps )
1270
+ optional_deps = dependency_relations .get ('optionalDependencies' )
1271
+ if optional_deps :
1272
+ optional_dependencies .update (optional_deps )
1273
+ transitive_peer_deps = dependency_relations .get ('transitivePeerDependencies' )
1274
+ if transitive_peer_deps :
1275
+ transitive_peer_dependencies .extend (transitive_peer_deps )
1276
+
1228
1277
peer_dependencies = data .get ('peerDependencies' ) or {}
1229
1278
peer_dependencies_meta = data .get ('peerDependenciesMeta' ) or {}
1230
1279
0 commit comments