Files
artifactapi/docs/npm/virtual.md
T
unkin-agent 2c671a1be7
ci/woodpecker/tag/docker Pipeline was successful
Add npm virtual repositories (#152)
npm clients need one registry for internal and public packages, but npm virtuals have no merger, so a local npm repo and npmjs cannot be served together.

- merge packuments across members: union versions (member order wins), first-defined dist-tags minus ones naming missing versions
- serve full and abbreviated (`install-v1`) packuments, scoped names included, via the shared virtual merge cache
- point tarballs at `<virtual>/<member>/<path>` and 302 them to the owning member
- reject an invalid Host with 400; serve virtual and local packuments `no-store` with `Vary: Host, X-Forwarded-Proto, Accept`
- return 502 when a member errors; skip members without the package
- add `docs/npm/virtual.md` and a stock `node:22` e2e-docker case

Reviewed-on: #152
Co-authored-by: unkin-agent <unkin-agent@unkin.net>
Co-committed-by: unkin-agent <unkin-agent@unkin.net>
2026-10-17 21:52:55 +11:00

1021 B

npm virtual

An npm virtual serves one registry over local and remote npm members: npm install and npm view work against /api/v1/virtual/<name>/.

  • Versions are the union across members; on a duplicate version the earlier member wins.
  • Each dist-tag comes from the first member defining it, and is dropped if it names a version missing from the merged set.
  • Tarball URLs point at the virtual (<member>/<path>), which 302s to the owning member.
  • Full and abbreviated (application/vnd.npm.install-v1+json) packuments are both served.
  • A member error fails the request with 502; a member without the package is skipped. Merges are cached for 60s per package.
resource "artifactapi_virtual" "npm" {
  name         = "npm"
  package_type = "npm"
  members      = [artifactapi_local_npm.internal.name, artifactapi_remote_npm.npmjs.name]
}
# .npmrc
registry=https://artifactapi.example.com/api/v1/virtual/npm/

Publish to the local member directly; the virtual is read-only.