Skip to content

Commit a3dfd38

Browse files
authored
feat: Add toStringDefaults option (#337)
1 parent b94d10b commit a3dfd38

File tree

5 files changed

+50
-19
lines changed

5 files changed

+50
-19
lines changed

docs/03_options.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,15 @@ The `!!value` and `!!yaml` types are not supported.
7171

7272
Used by: `parse()`, `parseDocument()`, `parseAllDocuments()`, `stringify()`, `new Composer()`, `new Document()`, and `doc.setSchema()`
7373

74-
| Name | Type | Default | Description |
75-
| ---------------- | ------------------------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76-
| compat | `string ⎮ Tag[] ⎮ null` | `null` | When parsing, warn about compatibility issues with the given schema. When stringifying, use scalar styles that are parsed correctly by the `compat` schema as well as the actual schema. |
77-
| customTags | `Tag[] ⎮ function` | | Array of [additional tags](#custom-data-types) to include in the schema |
78-
| merge | `boolean` | 1.1:&nbsp;`true` 1.2:&nbsp;`false` | Enable support for `<<` merge keys. Default value depends on YAML version. |
79-
| resolveKnownTags | `boolean` | `true` | When using the `'core'` schema, support parsing values with these explicit [YAML 1.1 tags]: `!!binary`, `!!omap`, `!!pairs`, `!!set`, `!!timestamp`. By default `true`. |
74+
| Name | Type | Default | Description |
75+
| ---------------- | ------------------------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
76+
| compat | `string ⎮ Tag[] ⎮ null` | `null` | When parsing, warn about compatibility issues with the given schema. When stringifying, use scalar styles that are parsed correctly by the `compat` schema as well as the actual schema. |
77+
| customTags | `Tag[] ⎮ function` | | Array of [additional tags](#custom-data-types) to include in the schema |
78+
| merge | `boolean` | 1.1:&nbsp;`true` 1.2:&nbsp;`false` | Enable support for `<<` merge keys. Default value depends on YAML version. |
79+
| resolveKnownTags | `boolean` | `true` | When using the `'core'` schema, support parsing values with these explicit [YAML 1.1 tags]: `!!binary`, `!!omap`, `!!pairs`, `!!set`, `!!timestamp`. By default `true`. |
8080
| schema | `string` | 1.1:&nbsp;`'yaml-1.1` 1.2:&nbsp;`'core'` | The base schema to use. Default value depends on YAML version. Built-in support is provided for `'core'`, `'failsafe'`, `'json'`, and `'yaml-1.1'`. If using another value, `customTags` must be an array of tags. |
81-
| sortMapEntries | `boolean ⎮` `(a, b: Pair) => number` | `false` | When stringifying, sort map entries. If `true`, sort by comparing key values using the native less-than `<` operator. |
81+
| sortMapEntries | `boolean ⎮` `(a, b: Pair) => number` | `false` | When stringifying, sort map entries. If `true`, sort by comparing key values using the native less-than `<` operator. |
82+
| toStringDefaults | `ToStringOptions` | | Override default values for `toString()` options. |
8283

8384
[yaml 1.1 tags]: https://yaml.org/type/
8485

src/options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ export type SchemaOptions = {
141141
* Default: `false`
142142
*/
143143
sortMapEntries?: boolean | ((a: Pair, b: Pair) => number)
144+
145+
/**
146+
* Override default values for `toString()` options.
147+
*/
148+
toStringDefaults?: ToStringOptions
144149
}
145150

146151
export type CreateNodeOptions = {

src/schema/Schema.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { MAP, SCALAR, SEQ } from '../nodes/Node.js'
22
import type { Pair } from '../nodes/Pair.js'
3-
import type { SchemaOptions } from '../options.js'
3+
import type { SchemaOptions, ToStringOptions } from '../options.js'
44
import { map } from './common/map.js'
55
import { seq } from './common/seq.js'
66
import { string } from './common/string.js'
@@ -16,7 +16,8 @@ export class Schema {
1616
merge: boolean
1717
name: string
1818
sortMapEntries: ((a: Pair, b: Pair) => number) | null
19-
tags: Array<CollectionTag | ScalarTag>;
19+
tags: Array<CollectionTag | ScalarTag>
20+
toStringOptions: Readonly<ToStringOptions> | null;
2021

2122
// Used by createNode() and composeScalar()
2223
[MAP]: CollectionTag;
@@ -29,7 +30,8 @@ export class Schema {
2930
merge,
3031
resolveKnownTags,
3132
schema,
32-
sortMapEntries
33+
sortMapEntries,
34+
toStringDefaults
3335
}: SchemaOptions) {
3436
this.compat = Array.isArray(compat)
3537
? getTags(compat, 'compat')
@@ -40,6 +42,7 @@ export class Schema {
4042
this.name = schema || 'core'
4143
this.knownTags = resolveKnownTags ? coreKnownTags : {}
4244
this.tags = getTags(customTags, this.name)
45+
this.toStringOptions = toStringDefaults || null
4346

4447
Object.defineProperty(this, MAP, { value: map })
4548
Object.defineProperty(this, SCALAR, { value: string })

src/stringify/stringify.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,11 @@ export type StringifyContext = {
2929
options: Readonly<Required<Omit<ToStringOptions, 'indent'>>>
3030
}
3131

32-
export const createStringifyContext = (
32+
export function createStringifyContext(
3333
doc: Document,
3434
options: ToStringOptions
35-
): StringifyContext => ({
36-
anchors: new Set(),
37-
doc,
38-
indent: '',
39-
indentStep:
40-
typeof options.indent === 'number' ? ' '.repeat(options.indent) : ' ',
41-
options: Object.assign(
35+
): StringifyContext {
36+
const opt = Object.assign(
4237
{
4338
blockQuote: true,
4439
commentString: stringifyComment,
@@ -57,9 +52,18 @@ export const createStringifyContext = (
5752
trueStr: 'true',
5853
verifyAliasOrder: true
5954
},
55+
doc.schema.toStringOptions,
6056
options
6157
)
62-
})
58+
59+
return {
60+
anchors: new Set(),
61+
doc,
62+
indent: '',
63+
indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : ' ',
64+
options: opt
65+
}
66+
}
6367

6468
function getTagObject(tags: Array<ScalarTag | CollectionTag>, item: Node) {
6569
if (item.tag) {

tests/doc/stringify.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,24 @@ describe('Scalar options', () => {
870870
}
871871
})
872872

873+
describe('toStringDefaults', () => {
874+
test('Set on Document creation', () => {
875+
const doc = new YAML.Document(
876+
{ foo: null },
877+
{ toStringDefaults: { nullStr: '~' } }
878+
)
879+
expect(doc.toString()).toBe('foo: ~\n')
880+
})
881+
882+
test('Override in toString()', () => {
883+
const doc = new YAML.Document(
884+
{ foo: null },
885+
{ toStringDefaults: { nullStr: '~' } }
886+
)
887+
expect(doc.toString({ nullStr: '' })).toBe('foo:\n')
888+
})
889+
})
890+
873891
describe('Document markers in top-level scalars', () => {
874892
test('---', () => {
875893
const str = YAML.stringify('---')

0 commit comments

Comments
 (0)