@pnpm/napi 12.0.0-rc.8 → 12.0.0-rc.9

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @pnpm/napi
2
2
 
3
+ ## 12.0.0-rc.9
4
+
5
+ ### Minor Changes
6
+
7
+ - Added `fetchWarnTimeoutMs` and `fetchMinSpeedKiBps` to the Rust pnpm CLI and its N-API bindings. Slow registry metadata requests and tarball downloads now emit pnpm-compatible warnings without exposing URL credentials, query parameters, fragments, or control characters [pnpm/pnpm#12042](https://github.com/pnpm/pnpm/issues/12042).
8
+
3
9
  ## 12.0.0-rc.8
4
10
 
5
11
  ## 12.0.0-rc.7
package/README.md CHANGED
@@ -5,10 +5,20 @@ programmatic API — install, rebuild, dependency resolution, and pack — to a
5
5
  JavaScript host. The reference consumer is [Bit](https://bit.dev), which drives
6
6
  pnpm entirely through its programmatic API.
7
7
 
8
- This package binds only pnpm's **engine**. Pure data utilities that operate on
9
- in-memory objects or the (byte-stable) on-disk lockfile/store formats stay as
10
- regular `@pnpm/*` JS packages — both stacks share the same lockfile v9 shape,
11
- `.modules.yaml` format, and store layout.
8
+ This package binds pnpm's **engine**, and alongside it the pieces of pnpm a
9
+ host would otherwise have to reimplement over that engine: pnpm's terminal
10
+ output (`options.reporter`), its reverse dependency tree (`getDependents` /
11
+ `renderDependents`, what `pnpm why` is built on), and the files it owns —
12
+ `pnpm-lock.yaml` and `.modules.yaml` (`readLockfile` / `writeLockfile` /
13
+ `filterLockfileByImporters` / `readModulesManifest`). The lockfile ones
14
+ include pure in-memory transforms: `filterLockfileByImporters` touches no
15
+ disk at all. They are bound anyway, because the alternative is a second
16
+ implementation of a format the engine writes, kept in step by hand.
17
+
18
+ What stays a regular `@pnpm/*` JS package is what the engine has no part in:
19
+ type-only packages, and small pure helpers whose call sites are hot enough
20
+ that a boundary crossing per call would cost more than it saves (dep-path
21
+ string parsing runs once per graph edge).
12
22
 
13
23
  ## API
14
24
 
@@ -16,14 +26,61 @@ See [`index.d.ts`](./index.d.ts) for the full typed contract.
16
26
 
17
27
  | Export | Purpose |
18
28
  | --- | --- |
19
- | `install(options, onLog?, readPackageHook?)` | Install in-memory importers (single or workspace); `readPackageHook` transforms each resolved dependency manifest (must be synchronous). Returns `{ stats, depsRequiringBuild?, storeDir }`. |
20
- | `rebuild(options, onLog?, selectedNames?)` | Re-run dependency build scripts against a materialized install (frozen path). |
29
+ | `install(options, onLog?, readPackageHook?, onOutput?)` | Install in-memory importers (single or workspace); `readPackageHook` transforms each resolved dependency manifest (must be synchronous). Returns `{ stats, depsRequiringBuild?, storeDir }`. |
30
+ | `rebuild(options, onLog?, selectedNames?, onOutput?)` | Re-run dependency build scripts against a materialized install (frozen path). |
21
31
  | `resolveDependency(wanted, options)` | Resolve an npm-registry specifier to `{ id, manifest, resolvedVia, … }`. |
22
32
  | `pack(options, onLog?)` | Build a publishable `.tgz` from a project directory. |
23
33
  | `parseBareSpecifier(spec, alias?)` | Split/validate a dependency specifier; `null` when unparsable. |
34
+ | `getDependents(options)` | Every package matching `packages`, each with the reverse tree of what depends on it — the engine side of `pnpm why`. |
35
+ | `renderDependents(trees, options?)` | Return those trees rendered as `pnpm why` renders its own: `tree`, `parseable`, or `json`. |
36
+ | `readLockfile(options)` / `writeLockfile(options)` | Read and write `pnpm-lock.yaml` (or the current lockfile under the virtual store) with the engine's own parser and emitter. |
37
+ | `filterLockfileByImporters(lockfile, importerIds, options?)` | Narrow a lockfile to the transitive closure of what the named importers reach. |
38
+ | `readModulesManifest(modulesDir)` | The `.modules.yaml` state of an installed `node_modules`. |
24
39
  | `engineVersion()` | Version string of the underlying Rust engine (pacquet). |
25
40
  | `getPeerDependencyIssues(options)` | **Not yet implemented** — throws `ERR_PNPM_NAPI_UNIMPLEMENTED`. Peer-issue reporting is not ported in pacquet's CLI either; consumers should degrade gracefully. |
26
41
 
42
+ ### Output
43
+
44
+ Set `options.reporter` and the engine renders pnpm's own terminal output —
45
+ progress line, packages-diff summary, lifecycle output, the `Done in …`
46
+ footer — with the reporter `pnpm install` itself uses. Without it the call
47
+ prints nothing and `onLog` hands the host the raw event stream to render
48
+ however it likes.
49
+
50
+ By default the rendered chunks go to stdout. Pass `onOutput` to receive them
51
+ instead, for a host that has redirected its own output at the JavaScript
52
+ level (a monkey-patched `process.stdout.write`, a stream forwarding to a
53
+ remote terminal) where a write from Rust would bypass the redirection. Pass
54
+ `reporter.width` alongside it: the engine cannot see where those chunks end
55
+ up.
56
+
57
+ ### Lockfile
58
+
59
+ `readLockfile` / `writeLockfile` hand the host the engine's own parser and
60
+ emitter, so it does not carry a second implementation of a file both of them
61
+ own. The JSON crossing the boundary is the file's own shape — `LockfileFile`
62
+ in `@pnpm/lockfile.types` terms — and **top-level keys pnpm does not define
63
+ round-trip untouched**, so a host that records its own state beside the
64
+ lockfile can read it, edit its block, and write it back without losing the
65
+ rest. (An install builds a fresh lockfile rather than rewriting the previous
66
+ one, so a host re-asserts its block afterwards.)
67
+
68
+ `filterLockfileByImporters` is the engine-side `@pnpm/lockfile.filtering`:
69
+ the named importers keep only the dependency groups asked for, and
70
+ `packages` / `snapshots` are pruned to what they still reach.
71
+
72
+ ### Dependents (`pnpm why`)
73
+
74
+ `getDependents` returns the reverse trees as plain data and
75
+ `renderDependents` returns them rendered as a string — it prints nothing
76
+ itself — mirroring the split between
77
+ `@pnpm/deps.inspection.tree-builder` and `@pnpm/deps.inspection.list`. The
78
+ split is also what replaces that API's `nameFormatter` callback: the tree
79
+ walk is synchronous Rust and cannot call back into JavaScript, so a host
80
+ that renames nodes after a manifest field asks for the field via
81
+ `manifestFields`, writes `displayName` onto the returned trees, and passes
82
+ them back to be rendered.
83
+
27
84
  Errors are plain `Error` objects carrying pnpm's `code` (`ERR_PNPM_*`) and,
28
85
  where applicable, `hint` — lifted onto the error by the loader from the engine's
29
86
  structured envelope.
package/index.d.ts CHANGED
@@ -65,6 +65,8 @@ export interface NetworkConfig {
65
65
  fetchRetryMintimeout?: number
66
66
  fetchRetryMaxtimeout?: number
67
67
  fetchTimeout?: number
68
+ fetchWarnTimeoutMs?: number
69
+ fetchMinSpeedKiBps?: number
68
70
  userAgent?: string
69
71
  }
70
72
 
@@ -117,6 +119,10 @@ export interface InstallOptions extends SharedEngineOptions {
117
119
  dir: string
118
120
  projects: NodeApiProject[]
119
121
  storeDir?: string
122
+ /** Slow metadata-request warning threshold in milliseconds. Overrides `networkConfig`. */
123
+ fetchWarnTimeoutMs?: number
124
+ /** Minimum average tarball download speed in KiB/s. Overrides `networkConfig`. */
125
+ fetchMinSpeedKiBps?: number
120
126
  nodeLinker?: 'hoisted' | 'isolated'
121
127
  /**
122
128
  * pnpm's `linkWorkspacePackages`. When `true`/`'deep'`, a bare-semver
@@ -230,6 +236,12 @@ export interface InstallOptions extends SharedEngineOptions {
230
236
  returnListOfDepsRequiringBuild?: boolean
231
237
  /** Customizations for how peer-dependency mismatches are treated. */
232
238
  peerDependencyRules?: PeerDependencyRules
239
+ /**
240
+ * Render pnpm's own terminal output for this call. Omitted, the call
241
+ * prints nothing and the host renders the `onLog` stream itself (or not
242
+ * at all).
243
+ */
244
+ reporter?: ReporterOptions
233
245
  }
234
246
 
235
247
  /** pnpm's `peerDependencyRules`. */
@@ -239,6 +251,85 @@ export interface PeerDependencyRules {
239
251
  allowedVersions?: Record<string, string>
240
252
  }
241
253
 
254
+
255
+ /**
256
+ * pnpm's own terminal output, rendered by the engine.
257
+ *
258
+ * Without this the host gets only the `onLog` event stream and has to
259
+ * render it itself — in practice by keeping `@pnpm/logger` and
260
+ * `@pnpm/cli.default-reporter` and feeding the events into them, a
261
+ * coupling between one pnpm line's reporter and another's event stream
262
+ * that the host then has to maintain. Set `reporter` and the engine
263
+ * renders with the reporter `pnpm install` itself uses.
264
+ *
265
+ * Every field maps onto the option of the same name in
266
+ * `@pnpm/cli.default-reporter`'s `reportingOptions`.
267
+ */
268
+ export interface ReporterOptions {
269
+ /**
270
+ * Print each update on its own line instead of redrawing the frame in
271
+ * place. Defaults to `true` whenever the output is not a terminal.
272
+ */
273
+ appendOnly?: boolean
274
+ /**
275
+ * Milliseconds between progress redraws. Defaults to 1000 in
276
+ * append-only mode and 200 otherwise.
277
+ */
278
+ throttleProgress?: number
279
+ /** Leave the materialized-package count out of the progress line. */
280
+ hideAddedPkgsProgress?: boolean
281
+ /** Leave the workspace-project prefix out of progress lines. */
282
+ hideProgressPrefix?: boolean
283
+ /**
284
+ * Keep dependency build-script output in its collapsed block instead of
285
+ * streaming every line.
286
+ */
287
+ hideLifecycleOutput?: boolean
288
+ /**
289
+ * Replaces the `Run "pnpm approve-builds"…` line under the list of
290
+ * packages whose build scripts were blocked, for a host whose users
291
+ * approve builds through its own configuration.
292
+ */
293
+ ignoredBuildsInstructionText?: string
294
+ /**
295
+ * Package-name patterns whose *linked* entries are left out of the
296
+ * packages-diff summary — an entry is linked when it was symlinked in
297
+ * rather than materialized from the store. A host that links its own
298
+ * runtime into every project silences that noise without silencing the
299
+ * same packages when they are really installed. The Rust counterpart of
300
+ * the TypeScript reporter's `filterPkgsDiff` callback, which cannot
301
+ * cross the addon boundary.
302
+ */
303
+ hideLinkedPkgsDiff?: string[]
304
+ /** Verbosity ceiling. Defaults to `'info'`. */
305
+ logLevel?: 'error' | 'warn' | 'info' | 'debug'
306
+ /**
307
+ * Width to wrap at, at least one column. Defaults to the output stream's
308
+ * width when it is a terminal, else 80. Pass it explicitly alongside
309
+ * `onOutput`: the engine cannot see where those chunks end up.
310
+ */
311
+ width?: number
312
+ /**
313
+ * Whether to emit ANSI color. Defaults to "the output stream is a
314
+ * terminal and `NO_COLOR` is unset"; with `onOutput`, to `false`.
315
+ */
316
+ color?: boolean
317
+ /** Render on stderr rather than stdout. Ignored when `onOutput` is given. */
318
+ useStderr?: boolean
319
+ /** Directory paths are rendered relative to. Defaults to `dir`. */
320
+ cwd?: string
321
+ }
322
+
323
+ /**
324
+ * Receives each rendered output chunk instead of the engine writing it to
325
+ * a file descriptor. For a host that has redirected its own output at the
326
+ * JavaScript level — a monkey-patched `process.stdout.write`, a stream
327
+ * that forwards to a remote terminal — where a write from Rust would
328
+ * bypass the redirection. Chunks arrive in order and already carry their
329
+ * newlines and cursor-control sequences; write them verbatim.
330
+ */
331
+ export type OutputListener = (chunk: string) => void
332
+
242
333
  export interface InstallResult {
243
334
  stats: {
244
335
  added: number
@@ -262,11 +353,14 @@ export interface InstallResult {
262
353
  * @param readPackageHook a **synchronous** `(manifest, resolvedDir?) => manifest`
263
354
  * transform applied to every resolved dependency manifest during resolution
264
355
  * (the `readPackage` hook). Must return the manifest object, not a promise.
356
+ * @param onOutput receives the rendered output of `options.reporter`
357
+ * instead of the engine writing it to stdout/stderr.
265
358
  */
266
359
  export function install(
267
360
  options: InstallOptions,
268
361
  onLog?: LogListener,
269
362
  readPackageHook?: ReadPackageHook,
363
+ onOutput?: OutputListener,
270
364
  ): Promise<InstallResult>
271
365
 
272
366
  /**
@@ -279,6 +373,7 @@ export function rebuild(
279
373
  options: InstallOptions,
280
374
  onLog?: LogListener,
281
375
  selectedNames?: string[],
376
+ onOutput?: OutputListener,
282
377
  ): Promise<void>
283
378
 
284
379
  export interface PeerIssuesOptions extends SharedEngineOptions {
@@ -423,6 +518,8 @@ export interface ResolvedConfig {
423
518
  fetchRetryMintimeout: number
424
519
  fetchRetryMaxtimeout: number
425
520
  fetchTimeout: number
521
+ fetchWarnTimeoutMs: number
522
+ fetchMinSpeedKiBps: number
426
523
  /**
427
524
  * The explicitly configured user agent, when the cascade set one. The
428
525
  * engine's own computed default is omitted — an embedder that passes
@@ -461,5 +558,214 @@ export interface ResolvedConfig {
461
558
  */
462
559
  export function readConfig(options: ReadConfigOptions): ResolvedConfig
463
560
 
561
+ /**
562
+ * Inputs for {@link getDependents} — the engine side of `pnpm why`.
563
+ *
564
+ * The reverse tree is pure lockfile analysis, so a host that asks the
565
+ * engine for it needs neither `@pnpm/deps.inspection.tree-builder` and
566
+ * `@pnpm/deps.inspection.list` nor the `@pnpm/lockfile.fs` /
567
+ * `@pnpm/installing.modules-yaml` readers that feed them.
568
+ */
569
+ export interface DependentsOptions {
570
+ /** Lockfile / workspace root directory. */
571
+ dir: string
572
+ /** Package selectors to search for: a name, or `name@range`. */
573
+ packages: string[]
574
+ /**
575
+ * Importer directories to walk from. Absolute, or relative to `dir`.
576
+ * Omitted means every importer the lockfile records.
577
+ */
578
+ projectDirs?: string[]
579
+ /**
580
+ * Importer-id patterns to skip when `projectDirs` is omitted, in pnpm's
581
+ * `hoistPattern` glob syntax (`*` is the only wildcard). Lets a host keep
582
+ * its own generated importers out of the answer without reading the
583
+ * lockfile itself to enumerate the rest.
584
+ */
585
+ excludeProjectPatterns?: string[]
586
+ /** `node_modules` directory. Defaults to `<dir>/node_modules`. */
587
+ modulesDir?: string
588
+ /** Follow `dependencies` edges. Defaults to `true`. */
589
+ includeDependencies?: boolean
590
+ /** Follow `devDependencies` edges. Defaults to `true`. */
591
+ includeDevDependencies?: boolean
592
+ /** Follow `optionalDependencies` edges. Defaults to `true`. */
593
+ includeOptionalDependencies?: boolean
594
+ /** Registry routes, used to reconstruct tarball URLs. */
595
+ registries?: Record<string, string>
596
+ /** Fallback when `.modules.yaml` records no value. */
597
+ virtualStoreDirMaxLength?: number
598
+ /**
599
+ * `package.json` fields to project onto every package node as
600
+ * `manifest`. This is what the TypeScript tree-builder's `nameFormatter`
601
+ * callback is for: the walk is synchronous Rust and cannot call back
602
+ * into JavaScript, so a host that renames nodes after a manifest field
603
+ * asks for that field here, writes `displayName` on the returned trees,
604
+ * and passes them to {@link renderDependents}. Nodes whose manifest is
605
+ * unreadable — and every workspace-project node — carry none.
606
+ */
607
+ manifestFields?: string[]
608
+ }
609
+
610
+ /** One entry of a {@link DependentsTree}'s reverse tree. */
611
+ export interface DependentNode {
612
+ name: string
613
+ /** Rendered in place of `name`, when set. */
614
+ displayName?: string
615
+ version: string
616
+ /** The node was reached again on its own path; the walk stopped there. */
617
+ circular?: boolean
618
+ /** Short hash distinguishing peer-dependency variants of a `name@version`. */
619
+ peersSuffixHash?: string
620
+ /** The node is expanded elsewhere in the tree and shown here as a leaf. */
621
+ deduped?: boolean
622
+ /** For a workspace-project leaf: which manifest field declares the edge. */
623
+ depField?: 'dependencies' | 'devDependencies' | 'optionalDependencies'
624
+ dependents?: DependentNode[]
625
+ /** The `manifestFields` projection of this node's `package.json`. */
626
+ manifest?: Record<string, unknown>
627
+ }
628
+
629
+ /** One matched package and everything that depends on it. */
630
+ export interface DependentsTree {
631
+ name: string
632
+ /** Rendered in place of `name`, when set. */
633
+ displayName?: string
634
+ version: string
635
+ /** Resolved filesystem path of the package. */
636
+ path?: string
637
+ peersSuffixHash?: string
638
+ dependents: DependentNode[]
639
+ /** Message returned by a `--find-by` finder, when one matched. */
640
+ searchMessage?: string
641
+ /** See {@link DependentNode.manifest}. */
642
+ manifest?: Record<string, unknown>
643
+ }
644
+
645
+ /**
646
+ * Every package matching `packages`, each with the reverse tree of what
647
+ * depends on it. An empty array when the directory has no lockfile: an
648
+ * un-installed workspace has no dependents to report, which is an answer
649
+ * rather than an error.
650
+ */
651
+ export function getDependents(options: DependentsOptions): Promise<DependentsTree[]>
652
+
653
+ export interface RenderDependentsOptions {
654
+ /** Defaults to `'tree'`. */
655
+ format?: 'tree' | 'parseable' | 'json'
656
+ /** Max display depth. Omitted renders the whole tree. */
657
+ depth?: number
658
+ /** Include description / repository / homepage / path for each root. */
659
+ long?: boolean
660
+ }
661
+
662
+ /**
663
+ * Render trees from {@link getDependents} — after any `displayName` the
664
+ * caller wrote onto them — the way `pnpm why` renders its own.
665
+ */
666
+ export function renderDependents(
667
+ trees: DependentsTree[],
668
+ options?: RenderDependentsOptions,
669
+ ): string
670
+
671
+ /**
672
+ * A `pnpm-lock.yaml` as JSON — the file's own shape, which is
673
+ * `LockfileFile` in `@pnpm/lockfile.types` terms: each importer dependency
674
+ * is an `{ specifier, version }` pair, and `packages` (metadata) and
675
+ * `snapshots` (edges) are separate maps. There is no in-memory-only
676
+ * variant to convert to or from.
677
+ *
678
+ * Top-level keys pnpm does not define are preserved, so a host that
679
+ * records its own state beside the lockfile can read it, edit its own
680
+ * block, and write the file back without losing anything else.
681
+ *
682
+ * The lockfile functions are generic over this so a host that already has
683
+ * a precise type for the format — `LockfileFile` from
684
+ * `@pnpm/lockfile.types`, or its own extension of it — can name it rather
685
+ * than casting: `readLockfile<MyLockfile>({ dir })`.
686
+ */
687
+ export type LockfileFile = Record<string, unknown>
688
+
689
+ export interface ReadLockfileOptions {
690
+ /** Lockfile / workspace root directory. */
691
+ dir: string
692
+ /**
693
+ * `'wanted'` (the default) reads `<dir>/pnpm-lock.yaml`, what the
694
+ * workspace asks for. `'current'` reads
695
+ * `<modulesDir>/.pnpm/lock.yaml`, what the last install actually
696
+ * materialized.
697
+ */
698
+ kind?: 'wanted' | 'current'
699
+ /**
700
+ * `node_modules` directory, which the current lockfile lives under.
701
+ * Absolute, or relative to `dir`. Defaults to `<dir>/node_modules`.
702
+ */
703
+ modulesDir?: string
704
+ }
705
+
706
+ export interface WriteLockfileOptions<Lockfile = LockfileFile> {
707
+ /** Lockfile / workspace root directory. */
708
+ dir: string
709
+ /** The lockfile to write, in the shape {@link readLockfile} returns. */
710
+ lockfile: Lockfile
711
+ /** See {@link ReadLockfileOptions.kind}. */
712
+ kind?: 'wanted' | 'current'
713
+ /** See {@link ReadLockfileOptions.modulesDir}. */
714
+ modulesDir?: string
715
+ }
716
+
717
+ /** `null` when the lockfile is absent or empty. */
718
+ export function readLockfile<Lockfile = LockfileFile>(
719
+ options: ReadLockfileOptions,
720
+ ): Promise<Lockfile | null>
721
+
722
+ /** Write the lockfile, formatted exactly as an install writes it. */
723
+ export function writeLockfile<Lockfile = LockfileFile>(
724
+ options: WriteLockfileOptions<Lockfile>,
725
+ ): Promise<void>
726
+
727
+ export interface FilterLockfileOptions {
728
+ /** Whether the listed importers keep their `dependencies`. Default `true`. */
729
+ includeDependencies?: boolean
730
+ /** Whether they keep their `devDependencies`. Default `true`. */
731
+ includeDevDependencies?: boolean
732
+ /** Whether they keep their `optionalDependencies`. Default `true`. */
733
+ includeOptionalDependencies?: boolean
734
+ /**
735
+ * Dep paths to treat as already visited — the optional dependencies this
736
+ * platform did not install. Neither they nor anything reachable only
737
+ * through them is kept.
738
+ */
739
+ skipped?: string[]
740
+ /**
741
+ * Whether a dependency reference with no `snapshots` entry fails with
742
+ * `ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY`. Defaults to `false`, which
743
+ * drops the reference and keeps walking — what a caller inspecting a
744
+ * possibly-stale lockfile wants.
745
+ */
746
+ failOnMissingDependencies?: boolean
747
+ }
748
+
749
+ /**
750
+ * The lockfile narrowed to what `importerIds` reaches: those importers keep
751
+ * only the dependency groups asked for, and `packages` / `snapshots` are
752
+ * pruned to the transitive closure of what they still depend on. Every
753
+ * other importer entry is carried through untouched — the filter narrows
754
+ * the package graph, not the workspace.
755
+ *
756
+ * Synchronous: a transform over data the caller already holds.
757
+ */
758
+ export function filterLockfileByImporters<Lockfile = LockfileFile>(
759
+ lockfile: Lockfile,
760
+ importerIds: string[],
761
+ options?: FilterLockfileOptions,
762
+ ): Lockfile
763
+
764
+ /**
765
+ * The `.modules.yaml` state of an installed `node_modules`, or `null` when
766
+ * the directory has none.
767
+ */
768
+ export function readModulesManifest(modulesDir: string): Promise<Record<string, unknown> | null>
769
+
464
770
  /** Version of the underlying Rust engine (pacquet). */
465
771
  export function engineVersion(): string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/napi",
3
- "version": "12.0.0-rc.8",
3
+ "version": "12.0.0-rc.9",
4
4
  "description": "Node.js addon bindings for the pnpm v12 Rust engine (pacquet)",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -28,14 +28,14 @@
28
28
  "THIRD-PARTY-NOTICES.md"
29
29
  ],
30
30
  "optionalDependencies": {
31
- "@pnpm/napi.win32-x64": "12.0.0-rc.8",
32
- "@pnpm/napi.win32-arm64": "12.0.0-rc.8",
33
- "@pnpm/napi.darwin-x64": "12.0.0-rc.8",
34
- "@pnpm/napi.darwin-arm64": "12.0.0-rc.8",
35
- "@pnpm/napi.linux-x64": "12.0.0-rc.8",
36
- "@pnpm/napi.linux-arm64": "12.0.0-rc.8",
37
- "@pnpm/napi.linux-x64-musl": "12.0.0-rc.8",
38
- "@pnpm/napi.linux-arm64-musl": "12.0.0-rc.8"
31
+ "@pnpm/napi.win32-x64": "12.0.0-rc.9",
32
+ "@pnpm/napi.win32-arm64": "12.0.0-rc.9",
33
+ "@pnpm/napi.darwin-x64": "12.0.0-rc.9",
34
+ "@pnpm/napi.darwin-arm64": "12.0.0-rc.9",
35
+ "@pnpm/napi.linux-x64": "12.0.0-rc.9",
36
+ "@pnpm/napi.linux-arm64": "12.0.0-rc.9",
37
+ "@pnpm/napi.linux-x64-musl": "12.0.0-rc.9",
38
+ "@pnpm/napi.linux-arm64-musl": "12.0.0-rc.9"
39
39
  },
40
40
  "scripts": {
41
41
  "generate-packages": "node scripts/generate-packages.mjs"