Files
pnpm/yaml/document-sync
Zoltan Kochan 1701a65845 chore: reduce noisy warnings in test output (#11022)
* chore: reduce noisy warnings in test output

- Suppress ExperimentalWarning and DEP0169 via --disable-warning in NODE_OPTIONS
- Fix MaxListenersExceededWarning by raising limit in StoreIndex when adding exit listeners
- Update meta-updater to generate the new _test scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: stop streaming pnpm subprocess output during CLI tests

Buffer stdout/stderr from execPnpm instead of writing to the parent
process in real time. Output is still included in the error message on
failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: pipe all subprocess output in CLI tests

Use stdio: 'pipe' for all pnpm/pnpx spawn helpers so subprocess output
is buffered instead of printed. Output is still included in error
messages on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove duplicate @pnpm/installing.env-installer in pnpm/package.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: use pipe stdio in dlx and errorHandler tests

Replace stdio: 'inherit' and [null, 'pipe', 'inherit'] with 'pipe' to
prevent subprocess output from leaking into test output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: skip maxListeners adjustment when set to unlimited (0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:43:12 +01:00
..
2026-01-17 12:01:23 +01: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