next-posts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README-zh.md +334 -0
- package/README.md +337 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1751 -0
- package/index.ts +65 -0
- package/package.json +34 -0
- package/tests/fixtures/custom-posts/custom.md +6 -0
- package/tests/fixtures/posts/hello-world.md +6 -0
- package/tests/fixtures/posts/second-post.md +9 -0
- package/tests/index.test.ts +252 -0
- package/tsconfig.json +14 -0
- package/tsdown.config.ts +10 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1751 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
//#region node_modules/@std/yaml/_chars.js
|
|
5
|
+
const TAB = 9;
|
|
6
|
+
const LINE_FEED = 10;
|
|
7
|
+
const CARRIAGE_RETURN = 13;
|
|
8
|
+
const SPACE = 32;
|
|
9
|
+
const EXCLAMATION = 33;
|
|
10
|
+
const DOUBLE_QUOTE = 34;
|
|
11
|
+
const SHARP = 35;
|
|
12
|
+
const PERCENT = 37;
|
|
13
|
+
const AMPERSAND = 38;
|
|
14
|
+
const SINGLE_QUOTE = 39;
|
|
15
|
+
const ASTERISK = 42;
|
|
16
|
+
const PLUS = 43;
|
|
17
|
+
const COMMA = 44;
|
|
18
|
+
const MINUS = 45;
|
|
19
|
+
const DOT = 46;
|
|
20
|
+
const COLON = 58;
|
|
21
|
+
const SMALLER_THAN = 60;
|
|
22
|
+
const GREATER_THAN = 62;
|
|
23
|
+
const QUESTION = 63;
|
|
24
|
+
const COMMERCIAL_AT = 64;
|
|
25
|
+
const LEFT_SQUARE_BRACKET = 91;
|
|
26
|
+
const BACKSLASH = 92;
|
|
27
|
+
const RIGHT_SQUARE_BRACKET = 93;
|
|
28
|
+
const GRAVE_ACCENT = 96;
|
|
29
|
+
const LEFT_CURLY_BRACKET = 123;
|
|
30
|
+
const VERTICAL_LINE = 124;
|
|
31
|
+
const RIGHT_CURLY_BRACKET = 125;
|
|
32
|
+
function isEOL(c) {
|
|
33
|
+
return c === LINE_FEED || c === CARRIAGE_RETURN;
|
|
34
|
+
}
|
|
35
|
+
function isWhiteSpace(c) {
|
|
36
|
+
return c === TAB || c === SPACE;
|
|
37
|
+
}
|
|
38
|
+
function isWhiteSpaceOrEOL(c) {
|
|
39
|
+
return isWhiteSpace(c) || isEOL(c);
|
|
40
|
+
}
|
|
41
|
+
function isFlowIndicator(c) {
|
|
42
|
+
return c === COMMA || c === LEFT_SQUARE_BRACKET || c === RIGHT_SQUARE_BRACKET || c === LEFT_CURLY_BRACKET || c === RIGHT_CURLY_BRACKET;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region node_modules/@std/yaml/_type/binary.js
|
|
47
|
+
const BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
|
|
48
|
+
function resolveYamlBinary(data) {
|
|
49
|
+
if (data === null) return false;
|
|
50
|
+
let code;
|
|
51
|
+
let bitlen = 0;
|
|
52
|
+
const max = data.length;
|
|
53
|
+
const map = BASE64_MAP;
|
|
54
|
+
for (let idx = 0; idx < max; idx++) {
|
|
55
|
+
code = map.indexOf(data.charAt(idx));
|
|
56
|
+
if (code > 64) continue;
|
|
57
|
+
if (code < 0) return false;
|
|
58
|
+
bitlen += 6;
|
|
59
|
+
}
|
|
60
|
+
return bitlen % 8 === 0;
|
|
61
|
+
}
|
|
62
|
+
function constructYamlBinary(data) {
|
|
63
|
+
const input = data.replace(/[\r\n=]/g, "");
|
|
64
|
+
const max = input.length;
|
|
65
|
+
const map = BASE64_MAP;
|
|
66
|
+
const result = [];
|
|
67
|
+
let bits = 0;
|
|
68
|
+
for (let idx = 0; idx < max; idx++) {
|
|
69
|
+
if (idx % 4 === 0 && idx) {
|
|
70
|
+
result.push(bits >> 16 & 255);
|
|
71
|
+
result.push(bits >> 8 & 255);
|
|
72
|
+
result.push(bits & 255);
|
|
73
|
+
}
|
|
74
|
+
bits = bits << 6 | map.indexOf(input.charAt(idx));
|
|
75
|
+
}
|
|
76
|
+
const tailbits = max % 4 * 6;
|
|
77
|
+
if (tailbits === 0) {
|
|
78
|
+
result.push(bits >> 16 & 255);
|
|
79
|
+
result.push(bits >> 8 & 255);
|
|
80
|
+
result.push(bits & 255);
|
|
81
|
+
} else if (tailbits === 18) {
|
|
82
|
+
result.push(bits >> 10 & 255);
|
|
83
|
+
result.push(bits >> 2 & 255);
|
|
84
|
+
} else if (tailbits === 12) result.push(bits >> 4 & 255);
|
|
85
|
+
return new Uint8Array(result);
|
|
86
|
+
}
|
|
87
|
+
function representYamlBinary(object) {
|
|
88
|
+
const max = object.length;
|
|
89
|
+
const map = BASE64_MAP;
|
|
90
|
+
let result = "";
|
|
91
|
+
let bits = 0;
|
|
92
|
+
for (let idx = 0; idx < max; idx++) {
|
|
93
|
+
if (idx % 3 === 0 && idx) {
|
|
94
|
+
result += map[bits >> 18 & 63];
|
|
95
|
+
result += map[bits >> 12 & 63];
|
|
96
|
+
result += map[bits >> 6 & 63];
|
|
97
|
+
result += map[bits & 63];
|
|
98
|
+
}
|
|
99
|
+
bits = (bits << 8) + object[idx];
|
|
100
|
+
}
|
|
101
|
+
const tail = max % 3;
|
|
102
|
+
if (tail === 0) {
|
|
103
|
+
result += map[bits >> 18 & 63];
|
|
104
|
+
result += map[bits >> 12 & 63];
|
|
105
|
+
result += map[bits >> 6 & 63];
|
|
106
|
+
result += map[bits & 63];
|
|
107
|
+
} else if (tail === 2) {
|
|
108
|
+
result += map[bits >> 10 & 63];
|
|
109
|
+
result += map[bits >> 4 & 63];
|
|
110
|
+
result += map[bits << 2 & 63];
|
|
111
|
+
result += map[64];
|
|
112
|
+
} else if (tail === 1) {
|
|
113
|
+
result += map[bits >> 2 & 63];
|
|
114
|
+
result += map[bits << 4 & 63];
|
|
115
|
+
result += map[64];
|
|
116
|
+
result += map[64];
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
function isBinary(obj) {
|
|
121
|
+
return obj instanceof Uint8Array;
|
|
122
|
+
}
|
|
123
|
+
const binary = {
|
|
124
|
+
tag: "tag:yaml.org,2002:binary",
|
|
125
|
+
construct: constructYamlBinary,
|
|
126
|
+
kind: "scalar",
|
|
127
|
+
predicate: isBinary,
|
|
128
|
+
represent: representYamlBinary,
|
|
129
|
+
resolve: resolveYamlBinary
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region node_modules/@std/yaml/_type/bool.js
|
|
134
|
+
const YAML_TRUE_BOOLEANS = [
|
|
135
|
+
"true",
|
|
136
|
+
"True",
|
|
137
|
+
"TRUE"
|
|
138
|
+
];
|
|
139
|
+
const YAML_FALSE_BOOLEANS = [
|
|
140
|
+
"false",
|
|
141
|
+
"False",
|
|
142
|
+
"FALSE"
|
|
143
|
+
];
|
|
144
|
+
const YAML_BOOLEANS = [...YAML_TRUE_BOOLEANS, ...YAML_FALSE_BOOLEANS];
|
|
145
|
+
const bool = {
|
|
146
|
+
tag: "tag:yaml.org,2002:bool",
|
|
147
|
+
kind: "scalar",
|
|
148
|
+
defaultStyle: "lowercase",
|
|
149
|
+
predicate: (value) => typeof value === "boolean" || value instanceof Boolean,
|
|
150
|
+
construct: (data) => YAML_TRUE_BOOLEANS.includes(data),
|
|
151
|
+
resolve: (data) => YAML_BOOLEANS.includes(data),
|
|
152
|
+
represent: {
|
|
153
|
+
lowercase: (object) => {
|
|
154
|
+
return (object instanceof Boolean ? object.valueOf() : object) ? "true" : "false";
|
|
155
|
+
},
|
|
156
|
+
uppercase: (object) => {
|
|
157
|
+
return (object instanceof Boolean ? object.valueOf() : object) ? "TRUE" : "FALSE";
|
|
158
|
+
},
|
|
159
|
+
camelcase: (object) => {
|
|
160
|
+
return (object instanceof Boolean ? object.valueOf() : object) ? "True" : "False";
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region node_modules/@std/yaml/_utils.js
|
|
167
|
+
function isObject(value) {
|
|
168
|
+
return value !== null && typeof value === "object";
|
|
169
|
+
}
|
|
170
|
+
function isNegativeZero(i) {
|
|
171
|
+
return i === 0 && Number.NEGATIVE_INFINITY === 1 / i;
|
|
172
|
+
}
|
|
173
|
+
function isPlainObject(object) {
|
|
174
|
+
return Object.prototype.toString.call(object) === "[object Object]";
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region node_modules/@std/yaml/_type/float.js
|
|
179
|
+
const YAML_FLOAT_PATTERN = new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
|
|
180
|
+
function resolveYamlFloat(data) {
|
|
181
|
+
if (!YAML_FLOAT_PATTERN.test(data) || data[data.length - 1] === "_") return false;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
function constructYamlFloat(data) {
|
|
185
|
+
let value = data.replace(/_/g, "").toLowerCase();
|
|
186
|
+
const sign = value[0] === "-" ? -1 : 1;
|
|
187
|
+
if (value[0] && "+-".includes(value[0])) value = value.slice(1);
|
|
188
|
+
if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
|
|
189
|
+
if (value === ".nan") return NaN;
|
|
190
|
+
return sign * parseFloat(value);
|
|
191
|
+
}
|
|
192
|
+
const SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
|
|
193
|
+
function representYamlFloat(object, style) {
|
|
194
|
+
const value = object instanceof Number ? object.valueOf() : object;
|
|
195
|
+
if (isNaN(value)) switch (style) {
|
|
196
|
+
case "lowercase": return ".nan";
|
|
197
|
+
case "uppercase": return ".NAN";
|
|
198
|
+
case "camelcase": return ".NaN";
|
|
199
|
+
}
|
|
200
|
+
else if (Number.POSITIVE_INFINITY === value) switch (style) {
|
|
201
|
+
case "lowercase": return ".inf";
|
|
202
|
+
case "uppercase": return ".INF";
|
|
203
|
+
case "camelcase": return ".Inf";
|
|
204
|
+
}
|
|
205
|
+
else if (Number.NEGATIVE_INFINITY === value) switch (style) {
|
|
206
|
+
case "lowercase": return "-.inf";
|
|
207
|
+
case "uppercase": return "-.INF";
|
|
208
|
+
case "camelcase": return "-.Inf";
|
|
209
|
+
}
|
|
210
|
+
else if (isNegativeZero(value)) return "-0.0";
|
|
211
|
+
const res = value.toString(10);
|
|
212
|
+
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;
|
|
213
|
+
}
|
|
214
|
+
function isFloat(object) {
|
|
215
|
+
if (object instanceof Number) object = object.valueOf();
|
|
216
|
+
return typeof object === "number" && (object % 1 !== 0 || isNegativeZero(object));
|
|
217
|
+
}
|
|
218
|
+
const float = {
|
|
219
|
+
tag: "tag:yaml.org,2002:float",
|
|
220
|
+
construct: constructYamlFloat,
|
|
221
|
+
defaultStyle: "lowercase",
|
|
222
|
+
kind: "scalar",
|
|
223
|
+
predicate: isFloat,
|
|
224
|
+
represent: representYamlFloat,
|
|
225
|
+
resolve: resolveYamlFloat
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region node_modules/@std/yaml/_type/int.js
|
|
230
|
+
function isCharCodeInRange(c, lower, upper) {
|
|
231
|
+
return lower <= c && c <= upper;
|
|
232
|
+
}
|
|
233
|
+
function isHexCode(c) {
|
|
234
|
+
return isCharCodeInRange(c, 48, 57) || isCharCodeInRange(c, 65, 70) || isCharCodeInRange(c, 97, 102);
|
|
235
|
+
}
|
|
236
|
+
function isOctCode(c) {
|
|
237
|
+
return isCharCodeInRange(c, 48, 55);
|
|
238
|
+
}
|
|
239
|
+
function isDecCode(c) {
|
|
240
|
+
return isCharCodeInRange(c, 48, 57);
|
|
241
|
+
}
|
|
242
|
+
function resolveYamlInteger(data) {
|
|
243
|
+
const max = data.length;
|
|
244
|
+
let index = 0;
|
|
245
|
+
let hasDigits = false;
|
|
246
|
+
if (!max) return false;
|
|
247
|
+
let ch = data[index];
|
|
248
|
+
if (ch === "-" || ch === "+") ch = data[++index];
|
|
249
|
+
if (ch === "0") {
|
|
250
|
+
if (index + 1 === max) return true;
|
|
251
|
+
ch = data[++index];
|
|
252
|
+
if (ch === "b") {
|
|
253
|
+
index++;
|
|
254
|
+
for (; index < max; index++) {
|
|
255
|
+
ch = data[index];
|
|
256
|
+
if (ch === "_") continue;
|
|
257
|
+
if (ch !== "0" && ch !== "1") return false;
|
|
258
|
+
hasDigits = true;
|
|
259
|
+
}
|
|
260
|
+
return hasDigits && ch !== "_";
|
|
261
|
+
}
|
|
262
|
+
if (ch === "x") {
|
|
263
|
+
index++;
|
|
264
|
+
for (; index < max; index++) {
|
|
265
|
+
ch = data[index];
|
|
266
|
+
if (ch === "_") continue;
|
|
267
|
+
if (!isHexCode(data.charCodeAt(index))) return false;
|
|
268
|
+
hasDigits = true;
|
|
269
|
+
}
|
|
270
|
+
return hasDigits && ch !== "_";
|
|
271
|
+
}
|
|
272
|
+
for (; index < max; index++) {
|
|
273
|
+
ch = data[index];
|
|
274
|
+
if (ch === "_") continue;
|
|
275
|
+
if (!isOctCode(data.charCodeAt(index))) return false;
|
|
276
|
+
hasDigits = true;
|
|
277
|
+
}
|
|
278
|
+
return hasDigits && ch !== "_";
|
|
279
|
+
}
|
|
280
|
+
if (ch === "_") return false;
|
|
281
|
+
for (; index < max; index++) {
|
|
282
|
+
ch = data[index];
|
|
283
|
+
if (ch === "_") continue;
|
|
284
|
+
if (!isDecCode(data.charCodeAt(index))) return false;
|
|
285
|
+
hasDigits = true;
|
|
286
|
+
}
|
|
287
|
+
if (!hasDigits || ch === "_") return false;
|
|
288
|
+
return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
|
|
289
|
+
}
|
|
290
|
+
function constructYamlInteger(data) {
|
|
291
|
+
let value = data;
|
|
292
|
+
if (value.includes("_")) value = value.replace(/_/g, "");
|
|
293
|
+
let sign = 1;
|
|
294
|
+
let ch = value[0];
|
|
295
|
+
if (ch === "-" || ch === "+") {
|
|
296
|
+
if (ch === "-") sign = -1;
|
|
297
|
+
value = value.slice(1);
|
|
298
|
+
ch = value[0];
|
|
299
|
+
}
|
|
300
|
+
if (value === "0") return 0;
|
|
301
|
+
if (ch === "0") {
|
|
302
|
+
if (value[1] === "b") return sign * parseInt(value.slice(2), 2);
|
|
303
|
+
if (value[1] === "x") return sign * parseInt(value, 16);
|
|
304
|
+
return sign * parseInt(value, 8);
|
|
305
|
+
}
|
|
306
|
+
return sign * parseInt(value, 10);
|
|
307
|
+
}
|
|
308
|
+
function isInteger(object) {
|
|
309
|
+
if (object instanceof Number) object = object.valueOf();
|
|
310
|
+
return typeof object === "number" && object % 1 === 0 && !isNegativeZero(object);
|
|
311
|
+
}
|
|
312
|
+
const int = {
|
|
313
|
+
tag: "tag:yaml.org,2002:int",
|
|
314
|
+
construct: constructYamlInteger,
|
|
315
|
+
defaultStyle: "decimal",
|
|
316
|
+
kind: "scalar",
|
|
317
|
+
predicate: isInteger,
|
|
318
|
+
represent: {
|
|
319
|
+
binary(object) {
|
|
320
|
+
const value = object instanceof Number ? object.valueOf() : object;
|
|
321
|
+
return value >= 0 ? `0b${value.toString(2)}` : `-0b${value.toString(2).slice(1)}`;
|
|
322
|
+
},
|
|
323
|
+
octal(object) {
|
|
324
|
+
const value = object instanceof Number ? object.valueOf() : object;
|
|
325
|
+
return value >= 0 ? `0${value.toString(8)}` : `-0${value.toString(8).slice(1)}`;
|
|
326
|
+
},
|
|
327
|
+
decimal(object) {
|
|
328
|
+
return (object instanceof Number ? object.valueOf() : object).toString(10);
|
|
329
|
+
},
|
|
330
|
+
hexadecimal(object) {
|
|
331
|
+
const value = object instanceof Number ? object.valueOf() : object;
|
|
332
|
+
return value >= 0 ? `0x${value.toString(16).toUpperCase()}` : `-0x${value.toString(16).toUpperCase().slice(1)}`;
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
resolve: resolveYamlInteger
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region node_modules/@std/yaml/_type/map.js
|
|
340
|
+
const map = {
|
|
341
|
+
tag: "tag:yaml.org,2002:map",
|
|
342
|
+
resolve() {
|
|
343
|
+
return true;
|
|
344
|
+
},
|
|
345
|
+
construct(data) {
|
|
346
|
+
return data !== null ? data : {};
|
|
347
|
+
},
|
|
348
|
+
kind: "mapping"
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region node_modules/@std/yaml/_type/merge.js
|
|
353
|
+
const merge = {
|
|
354
|
+
tag: "tag:yaml.org,2002:merge",
|
|
355
|
+
kind: "scalar",
|
|
356
|
+
resolve: (data) => data === "<<" || data === null,
|
|
357
|
+
construct: (data) => data
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region node_modules/@std/yaml/_type/nil.js
|
|
362
|
+
const nil = {
|
|
363
|
+
tag: "tag:yaml.org,2002:null",
|
|
364
|
+
kind: "scalar",
|
|
365
|
+
defaultStyle: "lowercase",
|
|
366
|
+
predicate: (object) => object === null,
|
|
367
|
+
construct: () => null,
|
|
368
|
+
resolve: (data) => {
|
|
369
|
+
return data === "~" || data === "null" || data === "Null" || data === "NULL";
|
|
370
|
+
},
|
|
371
|
+
represent: {
|
|
372
|
+
lowercase: () => "null",
|
|
373
|
+
uppercase: () => "NULL",
|
|
374
|
+
camelcase: () => "Null"
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
//#endregion
|
|
379
|
+
//#region node_modules/@std/yaml/_type/omap.js
|
|
380
|
+
function resolveYamlOmap(data) {
|
|
381
|
+
const objectKeys = /* @__PURE__ */ new Set();
|
|
382
|
+
for (const object of data) {
|
|
383
|
+
if (!isPlainObject(object)) return false;
|
|
384
|
+
const keys = Object.keys(object);
|
|
385
|
+
if (keys.length !== 1) return false;
|
|
386
|
+
for (const key of keys) {
|
|
387
|
+
if (objectKeys.has(key)) return false;
|
|
388
|
+
objectKeys.add(key);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
const omap = {
|
|
394
|
+
tag: "tag:yaml.org,2002:omap",
|
|
395
|
+
kind: "sequence",
|
|
396
|
+
resolve: resolveYamlOmap,
|
|
397
|
+
construct(data) {
|
|
398
|
+
return data;
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region node_modules/@std/yaml/_type/pairs.js
|
|
404
|
+
function resolveYamlPairs(data) {
|
|
405
|
+
if (data === null) return true;
|
|
406
|
+
return data.every((it) => isPlainObject(it) && Object.keys(it).length === 1);
|
|
407
|
+
}
|
|
408
|
+
const pairs = {
|
|
409
|
+
tag: "tag:yaml.org,2002:pairs",
|
|
410
|
+
construct(data) {
|
|
411
|
+
return data?.flatMap(Object.entries) ?? [];
|
|
412
|
+
},
|
|
413
|
+
kind: "sequence",
|
|
414
|
+
resolve: resolveYamlPairs
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
//#endregion
|
|
418
|
+
//#region node_modules/@std/yaml/_type/regexp.js
|
|
419
|
+
const REGEXP = /^\/(?<regexp>[\s\S]+)\/(?<modifiers>[gismuy]*)$/;
|
|
420
|
+
const regexp = {
|
|
421
|
+
tag: "tag:yaml.org,2002:js/regexp",
|
|
422
|
+
kind: "scalar",
|
|
423
|
+
resolve(data) {
|
|
424
|
+
if (data === null || !data.length) return false;
|
|
425
|
+
if (data.charAt(0) === "/") {
|
|
426
|
+
const groups = data.match(REGEXP)?.groups;
|
|
427
|
+
if (!groups) return false;
|
|
428
|
+
const modifiers = groups.modifiers ?? "";
|
|
429
|
+
if (new Set(modifiers).size < modifiers.length) return false;
|
|
430
|
+
}
|
|
431
|
+
return true;
|
|
432
|
+
},
|
|
433
|
+
construct(data) {
|
|
434
|
+
const { regexp = data, modifiers = "" } = data.match(REGEXP)?.groups ?? {};
|
|
435
|
+
return new RegExp(regexp, modifiers);
|
|
436
|
+
},
|
|
437
|
+
predicate: (object) => object instanceof RegExp,
|
|
438
|
+
represent: (object) => object.toString()
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region node_modules/@std/yaml/_type/seq.js
|
|
443
|
+
const seq = {
|
|
444
|
+
tag: "tag:yaml.org,2002:seq",
|
|
445
|
+
kind: "sequence",
|
|
446
|
+
resolve: () => true,
|
|
447
|
+
construct: (data) => data !== null ? data : []
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region node_modules/@std/yaml/_type/set.js
|
|
452
|
+
const set = {
|
|
453
|
+
tag: "tag:yaml.org,2002:set",
|
|
454
|
+
kind: "mapping",
|
|
455
|
+
construct: (data) => data !== null ? data : {},
|
|
456
|
+
resolve: (data) => {
|
|
457
|
+
if (data === null) return true;
|
|
458
|
+
return Object.values(data).every((it) => it === null);
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region node_modules/@std/yaml/_type/str.js
|
|
464
|
+
const str = {
|
|
465
|
+
tag: "tag:yaml.org,2002:str",
|
|
466
|
+
kind: "scalar",
|
|
467
|
+
resolve: () => true,
|
|
468
|
+
construct: (data) => data !== null ? data : ""
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region node_modules/@std/yaml/_type/timestamp.js
|
|
473
|
+
const YAML_DATE_REGEXP = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
|
|
474
|
+
const YAML_TIMESTAMP_REGEXP = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
|
|
475
|
+
function resolveYamlTimestamp(data) {
|
|
476
|
+
if (data === null) return false;
|
|
477
|
+
if (YAML_DATE_REGEXP.exec(data) !== null) return true;
|
|
478
|
+
if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
function constructYamlTimestamp(data) {
|
|
482
|
+
let match = YAML_DATE_REGEXP.exec(data);
|
|
483
|
+
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
|
|
484
|
+
if (match === null) throw new Error("Cannot construct YAML timestamp: date resolve error");
|
|
485
|
+
const year = +match[1];
|
|
486
|
+
const month = +match[2] - 1;
|
|
487
|
+
const day = +match[3];
|
|
488
|
+
if (!match[4]) return new Date(Date.UTC(year, month, day));
|
|
489
|
+
const hour = +match[4];
|
|
490
|
+
const minute = +match[5];
|
|
491
|
+
const second = +match[6];
|
|
492
|
+
let fraction = 0;
|
|
493
|
+
if (match[7]) {
|
|
494
|
+
let partFraction = match[7].slice(0, 3);
|
|
495
|
+
while (partFraction.length < 3) partFraction += "0";
|
|
496
|
+
fraction = +partFraction;
|
|
497
|
+
}
|
|
498
|
+
let delta = null;
|
|
499
|
+
if (match[9] && match[10]) {
|
|
500
|
+
const tzHour = +match[10];
|
|
501
|
+
const tzMinute = +(match[11] || 0);
|
|
502
|
+
delta = (tzHour * 60 + tzMinute) * 6e4;
|
|
503
|
+
if (match[9] === "-") delta = -delta;
|
|
504
|
+
}
|
|
505
|
+
const date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
|
|
506
|
+
if (delta) date.setTime(date.getTime() - delta);
|
|
507
|
+
return date;
|
|
508
|
+
}
|
|
509
|
+
function representYamlTimestamp(date) {
|
|
510
|
+
return date.toISOString();
|
|
511
|
+
}
|
|
512
|
+
const timestamp = {
|
|
513
|
+
tag: "tag:yaml.org,2002:timestamp",
|
|
514
|
+
construct: constructYamlTimestamp,
|
|
515
|
+
predicate(object) {
|
|
516
|
+
return object instanceof Date;
|
|
517
|
+
},
|
|
518
|
+
kind: "scalar",
|
|
519
|
+
represent: representYamlTimestamp,
|
|
520
|
+
resolve: resolveYamlTimestamp
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
//#endregion
|
|
524
|
+
//#region node_modules/@std/yaml/_type/undefined.js
|
|
525
|
+
const undefinedType = {
|
|
526
|
+
tag: "tag:yaml.org,2002:js/undefined",
|
|
527
|
+
kind: "scalar",
|
|
528
|
+
resolve() {
|
|
529
|
+
return true;
|
|
530
|
+
},
|
|
531
|
+
construct() {},
|
|
532
|
+
predicate(object) {
|
|
533
|
+
return typeof object === "undefined";
|
|
534
|
+
},
|
|
535
|
+
represent() {
|
|
536
|
+
return "";
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
//#endregion
|
|
541
|
+
//#region node_modules/@std/yaml/_schema.js
|
|
542
|
+
function createTypeMap(implicitTypes, explicitTypes) {
|
|
543
|
+
const result = {
|
|
544
|
+
fallback: /* @__PURE__ */ new Map(),
|
|
545
|
+
mapping: /* @__PURE__ */ new Map(),
|
|
546
|
+
scalar: /* @__PURE__ */ new Map(),
|
|
547
|
+
sequence: /* @__PURE__ */ new Map()
|
|
548
|
+
};
|
|
549
|
+
const fallbackMap = result.fallback;
|
|
550
|
+
for (const type of [...implicitTypes, ...explicitTypes]) {
|
|
551
|
+
result[type.kind].set(type.tag, type);
|
|
552
|
+
fallbackMap.set(type.tag, type);
|
|
553
|
+
}
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
function createSchema({ explicitTypes = [], implicitTypes = [], include }) {
|
|
557
|
+
if (include) {
|
|
558
|
+
implicitTypes.push(...include.implicitTypes);
|
|
559
|
+
explicitTypes.push(...include.explicitTypes);
|
|
560
|
+
}
|
|
561
|
+
return {
|
|
562
|
+
implicitTypes,
|
|
563
|
+
explicitTypes,
|
|
564
|
+
typeMap: createTypeMap(implicitTypes, explicitTypes)
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Standard YAML's failsafe schema.
|
|
569
|
+
*
|
|
570
|
+
* @see {@link http://www.yaml.org/spec/1.2/spec.html#id2802346}
|
|
571
|
+
*/ const FAILSAFE_SCHEMA = createSchema({ explicitTypes: [
|
|
572
|
+
str,
|
|
573
|
+
seq,
|
|
574
|
+
map
|
|
575
|
+
] });
|
|
576
|
+
/**
|
|
577
|
+
* Standard YAML's JSON schema.
|
|
578
|
+
*
|
|
579
|
+
* @see {@link http://www.yaml.org/spec/1.2/spec.html#id2803231}
|
|
580
|
+
*/ const JSON_SCHEMA = createSchema({
|
|
581
|
+
implicitTypes: [
|
|
582
|
+
nil,
|
|
583
|
+
bool,
|
|
584
|
+
int,
|
|
585
|
+
float
|
|
586
|
+
],
|
|
587
|
+
include: FAILSAFE_SCHEMA
|
|
588
|
+
});
|
|
589
|
+
/**
|
|
590
|
+
* Standard YAML's core schema.
|
|
591
|
+
*
|
|
592
|
+
* @see {@link http://www.yaml.org/spec/1.2/spec.html#id2804923}
|
|
593
|
+
*/ const CORE_SCHEMA = createSchema({ include: JSON_SCHEMA });
|
|
594
|
+
/**
|
|
595
|
+
* Default YAML schema. It is not described in the YAML specification.
|
|
596
|
+
*/ const DEFAULT_SCHEMA = createSchema({
|
|
597
|
+
explicitTypes: [
|
|
598
|
+
binary,
|
|
599
|
+
omap,
|
|
600
|
+
pairs,
|
|
601
|
+
set
|
|
602
|
+
],
|
|
603
|
+
implicitTypes: [timestamp, merge],
|
|
604
|
+
include: CORE_SCHEMA
|
|
605
|
+
});
|
|
606
|
+
/***
|
|
607
|
+
* Extends JS-YAML default schema with additional JavaScript types
|
|
608
|
+
* It is not described in the YAML specification.
|
|
609
|
+
* Functions are no longer supported for security reasons.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* import { parse } from "@std/yaml";
|
|
614
|
+
*
|
|
615
|
+
* const data = parse(
|
|
616
|
+
* `
|
|
617
|
+
* regexp:
|
|
618
|
+
* simple: !!js/regexp foobar
|
|
619
|
+
* modifiers: !!js/regexp /foobar/mi
|
|
620
|
+
* undefined: !!js/undefined ~
|
|
621
|
+
* `,
|
|
622
|
+
* { schema: "extended" },
|
|
623
|
+
* );
|
|
624
|
+
* ```
|
|
625
|
+
*/ const EXTENDED_SCHEMA = createSchema({
|
|
626
|
+
explicitTypes: [regexp, undefinedType],
|
|
627
|
+
include: DEFAULT_SCHEMA
|
|
628
|
+
});
|
|
629
|
+
const SCHEMA_MAP = new Map([
|
|
630
|
+
["core", CORE_SCHEMA],
|
|
631
|
+
["default", DEFAULT_SCHEMA],
|
|
632
|
+
["failsafe", FAILSAFE_SCHEMA],
|
|
633
|
+
["json", JSON_SCHEMA],
|
|
634
|
+
["extended", EXTENDED_SCHEMA]
|
|
635
|
+
]);
|
|
636
|
+
|
|
637
|
+
//#endregion
|
|
638
|
+
//#region node_modules/@std/yaml/_loader_state.js
|
|
639
|
+
const CONTEXT_FLOW_IN = 1;
|
|
640
|
+
const CONTEXT_FLOW_OUT = 2;
|
|
641
|
+
const CONTEXT_BLOCK_IN = 3;
|
|
642
|
+
const CONTEXT_BLOCK_OUT = 4;
|
|
643
|
+
const CHOMPING_CLIP = 1;
|
|
644
|
+
const CHOMPING_STRIP = 2;
|
|
645
|
+
const CHOMPING_KEEP = 3;
|
|
646
|
+
const PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
|
|
647
|
+
const PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
|
|
648
|
+
const PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
|
|
649
|
+
const PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
|
|
650
|
+
const PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
|
|
651
|
+
const ESCAPED_HEX_LENGTHS = new Map([
|
|
652
|
+
[120, 2],
|
|
653
|
+
[117, 4],
|
|
654
|
+
[85, 8]
|
|
655
|
+
]);
|
|
656
|
+
const SIMPLE_ESCAPE_SEQUENCES = new Map([
|
|
657
|
+
[48, "\0"],
|
|
658
|
+
[97, "\x07"],
|
|
659
|
+
[98, "\b"],
|
|
660
|
+
[116, " "],
|
|
661
|
+
[9, " "],
|
|
662
|
+
[110, "\n"],
|
|
663
|
+
[118, "\v"],
|
|
664
|
+
[102, "\f"],
|
|
665
|
+
[114, "\r"],
|
|
666
|
+
[101, "\x1B"],
|
|
667
|
+
[32, " "],
|
|
668
|
+
[34, "\""],
|
|
669
|
+
[47, "/"],
|
|
670
|
+
[92, "\\"],
|
|
671
|
+
[78, "
"],
|
|
672
|
+
[95, "\xA0"],
|
|
673
|
+
[76, "\u2028"],
|
|
674
|
+
[80, "\u2029"]
|
|
675
|
+
]);
|
|
676
|
+
/**
|
|
677
|
+
* Converts a hexadecimal character code to its decimal value.
|
|
678
|
+
*/ function hexCharCodeToNumber(charCode) {
|
|
679
|
+
if (48 <= charCode && charCode <= 57) return charCode - 48;
|
|
680
|
+
const lc = charCode | 32;
|
|
681
|
+
if (97 <= lc && lc <= 102) return lc - 97 + 10;
|
|
682
|
+
return -1;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Converts a decimal character code to its decimal value.
|
|
686
|
+
*/ function decimalCharCodeToNumber(charCode) {
|
|
687
|
+
if (48 <= charCode && charCode <= 57) return charCode - 48;
|
|
688
|
+
return -1;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Converts a Unicode code point to a string.
|
|
692
|
+
*/ function codepointToChar(codepoint) {
|
|
693
|
+
if (codepoint <= 65535) return String.fromCharCode(codepoint);
|
|
694
|
+
return String.fromCharCode((codepoint - 65536 >> 10) + 55296, (codepoint - 65536 & 1023) + 56320);
|
|
695
|
+
}
|
|
696
|
+
const INDENT = 4;
|
|
697
|
+
const MAX_LENGTH = 75;
|
|
698
|
+
const DELIMITERS = "\0\r\n
\u2028\u2029";
|
|
699
|
+
function getSnippet(buffer, position) {
|
|
700
|
+
if (!buffer) return null;
|
|
701
|
+
let start = position;
|
|
702
|
+
let end = position;
|
|
703
|
+
let head = "";
|
|
704
|
+
let tail = "";
|
|
705
|
+
while (start > 0 && !DELIMITERS.includes(buffer.charAt(start - 1))) {
|
|
706
|
+
start--;
|
|
707
|
+
if (position - start > MAX_LENGTH / 2 - 1) {
|
|
708
|
+
head = " ... ";
|
|
709
|
+
start += 5;
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
while (end < buffer.length && !DELIMITERS.includes(buffer.charAt(end))) {
|
|
714
|
+
end++;
|
|
715
|
+
if (end - position > MAX_LENGTH / 2 - 1) {
|
|
716
|
+
tail = " ... ";
|
|
717
|
+
end -= 5;
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
const snippet = buffer.slice(start, end);
|
|
722
|
+
const indent = " ".repeat(INDENT);
|
|
723
|
+
const caretIndent = " ".repeat(INDENT + position - start + head.length);
|
|
724
|
+
return `${indent + head + snippet + tail}\n${caretIndent}^`;
|
|
725
|
+
}
|
|
726
|
+
function markToString(buffer, position, line, column) {
|
|
727
|
+
let where = `at line ${line + 1}, column ${column + 1}`;
|
|
728
|
+
const snippet = getSnippet(buffer, position);
|
|
729
|
+
if (snippet) where += `:\n${snippet}`;
|
|
730
|
+
return where;
|
|
731
|
+
}
|
|
732
|
+
function getIndentStatus(lineIndent, parentIndent) {
|
|
733
|
+
if (lineIndent > parentIndent) return 1;
|
|
734
|
+
if (lineIndent < parentIndent) return -1;
|
|
735
|
+
return 0;
|
|
736
|
+
}
|
|
737
|
+
function writeFoldedLines(count) {
|
|
738
|
+
if (count === 1) return " ";
|
|
739
|
+
if (count > 1) return "\n".repeat(count - 1);
|
|
740
|
+
return "";
|
|
741
|
+
}
|
|
742
|
+
var Scanner = class {
|
|
743
|
+
source;
|
|
744
|
+
#length;
|
|
745
|
+
position = 0;
|
|
746
|
+
constructor(source) {
|
|
747
|
+
source += "\0";
|
|
748
|
+
this.source = source;
|
|
749
|
+
this.#length = source.length;
|
|
750
|
+
}
|
|
751
|
+
peek(offset = 0) {
|
|
752
|
+
return this.source.charCodeAt(this.position + offset);
|
|
753
|
+
}
|
|
754
|
+
next() {
|
|
755
|
+
this.position += 1;
|
|
756
|
+
}
|
|
757
|
+
eof() {
|
|
758
|
+
return this.position >= this.#length - 1;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
var LoaderState = class {
|
|
762
|
+
#scanner;
|
|
763
|
+
lineIndent = 0;
|
|
764
|
+
lineStart = 0;
|
|
765
|
+
line = 0;
|
|
766
|
+
onWarning;
|
|
767
|
+
allowDuplicateKeys;
|
|
768
|
+
implicitTypes;
|
|
769
|
+
typeMap;
|
|
770
|
+
checkLineBreaks = false;
|
|
771
|
+
tagMap = /* @__PURE__ */ new Map();
|
|
772
|
+
anchorMap = /* @__PURE__ */ new Map();
|
|
773
|
+
constructor(input, { schema = DEFAULT_SCHEMA, onWarning, allowDuplicateKeys = false }) {
|
|
774
|
+
this.#scanner = new Scanner(input);
|
|
775
|
+
this.onWarning = onWarning;
|
|
776
|
+
this.allowDuplicateKeys = allowDuplicateKeys;
|
|
777
|
+
this.implicitTypes = schema.implicitTypes;
|
|
778
|
+
this.typeMap = schema.typeMap;
|
|
779
|
+
this.readIndent();
|
|
780
|
+
}
|
|
781
|
+
skipWhitespaces() {
|
|
782
|
+
let ch = this.#scanner.peek();
|
|
783
|
+
while (isWhiteSpace(ch)) {
|
|
784
|
+
this.#scanner.next();
|
|
785
|
+
ch = this.#scanner.peek();
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
skipComment() {
|
|
789
|
+
let ch = this.#scanner.peek();
|
|
790
|
+
if (ch !== SHARP) return;
|
|
791
|
+
this.#scanner.next();
|
|
792
|
+
ch = this.#scanner.peek();
|
|
793
|
+
while (ch !== 0 && !isEOL(ch)) {
|
|
794
|
+
this.#scanner.next();
|
|
795
|
+
ch = this.#scanner.peek();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
readIndent() {
|
|
799
|
+
let ch = this.#scanner.peek();
|
|
800
|
+
while (ch === SPACE) {
|
|
801
|
+
this.lineIndent += 1;
|
|
802
|
+
this.#scanner.next();
|
|
803
|
+
ch = this.#scanner.peek();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
#createError(message) {
|
|
807
|
+
const mark = markToString(this.#scanner.source, this.#scanner.position, this.line, this.#scanner.position - this.lineStart);
|
|
808
|
+
return /* @__PURE__ */ new SyntaxError(`${message} ${mark}`);
|
|
809
|
+
}
|
|
810
|
+
dispatchWarning(message) {
|
|
811
|
+
const error = this.#createError(message);
|
|
812
|
+
this.onWarning?.(error);
|
|
813
|
+
}
|
|
814
|
+
yamlDirectiveHandler(args) {
|
|
815
|
+
if (args.length !== 1) throw this.#createError("Cannot handle YAML directive: YAML directive accepts exactly one argument");
|
|
816
|
+
const match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
|
|
817
|
+
if (match === null) throw this.#createError("Cannot handle YAML directive: ill-formed argument");
|
|
818
|
+
const major = parseInt(match[1], 10);
|
|
819
|
+
const minor = parseInt(match[2], 10);
|
|
820
|
+
if (major !== 1) throw this.#createError("Cannot handle YAML directive: unacceptable YAML version");
|
|
821
|
+
this.checkLineBreaks = minor < 2;
|
|
822
|
+
if (minor !== 1 && minor !== 2) this.dispatchWarning("Cannot handle YAML directive: unsupported YAML version");
|
|
823
|
+
return args[0] ?? null;
|
|
824
|
+
}
|
|
825
|
+
tagDirectiveHandler(args) {
|
|
826
|
+
if (args.length !== 2) throw this.#createError(`Cannot handle tag directive: directive accepts exactly two arguments, received ${args.length}`);
|
|
827
|
+
const handle = args[0];
|
|
828
|
+
const prefix = args[1];
|
|
829
|
+
if (!PATTERN_TAG_HANDLE.test(handle)) throw this.#createError(`Cannot handle tag directive: ill-formed handle (first argument) in "${handle}"`);
|
|
830
|
+
if (this.tagMap.has(handle)) throw this.#createError(`Cannot handle tag directive: previously declared suffix for "${handle}" tag handle`);
|
|
831
|
+
if (!PATTERN_TAG_URI.test(prefix)) throw this.#createError("Cannot handle tag directive: ill-formed tag prefix (second argument) of the TAG directive");
|
|
832
|
+
this.tagMap.set(handle, prefix);
|
|
833
|
+
}
|
|
834
|
+
captureSegment(start, end, checkJson) {
|
|
835
|
+
if (start < end) {
|
|
836
|
+
const result = this.#scanner.source.slice(start, end);
|
|
837
|
+
if (checkJson) for (let position = 0; position < result.length; position++) {
|
|
838
|
+
const character = result.charCodeAt(position);
|
|
839
|
+
if (!(character === 9 || 32 <= character && character <= 1114111)) throw this.#createError(`Expected valid JSON character: received "${character}"`);
|
|
840
|
+
}
|
|
841
|
+
else if (PATTERN_NON_PRINTABLE.test(result)) throw this.#createError("Stream contains non-printable characters");
|
|
842
|
+
return result;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
readBlockSequence(tag, anchor, nodeIndent) {
|
|
846
|
+
let detected = false;
|
|
847
|
+
const result = [];
|
|
848
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
849
|
+
let ch = this.#scanner.peek();
|
|
850
|
+
while (ch !== 0) {
|
|
851
|
+
if (ch !== MINUS) break;
|
|
852
|
+
if (!isWhiteSpaceOrEOL(this.#scanner.peek(1))) break;
|
|
853
|
+
detected = true;
|
|
854
|
+
this.#scanner.next();
|
|
855
|
+
if (this.skipSeparationSpace(true, -1)) {
|
|
856
|
+
if (this.lineIndent <= nodeIndent) {
|
|
857
|
+
result.push(null);
|
|
858
|
+
ch = this.#scanner.peek();
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
const line = this.line;
|
|
863
|
+
const newState = this.composeNode({
|
|
864
|
+
parentIndent: nodeIndent,
|
|
865
|
+
nodeContext: CONTEXT_BLOCK_IN,
|
|
866
|
+
allowToSeek: false,
|
|
867
|
+
allowCompact: true
|
|
868
|
+
});
|
|
869
|
+
if (newState) result.push(newState.result);
|
|
870
|
+
this.skipSeparationSpace(true, -1);
|
|
871
|
+
ch = this.#scanner.peek();
|
|
872
|
+
if ((this.line === line || this.lineIndent > nodeIndent) && ch !== 0) throw this.#createError("Cannot read block sequence: bad indentation of a sequence entry");
|
|
873
|
+
else if (this.lineIndent < nodeIndent) break;
|
|
874
|
+
}
|
|
875
|
+
if (detected) return {
|
|
876
|
+
tag,
|
|
877
|
+
anchor,
|
|
878
|
+
kind: "sequence",
|
|
879
|
+
result
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
mergeMappings(destination, source, overridableKeys) {
|
|
883
|
+
if (!isObject(source)) throw this.#createError("Cannot merge mappings: the provided source object is unacceptable");
|
|
884
|
+
for (const [key, value] of Object.entries(source)) {
|
|
885
|
+
if (Object.hasOwn(destination, key)) continue;
|
|
886
|
+
Object.defineProperty(destination, key, {
|
|
887
|
+
value,
|
|
888
|
+
writable: true,
|
|
889
|
+
enumerable: true,
|
|
890
|
+
configurable: true
|
|
891
|
+
});
|
|
892
|
+
overridableKeys.add(key);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode, startLine, startPos) {
|
|
896
|
+
if (Array.isArray(keyNode)) {
|
|
897
|
+
keyNode = Array.prototype.slice.call(keyNode);
|
|
898
|
+
for (let index = 0; index < keyNode.length; index++) {
|
|
899
|
+
if (Array.isArray(keyNode[index])) throw this.#createError("Cannot store mapping pair: nested arrays are not supported inside keys");
|
|
900
|
+
if (typeof keyNode === "object" && isPlainObject(keyNode[index])) keyNode[index] = "[object Object]";
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
if (typeof keyNode === "object" && isPlainObject(keyNode)) keyNode = "[object Object]";
|
|
904
|
+
keyNode = String(keyNode);
|
|
905
|
+
if (keyTag === "tag:yaml.org,2002:merge") if (Array.isArray(valueNode)) for (let index = 0; index < valueNode.length; index++) this.mergeMappings(result, valueNode[index], overridableKeys);
|
|
906
|
+
else this.mergeMappings(result, valueNode, overridableKeys);
|
|
907
|
+
else {
|
|
908
|
+
if (!this.allowDuplicateKeys && !overridableKeys.has(keyNode) && Object.hasOwn(result, keyNode)) {
|
|
909
|
+
this.line = startLine || this.line;
|
|
910
|
+
this.#scanner.position = startPos || this.#scanner.position;
|
|
911
|
+
throw this.#createError("Cannot store mapping pair: duplicated key");
|
|
912
|
+
}
|
|
913
|
+
Object.defineProperty(result, keyNode, {
|
|
914
|
+
value: valueNode,
|
|
915
|
+
writable: true,
|
|
916
|
+
enumerable: true,
|
|
917
|
+
configurable: true
|
|
918
|
+
});
|
|
919
|
+
overridableKeys.delete(keyNode);
|
|
920
|
+
}
|
|
921
|
+
return result;
|
|
922
|
+
}
|
|
923
|
+
readLineBreak() {
|
|
924
|
+
const ch = this.#scanner.peek();
|
|
925
|
+
if (ch === LINE_FEED) this.#scanner.next();
|
|
926
|
+
else if (ch === CARRIAGE_RETURN) {
|
|
927
|
+
this.#scanner.next();
|
|
928
|
+
if (this.#scanner.peek() === LINE_FEED) this.#scanner.next();
|
|
929
|
+
} else throw this.#createError("Cannot read line: line break not found");
|
|
930
|
+
this.line += 1;
|
|
931
|
+
this.lineStart = this.#scanner.position;
|
|
932
|
+
}
|
|
933
|
+
skipSeparationSpace(allowComments, checkIndent) {
|
|
934
|
+
let lineBreaks = 0;
|
|
935
|
+
let ch = this.#scanner.peek();
|
|
936
|
+
while (ch !== 0) {
|
|
937
|
+
this.skipWhitespaces();
|
|
938
|
+
ch = this.#scanner.peek();
|
|
939
|
+
if (allowComments) {
|
|
940
|
+
this.skipComment();
|
|
941
|
+
ch = this.#scanner.peek();
|
|
942
|
+
}
|
|
943
|
+
if (isEOL(ch)) {
|
|
944
|
+
this.readLineBreak();
|
|
945
|
+
ch = this.#scanner.peek();
|
|
946
|
+
lineBreaks++;
|
|
947
|
+
this.lineIndent = 0;
|
|
948
|
+
this.readIndent();
|
|
949
|
+
ch = this.#scanner.peek();
|
|
950
|
+
} else break;
|
|
951
|
+
}
|
|
952
|
+
if (checkIndent !== -1 && lineBreaks !== 0 && this.lineIndent < checkIndent) this.dispatchWarning("deficient indentation");
|
|
953
|
+
return lineBreaks;
|
|
954
|
+
}
|
|
955
|
+
testDocumentSeparator() {
|
|
956
|
+
let ch = this.#scanner.peek();
|
|
957
|
+
if ((ch === MINUS || ch === DOT) && ch === this.#scanner.peek(1) && ch === this.#scanner.peek(2)) {
|
|
958
|
+
ch = this.#scanner.peek(3);
|
|
959
|
+
if (ch === 0 || isWhiteSpaceOrEOL(ch)) return true;
|
|
960
|
+
}
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
readPlainScalar(tag, anchor, nodeIndent, withinFlowCollection) {
|
|
964
|
+
let ch = this.#scanner.peek();
|
|
965
|
+
if (isWhiteSpaceOrEOL(ch) || isFlowIndicator(ch) || ch === SHARP || ch === AMPERSAND || ch === ASTERISK || ch === EXCLAMATION || ch === VERTICAL_LINE || ch === GREATER_THAN || ch === SINGLE_QUOTE || ch === DOUBLE_QUOTE || ch === PERCENT || ch === COMMERCIAL_AT || ch === GRAVE_ACCENT) return;
|
|
966
|
+
let following;
|
|
967
|
+
if (ch === QUESTION || ch === MINUS) {
|
|
968
|
+
following = this.#scanner.peek(1);
|
|
969
|
+
if (isWhiteSpaceOrEOL(following) || withinFlowCollection && isFlowIndicator(following)) return;
|
|
970
|
+
}
|
|
971
|
+
let result = "";
|
|
972
|
+
let captureEnd = this.#scanner.position;
|
|
973
|
+
let captureStart = this.#scanner.position;
|
|
974
|
+
let hasPendingContent = false;
|
|
975
|
+
let line = 0;
|
|
976
|
+
while (ch !== 0) {
|
|
977
|
+
if (ch === COLON) {
|
|
978
|
+
following = this.#scanner.peek(1);
|
|
979
|
+
if (isWhiteSpaceOrEOL(following) || withinFlowCollection && isFlowIndicator(following)) break;
|
|
980
|
+
} else if (ch === SHARP) {
|
|
981
|
+
if (isWhiteSpaceOrEOL(this.#scanner.peek(-1))) break;
|
|
982
|
+
} else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator() || withinFlowCollection && isFlowIndicator(ch)) break;
|
|
983
|
+
else if (isEOL(ch)) {
|
|
984
|
+
line = this.line;
|
|
985
|
+
const lineStart = this.lineStart;
|
|
986
|
+
const lineIndent = this.lineIndent;
|
|
987
|
+
this.skipSeparationSpace(false, -1);
|
|
988
|
+
if (this.lineIndent >= nodeIndent) {
|
|
989
|
+
hasPendingContent = true;
|
|
990
|
+
ch = this.#scanner.peek();
|
|
991
|
+
continue;
|
|
992
|
+
} else {
|
|
993
|
+
this.#scanner.position = captureEnd;
|
|
994
|
+
this.line = line;
|
|
995
|
+
this.lineStart = lineStart;
|
|
996
|
+
this.lineIndent = lineIndent;
|
|
997
|
+
break;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
if (hasPendingContent) {
|
|
1001
|
+
const segment = this.captureSegment(captureStart, captureEnd, false);
|
|
1002
|
+
if (segment) result += segment;
|
|
1003
|
+
result += writeFoldedLines(this.line - line);
|
|
1004
|
+
captureStart = captureEnd = this.#scanner.position;
|
|
1005
|
+
hasPendingContent = false;
|
|
1006
|
+
}
|
|
1007
|
+
if (!isWhiteSpace(ch)) captureEnd = this.#scanner.position + 1;
|
|
1008
|
+
this.#scanner.next();
|
|
1009
|
+
ch = this.#scanner.peek();
|
|
1010
|
+
}
|
|
1011
|
+
const segment = this.captureSegment(captureStart, captureEnd, false);
|
|
1012
|
+
if (segment) result += segment;
|
|
1013
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1014
|
+
if (result) return {
|
|
1015
|
+
tag,
|
|
1016
|
+
anchor,
|
|
1017
|
+
kind: "scalar",
|
|
1018
|
+
result
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
readSingleQuotedScalar(tag, anchor, nodeIndent) {
|
|
1022
|
+
let ch = this.#scanner.peek();
|
|
1023
|
+
if (ch !== SINGLE_QUOTE) return;
|
|
1024
|
+
let result = "";
|
|
1025
|
+
this.#scanner.next();
|
|
1026
|
+
let captureStart = this.#scanner.position;
|
|
1027
|
+
let captureEnd = this.#scanner.position;
|
|
1028
|
+
ch = this.#scanner.peek();
|
|
1029
|
+
while (ch !== 0) {
|
|
1030
|
+
if (ch === SINGLE_QUOTE) {
|
|
1031
|
+
const segment = this.captureSegment(captureStart, this.#scanner.position, true);
|
|
1032
|
+
if (segment) result += segment;
|
|
1033
|
+
this.#scanner.next();
|
|
1034
|
+
ch = this.#scanner.peek();
|
|
1035
|
+
if (ch === SINGLE_QUOTE) {
|
|
1036
|
+
captureStart = this.#scanner.position;
|
|
1037
|
+
this.#scanner.next();
|
|
1038
|
+
captureEnd = this.#scanner.position;
|
|
1039
|
+
} else {
|
|
1040
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1041
|
+
return {
|
|
1042
|
+
tag,
|
|
1043
|
+
anchor,
|
|
1044
|
+
kind: "scalar",
|
|
1045
|
+
result
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
} else if (isEOL(ch)) {
|
|
1049
|
+
const segment = this.captureSegment(captureStart, captureEnd, true);
|
|
1050
|
+
if (segment) result += segment;
|
|
1051
|
+
result += writeFoldedLines(this.skipSeparationSpace(false, nodeIndent));
|
|
1052
|
+
captureStart = captureEnd = this.#scanner.position;
|
|
1053
|
+
} else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) throw this.#createError("Unexpected end of the document within a single quoted scalar");
|
|
1054
|
+
else {
|
|
1055
|
+
this.#scanner.next();
|
|
1056
|
+
captureEnd = this.#scanner.position;
|
|
1057
|
+
}
|
|
1058
|
+
ch = this.#scanner.peek();
|
|
1059
|
+
}
|
|
1060
|
+
throw this.#createError("Unexpected end of the stream within a single quoted scalar");
|
|
1061
|
+
}
|
|
1062
|
+
readDoubleQuotedScalar(tag, anchor, nodeIndent) {
|
|
1063
|
+
let ch = this.#scanner.peek();
|
|
1064
|
+
if (ch !== DOUBLE_QUOTE) return;
|
|
1065
|
+
let result = "";
|
|
1066
|
+
this.#scanner.next();
|
|
1067
|
+
let captureEnd = this.#scanner.position;
|
|
1068
|
+
let captureStart = this.#scanner.position;
|
|
1069
|
+
let tmp;
|
|
1070
|
+
ch = this.#scanner.peek();
|
|
1071
|
+
while (ch !== 0) {
|
|
1072
|
+
if (ch === DOUBLE_QUOTE) {
|
|
1073
|
+
const segment = this.captureSegment(captureStart, this.#scanner.position, true);
|
|
1074
|
+
if (segment) result += segment;
|
|
1075
|
+
this.#scanner.next();
|
|
1076
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1077
|
+
return {
|
|
1078
|
+
tag,
|
|
1079
|
+
anchor,
|
|
1080
|
+
kind: "scalar",
|
|
1081
|
+
result
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
if (ch === BACKSLASH) {
|
|
1085
|
+
const segment = this.captureSegment(captureStart, this.#scanner.position, true);
|
|
1086
|
+
if (segment) result += segment;
|
|
1087
|
+
this.#scanner.next();
|
|
1088
|
+
ch = this.#scanner.peek();
|
|
1089
|
+
if (isEOL(ch)) this.skipSeparationSpace(false, nodeIndent);
|
|
1090
|
+
else if (ch < 256 && SIMPLE_ESCAPE_SEQUENCES.has(ch)) {
|
|
1091
|
+
result += SIMPLE_ESCAPE_SEQUENCES.get(ch);
|
|
1092
|
+
this.#scanner.next();
|
|
1093
|
+
} else if ((tmp = ESCAPED_HEX_LENGTHS.get(ch) ?? 0) > 0) {
|
|
1094
|
+
let hexLength = tmp;
|
|
1095
|
+
let hexResult = 0;
|
|
1096
|
+
for (; hexLength > 0; hexLength--) {
|
|
1097
|
+
this.#scanner.next();
|
|
1098
|
+
ch = this.#scanner.peek();
|
|
1099
|
+
if ((tmp = hexCharCodeToNumber(ch)) >= 0) hexResult = (hexResult << 4) + tmp;
|
|
1100
|
+
else throw this.#createError("Cannot read double quoted scalar: expected hexadecimal character");
|
|
1101
|
+
}
|
|
1102
|
+
result += codepointToChar(hexResult);
|
|
1103
|
+
this.#scanner.next();
|
|
1104
|
+
} else throw this.#createError("Cannot read double quoted scalar: unknown escape sequence");
|
|
1105
|
+
captureStart = captureEnd = this.#scanner.position;
|
|
1106
|
+
} else if (isEOL(ch)) {
|
|
1107
|
+
const segment = this.captureSegment(captureStart, captureEnd, true);
|
|
1108
|
+
if (segment) result += segment;
|
|
1109
|
+
result += writeFoldedLines(this.skipSeparationSpace(false, nodeIndent));
|
|
1110
|
+
captureStart = captureEnd = this.#scanner.position;
|
|
1111
|
+
} else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) throw this.#createError("Unexpected end of the document within a double quoted scalar");
|
|
1112
|
+
else {
|
|
1113
|
+
this.#scanner.next();
|
|
1114
|
+
captureEnd = this.#scanner.position;
|
|
1115
|
+
}
|
|
1116
|
+
ch = this.#scanner.peek();
|
|
1117
|
+
}
|
|
1118
|
+
throw this.#createError("Unexpected end of the stream within a double quoted scalar");
|
|
1119
|
+
}
|
|
1120
|
+
readFlowCollection(tag, anchor, nodeIndent) {
|
|
1121
|
+
let ch = this.#scanner.peek();
|
|
1122
|
+
let terminator;
|
|
1123
|
+
let isMapping = true;
|
|
1124
|
+
let result = {};
|
|
1125
|
+
if (ch === LEFT_SQUARE_BRACKET) {
|
|
1126
|
+
terminator = RIGHT_SQUARE_BRACKET;
|
|
1127
|
+
isMapping = false;
|
|
1128
|
+
result = [];
|
|
1129
|
+
} else if (ch === LEFT_CURLY_BRACKET) terminator = RIGHT_CURLY_BRACKET;
|
|
1130
|
+
else return;
|
|
1131
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1132
|
+
this.#scanner.next();
|
|
1133
|
+
ch = this.#scanner.peek();
|
|
1134
|
+
let readNext = true;
|
|
1135
|
+
let valueNode = null;
|
|
1136
|
+
let keyNode = null;
|
|
1137
|
+
let keyTag = null;
|
|
1138
|
+
let isExplicitPair = false;
|
|
1139
|
+
let isPair = false;
|
|
1140
|
+
let following = 0;
|
|
1141
|
+
let line = 0;
|
|
1142
|
+
const overridableKeys = /* @__PURE__ */ new Set();
|
|
1143
|
+
while (ch !== 0) {
|
|
1144
|
+
this.skipSeparationSpace(true, nodeIndent);
|
|
1145
|
+
ch = this.#scanner.peek();
|
|
1146
|
+
if (ch === terminator) {
|
|
1147
|
+
this.#scanner.next();
|
|
1148
|
+
return {
|
|
1149
|
+
tag,
|
|
1150
|
+
anchor,
|
|
1151
|
+
kind: isMapping ? "mapping" : "sequence",
|
|
1152
|
+
result
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
if (!readNext) throw this.#createError("Cannot read flow collection: missing comma between flow collection entries");
|
|
1156
|
+
keyTag = keyNode = valueNode = null;
|
|
1157
|
+
isPair = isExplicitPair = false;
|
|
1158
|
+
if (ch === QUESTION) {
|
|
1159
|
+
following = this.#scanner.peek(1);
|
|
1160
|
+
if (isWhiteSpaceOrEOL(following)) {
|
|
1161
|
+
isPair = isExplicitPair = true;
|
|
1162
|
+
this.#scanner.next();
|
|
1163
|
+
this.skipSeparationSpace(true, nodeIndent);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
line = this.line;
|
|
1167
|
+
const newState = this.composeNode({
|
|
1168
|
+
parentIndent: nodeIndent,
|
|
1169
|
+
nodeContext: CONTEXT_FLOW_IN,
|
|
1170
|
+
allowToSeek: false,
|
|
1171
|
+
allowCompact: true
|
|
1172
|
+
});
|
|
1173
|
+
if (newState) {
|
|
1174
|
+
keyTag = newState.tag || null;
|
|
1175
|
+
keyNode = newState.result;
|
|
1176
|
+
}
|
|
1177
|
+
this.skipSeparationSpace(true, nodeIndent);
|
|
1178
|
+
ch = this.#scanner.peek();
|
|
1179
|
+
if ((isExplicitPair || this.line === line) && ch === COLON) {
|
|
1180
|
+
isPair = true;
|
|
1181
|
+
this.#scanner.next();
|
|
1182
|
+
ch = this.#scanner.peek();
|
|
1183
|
+
this.skipSeparationSpace(true, nodeIndent);
|
|
1184
|
+
const newState = this.composeNode({
|
|
1185
|
+
parentIndent: nodeIndent,
|
|
1186
|
+
nodeContext: CONTEXT_FLOW_IN,
|
|
1187
|
+
allowToSeek: false,
|
|
1188
|
+
allowCompact: true
|
|
1189
|
+
});
|
|
1190
|
+
if (newState) valueNode = newState.result;
|
|
1191
|
+
}
|
|
1192
|
+
if (isMapping) this.storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode);
|
|
1193
|
+
else if (isPair) result.push(this.storeMappingPair({}, overridableKeys, keyTag, keyNode, valueNode));
|
|
1194
|
+
else result.push(keyNode);
|
|
1195
|
+
this.skipSeparationSpace(true, nodeIndent);
|
|
1196
|
+
ch = this.#scanner.peek();
|
|
1197
|
+
if (ch === COMMA) {
|
|
1198
|
+
readNext = true;
|
|
1199
|
+
this.#scanner.next();
|
|
1200
|
+
ch = this.#scanner.peek();
|
|
1201
|
+
} else readNext = false;
|
|
1202
|
+
}
|
|
1203
|
+
throw this.#createError("Cannot read flow collection: unexpected end of the stream within a flow collection");
|
|
1204
|
+
}
|
|
1205
|
+
readBlockScalar(tag, anchor, nodeIndent) {
|
|
1206
|
+
let chomping = CHOMPING_CLIP;
|
|
1207
|
+
let didReadContent = false;
|
|
1208
|
+
let detectedIndent = false;
|
|
1209
|
+
let textIndent = nodeIndent;
|
|
1210
|
+
let emptyLines = 0;
|
|
1211
|
+
let atMoreIndented = false;
|
|
1212
|
+
let ch = this.#scanner.peek();
|
|
1213
|
+
let folding = false;
|
|
1214
|
+
if (ch === VERTICAL_LINE) folding = false;
|
|
1215
|
+
else if (ch === GREATER_THAN) folding = true;
|
|
1216
|
+
else return;
|
|
1217
|
+
let result = "";
|
|
1218
|
+
let tmp = 0;
|
|
1219
|
+
while (ch !== 0) {
|
|
1220
|
+
this.#scanner.next();
|
|
1221
|
+
ch = this.#scanner.peek();
|
|
1222
|
+
if (ch === PLUS || ch === MINUS) if (CHOMPING_CLIP === chomping) chomping = ch === PLUS ? CHOMPING_KEEP : CHOMPING_STRIP;
|
|
1223
|
+
else throw this.#createError("Cannot read block: chomping mode identifier repeated");
|
|
1224
|
+
else if ((tmp = decimalCharCodeToNumber(ch)) >= 0) if (tmp === 0) throw this.#createError("Cannot read block: indentation width must be greater than 0");
|
|
1225
|
+
else if (!detectedIndent) {
|
|
1226
|
+
textIndent = nodeIndent + tmp - 1;
|
|
1227
|
+
detectedIndent = true;
|
|
1228
|
+
} else throw this.#createError("Cannot read block: indentation width identifier repeated");
|
|
1229
|
+
else break;
|
|
1230
|
+
}
|
|
1231
|
+
if (isWhiteSpace(ch)) {
|
|
1232
|
+
this.skipWhitespaces();
|
|
1233
|
+
this.skipComment();
|
|
1234
|
+
ch = this.#scanner.peek();
|
|
1235
|
+
}
|
|
1236
|
+
while (ch !== 0) {
|
|
1237
|
+
this.readLineBreak();
|
|
1238
|
+
this.lineIndent = 0;
|
|
1239
|
+
ch = this.#scanner.peek();
|
|
1240
|
+
while ((!detectedIndent || this.lineIndent < textIndent) && ch === SPACE) {
|
|
1241
|
+
this.lineIndent++;
|
|
1242
|
+
this.#scanner.next();
|
|
1243
|
+
ch = this.#scanner.peek();
|
|
1244
|
+
}
|
|
1245
|
+
if (!detectedIndent && this.lineIndent > textIndent) textIndent = this.lineIndent;
|
|
1246
|
+
if (isEOL(ch)) {
|
|
1247
|
+
emptyLines++;
|
|
1248
|
+
continue;
|
|
1249
|
+
}
|
|
1250
|
+
if (this.lineIndent < textIndent) {
|
|
1251
|
+
if (chomping === CHOMPING_KEEP) result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
|
|
1252
|
+
else if (chomping === CHOMPING_CLIP) {
|
|
1253
|
+
if (didReadContent) result += "\n";
|
|
1254
|
+
}
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
if (folding) if (isWhiteSpace(ch)) {
|
|
1258
|
+
atMoreIndented = true;
|
|
1259
|
+
result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
|
|
1260
|
+
} else if (atMoreIndented) {
|
|
1261
|
+
atMoreIndented = false;
|
|
1262
|
+
result += "\n".repeat(emptyLines + 1);
|
|
1263
|
+
} else if (emptyLines === 0) {
|
|
1264
|
+
if (didReadContent) result += " ";
|
|
1265
|
+
} else result += "\n".repeat(emptyLines);
|
|
1266
|
+
else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
|
|
1267
|
+
didReadContent = true;
|
|
1268
|
+
detectedIndent = true;
|
|
1269
|
+
emptyLines = 0;
|
|
1270
|
+
const captureStart = this.#scanner.position;
|
|
1271
|
+
while (!isEOL(ch) && ch !== 0) {
|
|
1272
|
+
this.#scanner.next();
|
|
1273
|
+
ch = this.#scanner.peek();
|
|
1274
|
+
}
|
|
1275
|
+
const segment = this.captureSegment(captureStart, this.#scanner.position, false);
|
|
1276
|
+
if (segment) result += segment;
|
|
1277
|
+
}
|
|
1278
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1279
|
+
return {
|
|
1280
|
+
tag,
|
|
1281
|
+
anchor,
|
|
1282
|
+
kind: "scalar",
|
|
1283
|
+
result
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
readBlockMapping(tag, anchor, nodeIndent, flowIndent) {
|
|
1287
|
+
const result = {};
|
|
1288
|
+
const overridableKeys = /* @__PURE__ */ new Set();
|
|
1289
|
+
let allowCompact = false;
|
|
1290
|
+
let line;
|
|
1291
|
+
let pos;
|
|
1292
|
+
let keyTag = null;
|
|
1293
|
+
let keyNode = null;
|
|
1294
|
+
let valueNode = null;
|
|
1295
|
+
let atExplicitKey = false;
|
|
1296
|
+
let detected = false;
|
|
1297
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1298
|
+
let ch = this.#scanner.peek();
|
|
1299
|
+
while (ch !== 0) {
|
|
1300
|
+
const following = this.#scanner.peek(1);
|
|
1301
|
+
line = this.line;
|
|
1302
|
+
pos = this.#scanner.position;
|
|
1303
|
+
if ((ch === QUESTION || ch === COLON) && isWhiteSpaceOrEOL(following)) {
|
|
1304
|
+
if (ch === QUESTION) {
|
|
1305
|
+
if (atExplicitKey) {
|
|
1306
|
+
this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
|
|
1307
|
+
keyTag = null;
|
|
1308
|
+
keyNode = null;
|
|
1309
|
+
valueNode = null;
|
|
1310
|
+
}
|
|
1311
|
+
detected = true;
|
|
1312
|
+
atExplicitKey = true;
|
|
1313
|
+
allowCompact = true;
|
|
1314
|
+
} else if (atExplicitKey) {
|
|
1315
|
+
atExplicitKey = false;
|
|
1316
|
+
allowCompact = true;
|
|
1317
|
+
} else throw this.#createError("Cannot read block as explicit mapping pair is incomplete: a key node is missed or followed by a non-tabulated empty line");
|
|
1318
|
+
this.#scanner.next();
|
|
1319
|
+
ch = following;
|
|
1320
|
+
} else {
|
|
1321
|
+
const newState = this.composeNode({
|
|
1322
|
+
parentIndent: flowIndent,
|
|
1323
|
+
nodeContext: CONTEXT_FLOW_OUT,
|
|
1324
|
+
allowToSeek: false,
|
|
1325
|
+
allowCompact: true
|
|
1326
|
+
});
|
|
1327
|
+
if (!newState) break;
|
|
1328
|
+
if (this.line === line) {
|
|
1329
|
+
ch = this.#scanner.peek();
|
|
1330
|
+
this.skipWhitespaces();
|
|
1331
|
+
ch = this.#scanner.peek();
|
|
1332
|
+
if (ch === COLON) {
|
|
1333
|
+
this.#scanner.next();
|
|
1334
|
+
ch = this.#scanner.peek();
|
|
1335
|
+
if (!isWhiteSpaceOrEOL(ch)) throw this.#createError("Cannot read block: a whitespace character is expected after the key-value separator within a block mapping");
|
|
1336
|
+
if (atExplicitKey) {
|
|
1337
|
+
this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
|
|
1338
|
+
keyTag = null;
|
|
1339
|
+
keyNode = null;
|
|
1340
|
+
valueNode = null;
|
|
1341
|
+
}
|
|
1342
|
+
detected = true;
|
|
1343
|
+
atExplicitKey = false;
|
|
1344
|
+
allowCompact = false;
|
|
1345
|
+
keyTag = newState.tag;
|
|
1346
|
+
keyNode = newState.result;
|
|
1347
|
+
} else if (detected) throw this.#createError("Cannot read an implicit mapping pair: missing colon");
|
|
1348
|
+
else {
|
|
1349
|
+
const { kind, result } = newState;
|
|
1350
|
+
return {
|
|
1351
|
+
tag,
|
|
1352
|
+
anchor,
|
|
1353
|
+
kind,
|
|
1354
|
+
result
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
} else if (detected) throw this.#createError("Cannot read a block mapping entry: a multiline key may not be an implicit key");
|
|
1358
|
+
else {
|
|
1359
|
+
const { kind, result } = newState;
|
|
1360
|
+
return {
|
|
1361
|
+
tag,
|
|
1362
|
+
anchor,
|
|
1363
|
+
kind,
|
|
1364
|
+
result
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
if (this.line === line || this.lineIndent > nodeIndent) {
|
|
1369
|
+
const newState = this.composeNode({
|
|
1370
|
+
parentIndent: nodeIndent,
|
|
1371
|
+
nodeContext: CONTEXT_BLOCK_OUT,
|
|
1372
|
+
allowToSeek: true,
|
|
1373
|
+
allowCompact
|
|
1374
|
+
});
|
|
1375
|
+
if (newState) if (atExplicitKey) keyNode = newState.result;
|
|
1376
|
+
else valueNode = newState.result;
|
|
1377
|
+
if (!atExplicitKey) {
|
|
1378
|
+
this.storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode, line, pos);
|
|
1379
|
+
keyTag = keyNode = valueNode = null;
|
|
1380
|
+
}
|
|
1381
|
+
this.skipSeparationSpace(true, -1);
|
|
1382
|
+
ch = this.#scanner.peek();
|
|
1383
|
+
}
|
|
1384
|
+
if (this.lineIndent > nodeIndent && ch !== 0) throw this.#createError("Cannot read block: bad indentation of a mapping entry");
|
|
1385
|
+
else if (this.lineIndent < nodeIndent) break;
|
|
1386
|
+
}
|
|
1387
|
+
if (atExplicitKey) this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
|
|
1388
|
+
if (detected) return {
|
|
1389
|
+
tag,
|
|
1390
|
+
anchor,
|
|
1391
|
+
kind: "mapping",
|
|
1392
|
+
result
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
readTagProperty(tag) {
|
|
1396
|
+
let isVerbatim = false;
|
|
1397
|
+
let isNamed = false;
|
|
1398
|
+
let tagHandle = "";
|
|
1399
|
+
let tagName;
|
|
1400
|
+
let ch = this.#scanner.peek();
|
|
1401
|
+
if (ch !== EXCLAMATION) return;
|
|
1402
|
+
if (tag !== null) throw this.#createError("Cannot read tag property: duplication of a tag property");
|
|
1403
|
+
this.#scanner.next();
|
|
1404
|
+
ch = this.#scanner.peek();
|
|
1405
|
+
if (ch === SMALLER_THAN) {
|
|
1406
|
+
isVerbatim = true;
|
|
1407
|
+
this.#scanner.next();
|
|
1408
|
+
ch = this.#scanner.peek();
|
|
1409
|
+
} else if (ch === EXCLAMATION) {
|
|
1410
|
+
isNamed = true;
|
|
1411
|
+
tagHandle = "!!";
|
|
1412
|
+
this.#scanner.next();
|
|
1413
|
+
ch = this.#scanner.peek();
|
|
1414
|
+
} else tagHandle = "!";
|
|
1415
|
+
let position = this.#scanner.position;
|
|
1416
|
+
if (isVerbatim) {
|
|
1417
|
+
do {
|
|
1418
|
+
this.#scanner.next();
|
|
1419
|
+
ch = this.#scanner.peek();
|
|
1420
|
+
} while (ch !== 0 && ch !== GREATER_THAN);
|
|
1421
|
+
if (!this.#scanner.eof()) {
|
|
1422
|
+
tagName = this.#scanner.source.slice(position, this.#scanner.position);
|
|
1423
|
+
this.#scanner.next();
|
|
1424
|
+
ch = this.#scanner.peek();
|
|
1425
|
+
} else throw this.#createError("Cannot read tag property: unexpected end of stream");
|
|
1426
|
+
} else {
|
|
1427
|
+
while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
|
|
1428
|
+
if (ch === EXCLAMATION) if (!isNamed) {
|
|
1429
|
+
tagHandle = this.#scanner.source.slice(position - 1, this.#scanner.position + 1);
|
|
1430
|
+
if (!PATTERN_TAG_HANDLE.test(tagHandle)) throw this.#createError("Cannot read tag property: named tag handle contains invalid characters");
|
|
1431
|
+
isNamed = true;
|
|
1432
|
+
position = this.#scanner.position + 1;
|
|
1433
|
+
} else throw this.#createError("Cannot read tag property: tag suffix cannot contain an exclamation mark");
|
|
1434
|
+
this.#scanner.next();
|
|
1435
|
+
ch = this.#scanner.peek();
|
|
1436
|
+
}
|
|
1437
|
+
tagName = this.#scanner.source.slice(position, this.#scanner.position);
|
|
1438
|
+
if (PATTERN_FLOW_INDICATORS.test(tagName)) throw this.#createError("Cannot read tag property: tag suffix cannot contain flow indicator characters");
|
|
1439
|
+
}
|
|
1440
|
+
if (tagName && !PATTERN_TAG_URI.test(tagName)) throw this.#createError(`Cannot read tag property: invalid characters in tag name "${tagName}"`);
|
|
1441
|
+
if (isVerbatim) return tagName;
|
|
1442
|
+
else if (this.tagMap.has(tagHandle)) return this.tagMap.get(tagHandle) + tagName;
|
|
1443
|
+
else if (tagHandle === "!") return `!${tagName}`;
|
|
1444
|
+
else if (tagHandle === "!!") return `tag:yaml.org,2002:${tagName}`;
|
|
1445
|
+
throw this.#createError(`Cannot read tag property: undeclared tag handle "${tagHandle}"`);
|
|
1446
|
+
}
|
|
1447
|
+
readAnchorProperty(anchor) {
|
|
1448
|
+
let ch = this.#scanner.peek();
|
|
1449
|
+
if (ch !== AMPERSAND) return;
|
|
1450
|
+
if (anchor !== null) throw this.#createError("Cannot read anchor property: duplicate anchor property");
|
|
1451
|
+
this.#scanner.next();
|
|
1452
|
+
ch = this.#scanner.peek();
|
|
1453
|
+
const position = this.#scanner.position;
|
|
1454
|
+
while (ch !== 0 && !isWhiteSpaceOrEOL(ch) && !isFlowIndicator(ch)) {
|
|
1455
|
+
this.#scanner.next();
|
|
1456
|
+
ch = this.#scanner.peek();
|
|
1457
|
+
}
|
|
1458
|
+
if (this.#scanner.position === position) throw this.#createError("Cannot read anchor property: name of an anchor node must contain at least one character");
|
|
1459
|
+
return this.#scanner.source.slice(position, this.#scanner.position);
|
|
1460
|
+
}
|
|
1461
|
+
readAlias() {
|
|
1462
|
+
if (this.#scanner.peek() !== ASTERISK) return;
|
|
1463
|
+
this.#scanner.next();
|
|
1464
|
+
let ch = this.#scanner.peek();
|
|
1465
|
+
const position = this.#scanner.position;
|
|
1466
|
+
while (ch !== 0 && !isWhiteSpaceOrEOL(ch) && !isFlowIndicator(ch)) {
|
|
1467
|
+
this.#scanner.next();
|
|
1468
|
+
ch = this.#scanner.peek();
|
|
1469
|
+
}
|
|
1470
|
+
if (this.#scanner.position === position) throw this.#createError("Cannot read alias: alias name must contain at least one character");
|
|
1471
|
+
const alias = this.#scanner.source.slice(position, this.#scanner.position);
|
|
1472
|
+
if (!this.anchorMap.has(alias)) throw this.#createError(`Cannot read alias: unidentified alias "${alias}"`);
|
|
1473
|
+
this.skipSeparationSpace(true, -1);
|
|
1474
|
+
return this.anchorMap.get(alias);
|
|
1475
|
+
}
|
|
1476
|
+
resolveTag(state) {
|
|
1477
|
+
switch (state.tag) {
|
|
1478
|
+
case null:
|
|
1479
|
+
case "!": return state;
|
|
1480
|
+
case "?":
|
|
1481
|
+
for (const type of this.implicitTypes) {
|
|
1482
|
+
if (!type.resolve(state.result)) continue;
|
|
1483
|
+
const result = type.construct(state.result);
|
|
1484
|
+
state.result = result;
|
|
1485
|
+
state.tag = type.tag;
|
|
1486
|
+
const { anchor } = state;
|
|
1487
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1488
|
+
return state;
|
|
1489
|
+
}
|
|
1490
|
+
return state;
|
|
1491
|
+
}
|
|
1492
|
+
const kind = state.kind ?? "fallback";
|
|
1493
|
+
const type = this.typeMap[kind].get(state.tag);
|
|
1494
|
+
if (!type) throw this.#createError(`Cannot resolve unknown tag !<${state.tag}>`);
|
|
1495
|
+
if (state.result !== null && type.kind !== state.kind) throw this.#createError(`Unacceptable node kind for !<${state.tag}> tag: it should be "${type.kind}", not "${state.kind}"`);
|
|
1496
|
+
if (!type.resolve(state.result)) throw this.#createError(`Cannot resolve a node with !<${state.tag}> explicit tag`);
|
|
1497
|
+
const result = type.construct(state.result);
|
|
1498
|
+
state.result = result;
|
|
1499
|
+
const { anchor } = state;
|
|
1500
|
+
if (anchor !== null) this.anchorMap.set(anchor, result);
|
|
1501
|
+
return state;
|
|
1502
|
+
}
|
|
1503
|
+
composeNode({ parentIndent, nodeContext, allowToSeek, allowCompact }) {
|
|
1504
|
+
let indentStatus = 1;
|
|
1505
|
+
let atNewLine = false;
|
|
1506
|
+
const allowBlockScalars = CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext;
|
|
1507
|
+
let allowBlockCollections = allowBlockScalars;
|
|
1508
|
+
const allowBlockStyles = allowBlockScalars;
|
|
1509
|
+
if (allowToSeek) {
|
|
1510
|
+
if (this.skipSeparationSpace(true, -1)) {
|
|
1511
|
+
atNewLine = true;
|
|
1512
|
+
indentStatus = getIndentStatus(this.lineIndent, parentIndent);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
let tag = null;
|
|
1516
|
+
let anchor = null;
|
|
1517
|
+
if (indentStatus === 1) while (true) {
|
|
1518
|
+
const newTag = this.readTagProperty(tag);
|
|
1519
|
+
if (newTag) tag = newTag;
|
|
1520
|
+
else {
|
|
1521
|
+
const newAnchor = this.readAnchorProperty(anchor);
|
|
1522
|
+
if (!newAnchor) break;
|
|
1523
|
+
anchor = newAnchor;
|
|
1524
|
+
}
|
|
1525
|
+
if (this.skipSeparationSpace(true, -1)) {
|
|
1526
|
+
atNewLine = true;
|
|
1527
|
+
allowBlockCollections = allowBlockStyles;
|
|
1528
|
+
indentStatus = getIndentStatus(this.lineIndent, parentIndent);
|
|
1529
|
+
} else allowBlockCollections = false;
|
|
1530
|
+
}
|
|
1531
|
+
if (allowBlockCollections) allowBlockCollections = atNewLine || allowCompact;
|
|
1532
|
+
if (indentStatus === 1) {
|
|
1533
|
+
const flowIndent = CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext ? parentIndent : parentIndent + 1;
|
|
1534
|
+
if (allowBlockCollections) {
|
|
1535
|
+
const blockIndent = this.#scanner.position - this.lineStart;
|
|
1536
|
+
const blockSequenceState = this.readBlockSequence(tag, anchor, blockIndent);
|
|
1537
|
+
if (blockSequenceState) return this.resolveTag(blockSequenceState);
|
|
1538
|
+
const blockMappingState = this.readBlockMapping(tag, anchor, blockIndent, flowIndent);
|
|
1539
|
+
if (blockMappingState) return this.resolveTag(blockMappingState);
|
|
1540
|
+
}
|
|
1541
|
+
const flowCollectionState = this.readFlowCollection(tag, anchor, flowIndent);
|
|
1542
|
+
if (flowCollectionState) return this.resolveTag(flowCollectionState);
|
|
1543
|
+
if (allowBlockScalars) {
|
|
1544
|
+
const blockScalarState = this.readBlockScalar(tag, anchor, flowIndent);
|
|
1545
|
+
if (blockScalarState) return this.resolveTag(blockScalarState);
|
|
1546
|
+
}
|
|
1547
|
+
const singleQuoteState = this.readSingleQuotedScalar(tag, anchor, flowIndent);
|
|
1548
|
+
if (singleQuoteState) return this.resolveTag(singleQuoteState);
|
|
1549
|
+
const doubleQuoteState = this.readDoubleQuotedScalar(tag, anchor, flowIndent);
|
|
1550
|
+
if (doubleQuoteState) return this.resolveTag(doubleQuoteState);
|
|
1551
|
+
const alias = this.readAlias();
|
|
1552
|
+
if (alias) {
|
|
1553
|
+
if (tag !== null || anchor !== null) throw this.#createError("Cannot compose node: alias node should not have any properties");
|
|
1554
|
+
return this.resolveTag({
|
|
1555
|
+
tag,
|
|
1556
|
+
anchor,
|
|
1557
|
+
kind: null,
|
|
1558
|
+
result: alias
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
const plainScalarState = this.readPlainScalar(tag, anchor, flowIndent, CONTEXT_FLOW_IN === nodeContext);
|
|
1562
|
+
if (plainScalarState) {
|
|
1563
|
+
plainScalarState.tag ??= "?";
|
|
1564
|
+
return this.resolveTag(plainScalarState);
|
|
1565
|
+
}
|
|
1566
|
+
} else if (indentStatus === 0 && CONTEXT_BLOCK_OUT === nodeContext && allowBlockCollections) {
|
|
1567
|
+
const blockIndent = this.#scanner.position - this.lineStart;
|
|
1568
|
+
const newState = this.readBlockSequence(tag, anchor, blockIndent);
|
|
1569
|
+
if (newState) return this.resolveTag(newState);
|
|
1570
|
+
}
|
|
1571
|
+
const newState = this.resolveTag({
|
|
1572
|
+
tag,
|
|
1573
|
+
anchor,
|
|
1574
|
+
kind: null,
|
|
1575
|
+
result: null
|
|
1576
|
+
});
|
|
1577
|
+
if (newState.tag !== null || newState.anchor !== null) return newState;
|
|
1578
|
+
}
|
|
1579
|
+
readDirectives() {
|
|
1580
|
+
let hasDirectives = false;
|
|
1581
|
+
let version = null;
|
|
1582
|
+
let ch = this.#scanner.peek();
|
|
1583
|
+
while (ch !== 0) {
|
|
1584
|
+
this.skipSeparationSpace(true, -1);
|
|
1585
|
+
ch = this.#scanner.peek();
|
|
1586
|
+
if (this.lineIndent > 0 || ch !== PERCENT) break;
|
|
1587
|
+
hasDirectives = true;
|
|
1588
|
+
this.#scanner.next();
|
|
1589
|
+
ch = this.#scanner.peek();
|
|
1590
|
+
let position = this.#scanner.position;
|
|
1591
|
+
while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
|
|
1592
|
+
this.#scanner.next();
|
|
1593
|
+
ch = this.#scanner.peek();
|
|
1594
|
+
}
|
|
1595
|
+
const directiveName = this.#scanner.source.slice(position, this.#scanner.position);
|
|
1596
|
+
const directiveArgs = [];
|
|
1597
|
+
if (directiveName.length < 1) throw this.#createError("Cannot read document: directive name length must be greater than zero");
|
|
1598
|
+
while (ch !== 0) {
|
|
1599
|
+
this.skipWhitespaces();
|
|
1600
|
+
this.skipComment();
|
|
1601
|
+
ch = this.#scanner.peek();
|
|
1602
|
+
if (isEOL(ch)) break;
|
|
1603
|
+
position = this.#scanner.position;
|
|
1604
|
+
while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
|
|
1605
|
+
this.#scanner.next();
|
|
1606
|
+
ch = this.#scanner.peek();
|
|
1607
|
+
}
|
|
1608
|
+
directiveArgs.push(this.#scanner.source.slice(position, this.#scanner.position));
|
|
1609
|
+
}
|
|
1610
|
+
if (ch !== 0) this.readLineBreak();
|
|
1611
|
+
switch (directiveName) {
|
|
1612
|
+
case "YAML":
|
|
1613
|
+
if (version !== null) throw this.#createError("Cannot handle YAML directive: duplication of %YAML directive");
|
|
1614
|
+
version = this.yamlDirectiveHandler(directiveArgs);
|
|
1615
|
+
break;
|
|
1616
|
+
case "TAG":
|
|
1617
|
+
this.tagDirectiveHandler(directiveArgs);
|
|
1618
|
+
break;
|
|
1619
|
+
default:
|
|
1620
|
+
this.dispatchWarning(`unknown document directive "${directiveName}"`);
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1623
|
+
ch = this.#scanner.peek();
|
|
1624
|
+
}
|
|
1625
|
+
return hasDirectives;
|
|
1626
|
+
}
|
|
1627
|
+
readDocument() {
|
|
1628
|
+
const documentStart = this.#scanner.position;
|
|
1629
|
+
this.checkLineBreaks = false;
|
|
1630
|
+
this.tagMap = /* @__PURE__ */ new Map();
|
|
1631
|
+
this.anchorMap = /* @__PURE__ */ new Map();
|
|
1632
|
+
const hasDirectives = this.readDirectives();
|
|
1633
|
+
this.skipSeparationSpace(true, -1);
|
|
1634
|
+
let result = null;
|
|
1635
|
+
if (this.lineIndent === 0 && this.#scanner.peek() === MINUS && this.#scanner.peek(1) === MINUS && this.#scanner.peek(2) === MINUS) {
|
|
1636
|
+
this.#scanner.position += 3;
|
|
1637
|
+
this.skipSeparationSpace(true, -1);
|
|
1638
|
+
} else if (hasDirectives) throw this.#createError("Cannot read document: directives end mark is expected");
|
|
1639
|
+
const newState = this.composeNode({
|
|
1640
|
+
parentIndent: this.lineIndent - 1,
|
|
1641
|
+
nodeContext: CONTEXT_BLOCK_OUT,
|
|
1642
|
+
allowToSeek: false,
|
|
1643
|
+
allowCompact: true
|
|
1644
|
+
});
|
|
1645
|
+
if (newState) result = newState.result;
|
|
1646
|
+
this.skipSeparationSpace(true, -1);
|
|
1647
|
+
if (this.checkLineBreaks && PATTERN_NON_ASCII_LINE_BREAKS.test(this.#scanner.source.slice(documentStart, this.#scanner.position))) this.dispatchWarning("non-ASCII line breaks are interpreted as content");
|
|
1648
|
+
if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) {
|
|
1649
|
+
if (this.#scanner.peek() === DOT) {
|
|
1650
|
+
this.#scanner.position += 3;
|
|
1651
|
+
this.skipSeparationSpace(true, -1);
|
|
1652
|
+
}
|
|
1653
|
+
} else if (!this.#scanner.eof()) throw this.#createError("Cannot read document: end of the stream or a document separator is expected");
|
|
1654
|
+
return result;
|
|
1655
|
+
}
|
|
1656
|
+
*readDocuments() {
|
|
1657
|
+
while (!this.#scanner.eof()) yield this.readDocument();
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1660
|
+
|
|
1661
|
+
//#endregion
|
|
1662
|
+
//#region node_modules/@std/yaml/parse.js
|
|
1663
|
+
function sanitizeInput(input) {
|
|
1664
|
+
input = String(input);
|
|
1665
|
+
if (input.length > 0) {
|
|
1666
|
+
if (!isEOL(input.charCodeAt(input.length - 1))) input += "\n";
|
|
1667
|
+
if (input.charCodeAt(0) === 65279) input = input.slice(1);
|
|
1668
|
+
}
|
|
1669
|
+
return input;
|
|
1670
|
+
}
|
|
1671
|
+
/**
|
|
1672
|
+
* Parse and return a YAML string as a parsed YAML document object.
|
|
1673
|
+
*
|
|
1674
|
+
* Note: This does not support functions. Untrusted data is safe to parse.
|
|
1675
|
+
*
|
|
1676
|
+
* @example Usage
|
|
1677
|
+
* ```ts
|
|
1678
|
+
* import { parse } from "@std/yaml/parse";
|
|
1679
|
+
* import { assertEquals } from "@std/assert";
|
|
1680
|
+
*
|
|
1681
|
+
* const data = parse(`
|
|
1682
|
+
* id: 1
|
|
1683
|
+
* name: Alice
|
|
1684
|
+
* `);
|
|
1685
|
+
*
|
|
1686
|
+
* assertEquals(data, { id: 1, name: "Alice" });
|
|
1687
|
+
* ```
|
|
1688
|
+
*
|
|
1689
|
+
* @throws {SyntaxError} Throws error on invalid YAML.
|
|
1690
|
+
* @param content YAML string to parse.
|
|
1691
|
+
* @param options Parsing options.
|
|
1692
|
+
* @returns Parsed document.
|
|
1693
|
+
*/ function parse(content, options = {}) {
|
|
1694
|
+
content = sanitizeInput(content);
|
|
1695
|
+
const documentGenerator = new LoaderState(content, {
|
|
1696
|
+
...options,
|
|
1697
|
+
schema: SCHEMA_MAP.get(options.schema)
|
|
1698
|
+
}).readDocuments();
|
|
1699
|
+
const document = documentGenerator.next().value;
|
|
1700
|
+
if (!documentGenerator.next().done) throw new SyntaxError("Found more than 1 document in the stream: expected a single document");
|
|
1701
|
+
return document ?? null;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
//#endregion
|
|
1705
|
+
//#region index.ts
|
|
1706
|
+
function parseFrontmatter(input) {
|
|
1707
|
+
const delimiter = "---";
|
|
1708
|
+
if (!input.startsWith(delimiter + "\n") && !input.startsWith(delimiter + "\r\n")) return {
|
|
1709
|
+
data: {},
|
|
1710
|
+
content: input
|
|
1711
|
+
};
|
|
1712
|
+
const afterOpen = input.slice(3);
|
|
1713
|
+
const closeIndex = afterOpen.indexOf("\n" + delimiter);
|
|
1714
|
+
if (closeIndex === -1) return {
|
|
1715
|
+
data: {},
|
|
1716
|
+
content: input
|
|
1717
|
+
};
|
|
1718
|
+
const yamlStr = afterOpen.slice(0, closeIndex).trim();
|
|
1719
|
+
let content = afterOpen.slice(closeIndex + 1 + 3);
|
|
1720
|
+
if (content.startsWith("\r\n")) content = content.slice(2);
|
|
1721
|
+
else if (content.startsWith("\n")) content = content.slice(1);
|
|
1722
|
+
const parsed = parse(yamlStr);
|
|
1723
|
+
return {
|
|
1724
|
+
data: typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {},
|
|
1725
|
+
content
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
function getAllPostSlugs(directory = "posts/") {
|
|
1729
|
+
const postsDirectory = path.join(process.cwd(), directory);
|
|
1730
|
+
return fs.readdirSync(postsDirectory);
|
|
1731
|
+
}
|
|
1732
|
+
function getAllPosts(directory = "posts/") {
|
|
1733
|
+
return getAllPostSlugs(directory).map((slug) => getPostBySlug(slug, directory));
|
|
1734
|
+
}
|
|
1735
|
+
function getAllPostParams(directory = "posts/") {
|
|
1736
|
+
return getAllPostSlugs(directory).map((slug) => ({ slug: slug.replace(/\.md$/, "") }));
|
|
1737
|
+
}
|
|
1738
|
+
function getPostBySlug(slug, directory = "posts/") {
|
|
1739
|
+
const realSlug = slug.replace(/\.md$/, "");
|
|
1740
|
+
const postsDirectory = path.join(process.cwd(), directory);
|
|
1741
|
+
const fullPath = path.join(postsDirectory, `${realSlug}.md`);
|
|
1742
|
+
const { data, content } = parseFrontmatter(fs.readFileSync(fullPath, "utf8"));
|
|
1743
|
+
return {
|
|
1744
|
+
slug: realSlug,
|
|
1745
|
+
metadata: data,
|
|
1746
|
+
content
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
//#endregion
|
|
1751
|
+
export { getAllPostParams, getAllPostSlugs, getAllPosts, getPostBySlug, parseFrontmatter };
|