Files
pnpm/yaml/document-sync
Zoltan Kochan 4d7cd56ccc chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2 (#11332)
* chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2

- Add explicit `types: ["node"]` to the shared tsconfig because tsgo
  20260421 no longer auto-acquires `@types/*` from `node_modules`.
- Refactor test files to explicitly import jest globals (`describe`,
  `it`, `test`, `expect`, `beforeEach`, etc.) from `@jest/globals`
  instead of relying on `@types/jest` ambient declarations. Under the
  new tsgo build, `import { jest } from '@jest/globals'` shadows the
  ambient `jest` namespace, breaking `@types/jest`'s `declare var
  describe: jest.Describe;` globals.
- Add `@jest/globals` to each package's devDependencies where tests
  now import from it, and add `@types/node` to packages that need it
  but were relying on hoisted resolution.
- Replace `fail()` calls with `throw new Error(...)` since `fail` is
  no longer globally available.

* chore: fix remaining tsgo type-strictness errors

- Strip `as <PnpmType>` casts on objects passed to toMatchObject /
  toStrictEqual / toEqual; @jest/globals rejects the typed objects
  (which include AsymmetricMatchers) vs. the repo-specific type.
- Type `jest.fn<...>()` explicitly where the mock's signature matters
  for toHaveBeenCalledWith.
- Replace `beforeEach(() => X)` with `beforeEach(() => { X })` so the
  return value is void, as the stricter jest typing requires.
- Use `expect.objectContaining({...})` in one place where the full
  expected object triggered stricter type resolution.
- Cast `prompt.mock.calls` arg through `as unknown as Record<...>[]`
  for patch.test.ts's nested-array matchers.
- Fix off-by-one `<reference path>` in pnpm/test/getConfig.test.ts
  that only surfaced now.
- Move `@jest/globals` from devDependencies to dependencies in the
  two `__utils__` packages that import it from `src/`.
- Clean up unused imports from the @jest/globals migration.

* chore: address Copilot review on #11332

- Move misplaced `@jest/globals` imports to the top import block in
  checkEngine, run.ts, and workspace/root-finder tests where the
  script dropped them below executable code.
- Replace `try { await x(); throw new Error('should have thrown') } catch`
  in bins/linker, lockfile/fs, and resolving/local-resolver tests with
  `await expect(x()).rejects.toMatchObject({...})`. The old pattern
  swallowed an unrelated `throw` if the under-test call silently
  succeeded, which would fail on the catch-block assertion with a
  misleading message.
2026-04-21 23:21:52 +02:00
..
2026-04-10 18:30:33 +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