| 100 | } |
| 101 | |
| 102 | const parseDoubleQuoted = (input: string): string => { |
| 103 | if (!input.endsWith("\"") || input.length < 2) { |
| 104 | throw new SyntaxError("Unterminated double-quoted YAML string") |
| 105 | } |
| 106 | let output = "" |
| 107 | for (let index = 1; index < input.length - 1; index++) { |
| 108 | const character = input[index] |
| 109 | if (character !== "\\") { |
| 110 | output += character |
| 111 | continue |
| 112 | } |
| 113 | const escape = input[++index] |
| 114 | const escapes: Record<string, string> = { |
| 115 | "0": "\0", |
| 116 | a: "\x07", |
| 117 | b: "\b", |
| 118 | t: "\t", |
| 119 | n: "\n", |
| 120 | v: "\v", |
| 121 | f: "\f", |
| 122 | r: "\r", |
| 123 | e: "\x1b", |
| 124 | " ": " ", |
| 125 | "\"": "\"", |
| 126 | "/": "/", |
| 127 | "\\": "\\", |
| 128 | N: "\u0085", |
| 129 | _: "\u00a0", |
| 130 | L: "\u2028", |
| 131 | P: "\u2029" |
| 132 | } |
| 133 | if (hasOwn.call(escapes, escape)) { |
| 134 | output += escapes[escape] |
| 135 | continue |
| 136 | } |
| 137 | if (escape === "x" || escape === "u" || escape === "U") { |
| 138 | const length = escape === "x" ? 2 : escape === "u" ? 4 : 8 |
| 139 | const hex = input.slice(index + 1, index + 1 + length) |
| 140 | if (!new RegExp(`^[0-9A-Fa-f]{${length}}$`).test(hex)) { |
| 141 | throw new SyntaxError("Invalid unicode escape in YAML string") |
| 142 | } |
| 143 | output += String.fromCodePoint(Number.parseInt(hex, 16)) |
| 144 | index += length |
| 145 | continue |
| 146 | } |
| 147 | throw new SyntaxError(`Invalid YAML escape '\\${escape}'`) |
| 148 | } |
| 149 | return output |
| 150 | } |
| 151 | |
| 152 | const parseScalar = (input: string): unknown => { |
| 153 | const value = input.trim() |