npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

yaml-doctor

v0.3.0

Published

Identify and fix dangerous or invalid YAML syntax

Downloads

32

Readme

YAML Doctor

YAML Doctor identifies YAML syntax errors in helpful human terms and [optionally] automatically fixes them, with a focus on predicting and identifying the YAML author’s intent.

What makes this different from most YAML linters?

YAML Doctor is focused on correctness and syntax errors rather than on syntax style. For example, in the following block of invalid YAML:

some_key: 'It's got a quoted value with an unescaped quote'
another_key: Some value
indented:
    key: 'String that breaks across lines
 but is not indented.'

A standard YAML parser or linter might exit with one somewhat cryptic error here:

> other-yaml-linter example.yaml

can not read a block mapping entry; a multiline key may not be an implicit key at line 2, column 12:
    another_key: Some value
               ^

But this checker is designed to give you more useful messaging, and find all the errors it can before quitting:

> yaml-doctor example.yaml

example.yaml
  1:14       error    unescaped quote in quoted string
  5:2        warning  line is under-indented (it should be indented at least 5)

Instead of finding some invalid syntax before the colon on line 2, it correctly susses out that you had a quote that should have been escaped on line 1. It also flagged the under-indented value on line 5. You might think of it like pyflakes in comparison to flake8.

Even better, you can run it with the --fix option to automatically fix what it can:

> yaml-doctor example.yaml --fix
example.yaml
  1:14       fixed    unescaped quote in quoted string
  5:2        fixed    line is under-indented (it should be indented at least 5)

> cat example.yaml
some_key: 'It''s got a quoted value with an unescaped quote'
another_key: Some value
indented:
    key: 'String that breaks across lines
      but is not indented.'

If you check a .md (Markdown) file, YAML Doctor is also smart enough to check just the front-matter, and only if it looks like YAML front-matter :)

If you check a directory, YAML Doctor will look for all the .yaml, .yml, and .md files in it.

What kinds of errors does it address?

  • Disallowed YAML characters. (e.g. Most unicode control characters, like Null, Bell, Backspace, etc.)

  • Under-indented lines in multi-line values.

    some_key:
        some_nested_key: "Some multi-line
    string that isn't indented like it should be."
  • Unescaped quotes in single- and double-quoted scalars.

    some_key: "These "quotes" should have been escaped"
    another: 'This should've been, too'
  • Unterminated or early-terminated quoted strings:

    some_key: "This string never ends.
    another: 'this is unrelated to the above'

    Or (a more common form of this mistake):

    some_key: "Amazing," said Joe.
    another: "\"Yes, indeed,\" said Alice, with proper escaping."
  • Invalid escape sequences in double-quoted strings.

    some_key: "Escaping a \' is not only unnecessary; but it's actually an error in YAML."
    another: "Unicode escapes MUST be 4 or 8 characters, not \u22, two"
  • @ signs at the start of strings.

    some_key: @this is not allowed
  • [ at the start of strings.

    some_key: [TAG] you're it! But this breaks your parser.
  • HTML entities at the start of strings, which are parsed as anchors in YAML:

    some_key: …some text
  • Mixed spaces and tabs in indentation.

  • Mustache-esque template substitutions that are unquoted (depending whether your templates parse the YAML before or after substituting, you might need to quote these). e.g:

    some_key: {{ premium_trial_link }}
    # vs:
    some_key: '{{ premium_trial_link }}'

Installation and Usage

YAML Doctor can be used as a CLI application or a library. It requires Node.js version 12.0.0 or higher.

Command-Line

You can install and use it as a command-line application via NPM:

> npm install -g yaml-doctor

And run it on a file:

> yaml-doctor example.yaml

Options

  • --fix Fix any issues that can be safely resolved automatically.
  • --debug Print debug messages while parsing.
  • --help Print information about usage and options.
  • --version Print the version of YAML Doctor that your are running.

Library

You can use it as a library in your own programs. Add it to your package.json with NPM:

> npm install yaml-doctor

And then use it in your JavaScript:

const yamlDoctor = require('yaml-doctor');

// Check a string of YAML code:
yamlDoctor.check('some: yaml text').then(results => console.log(results));

// Check a file:
yamlDoctor.checkFile('path/to/file.yaml').then(results => console.log(results));

// There's also a helper for checking Gulp/Vinyl streams:
function checkYamlFiles () {
  return gulp
    .src('path/to/files/*.yaml')
    .pipe(yamlDoctor.checkGulpFileStream());
}

Functions

check(yamlText, [options])

Checks a string of YAML source code. Arguments:

  • yamlText: string YAML source code to check.
  • options: object
    • filename: string Path of file being checked. Used to make nicer error messages.
    • debug: boolean Print debug messages.
    • fix: boolean Include a string of YAML source with any automatically fixable errors fixed in the returned object.
    • removeInvalidCharacters: boolean Some characters are not allowed in YAML at all. If true, this will simply remove them from the YAML source. Note this is true by default. See details in the YAML spec: https://yaml.org/spec/1.2/spec.html#id2770814

Returns an object with:

  • issues: Array List of YAMLException error objects. Each has:
    • message: string
    • mark: {line: number, column: number}
    • level: string One of: error, warning, or fixed
  • fixed: string Will be a string if the fix option was true or null otherwise. Contains the “fixed” YAML source code.
checkFile(filePath, [content], [options])

Checks a YAML or Markdown file. If you have the fix option set, this will rewrite the file at filePath with the new, fixed YAML string. Arguments:

  • filePath: string Path to file to check. If the has a .md extension, this will try and extract the front-matter from the file and, if it looks YAML-ish, check/fix that.
  • content: Buffer Optional Buffer object with the contents of the file. If not provided, this function will read the file at filePath.
  • options: object Options to pass to check().

Returns a promise for the return value of check().

checkGulpFileStream([options])

If you use Gulp, this is a helpful convenience. It creates a stream that will call checkFile() on each file object it receives with the given options. It will also print any issues with the files along the way and, at the end of the stream, print a summary of how many warnings, errors, and fixed issues were found.

Roadmap

First off, a HUGE thanks to Asana, Inc. for support the development of this package. It was originally developed as part of a consulting project there, and they have graciously supported open-sourcing the results.

  • Work to see how the ideas here might be integrated into existing YAML parsers. In many cases, parsers might be able to offer clearer messaging like what’s found here. Of course, this package does a lot of extra work not to stop early or to look at the surrounding context to determine what might have been intended. A lot of that might be reasonably outside the scope of a parser.

    • Work with js-yaml authors to solidify the private interfaces this relies on!
  • Clean up checking code and split different issue types into separate "rule" objects so it’s a little easier to manage.

  • Make it possible to specify which rules you’d like to fix instead of fixing everything or nothing.

  • Add style-focused rules? The Python yamllint already does a great job of this, so it’s not a huge priority at the moment.

Contributing

Have errors or additional situations this doesn’t handle well? Want to help with the above roadmap items? We’d love your help. Please file an issue or PR in GitHub :)

License

Copyright (c) 2019-2024 Rob Brackett and Asana, Inc.

Licensed under the MIT license. See the LICENSE file for the full text of the license.