@preventive/upstream 1.0.0-alpha.9 → 1.0.1
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/advisories.d.ts +21 -10
- package/cargo.d.ts +0 -2
- package/git.d.ts +2 -4
- package/github/write.d.ts +1 -2
- package/github.d.ts +63 -9
- package/npm.d.ts +120 -25
- package/npm.js +1 -1
- package/package.d.ts +5 -4
- package/package.json +4 -1
- package/semver.d.ts +0 -2
- package/soldeer.d.ts +0 -3
- package/src/advisories/github.js +87 -26
- package/src/advisories/index.js +4 -3
- package/src/advisories/osv.js +3 -3
- package/src/advisories/repos.js +21 -10
- package/src/args.js +1 -1
- package/src/cache.js +77 -24
- package/src/cargo/repos.js +8 -8
- package/src/download.js +8 -7
- package/src/git.js +1 -1
- package/src/github/read.js +91 -6
- package/src/http.js +4 -2
- package/src/lockfiles.js +113 -0
- package/src/npm/cacache.js +44 -0
- package/src/npm/registry.js +10 -4
- package/src/npm/repos.js +25 -13
- package/src/npm/tarball.js +99 -37
- package/src/npm/versions.js +97 -0
- package/src/package.js +24 -7
- package/src/remote.js +10 -3
package/advisories.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
// Hand-written against advisories.js; a change to either belongs with the
|
|
2
|
-
// other.
|
|
3
|
-
|
|
4
1
|
import type { Client, RepoName } from './github.js'
|
|
2
|
+
import type { CacheStore } from './npm.js'
|
|
5
3
|
|
|
6
4
|
export { HttpError } from './npm.js'
|
|
5
|
+
export type { CacheStore } from './npm.js'
|
|
7
6
|
|
|
8
7
|
// As purl and stasis name them.
|
|
9
8
|
export type Ecosystem = 'npm' | 'cargo' | 'composer' | 'soldeer' | 'github'
|
|
@@ -36,9 +35,16 @@ export interface AdvisoryOptions {
|
|
|
36
35
|
// Also asks each npm, cargo and composer package's GitHub repository
|
|
37
36
|
// for its published advisories, which it has before GitHub reviews them
|
|
38
37
|
// into the databases above: the package's `github` where given, else
|
|
39
|
-
// the one npm's
|
|
40
|
-
//
|
|
38
|
+
// the one looked up. An npm package's is the one the document of its
|
|
39
|
+
// newest version asked names, kept for good as getMeta keeps it (none
|
|
40
|
+
// where the registry does not have that version); a crate's and a
|
|
41
|
+
// composer package's, the one crates.io or Packagist names, kept a
|
|
42
|
+
// month. Needs `github`.
|
|
41
43
|
repoAdvisories?: boolean
|
|
44
|
+
// Where what this call caches is kept, as CacheOptions (npm.js) has it:
|
|
45
|
+
// a repository's listing, and each package's repository looked up (an
|
|
46
|
+
// npm package's as its version's document). See `advisories`.
|
|
47
|
+
cache?: CacheStore | false
|
|
42
48
|
// Also returns each advisory's full text, as `details`. OSV's records
|
|
43
49
|
// and a repository's listing already carry it; npm's registry does not,
|
|
44
50
|
// and its rows take OSV's record of their GHSA, one more request each
|
|
@@ -53,7 +59,7 @@ export interface Advisory {
|
|
|
53
59
|
name: string
|
|
54
60
|
// `registry`: npm's, as `npm audit` has it, one row per vulnerable
|
|
55
61
|
// range. `osv`: OSV's records for cargo and composer, RustSec's, GitHub's
|
|
56
|
-
// and malicious packages' (MAL
|
|
62
|
+
// and malicious packages' (MAL-...) among them; of the records naming each
|
|
57
63
|
// other as aliases, directly or through others, a version is reported
|
|
58
64
|
// under one only: RustSec's, else the GHSA, else the first by id. Each
|
|
59
65
|
// has the others' ids among its aliases.
|
|
@@ -62,17 +68,17 @@ export interface Advisory {
|
|
|
62
68
|
// under that GHSA. The only source for `soldeer` and `github`, where
|
|
63
69
|
// every range counts, whichever package it names.
|
|
64
70
|
source: 'registry' | 'osv' | 'repository'
|
|
65
|
-
// A GHSA, RUSTSEC
|
|
71
|
+
// A GHSA, RUSTSEC-..., MAL-..., DRUPAL-CORE-... or another OSV id, or
|
|
66
72
|
// npm:<id> for a registry row without a GHSA.
|
|
67
73
|
id: string
|
|
68
74
|
// The id itself, or an OSV record's one GHSA alias.
|
|
69
75
|
ghsa?: string
|
|
70
76
|
// GitHub's page for the GHSA, with it: a `repository` row's on its
|
|
71
|
-
// repository (https://github.com/owner/name/security/advisories/GHSA
|
|
77
|
+
// repository (https://github.com/owner/name/security/advisories/GHSA-...),
|
|
72
78
|
// which has it before GitHub reviews it into its advisory database; any
|
|
73
|
-
// other's in that database (https://github.com/advisories/GHSA
|
|
79
|
+
// other's in that database (https://github.com/advisories/GHSA-...). An
|
|
74
80
|
// `osv` row without one has osv.dev's page for its record
|
|
75
|
-
// (https://osv.dev/vulnerability/RUSTSEC
|
|
81
|
+
// (https://osv.dev/vulnerability/RUSTSEC-...). Built, never fetched: only
|
|
76
82
|
// a registry row without a GHSA (npm:<id>) has none.
|
|
77
83
|
url?: string
|
|
78
84
|
aliases: string[]
|
|
@@ -108,6 +114,11 @@ export interface Advisory {
|
|
|
108
114
|
// nothing, and a GHSA OSV does not have adds no `details`. Any other
|
|
109
115
|
// failure, a malformed answer, or one about something not asked, throws:
|
|
110
116
|
// nothing is left out quietly.
|
|
117
|
+
// A repository's listing is kept for 90 minutes, as one entry for every
|
|
118
|
+
// spelling of its name, holding only what rows are made from, `details`
|
|
119
|
+
// included: in setCacheDir's cache gzipped, in a `cache` store as it is,
|
|
120
|
+
// or with `cache` false, nowhere. 90 minutes is how late an advisory its
|
|
121
|
+
// maintainer publishes can be seen. One gone or malformed is not kept.
|
|
111
122
|
// Sorted by ecosystem and name. Versions are matched by npm's semver, from
|
|
112
123
|
// the npm beside node, or by the semver peer where there is no npm.
|
|
113
124
|
export function advisories(packages: Iterable<Package>, options?: AdvisoryOptions): Promise<Advisory[]>
|
package/cargo.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// Hand-written against cargo.js; a change to either belongs with the other.
|
|
2
|
-
//
|
|
3
1
|
// A name is asserted to be a crate name, a version an exact semver
|
|
4
2
|
// version, and a checksum 64 lowercase hex digits, before any request or
|
|
5
3
|
// cache path. The cache is setCacheDir's (npm.js).
|
package/git.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
// Hand-written against git.js; a change to either belongs with the other.
|
|
2
|
-
|
|
3
1
|
// The shape getRepo (package.js) answers in, and HEAD's commit. Each
|
|
4
2
|
// field best-effort: left out where it cannot be read.
|
|
5
3
|
export interface GitCheckout {
|
|
6
4
|
// `owner/name`, when the origin remote is a GitHub one. Never the
|
|
7
5
|
// remote's URL, which can name a private host or carry a token.
|
|
8
6
|
github?: string
|
|
9
|
-
// Where the directory sits in its checkout, `/`-separated;
|
|
10
|
-
//
|
|
7
|
+
// Where the directory sits in its checkout, `/`-separated; `''` at the
|
|
8
|
+
// root.
|
|
11
9
|
directory?: string
|
|
12
10
|
// `https://github.com/<github>`, whenever there is a `github`.
|
|
13
11
|
url?: string
|
package/github/write.d.ts
CHANGED
package/github.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// Hand-written against github.js; a change to either belongs with the other.
|
|
2
|
-
//
|
|
3
1
|
// Every method checks its arguments hard before any request is built: an
|
|
4
2
|
// options object holding only the keys listed here, a repo that is
|
|
5
3
|
// `owner/name` by GitHub's rules, branches and tags that git would take,
|
|
@@ -7,11 +5,12 @@
|
|
|
7
5
|
// component, titles and headlines on one line. A bad one is a rejection
|
|
8
6
|
// naming the method; nothing is sent. Every URL is built from checked,
|
|
9
7
|
// encoded segments and has to come back out of URL parsing unchanged.
|
|
10
|
-
// Redirects are refused,
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// message
|
|
8
|
+
// Redirects are refused, so an answer is about the repo asked for, except
|
|
9
|
+
// the tarballs' and, where asked, getRepo's for a repo renamed or
|
|
10
|
+
// transferred. A response is read up to a size limit (64 MiB of JSON, 128
|
|
11
|
+
// MiB of a file, 512 MiB of a tarball) and within a timeout (30 seconds, 5
|
|
12
|
+
// minutes for a tarball), and what it says goes into an error message
|
|
13
|
+
// escaped.
|
|
15
14
|
|
|
16
15
|
// `owner/name`.
|
|
17
16
|
export type RepoName = string
|
|
@@ -35,14 +34,62 @@ export interface RepoDirEntry {
|
|
|
35
34
|
sha: string
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
// A
|
|
37
|
+
// A lockfile's format, by the tool that writes it, with the names it
|
|
38
|
+
// writes one under and those of the project files it locks as
|
|
39
|
+
// src/lockfiles.js lists them. Those @preventive/lockfile reads are as it
|
|
40
|
+
// names the modules that do, yarn as yarn1.js, which reads Yarn 1's alone:
|
|
41
|
+
// only the text tells a later Yarn's apart.
|
|
42
|
+
export type LockfileFormat =
|
|
43
|
+
| 'pnpm' | 'npm' | 'yarn' | 'bun' | 'deno'
|
|
44
|
+
| 'uv' | 'poetry' | 'pylock' | 'pipenv' | 'pdm' | 'pixi' | 'conda-lock'
|
|
45
|
+
| 'bundler' | 'composer' | 'cargo' | 'soldeer' | 'foundry'
|
|
46
|
+
| 'cocoapods' | 'swiftpm' | 'carthage'
|
|
47
|
+
| 'go' | 'dep' | 'nuget' | 'paket' | 'gradle' | 'pub' | 'mix' | 'rebar' | 'julia'
|
|
48
|
+
| 'stack' | 'cabal' | 'shards' | 'opam' | 'nix' | 'conan' | 'bazel' | 'helm' | 'renv' | 'terraform'
|
|
49
|
+
|
|
50
|
+
// A file by a lockfile's name: `path` from the repo's root, as getRepoFile
|
|
51
|
+
// takes it, and `sha` its blob's id.
|
|
52
|
+
export interface RepoLockfile {
|
|
53
|
+
path: string
|
|
54
|
+
format: LockfileFormat
|
|
55
|
+
sha: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A file by a project file's name, as RepoLockfile is, and the formats of
|
|
59
|
+
// the lockfiles that may lock its project, in src/lockfiles.js' order:
|
|
60
|
+
// whether one does, and where, is the tool's to say, a workspace's at its
|
|
61
|
+
// root.
|
|
62
|
+
export interface RepoProjectFile {
|
|
63
|
+
path: string
|
|
64
|
+
formats: LockfileFormat[]
|
|
65
|
+
sha: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// A failed request: `status` is the HTTP status GitHub answered with, and
|
|
69
|
+
// `headers` its response's (a redirect's `location` among them), on every
|
|
70
|
+
// call but a GraphQL one (github/write.js).
|
|
39
71
|
export class HttpError extends Error {
|
|
40
72
|
name: 'HttpError'
|
|
41
73
|
status: number
|
|
74
|
+
headers?: Headers
|
|
42
75
|
}
|
|
43
76
|
|
|
44
77
|
// Reads only.
|
|
45
78
|
export interface Client {
|
|
79
|
+
// Every file by a lockfile's name, and every project file of a tool that
|
|
80
|
+
// writes one, in the full commit `sha`, or under its `directory`, found as
|
|
81
|
+
// getRepoTreeId finds it, each list sorted by path; and a project file no
|
|
82
|
+
// name tells, by a lockfile beside it named after it: a Python script
|
|
83
|
+
// `uv lock --script` locked, or a Stack or Cabal project file of another
|
|
84
|
+
// name than stack.yaml or cabal.project. From one listing of the tree
|
|
85
|
+
// with every tree under it, each hashed back to its id, so none is left
|
|
86
|
+
// out or changed; where GitHub cuts that short, as it does past 100,000
|
|
87
|
+
// entries, from the tree's own listing and then each subtree's in turn.
|
|
88
|
+
// Not looked in: a submodule, which is another repo's commit, or a
|
|
89
|
+
// `node_modules`, of packages installed. A symlink is no file. Refused
|
|
90
|
+
// where a path found is one getRepoFile does not take, such as one with a
|
|
91
|
+
// control character in it.
|
|
92
|
+
findRepoLockfiles(options: { repo: RepoName; sha: string; directory?: string }): Promise<{ lockfiles: RepoLockfile[]; projects: RepoProjectFile[] }>
|
|
46
93
|
// An advisory by its GHSA id. With `repo`, that repository's published
|
|
47
94
|
// copy: the maintainer's latest text, there before GitHub reviews it,
|
|
48
95
|
// and shaped as a repository advisory (`state`, `patched_versions`, no
|
|
@@ -58,7 +105,14 @@ export interface Client {
|
|
|
58
105
|
// Refused unless GitHub answers with that pull request in that repo.
|
|
59
106
|
getPullRequest(options: { repo: RepoName; number: number }): Promise<{ title: string; status: PullRequestStatus }>
|
|
60
107
|
// GitHub's repository object, refused unless it is the repo asked for.
|
|
61
|
-
|
|
108
|
+
// With `followRedirect`, a repository renamed or transferred, which GitHub
|
|
109
|
+
// answers with a redirect to it by its id
|
|
110
|
+
// (`https://api.github.com/repositories/<id>`), is asked for there, with
|
|
111
|
+
// the same token, once: the repository as it is now, refused unless it
|
|
112
|
+
// has that id and a `full_name` that is `owner/name`, the name to ask its
|
|
113
|
+
// other calls with. A redirect anywhere else, or a second, is refused as
|
|
114
|
+
// without it: an HttpError with the redirect's status.
|
|
115
|
+
getRepo(options: { repo: RepoName; followRedirect?: boolean }): Promise<any>
|
|
62
116
|
// A file's contents as text, at `ref` or the default branch. Refused for
|
|
63
117
|
// a directory, a symlink or a submodule, unless the bytes hash to the
|
|
64
118
|
// blob GitHub names for the path, and unless valid UTF-8.
|
package/npm.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// Hand-written against npm.js; a change to either belongs with the other.
|
|
2
|
-
//
|
|
3
1
|
// Every call that reaches the registry first asserts that the name is a
|
|
4
2
|
// string of the shape npm takes, and a version a string that npm's
|
|
5
3
|
// semver.valid answers with unchanged; neither goes near a request, or a
|
|
@@ -7,8 +5,9 @@
|
|
|
7
5
|
// a timeout, as github.d.ts describes, and lookups for many names go to
|
|
8
6
|
// the registry eight at a time.
|
|
9
7
|
//
|
|
10
|
-
// Where
|
|
11
|
-
//
|
|
8
|
+
// Where PREVENTIVE_MEASURES_NPM_TOKEN, STASIS_NPM_TOKEN or NPM_TOKEN is
|
|
9
|
+
// set, the first of them not empty, in that order, is sent with the
|
|
10
|
+
// requests for a scoped package, so a private one can be read.
|
|
12
11
|
|
|
13
12
|
// Where a program called `name` keeps its cache for this user, as each
|
|
14
13
|
// platform has it, read from the environment when called. macOS:
|
|
@@ -32,26 +31,59 @@ export const defaultCacheDir: string | undefined
|
|
|
32
31
|
// cache: every read of it misses and every write is skipped. getTarball
|
|
33
32
|
// reads ours all the same, set or not.
|
|
34
33
|
//
|
|
35
|
-
// The directory is trusted: a package's repo
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
34
|
+
// The directory is trusted: a package's repo, as recorded or as a version
|
|
35
|
+
// document kept here names it, and for 90 minutes a repository's published
|
|
36
|
+
// advisories (advisories.js), are answered from it as they were written,
|
|
37
|
+
// with no request. Point it only at storage that
|
|
38
|
+
// nothing less trusted than the caller can write, never a cache shared
|
|
39
|
+
// with or restored from lower-trust jobs. Tarballs, crates (cargo.js), zips
|
|
39
40
|
// (soldeer.js) and tree tarballs (github.js) don't rely on this, since
|
|
40
|
-
// they are checked against their integrity on every call
|
|
41
|
+
// they are checked against their integrity on every call; and the version
|
|
42
|
+
// documents kept here (getMeta) never supply an integrity, only confirm
|
|
43
|
+
// one a caller gives (verifyDist, and getMeta with a `dist`). A call's `cache` option, where it has
|
|
44
|
+
// one, keeps what it caches elsewhere, or writes none of it here.
|
|
41
45
|
export function setCacheDir(dir?: string | false): void
|
|
42
46
|
|
|
47
|
+
// A store of the caller's, a database's say, for what would otherwise be
|
|
48
|
+
// kept in setCacheDir's cache: `read` answers the value last written
|
|
49
|
+
// under that `type` and `key`, or null or undefined for none. A `type` is
|
|
50
|
+
// what is kept and a `key` which one: `npm/versions` and `npm/tarballs`
|
|
51
|
+
// with `<name>@<version>` for a version's document and tarball; and for
|
|
52
|
+
// advisories.js, `github/advisories` with the repository's `owner/name` in
|
|
53
|
+
// lowercase for its listing, and `cargo/repos`, `composer/repos` and
|
|
54
|
+
// `soldeer/repos` with a package's name for the repository it names.
|
|
55
|
+
// Values are plain JSON data, which `read` may answer as written or as a
|
|
56
|
+
// copy, but a tarball's are its bytes, a Uint8Array. Whatever it answers
|
|
57
|
+
// is checked as a cached file is: one malformed, stale or kept differently
|
|
58
|
+
// is a miss, and a tarball's bytes that do not match throw. A rejection
|
|
59
|
+
// from either is the call's. It is trusted as setCacheDir's directory is.
|
|
60
|
+
export interface CacheStore {
|
|
61
|
+
read(type: string, key: string): Promise<unknown>
|
|
62
|
+
write(type: string, key: string, value: unknown): Promise<void>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Where a call keeps what it caches: in setCacheDir's cache where `cache`
|
|
66
|
+
// is left out; in a store of the caller's in place of it; or with `false`,
|
|
67
|
+
// nowhere, though setCacheDir's cache is read all the same. Other tools'
|
|
68
|
+
// caches and ours are read for tarballs whatever it is (getTarball).
|
|
69
|
+
export interface CacheOptions {
|
|
70
|
+
cache?: CacheStore | false
|
|
71
|
+
}
|
|
72
|
+
|
|
43
73
|
// A failed request: `status` is the HTTP status the registry answered
|
|
44
|
-
// with (404 for a package or version it does not have)
|
|
74
|
+
// with (404 for a package or version it does not have), and `headers` its
|
|
75
|
+
// response's.
|
|
45
76
|
export class HttpError extends Error {
|
|
46
77
|
name: 'HttpError'
|
|
47
78
|
status: number
|
|
79
|
+
headers?: Headers
|
|
48
80
|
}
|
|
49
81
|
|
|
50
|
-
// A package's GitHub repo as its registry metadata names it
|
|
82
|
+
// A package's GitHub repo as its registry metadata names it -- getRepo
|
|
51
83
|
// (package.js) over its `latest` document: `github` is `owner/name`, and
|
|
52
|
-
// `directory` is where in the repo the package sits,
|
|
53
|
-
//
|
|
54
|
-
// names no GitHub repo.
|
|
84
|
+
// `directory` is where in the repo the package sits, `''` at the repo
|
|
85
|
+
// root, absent where it declares none. Throws when the package cannot be
|
|
86
|
+
// fetched or names no GitHub repo.
|
|
55
87
|
export interface GitHubLink {
|
|
56
88
|
github: string
|
|
57
89
|
directory?: string
|
|
@@ -71,7 +103,10 @@ export function resolvePackageRepos(packageNames: Iterable<string>, options?: {
|
|
|
71
103
|
// The disk cache resolvePackageRepos reads and writes, a month per entry.
|
|
72
104
|
// A read answers null for anything but a usable entry, one written by a
|
|
73
105
|
// release that resolved repos by other rules included; a write answers
|
|
74
|
-
// false where it could not write, and never throws.
|
|
106
|
+
// false where it could not write, and never throws. A write takes the
|
|
107
|
+
// `github` a lookup gives, `owner/name` with no trailing `.git`, so what
|
|
108
|
+
// it writes reads back; a `directory` left out is unknown, and `''` the
|
|
109
|
+
// repo root.
|
|
75
110
|
export function readPackageRepoCache(name: string): Promise<PackageRepo | null>
|
|
76
111
|
export function writePackageRepoCache(name: string, github: string, directory?: string): Promise<boolean>
|
|
77
112
|
|
|
@@ -84,25 +119,83 @@ export interface Dist {
|
|
|
84
119
|
integrity: string
|
|
85
120
|
}
|
|
86
121
|
|
|
122
|
+
// `gitHead` is the commit the document names, as npm reads it off the git
|
|
123
|
+
// checkout it publishes from, where it is a full commit id: 40 lowercase
|
|
124
|
+
// hex digits, or 64. `repository`, `homepage` and `bugs` are the
|
|
125
|
+
// document's, as the package.json published had them, or npm filled them
|
|
126
|
+
// in from one another: each a string as it is, or for `repository` and
|
|
127
|
+
// `bugs` an object, of which only the strings named below are read. Each is
|
|
128
|
+
// absent where the document has none, or has another shape, or an object
|
|
129
|
+
// with none of those strings. All of it is the publisher's word, held to no
|
|
130
|
+
// repository.
|
|
87
131
|
export interface PackageMeta {
|
|
88
132
|
name: string
|
|
89
133
|
version: string
|
|
90
134
|
dist: Dist
|
|
135
|
+
gitHead?: string
|
|
136
|
+
repository?: string | PackageRepository
|
|
137
|
+
homepage?: string
|
|
138
|
+
bugs?: string | PackageBugs
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface PackageRepository {
|
|
142
|
+
type: string | undefined
|
|
143
|
+
url: string | undefined
|
|
144
|
+
directory: string | undefined
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface PackageBugs {
|
|
148
|
+
url: string | undefined
|
|
149
|
+
email: string | undefined
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// getMeta's options: `cache`, and the `dist` a caller already has of that
|
|
153
|
+
// version, as a lockfile gives it, held to the rules above.
|
|
154
|
+
export interface MetaOptions extends CacheOptions {
|
|
155
|
+
dist?: Dist
|
|
91
156
|
}
|
|
92
157
|
|
|
93
158
|
// The registry's version document, refused unless it is for that name and
|
|
94
159
|
// version and its dist is held to the rules above.
|
|
95
|
-
|
|
160
|
+
//
|
|
161
|
+
// With `dist`, npm's own cache comes first, where getTarball looks for
|
|
162
|
+
// npm's tarballs: where it keeps the full packument of that name, as npm 10
|
|
163
|
+
// and later fetch it, and that version's entry there has the given dist's
|
|
164
|
+
// tarball and integrity, that entry answers, with no request, and neither
|
|
165
|
+
// `cache` nor setCacheDir's cache is read or written. An abbreviated
|
|
166
|
+
// packument, as earlier npm fetches, is passed over, as is one whose
|
|
167
|
+
// content does not match the sha512 npm filed it by. What it answers
|
|
168
|
+
// beside the dist is taken from npm's cache as it is from setCacheDir's.
|
|
169
|
+
// Else the document `cache` keeps answers, with no request, where its
|
|
170
|
+
// tarball and integrity are the given dist's; else the registry's is asked
|
|
171
|
+
// for, and throws where they are not.
|
|
172
|
+
//
|
|
173
|
+
// Without `dist`, the registry is asked on every call: a cache never
|
|
174
|
+
// supplies a dist. Kept whole, as `cache` says, and for good once it
|
|
175
|
+
// passes, as the registry never takes a version twice: in setCacheDir's
|
|
176
|
+
// cache, compressed, where `cache` is left out. One refused is not kept.
|
|
177
|
+
export function getMeta(name: string, version: string, options?: MetaOptions): Promise<PackageMeta>
|
|
178
|
+
|
|
179
|
+
// When the registry says each version of a package it lists was published,
|
|
180
|
+
// by version, as Date#toISOString writes it: from the whole package's
|
|
181
|
+
// document, the only one with `time`, megabytes for some. A version whose
|
|
182
|
+
// time is missing, not an ISO 8601 UTC time, or not one there is, as
|
|
183
|
+
// 2018-02-29, is left out. Refused unless the document is for that name.
|
|
184
|
+
export function getPublishTimes(name: string): Promise<Map<string, string>>
|
|
96
185
|
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
186
|
+
// Throws unless the integrity of that version is the one given, as for a
|
|
187
|
+
// dist read off a lockfile: by the version document `cache` keeps, with no
|
|
188
|
+
// request, else by the registry's, kept then as getMeta keeps it. One kept
|
|
189
|
+
// with another integrity, refused, or for another name or version, is
|
|
190
|
+
// passed over for the registry's, which throws where it has another.
|
|
191
|
+
export function verifyDist(name: string, version: string, dist: Dist, options?: CacheOptions): Promise<void>
|
|
100
192
|
|
|
101
193
|
// A published version's gzipped tarball, whole, in memory. Without `dist`,
|
|
102
|
-
// the version document is fetched on every call, cached tarball or not
|
|
103
|
-
// with one, it is trusted as given and
|
|
104
|
-
// for. Either way the bytes are checked
|
|
105
|
-
// they were downloaded (before they are
|
|
194
|
+
// the version document is fetched on every call, cached tarball or not,
|
|
195
|
+
// and kept as getMeta keeps it; with one, it is trusted as given and
|
|
196
|
+
// nothing but the tarball is asked for. Either way the bytes are checked
|
|
197
|
+
// against `dist.integrity`, whether they were downloaded (before they are
|
|
198
|
+
// cached) or read from a cache.
|
|
106
199
|
//
|
|
107
200
|
// Other caches are read first, and never written: npm's (cacache under
|
|
108
201
|
// npm_config_cache, else npm's default, `~/.npm` outside Windows; and npm
|
|
@@ -110,5 +203,7 @@ export function verifyDist(name: string, version: string, dist: Dist): Promise<v
|
|
|
110
203
|
// `~/.audit/cache/tgz/<org>:<name>-<version>.tgz`, then defaultCacheDir
|
|
111
204
|
// and cacheDirFor('stasis'), as setCacheDir files a tarball in either,
|
|
112
205
|
// whether set or not. A file there that does not match is passed over.
|
|
113
|
-
// Then setCacheDir's cache,
|
|
114
|
-
|
|
206
|
+
// Then setCacheDir's cache, or a `cache` store in its place, where bytes
|
|
207
|
+
// that do not match throw. A tarball downloaded is kept there, unless
|
|
208
|
+
// `cache` is false.
|
|
209
|
+
export function getTarball(name: string, version: string, dist?: Dist, options?: CacheOptions): Promise<Uint8Array>
|
package/npm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { cacheDirFor, defaultCacheDir, setCacheDir } from './src/cache.js'
|
|
2
2
|
export { HttpError } from './src/http.js'
|
|
3
3
|
export { getGitHub, readPackageRepoCache, resolvePackageRepos, writePackageRepoCache } from './src/npm/repos.js'
|
|
4
|
-
export { getMeta, getTarball, verifyDist } from './src/npm/tarball.js'
|
|
4
|
+
export { getMeta, getPublishTimes, getTarball, verifyDist } from './src/npm/tarball.js'
|
package/package.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
// Hand-written against package.js; a change to either belongs with the other.
|
|
2
|
-
|
|
3
1
|
export interface PackageRepoLink {
|
|
4
2
|
// `owner/name`, by GitHub's own rules.
|
|
5
3
|
github?: string
|
|
6
4
|
// Where in that repo the package sits, `/`-separated, as the tree path
|
|
7
|
-
// itself (a homepage URL's decoded
|
|
8
|
-
// `
|
|
5
|
+
// itself (a homepage URL's decoded; a `repository.directory`'s `\` read
|
|
6
|
+
// as `/`, its empty and `.` parts dropped); `''` at its root, where
|
|
7
|
+
// `repository.directory` declares it (`./`, `/`, `/.`, `.`, `''`). Absent
|
|
8
|
+
// where unknown: neither field names a directory in it (one with a `..`
|
|
9
|
+
// part names none), and whenever `github` is absent.
|
|
9
10
|
directory?: string
|
|
10
11
|
// `https://github.com/<github>`, whenever there is a `github`.
|
|
11
12
|
url?: string
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@preventive/upstream",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Minimal npm, crates.io and Soldeer registry clients, a GitHub client, and a git checkout reader: the calls we use, nothing more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -85,9 +85,12 @@
|
|
|
85
85
|
"src/github/read.js",
|
|
86
86
|
"src/github/write.js",
|
|
87
87
|
"src/http.js",
|
|
88
|
+
"src/lockfiles.js",
|
|
89
|
+
"src/npm/cacache.js",
|
|
88
90
|
"src/npm/registry.js",
|
|
89
91
|
"src/npm/repos.js",
|
|
90
92
|
"src/npm/tarball.js",
|
|
93
|
+
"src/npm/versions.js",
|
|
91
94
|
"src/package.js",
|
|
92
95
|
"src/pool.js",
|
|
93
96
|
"src/remote.js",
|
package/semver.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// Hand-written against semver.js; a change to either belongs with the other.
|
|
2
|
-
|
|
3
1
|
// npm's own semver, borrowed from the npm beside node and passed through
|
|
4
2
|
// as it is; where there is no npm, the `semver` package, an optional peer
|
|
5
3
|
// dependency. Without either, every call throws, except valid() on a plain
|
package/soldeer.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Hand-written against soldeer.js; a change to either belongs with the
|
|
2
|
-
// other.
|
|
3
|
-
//
|
|
4
1
|
// The name is asserted to be one Soldeer takes, the version a string of
|
|
5
2
|
// letters, digits, `.`, `_`, `+` and `-`, and the checksum 64 lowercase hex
|
|
6
3
|
// digits, before any request or cache path. The cache is setCacheDir's
|