/
pairs.ts
82 lines (79 loc) · 2.67 KB
/
pairs.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import type { CreateNodeContext } from '../../doc/createNode.js'
import { isMap, isPair, isSeq, ParsedNode } from '../../nodes/Node.js'
import { createPair, Pair } from '../../nodes/Pair.js'
import { Scalar } from '../../nodes/Scalar.js'
import { YAMLMap } from '../../nodes/YAMLMap.js'
import { YAMLSeq } from '../../nodes/YAMLSeq.js'
import type { Schema } from '../../schema/Schema.js'
import type { CollectionTag } from '../types.js'
export function resolvePairs(
seq:
| YAMLSeq.Parsed<ParsedNode | Pair<ParsedNode, ParsedNode | null>>
| YAMLMap.Parsed,
onError: (message: string) => void
) {
if (isSeq(seq)) {
for (let i = 0; i < seq.items.length; ++i) {
let item = seq.items[i]
if (isPair(item)) continue
else if (isMap(item)) {
if (item.items.length > 1)
onError('Each pair must have its own sequence indicator')
const pair =
item.items[0] || new Pair(new Scalar(null) as Scalar.Parsed)
if (item.commentBefore)
pair.key.commentBefore = pair.key.commentBefore
? `${item.commentBefore}\n${pair.key.commentBefore}`
: item.commentBefore
if (item.comment) {
const cn = pair.value || pair.key
cn.comment = cn.comment
? `${item.comment}\n${cn.comment}`
: item.comment
}
item = pair
}
seq.items[i] = isPair(item) ? item : new Pair(item)
}
} else onError('Expected a sequence for this tag')
return seq as YAMLSeq.Parsed<Pair<ParsedNode, ParsedNode | null>>
}
export function createPairs(
schema: Schema,
iterable: unknown,
ctx: CreateNodeContext
) {
const { replacer } = ctx
const pairs = new YAMLSeq(schema)
pairs.tag = 'tag:yaml.org,2002:pairs'
let i = 0
if (iterable && Symbol.iterator in Object(iterable))
for (let it of iterable as Iterable<unknown>) {
if (typeof replacer === 'function')
it = replacer.call(iterable, String(i++), it)
let key: unknown, value: unknown
if (Array.isArray(it)) {
if (it.length === 2) {
key = it[0]
value = it[1]
} else throw new TypeError(`Expected [key, value] tuple: ${it}`)
} else if (it && it instanceof Object) {
const keys = Object.keys(it)
if (keys.length === 1) {
key = keys[0]
value = (it as any)[key as string]
} else throw new TypeError(`Expected { key: value } tuple: ${it}`)
} else {
key = it
}
pairs.items.push(createPair(key, value, ctx))
}
return pairs
}
export const pairs: CollectionTag = {
collection: 'seq',
default: false,
tag: 'tag:yaml.org,2002:pairs',
resolve: resolvePairs,
createNode: createPairs
}