CodeSampleX

Ejemplo

yaml 2.9.0: Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml

Muestra verificada para npm yaml 2.9.0: Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml.…

sha256:e48bea588f5dd5489beab783c6a88de0ad1b37a153accb93af38e0689dfd3a1d

Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido. Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas. MIT-0

Evidencia de ejecución

El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.

Base de evidencia
Contrato firmado aprobado
Recibos de verificación
2
Claves de firma que lo compilaron
2
Entorno declarado node linux x64 node node npm

Entornos de las ejecuciones de verificación

Entorno Contrato Etapas Ejecución
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

Caso

HOW
Objetivo
Manipulate YAML Document AST paths, preserve comments, control scalar styles, and transform nodes with visit in yaml
Paquetes
Símbolos
  • yaml.parseDocument
  • yaml.Document
  • yaml.visit
  • yaml.Scalar
Entorno
node
Creado
2026-08-17T14:47:12Z

Contrato

  1. yaml.parseDocument returns a Document AST whose scalar values can be read and mutated via path arrays while preserving existing comments upon serialization
  2. doc.getIn with keepScalar flag returns the AST Scalar node to allow inspecting and updating scalar formatting styles
  3. doc.addIn, doc.deleteIn, and doc.hasIn manipulate sequence and mapping AST nodes at nested paths
  4. yaml.visit traverses document AST nodes and removes targeted nodes when returning visit.REMOVE
  5. doc.toJS with mapAsMap: true converts YAML mapping structures to native JavaScript Map instances

Archivos

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • src/index.mjs
  • test/contract.mjs

Descargar el artefacto de código fuente (tar.gz)

Código fuente

NOTES.md
# 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.
csx.json
{"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"}
package-lock.json
{
  "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"
      }
    }
  }
}
package.json
{
  "name": "sample-npm-yaml-version-depth",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "license": "MIT-0",
  "dependencies": {
    "yaml": "2.9.0"
  }
}
src/index.mjs
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;
test/contract.mjs
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');

Seeder de origen

csx-seed