dep-oracle 1.1.4 → 1.2.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.
@@ -509,7 +509,7 @@ function normalizePyPIName(name) {
509
509
  return name.toLowerCase().replace(/[-_.]+/g, "-");
510
510
  }
511
511
  function parsePep508(spec) {
512
- const cleaned = spec.split("#")[0].trim();
512
+ const cleaned = spec.replace(/\s+#.*$/, "").trim();
513
513
  if (!cleaned || cleaned.startsWith("-")) return null;
514
514
  const withoutMarkers = cleaned.split(";")[0].trim();
515
515
  const match = withoutMarkers.match(
@@ -870,7 +870,11 @@ var CacheManager = class {
870
870
  const raw = readFileSync(this.filePath, "utf-8");
871
871
  return JSON.parse(raw);
872
872
  }
873
- } catch {
873
+ } catch (err) {
874
+ if (err instanceof SyntaxError) {
875
+ } else {
876
+ console.error(`Cache load error: ${err instanceof Error ? err.message : String(err)}`);
877
+ }
874
878
  }
875
879
  return {};
876
880
  }
@@ -1181,7 +1185,11 @@ var GitHubCollector = class extends BaseCollector {
1181
1185
  /github\.com\/([^/]+)\/([^/]+)/
1182
1186
  );
1183
1187
  if (!match) return null;
1184
- return { owner: match[1], repo: match[2] };
1188
+ const owner = match[1];
1189
+ const repo = match[2];
1190
+ const GITHUB_NAME = /^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$/;
1191
+ if (!GITHUB_NAME.test(owner) || !GITHUB_NAME.test(repo)) return null;
1192
+ return { owner, repo };
1185
1193
  }
1186
1194
  // ---------------------------------------------------------------------------
1187
1195
  // GitHub API calls
@@ -1618,8 +1626,11 @@ var FundingCollector = class extends BaseCollector {
1618
1626
  const ghMatch = fundingYml.match(/github:\s*(.+)/i);
1619
1627
  if (ghMatch) {
1620
1628
  const sponsors = ghMatch[1].trim().replace(/^\[/, "").replace(/]$/, "").split(",").map((s) => s.trim().replace(/['"]/g, "")).filter(Boolean);
1629
+ const GITHUB_USERNAME = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$/;
1621
1630
  for (const sponsor of sponsors) {
1622
- urls.push(`https://github.com/sponsors/${sponsor}`);
1631
+ if (GITHUB_USERNAME.test(sponsor)) {
1632
+ urls.push(`https://github.com/sponsors/${sponsor}`);
1633
+ }
1623
1634
  }
1624
1635
  }
1625
1636
  const ocMatch = fundingYml.match(/open_collective:\s*(\S+)/i);
@@ -2019,9 +2030,30 @@ var CollectorOrchestrator = class {
2019
2030
  { key: "license", collector: this.licenseCollector }
2020
2031
  ];
2021
2032
  const results = {};
2033
+ const COLLECTOR_TIMEOUT = 3e4;
2022
2034
  const tasks = entries.map(
2023
2035
  ({ key, collector }) => limit(async () => {
2024
- const result = this.options.offline ? await this.offlineCollect(collector, packageName, version) : await this.onlineCollect(collector, packageName, version);
2036
+ let result;
2037
+ if (this.options.offline) {
2038
+ result = await this.offlineCollect(collector, packageName, version);
2039
+ } else {
2040
+ try {
2041
+ result = await Promise.race([
2042
+ this.onlineCollect(collector, packageName, version),
2043
+ new Promise(
2044
+ (_, reject) => setTimeout(() => reject(new Error("Collector timeout")), COLLECTOR_TIMEOUT)
2045
+ )
2046
+ ]);
2047
+ } catch {
2048
+ logger.warn(`[${collector.name}] ${packageName}@${version} => timeout (${COLLECTOR_TIMEOUT}ms)`);
2049
+ result = {
2050
+ status: "error",
2051
+ data: null,
2052
+ error: `Timeout after ${COLLECTOR_TIMEOUT / 1e3}s`,
2053
+ collectedAt: (/* @__PURE__ */ new Date()).toISOString()
2054
+ };
2055
+ }
2056
+ }
2025
2057
  logger.info(
2026
2058
  `[${collector.name}] ${packageName}@${version} => ${result.status}`
2027
2059
  );
@@ -2098,6 +2130,10 @@ var TrustScoreEngine = class {
2098
2130
  weights;
2099
2131
  constructor(weights) {
2100
2132
  this.weights = { ...DEFAULT_WEIGHTS, ...weights };
2133
+ const total = Object.values(this.weights).reduce((a, b) => a + b, 0);
2134
+ if (Math.abs(total - 1) > 0.01) {
2135
+ throw new Error(`Trust score weights must sum to 1.0, got ${total.toFixed(4)}`);
2136
+ }
2101
2137
  }
2102
2138
  /**
2103
2139
  * Calculate a full trust score from all collector results.
@@ -2156,10 +2192,10 @@ var TrustScoreEngine = class {
2156
2192
  } else {
2157
2193
  score = Math.max(20, 100 - vulns * 12);
2158
2194
  }
2159
- if (data.averagePatchDays !== null && data.averagePatchDays > 0) {
2195
+ if (vulns > 0 && data.averagePatchDays !== null && data.averagePatchDays > 0) {
2160
2196
  if (data.averagePatchDays <= 7) {
2161
2197
  score = Math.min(100, score + 10);
2162
- } else {
2198
+ } else if (data.averagePatchDays <= 30) {
2163
2199
  score = Math.min(100, score + 5);
2164
2200
  }
2165
2201
  }
@@ -4933,13 +4969,13 @@ var TyposquatDetector = class _TyposquatDetector {
4933
4969
  const allowed = substitutions[target[i]];
4934
4970
  if (allowed && allowed.includes(input[i])) {
4935
4971
  subCount++;
4936
- if (subCount > 1) return false;
4972
+ if (subCount > 2) return false;
4937
4973
  } else {
4938
4974
  return false;
4939
4975
  }
4940
4976
  }
4941
4977
  }
4942
- return subCount === 1;
4978
+ return subCount >= 1 && subCount <= 2;
4943
4979
  }
4944
4980
  };
4945
4981
  function levenshtein(a, b) {
@@ -6550,4 +6586,4 @@ export {
6550
6586
  getBlastRadius,
6551
6587
  getImportingFiles
6552
6588
  };
6553
- //# sourceMappingURL=chunk-7WUFMWUI.js.map
6589
+ //# sourceMappingURL=chunk-TXSNFX3N.js.map