Files
pnpm/pnpr/client
Zoltan Kochan de32f83a67 fix(pnpr): parse /v1/resolve NDJSON stream in the TypeScript client (#12246)
* fix(pnpr): parse /v1/resolve NDJSON stream in the TypeScript client

The pnpr server streams the /v1/resolve response as application/x-ndjson
(one package frame per resolved tarball, then a terminal done/error/
violations frame), but the TypeScript client still parsed the whole body
as a single JSON object, failing with "Unexpected non-whitespace
character after JSON". Parse the NDJSON frames and act on the terminal
frame instead.

Closes #12234 follow-up.

* fix(pnpr): reject unknown /v1/resolve frame types in the client

Fail fast with a protocol error when the NDJSON stream carries a frame
whose type is neither package nor a known terminal frame, instead of
returning it and surfacing a confusing lockfile error downstream.
2026-06-06 19:55:06 +02:00
..
2026-06-05 08:27:41 +02:00

@pnpm/pnpr.client

Client library for the pnpr server. Resolves a project's dependencies server-side and returns the resolved lockfile.

How it works

  1. Sends POST /v1/install to the pnpr server with the project's dependencies (and the existing lockfile, if any, for incremental resolution).
  2. The server resolves against the client's registries, verifies the input lockfile under the client's policy, and answers with one gzipped JSON object carrying the resolved lockfile and stats.
  3. Returns the resolved lockfile for use with pnpm's headless install, which fetches every tarball directly from the registries in parallel — like a normal install. See pnpm/pnpm#12230.

pnpr is a stateless resolver: it stores no tarballs and serves no file content.

Usage

This package is used internally by pnpm when the pnprServer config option is set. It is not intended to be called directly, but can be used programmatically:

import { fetchFromPnpmRegistry } from '@pnpm/pnpr.client'

const { lockfile, stats } = await fetchFromPnpmRegistry({
  registryUrl: 'http://localhost:4000',
  dependencies: { react: '^19.0.0' },
  devDependencies: { typescript: '^5.0.0' },
})

console.log(`Resolved ${stats.totalPackages} packages`)
// lockfile is ready for headless install

Configuration

Add to pnpm-workspace.yaml to enable automatically during pnpm install:

pnprServer: http://localhost:4000