YAML AST Parser for Language Servers

0.1.3 · active · verified Wed Apr 22

This package provides a robust YAML Abstract Syntax Tree (AST) parser, specifically a maintained fork of `YAML-AST-PARSER` tailored for use within the YAML Language Server ecosystem. It parses YAML documents into a detailed AST structure, offering features like error restoration during parsing, reporting errors directly as part of AST nodes, and built-in support for the non-standard `!include` tag commonly used in RAML specifications. The current stable version is 0.1.3, suggesting a focused, stable release cadence for its specific application. Its primary differentiators are its explicit maintenance for language server tooling, its robust error handling capabilities which are critical for IDE integration, and its direct lineage from `JS-YAML` for core parsing fidelity, combined with a focus on AST representation.

Common errors

Warnings

Install

Imports

Quickstart

Parses a multi-line YAML string into an Abstract Syntax Tree (AST), demonstrating how to navigate map and scalar nodes, identify their kinds, and use helper functions to determine and parse scalar values like integers and booleans. It also showcases accessing position information for nodes.

import { load, Kind, YAMLScalar, YamlMap, YAMLMapping, determineScalarType, parseYamlInteger, parseYamlBoolean } from 'yaml-language-server-parser';

const yamlString = `
# A simple YAML document
name: My Application
version: 1.0.0
config:
  port: 8080
  debug: true
  features:
    - user_auth
    - logging
`;

// Load the YAML string into an AST
const yamlNode = load(yamlString);

console.log('--- AST Analysis ---');

if (yamlNode.kind === Kind.MAP) {
  const rootMap = yamlNode as YamlMap;
  console.log(`Root node is a Map with ${rootMap.mappings.length} mappings.`);

  for (const mapping of rootMap.mappings) {
    if (mapping.key.value === 'name' && mapping.value?.kind === Kind.SCALAR) {
      const nameScalar = mapping.value as YAMLScalar;
      console.log(`Application Name: ${nameScalar.value}`);
    }

    if (mapping.key.value === 'config' && mapping.value?.kind === Kind.MAP) {
      const configMap = mapping.value as YamlMap;
      console.log(`  Config map found with ${configMap.mappings.length} items.`);

      for (const configMapping of configMap.mappings) {
        if (configMapping.key.value === 'port' && configMapping.value?.kind === Kind.SCALAR) {
          const portScalar = configMapping.value as YAMLScalar;
          console.log(`    Port (raw): ${portScalar.value}`);
          console.log(`    Port (type determined): ${determineScalarType(portScalar)}`);
          console.log(`    Port (parsed int): ${parseYamlInteger(portScalar.value)}`);
        }
        if (configMapping.key.value === 'debug' && configMapping.value?.kind === Kind.SCALAR) {
          const debugScalar = configMapping.value as YAMLScalar;
          console.log(`    Debug (raw): ${debugScalar.value}`);
          console.log(`    Debug (type determined): ${determineScalarType(debugScalar)}`);
          console.log(`    Debug (parsed bool): ${parseYamlBoolean(debugScalar.value)}`);
        }
      }
    }
  }
}

console.log(`\n'name' node starts at: ${yamlNode.mappings.find(m => m.key.value === 'name')?.key.startPosition}`);
console.log(`'name' node ends at: ${yamlNode.mappings.find(m => m.key.value === 'name')?.key.endPosition}`);

view raw JSON →