@socketsecurity/lib 5.7.0 → 5.8.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.
@@ -55,7 +55,8 @@ function createTtlCache(options) {
55
55
  }
56
56
  function isExpired(entry) {
57
57
  const now = Date.now();
58
- if (entry.expiresAt > now + ttl * 2) {
58
+ const maxFutureMs = 1e4;
59
+ if (entry.expiresAt > now + ttl + maxFutureMs) {
59
60
  return true;
60
61
  }
61
62
  return now > entry.expiresAt;
@@ -114,7 +115,7 @@ function createTtlCache(options) {
114
115
  memoCache.delete(key);
115
116
  continue;
116
117
  }
117
- const originalKey = key.slice((opts.prefix?.length ?? 0) + 1);
118
+ const originalKey = opts.prefix ? key.slice(opts.prefix.length + 1) : key;
118
119
  results.set(originalKey, entry.data);
119
120
  }
120
121
  }
@@ -128,7 +129,7 @@ function createTtlCache(options) {
128
129
  if (!matches(cacheEntry.key)) {
129
130
  continue;
130
131
  }
131
- const originalKey = cacheEntry.key.slice((opts.prefix?.length ?? 0) + 1);
132
+ const originalKey = opts.prefix ? cacheEntry.key.slice(opts.prefix.length + 1) : cacheEntry.key;
132
133
  if (results.has(originalKey)) {
133
134
  continue;
134
135
  }
@@ -174,14 +175,28 @@ function createTtlCache(options) {
174
175
  } catch {
175
176
  }
176
177
  }
178
+ const inflightRequests = /* @__PURE__ */ new Map();
177
179
  async function getOrFetch(key, fetcher) {
178
180
  const cached = await get(key);
179
181
  if (cached !== void 0) {
180
182
  return cached;
181
183
  }
182
- const data = await fetcher();
183
- await set(key, data);
184
- return data;
184
+ const fullKey = buildKey(key);
185
+ const existing = inflightRequests.get(fullKey);
186
+ if (existing) {
187
+ return await existing;
188
+ }
189
+ const promise = (async () => {
190
+ try {
191
+ const data = await fetcher();
192
+ await set(key, data);
193
+ return data;
194
+ } finally {
195
+ inflightRequests.delete(fullKey);
196
+ }
197
+ })();
198
+ inflightRequests.set(fullKey, promise);
199
+ return await promise;
185
200
  }
186
201
  async function deleteEntry(key) {
187
202
  if (key.includes("*")) {
@@ -47,7 +47,8 @@ function getNodeVersion() {
47
47
  return NODE_VERSION;
48
48
  }
49
49
  function getNodeMajorVersion() {
50
- return Number.parseInt(NODE_VERSION.slice(1).split(".")[0] ?? "0", 10);
50
+ const major = NODE_VERSION.slice(1).split(".")[0] ?? "0";
51
+ return Number.parseInt(major, 10) || 0;
51
52
  }
52
53
  function getNodeMinorVersion() {
53
54
  return Number.parseInt(NODE_VERSION.split(".")[1] ?? "0", 10);
@@ -77,7 +77,8 @@ function formatCoverage(options) {
77
77
  { count: 2 }
78
78
  );
79
79
  }
80
- const emoji = getCoverageEmoji(Number.parseFloat(overall));
80
+ const overallValue = Number.parseFloat(overall);
81
+ const emoji = getCoverageEmoji(Number.isNaN(overallValue) ? 0 : overallValue);
81
82
  output += `
82
83
  Overall: ${overall}%${emoji}
83
84
  `;
@@ -89,9 +90,10 @@ function calculateOverall(code, type) {
89
90
  Number.parseFloat(code.branches.percent),
90
91
  Number.parseFloat(code.functions.percent),
91
92
  Number.parseFloat(code.lines.percent)
92
- ];
93
+ ].map((val) => Number.isNaN(val) ? 0 : val);
93
94
  if (type) {
94
- metrics.push(Number.parseFloat(type.percent));
95
+ const typePercent = Number.parseFloat(type.percent);
96
+ metrics.push(Number.isNaN(typePercent) ? 0 : typePercent);
95
97
  }
96
98
  const average = metrics.reduce((sum, val) => sum + val, 0) / metrics.length;
97
99
  return average.toFixed(2);
@@ -234,7 +234,7 @@ function findBinaryPath(packageDir, packageName, binaryName) {
234
234
  });
235
235
  binPath = binObj[binName];
236
236
  } catch {
237
- const lastSegment = packageName.split("/").pop();
237
+ const lastSegment = packageName.split("/").pop() ?? packageName;
238
238
  const candidates = [
239
239
  binaryName,
240
240
  lastSegment,