@pnpm/pnpr 0.0.0-26062301 → 0.0.0-26070201
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/README.md +4 -4
- package/bin/pnpr +4 -76
- package/install.js +178 -0
- package/package.json +14 -9
package/README.md
CHANGED
|
@@ -28,11 +28,11 @@ Start the server with the bundled default config:
|
|
|
28
28
|
pnpr
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
It listens on `127.0.0.1:
|
|
31
|
+
It listens on `127.0.0.1:7677` and proxies `https://registry.npmjs.org/`
|
|
32
32
|
by default. Point a client at it with:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
pnpm config set registry http://127.0.0.1:
|
|
35
|
+
pnpm config set registry http://127.0.0.1:7677/
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## CLI flags
|
|
@@ -40,7 +40,7 @@ pnpm config set registry http://127.0.0.1:4873/
|
|
|
40
40
|
| Flag | Description |
|
|
41
41
|
| --- | --- |
|
|
42
42
|
| `-c, --config <path>` | Path to a verdaccio-shaped YAML config. When omitted, the bundled default is used. |
|
|
43
|
-
| `--listen <addr>` | Address to bind to. Defaults to `127.0.0.1:
|
|
43
|
+
| `--listen <addr>` | Address to bind to. Defaults to `127.0.0.1:7677`. |
|
|
44
44
|
| `--storage <path>` | Override the storage directory from the loaded config. |
|
|
45
45
|
| `--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
46
|
| `--public-url <url>` | URL clients should use to reach the server, used when rewriting `dist.tarball` in served packuments. Defaults to `http://<listen>`. |
|
|
@@ -165,7 +165,7 @@ packages:
|
|
|
165
165
|
```sh
|
|
166
166
|
export AWS_ACCESS_KEY_ID="<r2-access-key-id>"
|
|
167
167
|
export AWS_SECRET_ACCESS_KEY="<r2-secret-access-key>"
|
|
168
|
-
pnpr -c ./pnpr.yaml --listen 0.0.0.0:
|
|
168
|
+
pnpr -c ./pnpr.yaml --listen 0.0.0.0:7677 --public-url https://registry.example.com
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
(`--public-url` is what rewrites the `dist.tarball` URLs in served
|
package/bin/pnpr
CHANGED
|
@@ -1,76 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
win32: {
|
|
6
|
-
x64: "@pnpm/pnpr.win32-x64/pnpr.exe",
|
|
7
|
-
arm64: "@pnpm/pnpr.win32-arm64/pnpr.exe",
|
|
8
|
-
},
|
|
9
|
-
darwin: {
|
|
10
|
-
x64: "@pnpm/pnpr.darwin-x64/pnpr",
|
|
11
|
-
arm64: "@pnpm/pnpr.darwin-arm64/pnpr",
|
|
12
|
-
},
|
|
13
|
-
linux: {
|
|
14
|
-
x64: {
|
|
15
|
-
glibc: "@pnpm/pnpr.linux-x64/pnpr",
|
|
16
|
-
musl: "@pnpm/pnpr.linux-x64-musl/pnpr",
|
|
17
|
-
},
|
|
18
|
-
arm64: {
|
|
19
|
-
glibc: "@pnpm/pnpr.linux-arm64/pnpr",
|
|
20
|
-
musl: "@pnpm/pnpr.linux-arm64-musl/pnpr",
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const binPath = getBinPath();
|
|
26
|
-
if (binPath) {
|
|
27
|
-
const result = require("child_process").spawnSync(
|
|
28
|
-
require.resolve(binPath),
|
|
29
|
-
process.argv.slice(2),
|
|
30
|
-
{
|
|
31
|
-
shell: false,
|
|
32
|
-
stdio: "inherit",
|
|
33
|
-
env,
|
|
34
|
-
}
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
if (result.error) {
|
|
38
|
-
throw result.error;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// result.status is null when the child was killed by a signal; falling
|
|
42
|
-
// through to `exitCode = null` would make the wrapper appear to exit 0
|
|
43
|
-
// and mask the signal. Re-raise the signal so the parent terminates
|
|
44
|
-
// the same way; fall back to a non-zero exit if that's not possible.
|
|
45
|
-
if (typeof result.status === "number") {
|
|
46
|
-
process.exitCode = result.status;
|
|
47
|
-
} else if (result.signal) {
|
|
48
|
-
process.kill(process.pid, result.signal);
|
|
49
|
-
} else {
|
|
50
|
-
process.exitCode = 1;
|
|
51
|
-
}
|
|
52
|
-
} else {
|
|
53
|
-
console.error(
|
|
54
|
-
"The @pnpm/pnpr package doesn't ship with prebuilt binaries for your platform yet. " +
|
|
55
|
-
"You can create an issue at https://github.com/pnpm/pnpm/issues for support."
|
|
56
|
-
);
|
|
57
|
-
process.exitCode = 1;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function getBinPath() {
|
|
61
|
-
const platformEntry = PLATFORMS?.[platform]?.[arch];
|
|
62
|
-
|
|
63
|
-
if (platformEntry == null || typeof platformEntry === "string") {
|
|
64
|
-
return platformEntry;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return platformEntry[detectLinuxLibc()];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function detectLinuxLibc() {
|
|
71
|
-
if (platform !== "linux") {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return process.report.getReport().header.glibcVersionRuntime ? "glibc" : "musl";
|
|
76
|
-
}
|
|
1
|
+
This is a placeholder. pnpr's native binary replaces this file during
|
|
2
|
+
installation (see ../install.js). If you are reading this, the install/build
|
|
3
|
+
script did not run — reinstall with build scripts enabled (e.g. allow-list
|
|
4
|
+
@pnpm/pnpr's build under pnpm or Bun, or drop --ignore-scripts).
|
package/install.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Preinstall: replace the placeholder `bin/pnpr` with the platform's native
|
|
3
|
+
// binary, so the command runs the binary directly instead of paying Node.js
|
|
4
|
+
// startup on every call. Mirrors how `@pnpm/exe` ships pnpm.
|
|
5
|
+
//
|
|
6
|
+
// The published `bin/pnpr` is a shebang-less placeholder: the Windows `.bin`
|
|
7
|
+
// shim is generated from the bin file, so a Node launcher there would bake in a
|
|
8
|
+
// `node bin/pnpr` call this script cannot rewrite (npm does not re-read
|
|
9
|
+
// package.json after preinstall). The cost is that there is no fallback — when
|
|
10
|
+
// build scripts are blocked (`--ignore-scripts`, pnpm/Bun defaults) the
|
|
11
|
+
// placeholder stays until the build is allow-listed.
|
|
12
|
+
import console from 'node:console'
|
|
13
|
+
import fs from 'node:fs'
|
|
14
|
+
import { createRequire } from 'node:module'
|
|
15
|
+
import path from 'node:path'
|
|
16
|
+
import process from 'node:process'
|
|
17
|
+
import { fileURLToPath } from 'node:url'
|
|
18
|
+
|
|
19
|
+
const require = createRequire(import.meta.url)
|
|
20
|
+
const ownDir = path.dirname(fileURLToPath(import.meta.url))
|
|
21
|
+
const { platform, arch } = process
|
|
22
|
+
|
|
23
|
+
const PLATFORMS = {
|
|
24
|
+
win32: {
|
|
25
|
+
x64: '@pnpm/pnpr.win32-x64/pnpr.exe',
|
|
26
|
+
arm64: '@pnpm/pnpr.win32-arm64/pnpr.exe',
|
|
27
|
+
},
|
|
28
|
+
darwin: {
|
|
29
|
+
x64: '@pnpm/pnpr.darwin-x64/pnpr',
|
|
30
|
+
arm64: '@pnpm/pnpr.darwin-arm64/pnpr',
|
|
31
|
+
},
|
|
32
|
+
linux: {
|
|
33
|
+
x64: {
|
|
34
|
+
glibc: '@pnpm/pnpr.linux-x64/pnpr',
|
|
35
|
+
musl: '@pnpm/pnpr.linux-x64-musl/pnpr',
|
|
36
|
+
},
|
|
37
|
+
arm64: {
|
|
38
|
+
glibc: '@pnpm/pnpr.linux-arm64/pnpr',
|
|
39
|
+
musl: '@pnpm/pnpr.linux-arm64-musl/pnpr',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setup()
|
|
45
|
+
|
|
46
|
+
function setup () {
|
|
47
|
+
const candidates = getBinCandidates()
|
|
48
|
+
if (candidates.length === 0) {
|
|
49
|
+
fail(`@pnpm/pnpr does not ship a prebuilt binary for ${platform}-${arch}.`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Use whichever platform package the package manager installed: it already
|
|
53
|
+
// filtered by `os`/`cpu`/`libc`, more reliable than re-deriving the host.
|
|
54
|
+
let nativeBinary
|
|
55
|
+
for (const target of candidates) {
|
|
56
|
+
try {
|
|
57
|
+
nativeBinary = require.resolve(target)
|
|
58
|
+
break
|
|
59
|
+
} catch {
|
|
60
|
+
// Not installed for this host; try the next candidate.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (nativeBinary == null) {
|
|
64
|
+
const pkgName = candidates[0].split('/').slice(0, 2).join('/')
|
|
65
|
+
fail(
|
|
66
|
+
`The "${pkgName}" package is not installed, so pnpr has no native binary to run.\n` +
|
|
67
|
+
'If your package manager skipped optional dependencies or blocked build scripts, ' +
|
|
68
|
+
'enable them and reinstall.'
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const binDir = path.join(ownDir, 'bin')
|
|
73
|
+
if (platform === 'win32') {
|
|
74
|
+
// The existing shim points at `bin/pnpr`, so that file must become the
|
|
75
|
+
// binary; the `.exe` twin and `bin` rewrite are for shims generated later.
|
|
76
|
+
placeBinary(nativeBinary, path.join(binDir, 'pnpr.exe'))
|
|
77
|
+
placeBinary(nativeBinary, path.join(binDir, 'pnpr'))
|
|
78
|
+
rewriteBin('bin/pnpr.exe')
|
|
79
|
+
} else {
|
|
80
|
+
placeBinary(nativeBinary, path.join(binDir, 'pnpr'), 0o755)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Atomically place `nativeBinary` at `destPath` (hard link, falling back to a
|
|
86
|
+
* copy across filesystems, via a temp file + rename). Exits the process on
|
|
87
|
+
* failure — without the binary there is no working `pnpr`.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} nativeBinary Absolute path to the resolved native binary.
|
|
90
|
+
* @param {string} destPath Absolute path to create.
|
|
91
|
+
* @param {number} [mode] chmod for the copy path only; a hard link shares the
|
|
92
|
+
* source inode (the shared store blob under pnpm), so its mode must not change.
|
|
93
|
+
*/
|
|
94
|
+
function placeBinary (nativeBinary, destPath, mode) {
|
|
95
|
+
const tempPath = `${destPath}.pnpr-tmp`
|
|
96
|
+
try {
|
|
97
|
+
fs.rmSync(tempPath, { force: true })
|
|
98
|
+
let linked = false
|
|
99
|
+
try {
|
|
100
|
+
fs.linkSync(nativeBinary, tempPath)
|
|
101
|
+
linked = true
|
|
102
|
+
} catch {
|
|
103
|
+
fs.copyFileSync(nativeBinary, tempPath)
|
|
104
|
+
}
|
|
105
|
+
if (!linked && mode != null) {
|
|
106
|
+
fs.chmodSync(tempPath, mode)
|
|
107
|
+
}
|
|
108
|
+
fs.renameSync(tempPath, destPath)
|
|
109
|
+
} catch (err) {
|
|
110
|
+
try {
|
|
111
|
+
fs.rmSync(tempPath, { force: true })
|
|
112
|
+
} catch {
|
|
113
|
+
// Nothing to clean up.
|
|
114
|
+
}
|
|
115
|
+
fail(`Could not install the pnpr binary at ${destPath}: ${err.message}`)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function rewriteBin (binValue) {
|
|
120
|
+
const pkgJsonPath = path.join(ownDir, 'package.json')
|
|
121
|
+
// Write a fresh file and rename it over package.json rather than truncating in
|
|
122
|
+
// place: pnpm hard-links package.json from its content-addressable store, so an
|
|
123
|
+
// in-place write would mutate the shared store blob. Best-effort — it only
|
|
124
|
+
// helps shims generated later.
|
|
125
|
+
const tempPath = `${pkgJsonPath}.pnpr-tmp`
|
|
126
|
+
try {
|
|
127
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))
|
|
128
|
+
pkg.bin = binValue
|
|
129
|
+
fs.writeFileSync(tempPath, JSON.stringify(pkg, null, 2))
|
|
130
|
+
fs.renameSync(tempPath, pkgJsonPath)
|
|
131
|
+
} catch {
|
|
132
|
+
try {
|
|
133
|
+
fs.rmSync(tempPath, { force: true })
|
|
134
|
+
} catch {
|
|
135
|
+
// Nothing to clean up.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function fail (message) {
|
|
141
|
+
console.error(message)
|
|
142
|
+
process.exit(1)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Native binary specifiers to try, most-preferred first; empty when the host is
|
|
147
|
+
* unsupported. The linux glibc/musl pair is ordered by detected libc, which
|
|
148
|
+
* only decides the winner when both are installed (e.g. `npm install --force`).
|
|
149
|
+
*
|
|
150
|
+
* @returns {string[]}
|
|
151
|
+
*/
|
|
152
|
+
function getBinCandidates () {
|
|
153
|
+
const platformEntry = PLATFORMS?.[platform]?.[arch]
|
|
154
|
+
|
|
155
|
+
if (platformEntry == null) {
|
|
156
|
+
return []
|
|
157
|
+
}
|
|
158
|
+
if (typeof platformEntry === 'string') {
|
|
159
|
+
return [platformEntry]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const order = detectLinuxLibc() === 'musl' ? ['musl', 'glibc'] : ['glibc', 'musl']
|
|
163
|
+
return order.map((libc) => platformEntry[libc])
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function detectLinuxLibc () {
|
|
167
|
+
if (platform !== 'linux') {
|
|
168
|
+
return null
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// glibc builds set `glibcVersionRuntime`; musl leaves it unset. Guarded —
|
|
172
|
+
// `process.report` may be unavailable, leaving ordering to the default.
|
|
173
|
+
try {
|
|
174
|
+
return process.report?.getReport().header.glibcVersionRuntime ? 'glibc' : 'musl'
|
|
175
|
+
} catch {
|
|
176
|
+
return null
|
|
177
|
+
}
|
|
178
|
+
}
|
package/package.json
CHANGED
|
@@ -14,23 +14,28 @@
|
|
|
14
14
|
"url": "https://github.com/pnpm/pnpm",
|
|
15
15
|
"directory": "pnpr/npm/pnpr"
|
|
16
16
|
},
|
|
17
|
+
"type": "module",
|
|
17
18
|
"engines": {
|
|
18
19
|
"node": ">=18.*"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
22
|
"bin/pnpr",
|
|
23
|
+
"install.js",
|
|
22
24
|
"LICENSE.md"
|
|
23
25
|
],
|
|
24
|
-
"version": "0.0.0-
|
|
26
|
+
"version": "0.0.0-26070201",
|
|
25
27
|
"optionalDependencies": {
|
|
26
|
-
"@pnpm/pnpr.win32-x64": "0.0.0-
|
|
27
|
-
"@pnpm/pnpr.win32-arm64": "0.0.0-
|
|
28
|
-
"@pnpm/pnpr.darwin-x64": "0.0.0-
|
|
29
|
-
"@pnpm/pnpr.darwin-arm64": "0.0.0-
|
|
30
|
-
"@pnpm/pnpr.linux-x64": "0.0.0-
|
|
31
|
-
"@pnpm/pnpr.linux-arm64": "0.0.0-
|
|
32
|
-
"@pnpm/pnpr.linux-x64-musl": "0.0.0-
|
|
33
|
-
"@pnpm/pnpr.linux-arm64-musl": "0.0.0-
|
|
28
|
+
"@pnpm/pnpr.win32-x64": "0.0.0-26070201",
|
|
29
|
+
"@pnpm/pnpr.win32-arm64": "0.0.0-26070201",
|
|
30
|
+
"@pnpm/pnpr.darwin-x64": "0.0.0-26070201",
|
|
31
|
+
"@pnpm/pnpr.darwin-arm64": "0.0.0-26070201",
|
|
32
|
+
"@pnpm/pnpr.linux-x64": "0.0.0-26070201",
|
|
33
|
+
"@pnpm/pnpr.linux-arm64": "0.0.0-26070201",
|
|
34
|
+
"@pnpm/pnpr.linux-x64-musl": "0.0.0-26070201",
|
|
35
|
+
"@pnpm/pnpr.linux-arm64-musl": "0.0.0-26070201"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"preinstall": "node install.js"
|
|
34
39
|
},
|
|
35
40
|
"bin": {
|
|
36
41
|
"pnpr": "bin/pnpr"
|