Beispiel
yaml 2.9.0: Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml
Verifiziertes Beispiel für npm yaml 2.9.0: Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in…
sha256:e48bea588f5dd5489beab783c6a88de0ad1b37a153accb93af38e0689dfd3a1d
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 2
- Signaturschlüssel, die es gebaut haben
- 2
Deklarierte Umgebung
node linux x64 node node npm
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-17 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
Fall
HOW- Ziel
- Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml
- Pakete
- Symbole
-
- yaml.parseDocument
- yaml.Document
- yaml.visit
- yaml.Scalar
- Umgebung
- node
- Erstellt
- 2026-08-17T14:47:12Z
Contract
- yaml.parseDocument returns a Document AST whose scalar values can be read and mutated via path arrays while preserving existing comments upon serialization
- doc.getIn with keepScalar flag returns the AST Scalar node to allow inspecting and updating scalar formatting styles
- doc.addIn, doc.deleteIn, and doc.hasIn manipulate sequence and mapping AST nodes at nested paths
- yaml.visit traverses document AST nodes and removes targeted nodes when returning visit.REMOVE
- doc.toJS with mapAsMap: true converts YAML mapping structures to native JavaScript Map instances
Dateien
- NOTES.md
- csx.json
- package-lock.json
- package.json
- src/index.mjs
- test/contract.mjs
Quelltext
# Notes
## Search Known Solution Result
A search for `pkg:npm/yaml` returned an existing solution `sha256:2599e0d3b97c21e59a6f4de52c39dc7235d8c59d64db5fa9519e8114c1e197e6` covering `yaml.parse` and `yaml.stringify` schema options (YAML 1.2 boolean strings, merge keys, multi-document parsing errors, duplicate keys, and line width formatting). This sample investigates a distinct area: `Document` AST parsing, path-based manipulation, comment retention, scalar styling, and AST tree visitation.
## Pinned Release
- Package: `yaml`
- Pinned Version: `2.9.0`
## Observed Behaviour
In `yaml@2.9.0`:
1. `parseDocument(src)` returns a mutable `Document` Abstract Syntax Tree (AST). In-place updates via `doc.setIn(['path', 'to', 'key'], newValue)` preserve document header comments, top-level comments, and inline field comments upon serialization with `doc.toString()`.
2. Calling `doc.getIn(path, true)` returns the underlying `Scalar` AST node rather than the primitive value, exposing formatting controls such as `node.type = Scalar.QUOTE_DOUBLE` or `node.type = Scalar.BLOCK_LITERAL`.
3. Collection navigation supports path-based inspection and manipulation: `doc.hasIn(path)` returns a boolean indicating path existence, `doc.addIn(path, value)` appends elements to sequence nodes, and `doc.deleteIn(path)` removes items by index or mapping key while shifting remaining sequence elements.
4. `visit(doc, visitor)` performs depth-first AST traversal across `Document`, `YAMLMap`, `YAMLSeq`, and `Scalar` nodes. Returning `visit.REMOVE` inside a node visitor callback cleanly removes that node from its parent collection.
5. Calling `doc.toJS({ mapAsMap: true })` produces native JavaScript `Map` instances for all nested mapping structures, preserving key insertion order.
{"case":{"caseId":"case:sha256:7c83a0b9d927afb9c755f5b3f2257692a237216e46736d2e1d0e66a4844c50ec","contract":["yaml.parseDocument returns a Document AST whose scalar values can be read and mutated via path arrays while preserving existing comments upon serialization","doc.getIn with keepScalar flag returns the AST Scalar node to allow inspecting and updating scalar formatting styles","doc.addIn, doc.deleteIn, and doc.hasIn manipulate sequence and mapping AST nodes at nested paths","yaml.visit traverses document AST nodes and removes targeted nodes when returning visit.REMOVE","doc.toJS with mapAsMap: true converts YAML mapping structures to native JavaScript Map instances"],"goal":"Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml","kind":"HOW","packages":["pkg:npm/yaml@2.9.0"],"schemaVersion":1,"symbols":["yaml.parseDocument","yaml.Document","yaml.visit","yaml.Scalar"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/yaml@2.9.0"],"schemaVersion":1,"symbols":["yaml.parseDocument","yaml.Document","yaml.visit","yaml.Scalar"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-npm-yaml-version-depth",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-npm-yaml-version-depth",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"yaml": "2.9.0"
}
},
"node_modules/yaml": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
}
}
}
{
"name": "sample-npm-yaml-version-depth",
"version": "1.0.0",
"private": true,
"type": "module",
"license": "MIT-0",
"dependencies": {
"yaml": "2.9.0"
}
}
import YAML from 'yaml';
import {
parseDocument,
Document,
visit,
Scalar,
isDocument,
isScalar,
isMap,
isSeq,
} from 'yaml';
/**
* Parses a YAML string into a Document AST.
*/
export function parseDoc(src, options) {
return parseDocument(src, options);
}
/**
* Creates a new empty or initialized YAML Document AST.
*/
export function createDoc(value, options) {
return new Document(value, options);
}
/**
* Gets a nested value or AST node along a path.
* When keepScalar is true, returns the AST node (Scalar, YAMLMap, YAMLSeq).
*/
export function getDocPath(doc, path, keepScalar = false) {
return doc.getIn(path, keepScalar);
}
/**
* Sets a nested value along a path, mutating AST while preserving surrounding comments.
*/
export function setDocPath(doc, path, value) {
doc.setIn(path, value);
return doc;
}
/**
* Appends a value to a sequence node along a path.
*/
export function addDocPath(doc, path, value) {
doc.addIn(path, value);
return doc;
}
/**
* Deletes a nested entry or sequence element along a path.
*/
export function deleteDocPath(doc, path) {
return doc.deleteIn(path);
}
/**
* Checks whether a path exists in the document AST.
*/
export function hasDocPath(doc, path) {
return doc.hasIn(path);
}
/**
* Sets the scalar style (e.g. Scalar.QUOTE_DOUBLE, Scalar.BLOCK_LITERAL) on a node at the specified path.
*/
export function setScalarStyle(doc, path, styleType) {
const node = doc.getIn(path, true);
if (isScalar(node)) {
node.type = styleType;
}
return doc;
}
/**
* Traverses and transforms the document AST with a visitor.
*/
export function transformDoc(doc, visitor) {
visit(doc, visitor);
return doc;
}
/**
* Converts Document AST to JavaScript value (object, array, or Map).
*/
export function docToJS(doc, options = {}) {
return doc.toJS(options);
}
/**
* Serializes Document AST back to YAML string.
*/
export function docToString(doc) {
return doc.toString();
}
export { YAML, Scalar, Document, parseDocument, visit, isDocument, isScalar, isMap, isSeq };
export default YAML;
import { strict as assert } from 'node:assert';
import YAML, {
parseDoc,
createDoc,
getDocPath,
setDocPath,
addDocPath,
deleteDocPath,
hasDocPath,
setScalarStyle,
transformDoc,
docToJS,
docToString,
Scalar,
isDocument,
isScalar,
isMap,
isSeq,
visit,
} from '../src/index.mjs';
// Section 1: parseDocument and path-based mutation preserving comments
const sampleYaml = `# Service configuration
app:
# Primary endpoint
server: example.com
port: 8080
description: Fast web service
tags:
- web
- api
- deprecated_flag
`;
const doc = parseDoc(sampleYaml);
assert.ok(isDocument(doc), 'doc should be an instance of YAML Document');
// Verify reading values via getIn
assert.strictEqual(getDocPath(doc, ['app', 'port']), 8080, 'getDocPath retrieves primitive number');
assert.strictEqual(getDocPath(doc, ['app', 'server']), 'example.com', 'getDocPath retrieves primitive string');
// Mutate values in-place
setDocPath(doc, ['app', 'port'], 9443);
setDocPath(doc, ['app', 'server'], 'example.org');
doc.commentBefore = ' Global header';
const serializedMutated = docToString(doc);
assert.ok(serializedMutated.includes('# Global header'), 'Document header comment preserved');
assert.ok(serializedMutated.includes('# Service configuration'), 'Top-level key comment preserved');
assert.ok(serializedMutated.includes('# Primary endpoint'), 'Nested property comment preserved');
assert.ok(serializedMutated.includes('server: example.org'), 'Server field updated in serialized output');
assert.ok(serializedMutated.includes('port: 9443'), 'Port field updated in serialized output');
// Section 2: AST Scalar node inspection and style modification
const serverScalar = getDocPath(doc, ['app', 'server'], true);
assert.ok(isScalar(serverScalar), 'getDocPath with keepScalar=true returns Scalar node');
assert.strictEqual(serverScalar.value, 'example.org', 'Scalar node contains expected value');
// Modify scalar formatting styles
setScalarStyle(doc, ['app', 'server'], Scalar.QUOTE_DOUBLE);
setScalarStyle(doc, ['app', 'description'], Scalar.BLOCK_LITERAL);
const serializedStyled = docToString(doc);
assert.ok(serializedStyled.includes('server: "example.org"'), 'Double-quoted scalar style applied');
assert.ok(
serializedStyled.includes('description: |-\n Fast web service'),
'Block literal scalar style applied'
);
// Section 3: Sequence and mapping navigation (hasIn, addIn, deleteIn)
assert.strictEqual(hasDocPath(doc, ['app', 'tags']), true, 'hasDocPath returns true for existing sequence');
assert.strictEqual(hasDocPath(doc, ['app', 'database']), false, 'hasDocPath returns false for missing path');
// Append to sequence
addDocPath(doc, ['app', 'tags'], 'metrics');
assert.strictEqual(getDocPath(doc, ['app', 'tags', 3]), 'metrics', 'addDocPath appends item to sequence');
// Delete sequence element by index
const deletedWeb = deleteDocPath(doc, ['app', 'tags', 0]);
assert.strictEqual(deletedWeb, true, 'deleteDocPath returns true on successful deletion');
assert.strictEqual(getDocPath(doc, ['app', 'tags', 0]), 'api', 'Sequence shifts after index deletion');
assert.strictEqual(getDocPath(doc, ['app', 'tags', 1]), 'deprecated_flag', 'Second item shifted to index 1');
assert.strictEqual(getDocPath(doc, ['app', 'tags', 2]), 'metrics', 'Appended item at index 2');
// Section 4: AST traversal and node transformation using visit
const visitedValues = [];
transformDoc(doc, {
Scalar(key, node) {
if (typeof node.value === 'string' || typeof node.value === 'number') {
visitedValues.push(node.value);
}
// Remove deprecated_flag tag during traversal
if (node.value === 'deprecated_flag') {
return visit.REMOVE;
}
},
});
assert.ok(
visitedValues.includes('example.org'),
'visit traversed server scalar'
);
assert.ok(
visitedValues.includes('deprecated_flag'),
'visit traversed deprecated_flag scalar'
);
const tagsSeq = getDocPath(doc, ['app', 'tags']);
assert.ok(isSeq(tagsSeq), 'tagsSeq is a YAMLSeq');
assert.strictEqual(
tagsSeq.items.length,
2,
'visit.REMOVE successfully removed deprecated_flag scalar from sequence'
);
assert.strictEqual(
getDocPath(doc, ['app', 'tags', 0]),
'api',
'First item in tags is api'
);
assert.strictEqual(
getDocPath(doc, ['app', 'tags', 1]),
'metrics',
'Second item in tags is metrics'
);
// Section 5: Native JS conversion (Plain Object vs Map)
const plainJS = docToJS(doc);
assert.strictEqual(typeof plainJS, 'object', 'docToJS returns standard JavaScript object');
assert.strictEqual(plainJS.app.server, 'example.org');
assert.strictEqual(plainJS.app.port, 9443);
assert.deepStrictEqual(plainJS.app.tags, ['api', 'metrics']);
const mapJS = docToJS(doc, { mapAsMap: true });
assert.ok(mapJS instanceof Map, 'docToJS with mapAsMap: true returns Map instance');
assert.ok(mapJS.get('app') instanceof Map, 'Nested mappings return Map instances');
assert.strictEqual(mapJS.get('app').get('port'), 9443, 'Map instance contains correct value');
assert.deepStrictEqual(mapJS.get('app').get('tags'), ['api', 'metrics'], 'Sequence inside Map is an array');
console.log('CONTRACT PASS: yaml Document AST manipulation, comments, scalar styles, and visit');