diff --git a/core/package.json b/core/package.json index 0c4f8d3a..3f720633 100644 --- a/core/package.json +++ b/core/package.json @@ -155,7 +155,7 @@ "vfile-statistics": "2.0.0", "what-input": "5.2.12", "what-the-diff": "0.6.0", - "yaml": "1.10.2" + "yaml": "2.1.3" }, "devDependencies": { "@babel/cli": "7.19.3", diff --git a/core/src/formats/YamlFormatter.ts b/core/src/formats/YamlFormatter.ts index c2332d2c..0a331dd1 100644 --- a/core/src/formats/YamlFormatter.ts +++ b/core/src/formats/YamlFormatter.ts @@ -1,20 +1,21 @@ -import yaml from 'yaml'; +import yaml, { isNode, isMap } from 'yaml'; import { sortKeys } from './helpers'; import FileFormatter from './FileFormatter'; +import { isNotNullish } from '../lib/util/null.util'; -import type { Pair, YAMLMap, YAMLSeq } from 'yaml/types'; +import type { Pair, YAMLMap, Node } from 'yaml'; function addComments(items: Array, comments: Record, prefix = '') { items.forEach(item => { - if (item.key !== undefined) { - const itemKey = item.key.toString(); + if (isNotNullish(item.key)) { + const itemKey = item.key?.toString() ?? ''; const key = prefix ? `${prefix}.${itemKey}` : itemKey; - if (comments[key]) { + if (isNode(item.key) && comments[key]) { const value = comments[key].split('\\n').join('\n '); - item.commentBefore = ` ${value}`; + item.key.commentBefore = ` ${value}`; } - if (Array.isArray(item.value?.items)) { + if (isMap(item.value)) { addComments(item.value.items, comments, key); } } @@ -30,12 +31,12 @@ class YamlFormatter extends FileFormatter { } toFile(data: object, sortedKeys: string[] = [], comments: Record = {}) { - const contents = yaml.createNode(data) as YAMLMap | YAMLSeq; + const doc = new yaml.Document(); + const contents = doc.createNode(data) as YAMLMap; - addComments(contents.items, comments); + addComments(contents.items as Pair[], comments); contents.items.sort(sortKeys(sortedKeys, item => item.key?.toString())); - const doc = new yaml.Document(); doc.contents = contents; return doc.toString(); diff --git a/core/src/formats/__tests__/YamlFormatter.spec.ts b/core/src/formats/__tests__/YamlFormatter.spec.ts new file mode 100644 index 00000000..2ba22ede --- /dev/null +++ b/core/src/formats/__tests__/YamlFormatter.spec.ts @@ -0,0 +1,69 @@ +import yamlFormatter from '../YamlFormatter'; + +const json = { + keyF: 'valueF', + keyA: 'valueA', + keyB: 'valueB', + keyD: 'valueD', + keyC: 'valueC', + keyE: 'valueE', +}; + +const unsortedYaml = `keyF: valueF +keyA: valueA +keyB: valueB +keyD: valueD +keyC: valueC +keyE: valueE +`; + +const sortedYaml = `keyA: valueA +keyB: valueB +keyC: valueC +keyD: valueD +keyE: valueE +keyF: valueF +`; + +const sortedCommentedYaml = `keyA: valueA +# New comment here +keyB: valueB +keyC: valueC +keyD: valueD +keyE: valueE +# Last comment +keyF: valueF +`; + +describe('YamlFormatter', () => { + describe('toFile', () => { + it('should convert json to yaml', () => { + expect(yamlFormatter.toFile(json)).toEqual(unsortedYaml); + }); + + it('should sort yaml', () => { + expect(yamlFormatter.toFile(json, ['keyA', 'keyB', 'keyC', 'keyD', 'keyE', 'keyF'])).toEqual( + sortedYaml, + ); + }); + + it('should add comments', () => { + expect( + yamlFormatter.toFile(json, ['keyA', 'keyB', 'keyC', 'keyD', 'keyE', 'keyF'], { + keyB: 'New comment here', + keyF: 'Last comment', + }), + ).toEqual(sortedCommentedYaml); + }); + }); + + describe('fromFile', () => { + it('should convert yaml to json', () => { + expect(yamlFormatter.fromFile(unsortedYaml)).toEqual(json); + }); + + it('should handle yaml with comments', () => { + expect(yamlFormatter.fromFile(sortedCommentedYaml)).toEqual(json); + }); + }); +}); diff --git a/core/yarn.lock b/core/yarn.lock index 122465c6..005695c2 100644 --- a/core/yarn.lock +++ b/core/yarn.lock @@ -12104,7 +12104,12 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@1.10.2, yaml@^1.10.0: +yaml@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207" + integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg== + +yaml@^1.10.0: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==