upstream-radar 0.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/LICENSE +176 -0
- package/README.md +222 -0
- package/README.zh-CN.md +170 -0
- package/cordis.patch.yml +11 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +286 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/compatibility.d.ts +12 -0
- package/dist/src/compatibility.d.ts.map +1 -0
- package/dist/src/compatibility.js +195 -0
- package/dist/src/compatibility.js.map +1 -0
- package/dist/src/dsh-analysis.d.ts +7 -0
- package/dist/src/dsh-analysis.d.ts.map +1 -0
- package/dist/src/dsh-analysis.js +53 -0
- package/dist/src/dsh-analysis.js.map +1 -0
- package/dist/src/dsh-plugin.d.ts +45 -0
- package/dist/src/dsh-plugin.d.ts.map +1 -0
- package/dist/src/dsh-plugin.js +121 -0
- package/dist/src/dsh-plugin.js.map +1 -0
- package/dist/src/graph.d.ts +14 -0
- package/dist/src/graph.d.ts.map +1 -0
- package/dist/src/graph.js +198 -0
- package/dist/src/graph.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +19 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/inventory.d.ts +4 -0
- package/dist/src/inventory.d.ts.map +1 -0
- package/dist/src/inventory.js +182 -0
- package/dist/src/inventory.js.map +1 -0
- package/dist/src/npm-release.d.ts +24 -0
- package/dist/src/npm-release.d.ts.map +1 -0
- package/dist/src/npm-release.js +131 -0
- package/dist/src/npm-release.js.map +1 -0
- package/dist/src/npm.d.ts +36 -0
- package/dist/src/npm.d.ts.map +1 -0
- package/dist/src/npm.js +803 -0
- package/dist/src/npm.js.map +1 -0
- package/dist/src/osv.d.ts +18 -0
- package/dist/src/osv.d.ts.map +1 -0
- package/dist/src/osv.js +238 -0
- package/dist/src/osv.js.map +1 -0
- package/dist/src/policy.d.ts +5 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/policy.js +32 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/radar-render.d.ts +4 -0
- package/dist/src/radar-render.d.ts.map +1 -0
- package/dist/src/radar-render.js +50 -0
- package/dist/src/radar-render.js.map +1 -0
- package/dist/src/radar-state.d.ts +5 -0
- package/dist/src/radar-state.d.ts.map +1 -0
- package/dist/src/radar-state.js +87 -0
- package/dist/src/radar-state.js.map +1 -0
- package/dist/src/radar-types.d.ts +163 -0
- package/dist/src/radar-types.d.ts.map +1 -0
- package/dist/src/radar-types.js +7 -0
- package/dist/src/radar-types.js.map +1 -0
- package/dist/src/radar.d.ts +24 -0
- package/dist/src/radar.d.ts.map +1 -0
- package/dist/src/radar.js +234 -0
- package/dist/src/radar.js.map +1 -0
- package/dist/src/render.d.ts +3 -0
- package/dist/src/render.d.ts.map +1 -0
- package/dist/src/render.js +58 -0
- package/dist/src/render.js.map +1 -0
- package/dist/src/scan.d.ts +8 -0
- package/dist/src/scan.d.ts.map +1 -0
- package/dist/src/scan.js +293 -0
- package/dist/src/scan.js.map +1 -0
- package/dist/src/semver.d.ts +13 -0
- package/dist/src/semver.d.ts.map +1 -0
- package/dist/src/semver.js +136 -0
- package/dist/src/semver.js.map +1 -0
- package/dist/src/tar.d.ts +25 -0
- package/dist/src/tar.d.ts.map +1 -0
- package/dist/src/tar.js +327 -0
- package/dist/src/tar.js.map +1 -0
- package/dist/src/types.d.ts +111 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +2 -0
- package/dist/src/version.js.map +1 -0
- package/docs/assets/upstream-radar-hero-mobile.jpg +0 -0
- package/docs/assets/upstream-radar-hero.jpg +0 -0
- package/package.json +84 -0
- package/schemas/analysis-result.schema.json +39 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { DEPENDENCY_GRAPH_SCHEMA, INVENTORY_SCHEMA, RADAR_CONFIG_SCHEMA, } from './radar-types.js';
|
|
2
|
+
const MAX_PROJECTS = 1_000;
|
|
3
|
+
const MAX_PLUGINS_PER_PROJECT = 1_000;
|
|
4
|
+
const MAX_NODES_PER_GRAPH = 100_000;
|
|
5
|
+
const MAX_EDGES_PER_GRAPH = 250_000;
|
|
6
|
+
function record(value, label) {
|
|
7
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
8
|
+
throw new Error(`${label} must be an object`);
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function string(value, label, max = 4_096) {
|
|
12
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > max)
|
|
13
|
+
throw new Error(`${label} must be a non-empty bounded string`);
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function optionalString(value, label, max = 4_096) {
|
|
17
|
+
return value === undefined ? undefined : string(value, label, max);
|
|
18
|
+
}
|
|
19
|
+
function stringArray(value, label) {
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (!Array.isArray(value) || value.length > 100)
|
|
23
|
+
throw new Error(`${label} must be an array with at most 100 entries`);
|
|
24
|
+
return value.map((item, index) => string(item, `${label}[${index}]`, 1_024));
|
|
25
|
+
}
|
|
26
|
+
function stringRecord(value, label) {
|
|
27
|
+
if (value === undefined)
|
|
28
|
+
return undefined;
|
|
29
|
+
const source = record(value, label);
|
|
30
|
+
if (Object.keys(source).length > 10_000)
|
|
31
|
+
throw new Error(`${label} has too many entries`);
|
|
32
|
+
return Object.fromEntries(Object.entries(source).map(([key, item]) => [
|
|
33
|
+
string(key, `${label} key`, 512),
|
|
34
|
+
string(item, `${label}.${key}`, 2_048),
|
|
35
|
+
]));
|
|
36
|
+
}
|
|
37
|
+
function coordinate(value, label) {
|
|
38
|
+
const source = record(value, label);
|
|
39
|
+
if (source.ecosystem !== 'npm')
|
|
40
|
+
throw new Error(`${label}.ecosystem must be npm`);
|
|
41
|
+
return {
|
|
42
|
+
ecosystem: 'npm',
|
|
43
|
+
name: string(source.name, `${label}.name`, 512),
|
|
44
|
+
version: string(source.version, `${label}.version`, 512),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function manifest(value, label) {
|
|
48
|
+
if (value === undefined)
|
|
49
|
+
return undefined;
|
|
50
|
+
const source = record(value, label);
|
|
51
|
+
const type = optionalString(source.type, `${label}.type`, 128);
|
|
52
|
+
const main = optionalString(source.main, `${label}.main`, 4_096);
|
|
53
|
+
const engines = stringRecord(source.engines, `${label}.engines`);
|
|
54
|
+
const dependencies = stringRecord(source.dependencies, `${label}.dependencies`);
|
|
55
|
+
const optionalDependencies = stringRecord(source.optionalDependencies, `${label}.optionalDependencies`);
|
|
56
|
+
const peerDependencies = stringRecord(source.peerDependencies, `${label}.peerDependencies`);
|
|
57
|
+
return {
|
|
58
|
+
name: string(source.name, `${label}.name`, 512),
|
|
59
|
+
version: string(source.version, `${label}.version`, 512),
|
|
60
|
+
...(type === undefined ? {} : { type }),
|
|
61
|
+
...(main === undefined ? {} : { main }),
|
|
62
|
+
...(source.exports === undefined ? {} : { exports: structuredClone(source.exports) }),
|
|
63
|
+
...(engines === undefined ? {} : { engines }),
|
|
64
|
+
...(dependencies === undefined ? {} : { dependencies }),
|
|
65
|
+
...(optionalDependencies === undefined ? {} : { optionalDependencies }),
|
|
66
|
+
...(peerDependencies === undefined ? {} : { peerDependencies }),
|
|
67
|
+
...(source.dsh === undefined ? {} : { dsh: structuredClone(source.dsh) }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function parsePackageManifestSnapshot(value) {
|
|
71
|
+
const parsed = manifest(value, 'package manifest');
|
|
72
|
+
if (parsed === undefined)
|
|
73
|
+
throw new Error('package manifest must be present');
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
function graph(value, label) {
|
|
77
|
+
const source = record(value, label);
|
|
78
|
+
if (source.schema !== DEPENDENCY_GRAPH_SCHEMA)
|
|
79
|
+
throw new Error(`${label} has an unsupported schema`);
|
|
80
|
+
if (!Array.isArray(source.nodes) || source.nodes.length === 0 || source.nodes.length > MAX_NODES_PER_GRAPH) {
|
|
81
|
+
throw new Error(`${label}.nodes must contain between 1 and ${MAX_NODES_PER_GRAPH} entries`);
|
|
82
|
+
}
|
|
83
|
+
if (!Array.isArray(source.edges) || source.edges.length > MAX_EDGES_PER_GRAPH) {
|
|
84
|
+
throw new Error(`${label}.edges must contain at most ${MAX_EDGES_PER_GRAPH} entries`);
|
|
85
|
+
}
|
|
86
|
+
const nodes = source.nodes.map((rawNode, index) => {
|
|
87
|
+
const node = record(rawNode, `${label}.nodes[${index}]`);
|
|
88
|
+
return {
|
|
89
|
+
id: string(node.id, `${label}.nodes[${index}].id`, 4_096),
|
|
90
|
+
name: string(node.name, `${label}.nodes[${index}].name`, 512),
|
|
91
|
+
version: string(node.version, `${label}.nodes[${index}].version`, 512),
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
const ids = new Set(nodes.map(node => node.id));
|
|
95
|
+
if (ids.size !== nodes.length)
|
|
96
|
+
throw new Error(`${label} contains duplicate node ids`);
|
|
97
|
+
const kinds = new Set(['runtime', 'development', 'optional', 'peer']);
|
|
98
|
+
const edges = source.edges.map((rawEdge, index) => {
|
|
99
|
+
const edge = record(rawEdge, `${label}.edges[${index}]`);
|
|
100
|
+
const from = string(edge.from, `${label}.edges[${index}].from`, 4_096);
|
|
101
|
+
const to = string(edge.to, `${label}.edges[${index}].to`, 4_096);
|
|
102
|
+
const kind = string(edge.kind, `${label}.edges[${index}].kind`, 32);
|
|
103
|
+
if (!kinds.has(kind))
|
|
104
|
+
throw new Error(`${label}.edges[${index}] has an invalid dependency kind`);
|
|
105
|
+
if (!ids.has(from) || !ids.has(to))
|
|
106
|
+
throw new Error(`${label}.edges[${index}] references a missing node`);
|
|
107
|
+
return { from, to, kind };
|
|
108
|
+
});
|
|
109
|
+
const rootNodeId = string(source.rootNodeId, `${label}.rootNodeId`, 4_096);
|
|
110
|
+
if (!ids.has(rootNodeId))
|
|
111
|
+
throw new Error(`${label} root references a missing node`);
|
|
112
|
+
const digest = optionalString(source.digest, `${label}.digest`, 512);
|
|
113
|
+
return {
|
|
114
|
+
schema: DEPENDENCY_GRAPH_SCHEMA,
|
|
115
|
+
rootNodeId,
|
|
116
|
+
nodes,
|
|
117
|
+
edges,
|
|
118
|
+
...(digest === undefined ? {} : { digest }),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function plugin(value, label) {
|
|
122
|
+
const source = record(value, label);
|
|
123
|
+
const packageValue = coordinate(source.package, `${label}.package`);
|
|
124
|
+
const graphValue = graph(source.graph, `${label}.graph`);
|
|
125
|
+
const root = graphValue.nodes.find(node => node.id === graphValue.rootNodeId);
|
|
126
|
+
if (root?.name !== packageValue.name || root.version !== packageValue.version) {
|
|
127
|
+
throw new Error(`${label} installed package does not match graph root`);
|
|
128
|
+
}
|
|
129
|
+
const manifestValue = manifest(source.manifest, `${label}.manifest`);
|
|
130
|
+
if (manifestValue !== undefined
|
|
131
|
+
&& (manifestValue.name !== packageValue.name || manifestValue.version !== packageValue.version)) {
|
|
132
|
+
throw new Error(`${label} installed package does not match manifest`);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
package: packageValue,
|
|
136
|
+
graph: graphValue,
|
|
137
|
+
...(manifestValue === undefined ? {} : { manifest: manifestValue }),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function project(value, index) {
|
|
141
|
+
const label = `projects[${index}]`;
|
|
142
|
+
const source = record(value, label);
|
|
143
|
+
if (source.schema !== INVENTORY_SCHEMA)
|
|
144
|
+
throw new Error(`${label} has an unsupported schema`);
|
|
145
|
+
const projectSource = record(source.project, `${label}.project`);
|
|
146
|
+
if (!Array.isArray(source.plugins) || source.plugins.length === 0 || source.plugins.length > MAX_PLUGINS_PER_PROJECT) {
|
|
147
|
+
throw new Error(`${label}.plugins must contain between 1 and ${MAX_PLUGINS_PER_PROJECT} entries`);
|
|
148
|
+
}
|
|
149
|
+
const repository = optionalString(projectSource.repository, `${label}.project.repository`);
|
|
150
|
+
const workspace = optionalString(projectSource.workspace, `${label}.project.workspace`);
|
|
151
|
+
const owner = optionalString(projectSource.owner, `${label}.project.owner`, 1_024);
|
|
152
|
+
const channels = stringArray(projectSource.channels, `${label}.project.channels`);
|
|
153
|
+
const environmentSource = source.environment === undefined ? undefined : record(source.environment, `${label}.environment`);
|
|
154
|
+
const nodeVersion = optionalString(environmentSource?.nodeVersion, `${label}.environment.nodeVersion`, 128);
|
|
155
|
+
return {
|
|
156
|
+
schema: INVENTORY_SCHEMA,
|
|
157
|
+
project: {
|
|
158
|
+
id: string(projectSource.id, `${label}.project.id`, 512),
|
|
159
|
+
name: string(projectSource.name, `${label}.project.name`, 1_024),
|
|
160
|
+
...(repository === undefined ? {} : { repository }),
|
|
161
|
+
...(workspace === undefined ? {} : { workspace }),
|
|
162
|
+
...(owner === undefined ? {} : { owner }),
|
|
163
|
+
...(channels === undefined ? {} : { channels }),
|
|
164
|
+
},
|
|
165
|
+
...(environmentSource === undefined ? {} : { environment: nodeVersion === undefined ? {} : { nodeVersion } }),
|
|
166
|
+
plugins: source.plugins.map((item, pluginIndex) => plugin(item, `${label}.plugins[${pluginIndex}]`)),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function parseRadarConfig(value) {
|
|
170
|
+
const source = record(value, 'radar config');
|
|
171
|
+
if (source.schema !== RADAR_CONFIG_SCHEMA)
|
|
172
|
+
throw new Error('radar config has an unsupported schema');
|
|
173
|
+
if (!Array.isArray(source.projects) || source.projects.length === 0 || source.projects.length > MAX_PROJECTS) {
|
|
174
|
+
throw new Error(`radar config projects must contain between 1 and ${MAX_PROJECTS} entries`);
|
|
175
|
+
}
|
|
176
|
+
const projects = source.projects.map(project);
|
|
177
|
+
const ids = new Set(projects.map(item => item.project.id));
|
|
178
|
+
if (ids.size !== projects.length)
|
|
179
|
+
throw new Error('radar config contains duplicate project ids');
|
|
180
|
+
return { schema: RADAR_CONFIG_SCHEMA, projects };
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PackageCoordinate, PackageManifestSnapshot } from './radar-types.js';
|
|
2
|
+
type FetchLike = (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
export interface NpmReleaseClientOptions {
|
|
4
|
+
registry?: string;
|
|
5
|
+
fetch?: FetchLike;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface NpmReleaseObservation {
|
|
9
|
+
installed: PackageCoordinate;
|
|
10
|
+
latestVersion: string;
|
|
11
|
+
previous: PackageManifestSnapshot;
|
|
12
|
+
candidate: PackageManifestSnapshot;
|
|
13
|
+
publishedAt?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class NpmReleaseClient {
|
|
16
|
+
private readonly registry;
|
|
17
|
+
private readonly fetcher;
|
|
18
|
+
private readonly timeoutMs;
|
|
19
|
+
constructor(options?: NpmReleaseClientOptions);
|
|
20
|
+
private fetchPackument;
|
|
21
|
+
query(input: readonly PackageCoordinate[]): Promise<Map<string, NpmReleaseObservation>>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=npm-release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-release.d.ts","sourceRoot":"","sources":["../../src/npm-release.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAOlF,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE/E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,iBAAiB,CAAA;IAC5B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,SAAS,EAAE,uBAAuB,CAAA;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AA2CD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAElC,YAAY,OAAO,GAAE,uBAA4B,EAOhD;YAEa,cAAc;IAYtB,KAAK,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAmD5F;CACF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { parsePackageManifestSnapshot } from './inventory.js';
|
|
2
|
+
import { packageKey } from './osv.js';
|
|
3
|
+
import { TOOL_VERSION } from './version.js';
|
|
4
|
+
const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';
|
|
5
|
+
const MAX_RESPONSE_BYTES = 32 * 1024 * 1024;
|
|
6
|
+
const MAX_PACKAGES = 10_000;
|
|
7
|
+
function asRecord(value) {
|
|
8
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
9
|
+
return undefined;
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function normalizeRegistry(input) {
|
|
13
|
+
const url = new URL(input);
|
|
14
|
+
if (url.protocol !== 'https:')
|
|
15
|
+
throw new Error('npm release registry must use HTTPS');
|
|
16
|
+
if (url.username !== '' || url.password !== '' || url.search !== '' || url.hash !== '') {
|
|
17
|
+
throw new Error('npm release registry must not contain credentials, a query string or a fragment');
|
|
18
|
+
}
|
|
19
|
+
if (!url.pathname.endsWith('/'))
|
|
20
|
+
url.pathname += '/';
|
|
21
|
+
return url.toString();
|
|
22
|
+
}
|
|
23
|
+
async function boundedJson(response) {
|
|
24
|
+
if (!response.ok)
|
|
25
|
+
throw new Error(`npm registry returned HTTP ${response.status}`);
|
|
26
|
+
const declared = response.headers.get('content-length');
|
|
27
|
+
if (declared !== null && Number(declared) > MAX_RESPONSE_BYTES)
|
|
28
|
+
throw new Error('npm packument exceeds the byte limit');
|
|
29
|
+
if (response.body === null)
|
|
30
|
+
throw new Error('npm registry returned an empty packument');
|
|
31
|
+
const reader = response.body.getReader();
|
|
32
|
+
const chunks = [];
|
|
33
|
+
let total = 0;
|
|
34
|
+
while (true) {
|
|
35
|
+
const next = await reader.read();
|
|
36
|
+
if (next.done)
|
|
37
|
+
break;
|
|
38
|
+
const chunk = Buffer.from(next.value);
|
|
39
|
+
total += chunk.length;
|
|
40
|
+
if (total > MAX_RESPONSE_BYTES) {
|
|
41
|
+
await reader.cancel('npm packument exceeded byte limit');
|
|
42
|
+
throw new Error('npm packument exceeds the byte limit');
|
|
43
|
+
}
|
|
44
|
+
chunks.push(chunk);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(Buffer.concat(chunks, total).toString('utf8'));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw new Error('npm registry returned invalid JSON');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class NpmReleaseClient {
|
|
54
|
+
registry;
|
|
55
|
+
fetcher;
|
|
56
|
+
timeoutMs;
|
|
57
|
+
constructor(options = {}) {
|
|
58
|
+
this.registry = normalizeRegistry(options.registry ?? DEFAULT_REGISTRY);
|
|
59
|
+
this.fetcher = options.fetch ?? fetch;
|
|
60
|
+
this.timeoutMs = options.timeoutMs ?? 20_000;
|
|
61
|
+
if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 1_000 || this.timeoutMs > 120_000) {
|
|
62
|
+
throw new Error('npm release timeout must be between 1000 and 120000 milliseconds');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async fetchPackument(name) {
|
|
66
|
+
const url = new URL(encodeURIComponent(name), this.registry);
|
|
67
|
+
return boundedJson(await this.fetcher(url, {
|
|
68
|
+
headers: {
|
|
69
|
+
accept: 'application/vnd.npm.install-v1+json, application/json',
|
|
70
|
+
'user-agent': `upstream-radar/${TOOL_VERSION}`,
|
|
71
|
+
},
|
|
72
|
+
redirect: 'follow',
|
|
73
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
async query(input) {
|
|
77
|
+
const unique = [...new Map(input.map(item => [packageKey(item), item])).values()];
|
|
78
|
+
if (unique.length > MAX_PACKAGES)
|
|
79
|
+
throw new Error(`npm release query exceeds the ${MAX_PACKAGES} package limit`);
|
|
80
|
+
const byName = new Map();
|
|
81
|
+
for (const item of unique) {
|
|
82
|
+
if (item.ecosystem !== 'npm' || item.name.length === 0 || item.version.length === 0) {
|
|
83
|
+
throw new Error('npm release queries require exact package names and versions');
|
|
84
|
+
}
|
|
85
|
+
const list = byName.get(item.name) ?? [];
|
|
86
|
+
list.push(item);
|
|
87
|
+
byName.set(item.name, list);
|
|
88
|
+
}
|
|
89
|
+
const packuments = new Map();
|
|
90
|
+
const queue = [...byName.keys()];
|
|
91
|
+
const workers = Array.from({ length: Math.min(8, queue.length) }, async () => {
|
|
92
|
+
while (queue.length > 0) {
|
|
93
|
+
const name = queue.shift();
|
|
94
|
+
if (name === undefined)
|
|
95
|
+
return;
|
|
96
|
+
packuments.set(name, await this.fetchPackument(name));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
await Promise.all(workers);
|
|
100
|
+
const result = new Map();
|
|
101
|
+
for (const [name, coordinates] of byName) {
|
|
102
|
+
const packument = asRecord(packuments.get(name));
|
|
103
|
+
const tags = asRecord(packument?.['dist-tags']);
|
|
104
|
+
const versions = asRecord(packument?.versions);
|
|
105
|
+
const times = asRecord(packument?.time);
|
|
106
|
+
const latestVersion = typeof tags?.latest === 'string' ? tags.latest : undefined;
|
|
107
|
+
if (latestVersion === undefined || versions === undefined)
|
|
108
|
+
throw new Error(`npm packument has no latest release for ${name}`);
|
|
109
|
+
const rawCandidate = versions[latestVersion];
|
|
110
|
+
const candidate = parsePackageManifestSnapshot(rawCandidate);
|
|
111
|
+
if (candidate.name !== name || candidate.version !== latestVersion)
|
|
112
|
+
throw new Error(`npm latest manifest identity mismatch for ${name}`);
|
|
113
|
+
for (const installed of coordinates) {
|
|
114
|
+
const previous = parsePackageManifestSnapshot(versions[installed.version]);
|
|
115
|
+
if (previous.name !== name || previous.version !== installed.version) {
|
|
116
|
+
throw new Error(`npm installed manifest identity mismatch for ${name}@${installed.version}`);
|
|
117
|
+
}
|
|
118
|
+
const publishedAt = typeof times?.[latestVersion] === 'string' ? times[latestVersion] : undefined;
|
|
119
|
+
result.set(packageKey(installed), {
|
|
120
|
+
installed: { ...installed },
|
|
121
|
+
latestVersion,
|
|
122
|
+
previous,
|
|
123
|
+
candidate,
|
|
124
|
+
...(publishedAt === undefined ? {} : { publishedAt }),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=npm-release.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-release.js","sourceRoot":"","sources":["../../src/npm-release.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type NpmEvidence, type ScanReport } from './types.js';
|
|
2
|
+
type FetchLike = (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
interface RegistrySignature {
|
|
4
|
+
keyid: string;
|
|
5
|
+
sig: string;
|
|
6
|
+
}
|
|
7
|
+
interface RegistryKey {
|
|
8
|
+
expires: string | null;
|
|
9
|
+
keyid: string;
|
|
10
|
+
keytype: string;
|
|
11
|
+
scheme: string;
|
|
12
|
+
key: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ParsedNpmSpec {
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
canonical: string;
|
|
18
|
+
}
|
|
19
|
+
export interface InspectNpmOptions {
|
|
20
|
+
registry?: string;
|
|
21
|
+
deep?: boolean;
|
|
22
|
+
fetch?: FetchLike;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface IntegrityResult {
|
|
26
|
+
status: 'verified' | 'invalid';
|
|
27
|
+
algorithm: string;
|
|
28
|
+
expected: string;
|
|
29
|
+
actual: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function parseNpmSpec(input: string): ParsedNpmSpec;
|
|
32
|
+
export declare function verifyIntegrity(contents: Buffer, integrity: string): IntegrityResult;
|
|
33
|
+
export declare function verifyRegistrySignatures(name: string, version: string, integrity: string, signatures: readonly RegistrySignature[], keys: readonly RegistryKey[], publishedAt?: string): NpmEvidence['registrySignature'];
|
|
34
|
+
export declare function inspectNpmPackage(input: string, options?: InspectNpmOptions): Promise<ScanReport>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=npm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm.d.ts","sourceRoot":"","sources":["../../src/npm.ts"],"names":[],"mappings":"AAeA,OAAO,EAIL,KAAK,WAAW,EAEhB,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAA;AAUnB,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAoB/E,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ;AAeD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAqDD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAiBzD;AAsGD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,CAsBpF;AAoBD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,WAAW,CAAC,EAAE,MAAM,GACnB,WAAW,CAAC,mBAAmB,CAAC,CAyBlC;AAkeD,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkL3G"}
|