@vltpkg/security-archive 1.3.8 → 1.4.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.
package/dist/index.d.ts CHANGED
@@ -3,19 +3,6 @@ import type { DepID } from '@vltpkg/dep-id';
3
3
  import type { PackageReportData, SecurityArchiveLike, SecurityArchiveRefreshOptions } from './types.ts';
4
4
  export * from './types.ts';
5
5
  export { npmRegistryURL, usesNpmRegistry } from './browser.ts';
6
- export type JSONItemResponse = {
7
- namespace?: `@{string}`;
8
- name: string;
9
- version: string;
10
- score: {
11
- overall: number;
12
- license: number;
13
- maintenance: number;
14
- quality: number;
15
- supplyChain: number;
16
- vulnerability: number;
17
- };
18
- };
19
6
  export type DBReadEntry = {
20
7
  depID: string;
21
8
  now: number;
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { asDepID, baseDepID } from '@vltpkg/dep-id';
9
9
  import { error } from '@vltpkg/error-cause';
10
10
  import { userAgent } from '@vltpkg/user-agent';
11
11
  import { XDG } from '@vltpkg/xdg';
12
- import { asPackageReportData } from "./types.js";
12
+ import { asPackageReportData, getItemScore } from "./types.js";
13
13
  import { __CODE_SPLIT_SCRIPT_NAME } from "./update-expired.js";
14
14
  import { usesNpmRegistry } from "./browser.js";
15
15
  export * from "./types.js";
@@ -270,30 +270,25 @@ export class SecurityArchive extends LRUCache {
270
270
  if (!line.trim())
271
271
  continue;
272
272
  const data = JSON.parse(line + '}');
273
+ // skip the purlError and summary wrapper items the API may
274
+ // include in the stream, they do not describe a package
275
+ if (data._type)
276
+ continue;
273
277
  const scope = data.namespace ? `${data.namespace}/` : '';
274
278
  const name = `${scope}${data.name}`;
275
- const node = this.#retrieveNodeByNameVersion(name, data.version);
279
+ const node = this.#retrieveNodeByNameVersion(name, String(data.version));
276
280
  if (node) {
281
+ const score = getItemScore(data);
282
+ // a package that socket.dev has not finished analyzing yet
283
+ // comes back without a score, leave it out of the archive so
284
+ // that it gets requested again on the next run
285
+ if (!score)
286
+ continue;
277
287
  const normalizedId = baseDepID(node.id);
278
- fetchedDepIDs.add(baseDepID(node.id));
279
- // Calculate average score from all score components
280
- const scoreComponents = [
281
- data.score.license,
282
- data.score.maintenance,
283
- data.score.quality,
284
- data.score.supplyChain,
285
- data.score.vulnerability,
286
- ];
287
- const newAverageScore = Number((scoreComponents.reduce((sum, score) => sum + score, 0) /
288
- scoreComponents.length).toFixed(2));
289
- // Add average score to the score object
290
- const scoreWithNewAverage = {
291
- ...data.score,
292
- overall: newAverageScore,
293
- };
288
+ fetchedDepIDs.add(normalizedId);
294
289
  this.set(normalizedId, asPackageReportData({
295
290
  ...data,
296
- score: scoreWithNewAverage,
291
+ score,
297
292
  }));
298
293
  }
299
294
  else {
package/dist/types.d.ts CHANGED
@@ -89,3 +89,30 @@ export type PackageReportData = {
89
89
  };
90
90
  export declare const isPackageReportData: (o: unknown) => o is PackageReportData;
91
91
  export declare const asPackageReportData: (o: unknown) => PackageReportData;
92
+ /**
93
+ * A single line of the NDJSON stream returned by the socket.dev
94
+ * batch purl API. Besides package artifacts, the stream can carry
95
+ * `purlError` and `summary` wrapper items, and a package that was
96
+ * published recently enough to not have been analyzed yet comes back
97
+ * as an artifact with no `score` object at all.
98
+ */
99
+ export type JSONItemResponse = {
100
+ _type?: 'purlError' | 'summary';
101
+ namespace?: `@${string}`;
102
+ name?: string;
103
+ version?: string;
104
+ score?: {
105
+ overall?: number;
106
+ license: number;
107
+ maintenance: number;
108
+ quality: number;
109
+ supplyChain: number;
110
+ vulnerability: number;
111
+ };
112
+ };
113
+ /**
114
+ * Returns the score of a response item with its `overall` value
115
+ * recalculated as the average of the individual components, or
116
+ * `undefined` when the item is not a scored package artifact.
117
+ */
118
+ export declare const getItemScore: (data: JSONItemResponse) => PackageScore | undefined;
package/dist/types.js CHANGED
@@ -27,3 +27,23 @@ export const asPackageReportData = (o) => {
27
27
  }
28
28
  return o;
29
29
  };
30
+ /**
31
+ * Returns the score of a response item with its `overall` value
32
+ * recalculated as the average of the individual components, or
33
+ * `undefined` when the item is not a scored package artifact.
34
+ */
35
+ export const getItemScore = (data) => {
36
+ if (data._type || !data.score)
37
+ return undefined;
38
+ const { license, maintenance, quality, supplyChain, vulnerability, } = data.score;
39
+ const scoreComponents = [
40
+ license,
41
+ maintenance,
42
+ quality,
43
+ supplyChain,
44
+ vulnerability,
45
+ ];
46
+ const overall = Number((scoreComponents.reduce((sum, score) => sum + score, 0) /
47
+ scoreComponents.length).toFixed(2));
48
+ return { ...data.score, overall };
49
+ };
@@ -6,7 +6,7 @@ import pRetry, { AbortError } from 'p-retry';
6
6
  import { asDepID, baseDepID } from '@vltpkg/dep-id';
7
7
  import { error } from '@vltpkg/error-cause';
8
8
  import { userAgent } from '@vltpkg/user-agent';
9
- import { asPackageReportData } from "./types.js";
9
+ import { asPackageReportData, getItemScore } from "./types.js";
10
10
  export const __CODE_SPLIT_SCRIPT_NAME = import.meta.filename;
11
11
  const SOCKET_API_V0_URL = 'https://api.socket.dev/v0/purl?alerts=true';
12
12
  const SOCKET_PUBLIC_API_TOKEN = 'sktsec_t_--RAN5U4ivauy4w37-6aoKyYPDt5ZbaT5JBVMqiwKo_api';
@@ -91,6 +91,10 @@ export const main = async (input = process.stdin) => {
91
91
  if (!line.trim())
92
92
  continue;
93
93
  const data = JSON.parse(line + '}');
94
+ // skip the purlError and summary wrapper items the API may
95
+ // include in the stream, they do not describe a package
96
+ if (data._type)
97
+ continue;
94
98
  const scope = data.namespace ? `${data.namespace}/` : '';
95
99
  const name = `${scope}${data.name}`;
96
100
  const key = `${name}@${data.version}`;
@@ -100,19 +104,15 @@ export const main = async (input = process.stdin) => {
100
104
  console.warn(`security-archive: failed to find entry for ${key} found in the response.`);
101
105
  continue;
102
106
  }
103
- // Calculate average score from all score components
104
- const scoreComponents = [
105
- data.score.license,
106
- data.score.maintenance,
107
- data.score.quality,
108
- data.score.supplyChain,
109
- data.score.vulnerability,
110
- ];
111
- const newAverageScore = Number((scoreComponents.reduce((sum, score) => sum + score, 0) /
112
- scoreComponents.length).toFixed(2));
107
+ const score = getItemScore(data);
108
+ // a package that socket.dev has not finished analyzing yet comes
109
+ // back without a score, keep the stale entry rather than replacing
110
+ // it with an invalid one
111
+ if (!score)
112
+ continue;
113
113
  const reportData = asPackageReportData({
114
114
  ...data,
115
- score: { ...data.score, overall: newAverageScore },
115
+ score,
116
116
  });
117
117
  results.push({
118
118
  depID: baseDepID(asDepID(entry.depID)),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vltpkg/security-archive",
3
3
  "description": "A database of security information of packages",
4
- "version": "1.3.8",
4
+ "version": "1.4.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",
@@ -13,12 +13,12 @@
13
13
  "url": "http://vlt.sh"
14
14
  },
15
15
  "dependencies": {
16
- "@vltpkg/dep-id": "1.3.8",
17
- "@vltpkg/error-cause": "1.3.8",
18
- "@vltpkg/spec": "1.3.8",
19
- "@vltpkg/types": "1.3.8",
20
- "@vltpkg/user-agent": "1.3.8",
21
- "@vltpkg/xdg": "1.3.8",
16
+ "@vltpkg/dep-id": "1.4.0",
17
+ "@vltpkg/error-cause": "1.4.0",
18
+ "@vltpkg/spec": "1.4.0",
19
+ "@vltpkg/types": "1.4.0",
20
+ "@vltpkg/user-agent": "1.4.0",
21
+ "@vltpkg/xdg": "1.4.0",
22
22
  "lru-cache": "^11.2.4",
23
23
  "p-retry": "^7.1.1"
24
24
  },