yaml

repository·main·Indexed 23 days ago

https://github.com/eemeli/yaml

A JavaScript parser and stringifier for YAML 1.1 and 1.2 that supports parsing, stringifying, and full manipulation of YAML comments and blank lines. Designed for Node.js and modern browsers with no external dependencies, it provides three API layers: a simple Parse & Stringify API, a Document API for AST manipulation, and a low-level Lexer, Parser, and Composer for direct source interaction.

Tokens
28.6K
Snippets
48
Records
115
Agent score
82%

What's inside yaml

  1. Overview of the yaml API layers

    main

    The yaml library provides three layers of abstraction depending on your needs:

    1. Parse & Stringify: The simplest API for basic conversion between YAML strings and JavaScript values.
    2. Documents: Provides access to the full feature set, including comments, blank lines, and a decent AST (Abstract Syntax Tree) via the Document class.
    3. Lexer, Parser, and Composer: The lowest level, allowing you to work closely with the YAML source through tokens and the concrete syntax tree.

    A command-line tool is also included.

  2. Understand YAML schemas and default versions

    main

    A YAML schema defines how tags are handled and how non-specific tags (values without an explicit tag like !!int) are resolved.

    • For YAML 1.2 documents, the recommended default is the 'core' schema.
    • For YAML 1.1 documents, the default is 'yaml-1.1'.

    If you are using the library to parse or stringify custom data types, you must configure it with a suitable tag object to enable automatic handling.

  3. How the YAML parsing process works

    main

    The yaml library converts a sequence of characters into usable Documents through three distinct stages. Depending on your needs, you can use high-level functions or access these individual stages:

    1. Lexer: Splits the character stream into lexical tokens (sequences of characters and control codes).
    2. Parser: Builds Concrete Syntax Tree (CST) representations of each document and directive in the stream.
    3. Composer: Builds a user-friendly and accessible Document representation from the CST.

    Usage Guidance:

    • If you only need the final JavaScript object: Use parse().
    • If you need to retain comments and metadata: Use parseDocument() or parseAllDocuments() to get Document instances.
    import {
      Composer,
      CST,
      lex,
      LineCounter,
      Parser,
    } from 'yaml'
  4. Differences between YAML 1.0 and 1.1

    main

    The tag syntax was completely refactored between YAML 1.0 and 1.1:

    • %TAG Directive: Introduced in 1.1 to allow prefix shorthands (e.g., !foo!).
    • Tag Prefixing: The ^ character no longer enables tag prefixing.
    • Scoping: The roles of ! and !! were switched; !!str became a default tag, while !bar became an application-specific tag.
    • Verbatim Notation: Added !<baz> notation.
    • Directives: Use a blank space ' ' instead of a colon : to separate the name from its parameter/value.

    Note: While yaml v1 supported YAML 1.0 (including ^ notation), explicit support for YAML 1.0 has been dropped in yaml v2.

  5. Understand Content Nodes and the Abstract Syntax Tree

    main

    After parsing a YAML document, the value property of the YAML.Document serves as the root of an Abstract Syntax Tree (AST). This tree consists of nodes representing the document structure.

    Nodes can have an anchor (prefixed with & in YAML, e.g., foo: &aa bar assigns anchor aa to bar). Anchors allow Alias nodes to reference the same value in multiple locations. It is valid to have an anchor even if no aliases exist.

  6. Working with the Concrete Syntax Tree (CST)

    main

    While the Document or pure JS interfaces are standard for most use cases, the Concrete Syntax Tree (CST) is used when you need to keep the original YAML source as pristine as possible. The CST retains every character of the input, including whitespace and comments. Use the CST namespace to manipulate these tokens directly.

    import { CST } from 'yaml'
  7. Configure Document Stream Directives

    main

    The directives property of a Document allows you to control YAML stream directives like %YAML and %TAG, as well as the document start/end markers. Modifying these properties will influence the resulting YAML string when calling toString().

    • docStart: Set to true to force the --- document-start marker.
    • docEnd: Set to true to force the ... document-end marker.
    • tags: A record of handles and prefixes used for %TAG directives and stringifying tags (e.g., { '!!': 'tag:yaml.org,2002:' }).
    • yaml: Controls the %YAML directive, including explicit (boolean) and version (e.g., '1.2').

    If you change the YAML version via directives.yaml, it is recommended to also use doc.setSchema(version) to ensure the schema is updated accordingly.

  8. Handle comments and blank lines programmatically

    main

    Unlike many YAML libraries, yaml allows you to manage comments and blank lines by attaching them to specific nodes.

    Available Properties:

    • comment: A string representing the comment text.
    • commentBefore: A string representing a comment appearing before the node.
    • spaceBefore: A boolean that, when true, adds an empty line before the comment.

    Supported Nodes:

    • Document
    • Scalar
    • Map
    • Seq

    Note on Stability: Comment handling (especially trailing comments) may be unstable; comments might sometimes be associated with a different node when reading/writing files.

    const seq = doc.get('it has')
    seq.spaceBefore // true
    
    seq.items[0].comment = ' item comment'
    seq.comment = ' collection end comment'
  9. Understand the security update policy

    main

    Security updates for yaml follow these rules:

    • Supported Versions: Security updates are provided for the most recent minor releases of v1 and v2.
    • Prereleases: No security updates are provided for prerelease versions.
    • Legacy Versions: No updates are provided for earlier releases. Once v3.0.0 is released, v1 releases will no longer receive updates.
    • Extended Support: For faster response times or stronger guarantees, contact the maintainer to discuss a support agreement.
  10. Work with YAML Documents

    main

    For more control, including access to comments, blank lines, and an AST, use the Document API. This layer allows you to manipulate the YAML structure directly rather than just working with plain JavaScript objects.

    Key components:

    • Document: A class representing a single YAML document. It can be instantiated via new Document(value, replacer?, options?) or created via parsing functions.
    • parseDocument(str, options?): Parses a string into a single Document instance.
    • parseAllDocuments(str, options?): Parses a string containing multiple YAML documents into an array of Document instances.

    Document provides access to #value (the parsed JS value), #directives, #errors, and #warnings.

    import {
      Document,
      parseAllDocuments,
      parseDocument
    } from 'yaml'
  11. How YAML tags and shorthands work

    main

    YAML tags allow you to specify the data type of a value.

    • Default Prefix: The default prefix is tag:yaml.org,2002:. The shorthand !! is used when stringifying these tags.
    • Custom Shorthands: You can define document-specific shorthands using the %TAG directive (e.g., !e! or ! for tag:example.com,2018:app/).
    • Unresolved Tags: If a tag is unresolved during parsing, the library will issue a YAMLWarning but will not error. The value will be parsed according to automatic tag resolution rules to prevent data loss.

    To enable automatic parsing and stringification for non-standard types, you must provide a tag object in the configuration.

    YAML.parse('"42"')
    // '42'
    
    YAML.parse('!!int "42"')
    // 42
    
    YAML.parse(`
    %TAG ! tag:example.com,2018:app/
    ---
    !foo 42
    `)
    // YAMLWarning:
    //   The tag tag:example.com,2018:app/foo is unavailable,
    //   falling back to tag:yaml.org,2002:str
    // '42'
  12. Differences between YAML 1.1 and 1.2

    main

    The yaml library is based on the YAML 1.2 spec. While it is largely backwards-compatible with 1.1, there are significant behavioral changes when using the recommended 1.2 'core' schema:

    • Booleans: Only true and false (case-insensitive) are parsed as booleans. Values like y, yes, or on are treated as strings.
    • Numbers:
      • Underlines _ are no longer allowed in numerical values.
      • Octal values must use the 0o prefix (e.g., 010 is parsed as decimal 10, not octal 8).
      • Binary and sexagesimal integer formats have been dropped.
    • Dropped Types: !!pairs, !!omap, !!set, !!timestamp, and !!binary are no longer supported.
    • Removed Features: The merge << key and value = special mapping keys have been removed.
    • JSON Compatibility: YAML 1.2 is a valid superset of JSON.
    • Line Breaks: Characters like (line-separator) and (paragraph-separator) are no longer considered line-break characters. For robustness, replace them with \n or \n\n.
    • Tag/Anchor Constraints: Tag shorthands and Anchors can no longer include the characters ,[]{}.