Files
Zoltan Kochan fc2f33912e refactor: move the TypeScript pnpm CLI into a pnpm11/ directory (#12537)
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet
port. To make that split legible, all TypeScript source, test, and build
directories move under a new top-level pnpm11/ directory. The name states
the version boundary rather than implying a behavioral fork, since the two
stacks are meant to behave identically.

Scope is source-only: the shared workspace root stays at the repo root.
pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs,
.meta-updater, __patches__, .changeset, .husky, and the lint/spell configs
remain in place, so one pnpm workspace and one Cargo workspace still span
all three products. pnpr/client and pacquet/tasks/registry-mock stay as
cross-product workspace members.

Rewiring the move required:
- pnpm-workspace.yaml globs prefixed with pnpm11/
- root package.json script paths, eslint.config.mjs, tsconfig.lint.json,
  .gitignore, and CODEOWNERS updated
- .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json,
  pnpm11/__utils__, pnpm11/__typings__, and the main package directory)
- regenerated every moved package's repository/homepage URL via meta-updater
- pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts
  climb one more level to reach the repo root

.meta-updater stays at the repo root because @pnpm/meta-updater resolves
its config at <cwd>/.meta-updater/main.mjs.

TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths
change, via a dorny/paths-filter changes job plus a TS CI / Success
aggregate gate; branch protection should require only that gate.
2026-06-20 14:36:25 +02:00
..

@pnpm/yaml.document-sync

Update a YAML document to match the contents of an in-memory object.

npm version

Installation

pnpm add @pnpm/yaml.document-sync

Usage

Given a "source" document such as:

foo:
  bar:
    # 25 is better than 24
    baz: 25

qux:
  # He was number 1
  - 1

And a "target" object in-memory:

import fs from 'node:fs'
import { patchDocument } from '@pnpm/yaml.document-sync'
import yaml from 'yaml'

const source = await fs.promises.readFile('source.yaml', 'utf8')
const document = yaml.parseDocument(source)

const target = {
  foo: { bar: { baz: 25 } },
  qux: [1, 2, 3]
}

patchDocument(document, target)

The patchDocument function will mutate document to match the target's contents, retaining comments along the way. In the example above, the final rendered document will be:

foo:
  bar:
    # 25 is better than 24
    baz: 25

qux:
  # He was number 1
  - 1
  - 2
  - 3

Purpose

This package is useful when your codebase:

  1. Uses the yaml library.
  2. Calls .toJSON() on the parse result and performs changes to it.
  3. Needs to "sync" those changes back to the source document.

Instead of this package, consider performing mutations directly on the yaml.Document returned from yaml.parseDocument() instead. Directly modifying will be faster and more accurate. This package exists as a workaround for codebases that make changes to a JSON object instead and need to reconcile changes back into the source yaml.Document.

Caveats

There are several cases where comment preservation is inherently ambiguous. If the caveats outlined below are problematic, consider modifying the source yaml.Document before running the patch function in this package.

Key Renames

For example, renames of a key are ambiguous. Given:

- foo:
    # Test
    bar: 1

And a target object to match:

{
  "baz": {
    "bar": 1
  }
}

The comment on bar won't be retained.

List Reconciliation

For simple lists (e.g. lists with only primitives), items will be uniquely matched using their contents. However, updates to complex lists are inherently ambiguous.

For example, given a source list with objects as elements:

- foo: 1
# Comment
- bar: 2

And a target:

[
  { "foo": 1 },
  { "baz": 3 },
  { "bar": 2 }
]

The result will erase the comment:

- foo: 1
- baz: 3
- bar: 2

It's not trivial to detect that the object with bar as a field moved down. Detecting this case would require a diffing algorithm, which would be best effort anyway.

Virtual DOM libraries such as React have the same problem. In React, list elements need to specify a key prop to uniquely identify each item. This library may take a similar approach in the future if needed. This is not a problem for primitive lists since their values can be compared using simple equality checks.

Aliases

Given:

foo: &config
  - 1
  - 2

bar: *config

And a target object:

{
  "foo": [1, 2],
  "bar": [1, 2, 3]
}

For correctness, the YAML alias needs to be removed.

foo: &config
  - 1
  - 2

bar:
  - 1
  - 2
  - 3

License

MIT