This tutorial shows you how to parse a YAML file in Deno and also how to write data to a file in YAML format.
YAML (YAML Ain't Markup Language) is a human-readable data-serialization language. YAML uses indentation to indicate nesting, [...] for lists and {...} for maps. It also has libraries available for many programming languages.
Deno itself has a module named yaml
as part of Deno Standard Modules. It has the functionalities for formatting an object to YAML format and parsing a string in YAML format.
For this tutorial, let's assume we have these two files, one with a single document and the other with multi-documents.
data.yaml
playerName: tuwaise
monsters:
- number: 1
type: fire
- number: 2
type: water
- number: 3
type: grass
data2.yaml
playerName: tuwaise
monsters:
- number: 1
type: fire
- number: 2
type: water
- number: 3
type: grass
---
playerName: chibi
monsters:
- number: 1
type: ice
- number: 2
type: psychic
Using Deno std
yaml Module
First, import and re-export the functions of yaml module in deps.ts
file. There are three functions we are going to use.
- parse: used to parse a yaml string to an object.
- parseAll: used to parse a yaml string containing multi-documents to a list of objects.
- stringify: used to format an object to YAML format.
deps.ts
import {
parse as yamlParse,
parseAll as yamlParseAll,
stringify as yamlStringify,
} from 'https://deno.land/std@0.82.0/encoding/yaml.ts';
Parse YAML File
Below is the function that allows you to parse a string in YAML format to a JSON object.
function parse(content: string, options?: ParseOptions): unknown
ParseOptions
has the following fields:
legacy?: boolean
: qqq.listener?: ((...args: Any[]) => void) | null
: qqq.filename?: string
: string to be used as a file path in error/warning message.schema?: SchemaDefinition
: qqq.json?: boolean
: Compatibility with JSON.parse behaviour.onWarning?(this: null, e?: YAMLError): void
: function to call on warning messages.
The function requires you to pass the content as a string. If you need to read the contents from a file, you can use Deno.readTextFile
. Since the code requires access to read files, you need to add --allow-read
flag while running deno run
command.
Example:
import { yamlParse } from './deps.ts';
const data = yamlParse(await Deno.readTextFile('data.yaml'));
console.log(data);
Output:
{
playerName: "tuwaise",
monsters: [
{ number: 1, type: "fire" },
{ number: 2, type: "water" },
{ number: 3, type: "grass" }
]
}
Make sure the file to be parsed contains a valid YAML format. Otherwise YAMLError
will be thrown.
The parse
function only works if the file contains a single document. If the file contains multi-documents, you need to use the parseAll
function:
function parseAll(
content: string,
iterator?: CbFunction,
options?: ParseOptions,
): unknown
Example:
import { yamlParseAll } from './deps.ts';
const data = yamlParseAll(await Deno.readTextFile('data2.yaml'));
console.log(data);
Output:
[
{
playerName: "tuwaise",
monsters: [
{ number: 1, type: "fire" },
{ number: 2, type: "water" },
{ number: 3, type: "grass" }
]
},
{
playerName: "chibi",
monsters: [ { number: 1, type: "ice" }, { number: 2, type: "psychic" } ]
}
]
Write YAML File
The module also has a function named stringify
that can be used to format an object to YAML format.
function stringify(
obj: Record<string, unknown>,
options?: DumpOptions,
): string
You need to pass the object as the first argument. Optionally, you can also pass a second argument which is an object whose type is DumpOptions
to customize the output format. DumpOptions
has the following fields:
indent?: number
: Indentation with in spaces.noArrayIndent?: boolean
: Iftrue
, it will not add an indentation level to array elements.skipInvalid?: boolean
: Iftrue
, it will not throw on invalid types and skip pairs and single values with such types.flowLevel?: number
: Specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everywhere.styles?: ArrayObject<StyleVariant> | null
: Each tag may have its own set of styles. - "tag" => "style" map.schema?: SchemaDefinition
: The schema to use.sortKeys?: boolean | ((a: string, b: string) => number)
: If true, sort keys when dumping YAML in ascending, ASCII character order. If a function, use the function to sort the keys. Defaults tofalse
.lineWidth?: number
: Set the maximum line width. Defaults to 80.noRefs?: boolean
: Iftrue
, don't convert duplicate objects into references. Defaults tofalse
.noCompatMode?: boolean
: Iftrue
, don't try to be compatible with older yaml versions.condenseFlow?: boolean
: Iftrue
flow sequences will be condensed, omitting the space between `key: value` or `a, b`.
Below is a basic usage example that doesn't pass the options argument. --allow-write
flag needs to be added if you want to write the output to a file.
const yaml = yamlStringify({
playerName: 'tuwaise',
monsters: [
{ number: 1, type: 'fire' },
{ number: 2, type: 'water' },
{ number: 3, type: 'grass' },
]
});
console.log(await Deno.writeTextFile('output.yaml', yaml));
Output:
playerName: tuwaise
monsters:
- number: 1
type: fire
- number: 2
type: water
- number: 3
type: grass
Here's another example with custom indent size and sorted keys.
const yaml = yamlStringify(
{
playerName: 'tuwaise',
monsters: [
{ number: 1, type: 'fire' },
{ number: 2, type: 'water' },
{ number: 3, type: 'grass' },
]
},
{
indent: 3,
sortKeys: true,
}
);
console.log(await Deno.writeTextFile('output.yaml', yaml));
Output:
monsters:
-
number: 1
type: fire
-
number: 2
type: water
-
number: 3
type: grass
playerName: tuwaise
Summary
That's how to parse data in YAML format and how to format data to YAML format. You can utilize yaml
module which is part of Deno Standard Modules.