@pnpm/pnpr 0.1.0-alpha.10 → 0.1.0-alpha.11
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/CHANGELOG.md +64 -0
- package/README.md +73 -0
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# @pnpm/pnpr
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.11
|
|
4
|
+
|
|
5
|
+
pnpr now serves Cargo, Python, and container registries alongside npm, publishes across all of them in one transaction, and signs users in through OIDC.
|
|
6
|
+
|
|
7
|
+
### Minor Changes
|
|
8
|
+
|
|
9
|
+
#### Cargo and Python registries
|
|
10
|
+
|
|
11
|
+
- pnpr now serves Cargo and Python registries alongside npm from one instance. Hosted Cargo registries support `cargo publish`, `cargo yank`, and crate downloads. Hosted Python registries support `pip install --index-url` and `twine upload`. Upstream registries can proxy crates.io and PyPI with checksum verified downloads, and a router can combine sources from all three ecosystems.
|
|
12
|
+
|
|
13
|
+
A registry that serves more than one ecosystem addresses them through `/npm/`, `/cargo/`, and `/pypi/`. A registry that serves only one ecosystem keeps serving packages at the root, so existing npm URLs still work. A `/~<name>/` registry prefix must arrive with an unencoded `~`.
|
|
14
|
+
|
|
15
|
+
Registry names can be reused across ecosystems by grouping configuration under `registries.npm`, `registries.cargo`, `registries.pypi`, or `registries.oci`. Router sources and defaults resolve within their own ecosystem.
|
|
16
|
+
|
|
17
|
+
- `pnpm install` now resolves Cargo and Python dependencies through the server configured in `pnprServer`. The client no longer fetches one sparse-index file per crate in the dependency graph, and no longer downloads a wheel to find out what it requires. If the server does not serve that resolution, pnpm resolves those dependencies locally.
|
|
18
|
+
|
|
19
|
+
- `pnpm install` can install Cargo dependencies from the sparse registry configured by `cargo.indexUrl`. The generated `Cargo.lock` records that registry as the source of every crate.
|
|
20
|
+
|
|
21
|
+
- `cargo search` works against a pnpr registry. It matches on crate name over the crates the registry hosts. Each result reports the crate's newest release that is not yanked, and a crate whose releases are all yanked reports its newest release.
|
|
22
|
+
|
|
23
|
+
#### Container images
|
|
24
|
+
|
|
25
|
+
- pnpr now serves container images [#14630](https://github.com/pnpm/pnpm/issues/14630). Declare a registry with `ecosystem: oci`, then push to it with `docker`, `podman`, or `skopeo`. The distribution API answers at `/v2/` on the host root, and an image keeps its own name with no registry key in the path. Sign in with `docker login`, using a pnpr token as the password, or set `oci.bearerAuth: true` to hand clients short lived, repository scoped credentials instead.
|
|
26
|
+
|
|
27
|
+
Ranged blob downloads, cross repository blob mounts, the referrers API, and paginated tag and repository listings are supported. Authorized users can delete unreferenced blobs, and a blob that a retained manifest still reaches stays protected while another publish is running. `oci.maxBlobBytes` and `oci.maxManifestBytes` cap what a client may upload.
|
|
28
|
+
|
|
29
|
+
- pnpr can cache image pulls from Docker Hub and GHCR [#14630](https://github.com/pnpm/pnpm/issues/14630). Upstream authentication supports repository scoped bearer tokens, and pnpr verifies every cached image by digest. A proxied download whose contents fail verification is aborted and stays out of the cache.
|
|
30
|
+
|
|
31
|
+
- pnpr can resume OCI uploads across replicas when it keeps blobs in S3. Abandoned shared upload sessions expire at startup after 24 hours of inactivity. `pnpr oci-gc --registry <name>` collects old, unreferenced image blobs while registry writers are stopped, and `--dry-run` previews the cleanup.
|
|
32
|
+
|
|
33
|
+
#### Publishing and authentication
|
|
34
|
+
|
|
35
|
+
- pnpr can now publish packages of more than one ecosystem in a single transaction. `PUT /-/pnpr/v0/publish` takes a batch whose entries each name their `ecosystem`, so a workspace that ships an npm package, a crate, and a Python distribution releases them together. OCI manifests can ride along in the same batch once their layers are uploaded [#14630](https://github.com/pnpm/pnpm/issues/14630). A batch that fails a check publishes none of it, and a server that stops midway finishes the release on the next startup. An entry without an `ecosystem` is an npm publish document, the same one `PUT /-/pnpm/v1/publish` takes.
|
|
36
|
+
|
|
37
|
+
- pnpr now supports OIDC browser sign in. Administrators can map provider subjects to registry users, and GitHub Actions can publish npm packages without a persistent registry token. Workload publishing is restricted to the packages you configure.
|
|
38
|
+
|
|
39
|
+
#### Builds and pipelines
|
|
40
|
+
|
|
41
|
+
- pnpr can share Cargo compilation caches between CI and developers through sccache. Configure `artifacts.compilerCaches` to grant read and publication access separately. sccache can combine its local disk cache with pnpr's remote cache.
|
|
42
|
+
|
|
43
|
+
- pnpr can store `pnpm pipeline` run reports. Turn it on with `pipeline.enabled` and configure each workspace's `access` and `publish` permissions under `pipeline.workspaces`. `pnpm pipeline --report` and `--report-to` submit run summaries and events, and pnpr answers with authenticated listing and detail endpoints and a web viewer. Records are kept with the hosted packages, so a run submitted through one replica is listed and served by every other.
|
|
44
|
+
|
|
45
|
+
#### Discovery and administration
|
|
46
|
+
|
|
47
|
+
- pnpr can now serve browser registry UIs through an origin allowlist. Search supports pagination and maintainer filters, organization package listings are available, and authenticated publishers are recorded for discovery. Upstream discovery can be enabled per registry. Passing `browse=true` to the search APIs pages through the npm packages and Cargo crates a registry hosts, respecting its routing and package access rules.
|
|
48
|
+
|
|
49
|
+
A registry directory endpoint lists the named registries, ecosystem endpoints, and routing order that the current user can see.
|
|
50
|
+
|
|
51
|
+
- pnpr now reads every command line option from an environment variable when the flag is omitted. The variable is named after the flag with a `PNPR_` prefix, so `--public-url` becomes `PNPR_PUBLIC_URL` and `--disable-resolver` becomes `PNPR_DISABLE_RESOLVER`. A flag given on the command line wins over its environment variable. Boolean flags accept `true`, `1`, `yes`, `on`, `false`, `0`, `no`, and `off`.
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- pnpr now rejects a package name that carries `?`, `#`, `%`, whitespace, or a control character, and holds artifact filenames to the same rule. A percent encoded delimiter let a request read an upstream package under a name the access rules had not checked.
|
|
56
|
+
|
|
57
|
+
- pnpr now resolves JSR packages without configuration. npm.jsr.io is a built-in public route, like the npm registry. The built-in routes are reachable over HTTPS only.
|
|
58
|
+
|
|
59
|
+
- A publish that loses a write race now reports `document_write_conflict` on every registry surface, and the message names the package document [#14599](https://github.com/pnpm/pnpm/issues/14599). A publish whose file another writer had already stored under the same name now answers `409` instead of `201`, which it answered while leaving the version out of the registry document. Both cases arise only where several pnpr instances share one object store.
|
|
60
|
+
|
|
61
|
+
- A staged publish is now approved once, whichever replica of a shared registry the approval reaches [#12199](https://github.com/pnpm/pnpm/issues/12199). A second approval of the same stage answers `409`. Rejecting a stage stops an approval that has not published it yet.
|
|
62
|
+
|
|
63
|
+
- Registration no longer fails when several users sign up at the same time against a libsql backend with a configured user limit.
|
|
64
|
+
|
|
65
|
+
- pnpr now records a URL's query exactly as it was written when it redacts the credentials in an error message. It re-encoded the query, rewriting `?options=a%20b` as `?options=a+b`.
|
|
66
|
+
|
|
3
67
|
## 0.1.0-alpha.10
|
|
4
68
|
|
|
5
69
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -35,6 +35,32 @@ by default. Point a client at it with:
|
|
|
35
35
|
pnpm config set registry http://127.0.0.1:7677/
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
### Install accelerator
|
|
39
|
+
|
|
40
|
+
pnpr also resolves dependencies on a client's behalf. Point pnpm at it
|
|
41
|
+
with `pnprServer` and pnpm sends its manifests instead of resolving
|
|
42
|
+
locally:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
pnpm config set pnprServer http://127.0.0.1:7677/
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
npm, Cargo and Python dependencies all resolve this way.
|
|
49
|
+
|
|
50
|
+
For Cargo, pnpr walks the crates.io sparse index and answers with the
|
|
51
|
+
`Cargo.lock`, so a workspace resolves without the client fetching one
|
|
52
|
+
index file per crate.
|
|
53
|
+
|
|
54
|
+
For Python, pnpr reads the index and answers with the `pylock.toml`.
|
|
55
|
+
Reading what a distribution requires means reading a wheel's `METADATA`,
|
|
56
|
+
so a client resolving alone downloads whole wheels for versions it then
|
|
57
|
+
rejects; pnpr reads the metadata file the index publishes beside each
|
|
58
|
+
wheel instead. When an index publishes no such file, pnpr downloads the
|
|
59
|
+
wheel itself and keeps the metadata it holds, so only the first client
|
|
60
|
+
pays for that download.
|
|
61
|
+
|
|
62
|
+
Everything pnpr reads is cached for every client that follows.
|
|
63
|
+
|
|
38
64
|
## CLI flags
|
|
39
65
|
|
|
40
66
|
| Flag | Description |
|
|
@@ -45,6 +71,19 @@ pnpm config set registry http://127.0.0.1:7677/
|
|
|
45
71
|
| `--cache <path>` | Override the disposable proxy-cache directory (the mirror of upstream registries plus the resolver cache). Defaults to a `.pnpr-cache` subdirectory of `--storage`. |
|
|
46
72
|
| `--public-url <url>` | URL clients should use to reach the server, used when rewriting `dist.tarball` in served packuments. Defaults to `http://<listen>`. |
|
|
47
73
|
| `--packument-ttl-secs <n>` | Seconds before a cached packument is considered stale and refetched. |
|
|
74
|
+
| `--osv` | Enable local OSV npm vulnerability checks. Requires a local OSV npm database at `--osv-db` or `<cache>/osv/npm/all.zip`. |
|
|
75
|
+
| `--osv-db <path>` | Path to the local OSV npm database zip or extracted JSON directory. |
|
|
76
|
+
| `--disable-registry` | Disable the npm-registry surface (packument and tarball reads, publish, unpublish, dist-tag, search). |
|
|
77
|
+
| `--disable-resolver` | Disable the install-accelerator surface (`/-/pnpr/v0/resolve` for npm, Cargo and Python, `/-/pnpr/v0/verify-lockfile`). |
|
|
78
|
+
| `--disable-artifacts` | Disable the signed shared-artifact surface. |
|
|
79
|
+
|
|
80
|
+
Every flag can also be set through an environment variable named after
|
|
81
|
+
it: `PNPR_` followed by the flag name in upper case with dashes replaced
|
|
82
|
+
by underscores. `--public-url` becomes `PNPR_PUBLIC_URL` and
|
|
83
|
+
`--packument-ttl-secs` becomes `PNPR_PACKUMENT_TTL_SECS`. A flag given on
|
|
84
|
+
the command line wins over its environment variable. Boolean flags such
|
|
85
|
+
as `--disable-registry` accept `true`, `1`, `yes`, `on`, `false`, `0`,
|
|
86
|
+
`no`, and `off`.
|
|
48
87
|
|
|
49
88
|
Log level is controlled via the standard `RUST_LOG` environment
|
|
50
89
|
variable (e.g. `RUST_LOG=debug pnpr`).
|
|
@@ -272,6 +311,40 @@ When the `backend:` block is absent, auth stays on local disk and the
|
|
|
272
311
|
`auth.htpasswd` / `auth.tokens` settings apply as before. The
|
|
273
312
|
`auth.htpasswd.max_users` registration cap is honored either way.
|
|
274
313
|
|
|
314
|
+
### Running several replicas
|
|
315
|
+
|
|
316
|
+
Several `pnpr` processes can serve one registry behind a load balancer once
|
|
317
|
+
they share their state. Give every replica the same `s3:` bucket for hosted
|
|
318
|
+
packages and the same `backend:` database for users and tokens, and give each
|
|
319
|
+
its own `storage` path for what stays local.
|
|
320
|
+
|
|
321
|
+
Requests need no affinity. Every write into the shared bucket is conditional:
|
|
322
|
+
a publish, a `dist-tag` change, a partial unpublish, and the approval of a
|
|
323
|
+
staged publish each rewrite the package document under the `ETag` they read it
|
|
324
|
+
at, and a replica that loses the race re-reads and merges on top of what the
|
|
325
|
+
other one wrote. A published tarball is written only if its key is still free,
|
|
326
|
+
so two replicas publishing one version can never overwrite each other's bytes:
|
|
327
|
+
the one whose bytes did not land is told so with a `409` instead of
|
|
328
|
+
advertising an integrity the store no longer serves. A staged publish is
|
|
329
|
+
approved once, whichever replica the approval reaches.
|
|
330
|
+
|
|
331
|
+
This needs an object store that honors the `If-Match` and `If-None-Match`
|
|
332
|
+
preconditions. AWS S3, Cloudflare R2 and MinIO do.
|
|
333
|
+
|
|
334
|
+
What stays local to each replica:
|
|
335
|
+
|
|
336
|
+
- the proxy cache of upstream registries, and the resolver cache
|
|
337
|
+
- publish staging scratch and the commit journal that rolls an interrupted
|
|
338
|
+
publish forward, so keep each replica's `storage` path on a volume that
|
|
339
|
+
outlives its restarts
|
|
340
|
+
- blob upload sessions of the image registry when hosted packages are on
|
|
341
|
+
local disk, which is why `docker push` needs sticky sessions there; with
|
|
342
|
+
`s3:` an upload continues on any replica
|
|
343
|
+
- accounts and tokens, unless a `backend:` database is configured
|
|
344
|
+
|
|
345
|
+
Pipeline run records are shared: a run submitted through one replica is listed
|
|
346
|
+
and served by every other, and a run id stays append-only across all of them.
|
|
347
|
+
|
|
275
348
|
## License
|
|
276
349
|
|
|
277
350
|
Source-available under the [PolyForm Shield License 1.0.0](https://github.com/pnpm/pnpm/blob/main/pnpr/LICENSE.md) — **not** open source. You may run, modify, and self-host pnpr for any purpose except providing a product that competes with it. Commercial / non-compete licenses are available from Zoltan Kochan (<https://kochan.io>).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/pnpr",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"description": "pnpm-compatible npm registry server, written in Rust",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"LICENSE.md"
|
|
29
29
|
],
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@pnpm/pnpr.win32-x64": "0.1.0-alpha.
|
|
32
|
-
"@pnpm/pnpr.win32-arm64": "0.1.0-alpha.
|
|
33
|
-
"@pnpm/pnpr.darwin-x64": "0.1.0-alpha.
|
|
34
|
-
"@pnpm/pnpr.darwin-arm64": "0.1.0-alpha.
|
|
35
|
-
"@pnpm/pnpr.linux-x64": "0.1.0-alpha.
|
|
36
|
-
"@pnpm/pnpr.linux-arm64": "0.1.0-alpha.
|
|
37
|
-
"@pnpm/pnpr.linux-x64-musl": "0.1.0-alpha.
|
|
38
|
-
"@pnpm/pnpr.linux-arm64-musl": "0.1.0-alpha.
|
|
31
|
+
"@pnpm/pnpr.win32-x64": "0.1.0-alpha.11",
|
|
32
|
+
"@pnpm/pnpr.win32-arm64": "0.1.0-alpha.11",
|
|
33
|
+
"@pnpm/pnpr.darwin-x64": "0.1.0-alpha.11",
|
|
34
|
+
"@pnpm/pnpr.darwin-arm64": "0.1.0-alpha.11",
|
|
35
|
+
"@pnpm/pnpr.linux-x64": "0.1.0-alpha.11",
|
|
36
|
+
"@pnpm/pnpr.linux-arm64": "0.1.0-alpha.11",
|
|
37
|
+
"@pnpm/pnpr.linux-x64-musl": "0.1.0-alpha.11",
|
|
38
|
+
"@pnpm/pnpr.linux-arm64-musl": "0.1.0-alpha.11"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"preinstall": "node install.js"
|