@getcodesentinel/codesentinel 1.9.4 → 1.9.5

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.
package/dist/index.js CHANGED
@@ -254,6 +254,46 @@ var DEFAULT_EXTERNAL_ANALYSIS_CONFIG = {
254
254
  maxHighRiskDependencies: 100,
255
255
  metadataRequestConcurrency: 8
256
256
  };
257
+ var mapWithConcurrency = async (values, limit, handler) => {
258
+ const effectiveLimit = Math.max(1, limit);
259
+ const workerCount = Math.min(effectiveLimit, values.length);
260
+ const results = new Array(values.length);
261
+ let index = 0;
262
+ const workers = Array.from({ length: workerCount }, async () => {
263
+ while (true) {
264
+ const current = index;
265
+ index += 1;
266
+ if (current >= values.length) {
267
+ return;
268
+ }
269
+ const value = values[current];
270
+ if (value !== void 0) {
271
+ results[current] = await handler(value);
272
+ }
273
+ }
274
+ });
275
+ await Promise.all(workers);
276
+ return results;
277
+ };
278
+ var collectDependencyMetadata = async (extraction, metadataProvider, concurrency, onProgress) => {
279
+ const directNames = new Set(extraction.directDependencies.map((dependency) => dependency.name));
280
+ let completed = 0;
281
+ return mapWithConcurrency(extraction.nodes, concurrency, async (node) => {
282
+ const result = {
283
+ key: `${node.name}@${node.version}`,
284
+ metadata: await metadataProvider.getMetadata(node.name, node.version, {
285
+ directDependency: directNames.has(node.name)
286
+ })
287
+ };
288
+ completed += 1;
289
+ onProgress?.({
290
+ completed,
291
+ total: extraction.nodes.length,
292
+ packageName: node.name
293
+ });
294
+ return result;
295
+ });
296
+ };
257
297
  var LOCKFILE_CANDIDATES = [
258
298
  { fileName: "pnpm-lock.yaml", kind: "pnpm" },
259
299
  { fileName: "package-lock.json", kind: "npm" },
@@ -545,6 +585,24 @@ var parseYarnLock = (raw, directSpecs) => {
545
585
  var parseBunLock = (_raw, _directSpecs) => {
546
586
  throw new Error("unsupported_lockfile_format");
547
587
  };
588
+ var parseLockfileExtraction = (lockfileKind, lockfileRaw, directSpecs) => {
589
+ switch (lockfileKind) {
590
+ case "pnpm":
591
+ return parsePnpmLockfile(lockfileRaw, directSpecs);
592
+ case "npm":
593
+ case "npm-shrinkwrap":
594
+ return {
595
+ ...parsePackageLock(lockfileRaw, directSpecs),
596
+ kind: lockfileKind
597
+ };
598
+ case "yarn":
599
+ return parseYarnLock(lockfileRaw, directSpecs);
600
+ case "bun":
601
+ return parseBunLock(lockfileRaw, directSpecs);
602
+ default:
603
+ throw new Error("unsupported_lockfile_format");
604
+ }
605
+ };
548
606
  var parseRetryAfterMs = (value) => {
549
607
  if (value === null) {
550
608
  return null;
@@ -977,77 +1035,31 @@ var resolveRegistryGraphFromDirectSpecs = async (directSpecs, options) => {
977
1035
  truncated
978
1036
  };
979
1037
  };
980
- var withDefaults = (overrides) => ({
981
- ...DEFAULT_EXTERNAL_ANALYSIS_CONFIG,
982
- ...overrides
983
- });
984
- var parseExtraction = (lockfileKind, lockfileRaw, directSpecs) => {
985
- switch (lockfileKind) {
986
- case "pnpm":
987
- return parsePnpmLockfile(lockfileRaw, directSpecs);
988
- case "npm":
989
- case "npm-shrinkwrap":
990
- return {
991
- ...parsePackageLock(lockfileRaw, directSpecs),
992
- kind: lockfileKind
993
- };
994
- case "yarn":
995
- return parseYarnLock(lockfileRaw, directSpecs);
996
- case "bun":
997
- return parseBunLock(lockfileRaw, directSpecs);
998
- default:
999
- throw new Error("unsupported_lockfile_format");
1000
- }
1001
- };
1002
- var mapWithConcurrency = async (values, limit, handler) => {
1003
- const effectiveLimit = Math.max(1, limit);
1004
- const workerCount = Math.min(effectiveLimit, values.length);
1005
- const results = new Array(values.length);
1006
- let index = 0;
1007
- const workers = Array.from({ length: workerCount }, async () => {
1008
- while (true) {
1009
- const current = index;
1010
- index += 1;
1011
- if (current >= values.length) {
1012
- return;
1013
- }
1014
- const value = values[current];
1015
- if (value !== void 0) {
1016
- results[current] = await handler(value);
1017
- }
1018
- }
1019
- });
1020
- await Promise.all(workers);
1021
- return results;
1022
- };
1023
- var analyzeDependencyExposure = async (input, metadataProvider, onProgress) => {
1024
- const config = withDefaults(input.config);
1025
- const packageJson = loadPackageJson(input.repositoryPath);
1038
+ var prepareDependencyExtraction = async (repositoryPath) => {
1039
+ const packageJson = loadPackageJson(repositoryPath);
1026
1040
  if (packageJson === null) {
1027
1041
  return {
1028
- targetPath: input.repositoryPath,
1029
1042
  available: false,
1030
1043
  reason: "package_json_not_found"
1031
1044
  };
1032
1045
  }
1033
- onProgress?.({ stage: "package_json_loaded" });
1034
- try {
1035
- const directSpecs = parsePackageJson(packageJson.raw);
1036
- const lockfile = selectLockfile(input.repositoryPath);
1037
- let extraction;
1038
- if (lockfile === null) {
1039
- const resolvedGraph = await resolveRegistryGraphFromDirectSpecs(directSpecs, {
1040
- maxNodes: 500,
1041
- maxDepth: 8
1042
- });
1043
- if (resolvedGraph.nodes.length === 0) {
1044
- return {
1045
- targetPath: input.repositoryPath,
1046
- available: false,
1047
- reason: "lockfile_not_found"
1048
- };
1049
- }
1050
- extraction = {
1046
+ const directSpecs = parsePackageJson(packageJson.raw);
1047
+ const lockfile = selectLockfile(repositoryPath);
1048
+ if (lockfile === null) {
1049
+ const resolvedGraph = await resolveRegistryGraphFromDirectSpecs(directSpecs, {
1050
+ maxNodes: 500,
1051
+ maxDepth: 8
1052
+ });
1053
+ if (resolvedGraph.nodes.length === 0) {
1054
+ return {
1055
+ available: false,
1056
+ reason: "lockfile_not_found"
1057
+ };
1058
+ }
1059
+ return {
1060
+ available: true,
1061
+ lockfileKind: "npm",
1062
+ extraction: {
1051
1063
  kind: "npm",
1052
1064
  directDependencies: resolvedGraph.directDependencies.map((dependency) => ({
1053
1065
  name: dependency.name,
@@ -1055,46 +1067,61 @@ var analyzeDependencyExposure = async (input, metadataProvider, onProgress) => {
1055
1067
  scope: dependency.scope
1056
1068
  })),
1057
1069
  nodes: resolvedGraph.nodes
1070
+ }
1071
+ };
1072
+ }
1073
+ return {
1074
+ available: true,
1075
+ lockfileKind: lockfile.kind,
1076
+ extraction: parseLockfileExtraction(lockfile.kind, lockfile.raw, directSpecs)
1077
+ };
1078
+ };
1079
+ var withDefaults = (overrides) => ({
1080
+ ...DEFAULT_EXTERNAL_ANALYSIS_CONFIG,
1081
+ ...overrides
1082
+ });
1083
+ var analyzeDependencyExposure = async (input, metadataProvider, onProgress) => {
1084
+ const config = withDefaults(input.config);
1085
+ try {
1086
+ const prepared = await prepareDependencyExtraction(input.repositoryPath);
1087
+ if (!prepared.available) {
1088
+ return {
1089
+ targetPath: input.repositoryPath,
1090
+ available: false,
1091
+ reason: prepared.reason
1058
1092
  };
1059
- onProgress?.({ stage: "lockfile_selected", kind: "npm" });
1060
- } else {
1061
- extraction = parseExtraction(lockfile.kind, lockfile.raw, directSpecs);
1062
- onProgress?.({ stage: "lockfile_selected", kind: lockfile.kind });
1063
1093
  }
1064
- const directNames = new Set(extraction.directDependencies.map((dependency) => dependency.name));
1094
+ onProgress?.({ stage: "package_json_loaded" });
1095
+ onProgress?.({ stage: "lockfile_selected", kind: prepared.lockfileKind });
1096
+ const { extraction } = prepared;
1065
1097
  onProgress?.({
1066
1098
  stage: "lockfile_parsed",
1067
1099
  dependencyNodes: extraction.nodes.length,
1068
1100
  directDependencies: extraction.directDependencies.length
1069
1101
  });
1070
1102
  onProgress?.({ stage: "metadata_fetch_started", total: extraction.nodes.length });
1071
- let completed = 0;
1072
- const metadataEntries = await mapWithConcurrency(
1073
- extraction.nodes,
1103
+ const metadataEntries = await collectDependencyMetadata(
1104
+ extraction,
1105
+ metadataProvider,
1074
1106
  config.metadataRequestConcurrency,
1075
- async (node) => {
1076
- const result = {
1077
- key: `${node.name}@${node.version}`,
1078
- metadata: await metadataProvider.getMetadata(node.name, node.version, {
1079
- directDependency: directNames.has(node.name)
1080
- })
1081
- };
1082
- completed += 1;
1083
- onProgress?.({
1084
- stage: "metadata_fetch_progress",
1085
- completed,
1086
- total: extraction.nodes.length,
1087
- packageName: node.name
1088
- });
1089
- return result;
1090
- }
1107
+ (event) => onProgress?.({
1108
+ stage: "metadata_fetch_progress",
1109
+ completed: event.completed,
1110
+ total: event.total,
1111
+ packageName: event.packageName
1112
+ })
1091
1113
  );
1092
1114
  onProgress?.({ stage: "metadata_fetch_completed", total: extraction.nodes.length });
1093
1115
  const metadataByKey = /* @__PURE__ */ new Map();
1094
1116
  for (const entry of metadataEntries) {
1095
1117
  metadataByKey.set(entry.key, entry.metadata);
1096
1118
  }
1097
- const summary = buildExternalAnalysisSummary(input.repositoryPath, extraction, metadataByKey, config);
1119
+ const summary = buildExternalAnalysisSummary(
1120
+ input.repositoryPath,
1121
+ extraction,
1122
+ metadataByKey,
1123
+ config
1124
+ );
1098
1125
  if (summary.available) {
1099
1126
  onProgress?.({
1100
1127
  stage: "summary_built",