New simple implementation for YAML serialization
Tiny in size so we don't need to fetch the 80KB yaml package for simple YAML serializaiton needs in various pages. It's also 8x faster than yaml package so that's a big plus for debug logging.
This commit is contained in:
1 parent
134ca46dde
commit
cc89fd92d7
8 files changed
+1096
-21
No files matched your search
@@ -0,0 +1,198 @@
|
||||
const LINE_WIDTH = 80;
|
||||
const INDENTATION = " ";
|
||||
|
||||
const STRING_RESERVED = new Set([
|
||||
"true",
|
||||
"True",
|
||||
"TRUE",
|
||||
"false",
|
||||
"False",
|
||||
"FALSE",
|
||||
"null",
|
||||
"Null",
|
||||
"NULL",
|
||||
]);
|
||||
|
||||
function isPrintable(str: string): boolean {
|
||||
return !/[^\t\n\x20-\x7e\x85\u{a0}-\u{d7ff}\u{e000}-\u{fffd}\u{10000}-\u{10ffff}]/u.test(
|
||||
str
|
||||
);
|
||||
}
|
||||
|
||||
function stringifyKey(str: string): string {
|
||||
if (!str || !isPrintable(str)) return JSON.stringify(str);
|
||||
if (/^[\s-?:,[\]{}#&$!|>'"%@`]|: | #|[\n,[\]{}]|\s$/.test(str))
|
||||
return JSON.stringify(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
function foldString(str: string): string[] {
|
||||
if (str.length <= LINE_WIDTH) return [str];
|
||||
if (str.startsWith(" ")) return [str];
|
||||
const words = str.split(/(?<=[^ ]) (?=[^ ])/);
|
||||
const lines: string[] = [];
|
||||
|
||||
let idx = 0;
|
||||
let len = 0;
|
||||
for (const [i, word] of words.entries()) {
|
||||
len += word.length + 1;
|
||||
if (len >= LINE_WIDTH && len !== word.length) {
|
||||
lines.push(words.slice(idx, i).join(" "));
|
||||
idx = i;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx < words.length) lines.push(words.slice(idx).join(" "));
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
function stringifyString(str: string, res: string[], prefix1, prefix2): void {
|
||||
if (/^\s*$/.test(str) || STRING_RESERVED.has(str) || !isPrintable(str)) {
|
||||
res.push(prefix1 + JSON.stringify(str));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prefix2) prefix2 = INDENTATION;
|
||||
|
||||
const lines = str.split("\n");
|
||||
if (lines.length > 1) {
|
||||
let idt = "";
|
||||
let chmp = "-";
|
||||
if ((lines.find((l) => l) || "").startsWith(" "))
|
||||
idt = `${INDENTATION.length}`;
|
||||
|
||||
if (!lines[lines.length - 1]) {
|
||||
lines.pop();
|
||||
if (lines[lines.length - 1]) chmp = "";
|
||||
else chmp = "+";
|
||||
}
|
||||
|
||||
if (/^\s+$/.test(lines[lines.length - 1])) {
|
||||
res.push(prefix1 + JSON.stringify(str));
|
||||
return;
|
||||
}
|
||||
|
||||
let isFolded = false;
|
||||
const folded = lines.map((l) => {
|
||||
const ls = foldString(l);
|
||||
if (ls.length > 1) isFolded = true;
|
||||
return ls;
|
||||
});
|
||||
|
||||
if (!isFolded) {
|
||||
res.push(
|
||||
`${prefix1}|${idt}${chmp}`,
|
||||
...lines.map((l) => (l ? prefix2 + l : l))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
res.push(`${prefix1}>${idt}${chmp}`);
|
||||
res.push(...folded[0].map((f) => prefix2 + f));
|
||||
for (let i = 1; i < folded.length; ++i) {
|
||||
const prevLine = folded[i - 1][0];
|
||||
if (prevLine && !folded[i - 1][0].startsWith(" ")) res.push("");
|
||||
res.push(...folded[i].map((f) => prefix2 + f));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
/^[\s-?:,[\]{}#&$!|>'"%@`]|: | #|\s$/.test(str) ||
|
||||
parseFloat(str) === +str
|
||||
) {
|
||||
res.push(prefix1 + JSON.stringify(str));
|
||||
return;
|
||||
}
|
||||
|
||||
res.push(prefix1 + str);
|
||||
}
|
||||
|
||||
function stringifyAny(
|
||||
obj: unknown,
|
||||
res: string[],
|
||||
prefix1 = "",
|
||||
prefix2 = ""
|
||||
): void {
|
||||
if (obj == null || typeof obj === "number" || typeof obj === "boolean") {
|
||||
res.push(`${prefix1}${obj}`);
|
||||
return;
|
||||
}
|
||||
if (obj instanceof Date) {
|
||||
res.push(`${prefix1}${obj.toJSON()}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof obj === "string") {
|
||||
stringifyString(obj, res, prefix1, prefix2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
if (!obj.length) {
|
||||
res.push(prefix1 + "[]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prefix1 || prefix1.endsWith("- ")) {
|
||||
stringifyAny(obj[0], res, prefix1 + "- ", prefix2 + INDENTATION);
|
||||
prefix1 = prefix2 + "- ";
|
||||
prefix2 = prefix2 + INDENTATION;
|
||||
for (let i = 1; i < obj.length; ++i)
|
||||
stringifyAny(obj[i], res, prefix1, prefix2);
|
||||
} else {
|
||||
res.push(prefix1);
|
||||
prefix1 = prefix2 + "- ";
|
||||
prefix2 = prefix2 + INDENTATION;
|
||||
for (let i = 0; i < obj.length; ++i)
|
||||
stringifyAny(obj[i], res, prefix1, prefix2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = Object.entries(obj);
|
||||
|
||||
if (!entries.length) {
|
||||
res.push(prefix1 + "{}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prefix1 || prefix1.endsWith("- ")) {
|
||||
stringifyAny(
|
||||
entries[0][1],
|
||||
res,
|
||||
prefix1 + `${stringifyKey(entries[0][0])}: `,
|
||||
prefix2 + INDENTATION
|
||||
);
|
||||
prefix1 = prefix2;
|
||||
prefix2 = prefix2 + INDENTATION;
|
||||
for (let i = 1; i < entries.length; ++i) {
|
||||
stringifyAny(
|
||||
entries[i][1],
|
||||
res,
|
||||
prefix1 + `${stringifyKey(entries[i][0])}: `,
|
||||
prefix2
|
||||
);
|
||||
}
|
||||
} else {
|
||||
res.push(prefix1);
|
||||
prefix1 = prefix2;
|
||||
prefix2 = prefix2 + INDENTATION;
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
stringifyAny(
|
||||
entries[i][1],
|
||||
res,
|
||||
prefix1 + `${stringifyKey(entries[i][0])}: `,
|
||||
prefix2
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function stringify(obj: unknown): string {
|
||||
const lines: string[] = [];
|
||||
stringifyAny(obj, lines);
|
||||
return lines.join("\n") + "\n";
|
||||
}
|
||||
+7
-7
@@ -25,7 +25,7 @@ import {
|
||||
} from "http";
|
||||
import { Socket } from "net";
|
||||
import { appendFileSync } from "fs";
|
||||
import * as yaml from "yaml";
|
||||
import { stringify } from "./common/yaml";
|
||||
import * as config from "./config";
|
||||
|
||||
const DEBUG_FILE = "" + config.get("DEBUG_FILE");
|
||||
@@ -64,7 +64,7 @@ export function incomingHttpRequest(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
@@ -90,7 +90,7 @@ export function outgoingHttpResponse(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
@@ -119,7 +119,7 @@ export function outgoingHttpRequest(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
@@ -147,7 +147,7 @@ export function outgoingHttpRequestError(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
@@ -173,7 +173,7 @@ export function incomingHttpResponse(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
@@ -197,7 +197,7 @@ export function outgoingUdpMessage(
|
||||
};
|
||||
|
||||
if (DEBUG_FORMAT === "yaml")
|
||||
appendFileSync(DEBUG_FILE, "---\n" + yaml.stringify(msg));
|
||||
appendFileSync(DEBUG_FILE, "---\n" + stringify(msg));
|
||||
else if (DEBUG_FORMAT === "json")
|
||||
appendFileSync(DEBUG_FILE, JSON.stringify(msg) + "\n");
|
||||
else throw new Error(`Unrecognized DEBUG_FORMAT option`);
|
||||
|
||||
Generated
+2
-1
@@ -8167,7 +8167,8 @@
|
||||
"yaml": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
|
||||
"integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg=="
|
||||
"integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.0.3",
|
||||
|
||||
+3
-3
@@ -33,8 +33,7 @@
|
||||
"later": "^1.2.0",
|
||||
"mongodb": "^3.6.2",
|
||||
"parsimmon": "^1.16.0",
|
||||
"seedrandom": "^3.0.5",
|
||||
"yaml": "^1.10.0"
|
||||
"seedrandom": "^3.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^16.0.0",
|
||||
@@ -72,7 +71,8 @@
|
||||
"svgo": "^1.3.2",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.0.5",
|
||||
"webpack": "^5.2.0"
|
||||
"webpack": "^5.2.0",
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
|
||||
@@ -0,0 +1,861 @@
|
||||
[
|
||||
[
|
||||
{
|
||||
"name": "Mark McGwire",
|
||||
"hr": 65,
|
||||
"avg": 0.278
|
||||
},
|
||||
{
|
||||
"name": "Sammy Sosa",
|
||||
"hr": 63,
|
||||
"avg": 0.288
|
||||
}
|
||||
],
|
||||
{
|
||||
"top1": {
|
||||
"key1": "scalar1"
|
||||
},
|
||||
"top2": {
|
||||
"key2": "scalar2"
|
||||
},
|
||||
"top3": {
|
||||
"scalar1": "scalar3"
|
||||
},
|
||||
"top4": {
|
||||
"scalar2": "scalar4"
|
||||
},
|
||||
"top5": "scalar5",
|
||||
"top6": {
|
||||
"key6": "scalar6"
|
||||
}
|
||||
},
|
||||
"text",
|
||||
["a", "b", 42, "d"],
|
||||
{
|
||||
"a!\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~": "safe",
|
||||
"?foo": "safe question mark",
|
||||
":foo": "safe colon",
|
||||
"-foo": "safe dash",
|
||||
"this is#not": "a comment"
|
||||
},
|
||||
{
|
||||
"": "a"
|
||||
},
|
||||
"foo",
|
||||
{
|
||||
"key": "value",
|
||||
"foo": "key"
|
||||
},
|
||||
[1, -2, 33],
|
||||
{
|
||||
"plain": "a b\nc"
|
||||
},
|
||||
[["s1_i1", "s1_i2"], "s2"],
|
||||
{
|
||||
"First occurrence": "Foo",
|
||||
"Second occurrence": "Foo",
|
||||
"Override anchor": "Bar",
|
||||
"Reuse anchor": "Bar"
|
||||
},
|
||||
"k:#foo &a !t s",
|
||||
["a"],
|
||||
{
|
||||
"escaped slash": "a/b"
|
||||
},
|
||||
{
|
||||
"plain": "This unquoted scalar spans many lines.",
|
||||
"quoted": "So does this quoted scalar.\n"
|
||||
},
|
||||
"here's to \"quotes\"",
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
"ab cd\nef\n\ngh\n",
|
||||
["detected\n", "\n\n# detected\n", " explicit\n", "detected\n"],
|
||||
"foo: bar\": baz",
|
||||
"plain\\value\\with\\backslashes",
|
||||
{
|
||||
"plain": "text lines",
|
||||
"quoted": "text lines",
|
||||
"block": "text\n \tlines\n"
|
||||
},
|
||||
"a",
|
||||
{
|
||||
"foo": "you",
|
||||
"bar": "far"
|
||||
},
|
||||
{
|
||||
"sequence": ["entry", ["nested"]],
|
||||
"mapping": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
{
|
||||
"literal": "some\ntext\n",
|
||||
"folded": "some text\n"
|
||||
},
|
||||
[
|
||||
{
|
||||
"one": "two",
|
||||
"three": "four"
|
||||
},
|
||||
{
|
||||
"five": "six",
|
||||
"seven": "eight"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Folding": "Empty line\nas a line feed",
|
||||
"Chomping": "Clipped empty lines\n"
|
||||
},
|
||||
[
|
||||
["one", "two"],
|
||||
["three", "four"]
|
||||
],
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
{
|
||||
"key": "value"
|
||||
},
|
||||
{
|
||||
"explicit key": null,
|
||||
"block key\n": ["one", "two"]
|
||||
},
|
||||
["foo"],
|
||||
[
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
["baz", "baz"]
|
||||
],
|
||||
"ab\n\n \n",
|
||||
{
|
||||
"foo: bar\\": "baz'"
|
||||
},
|
||||
{
|
||||
"Not indented": {
|
||||
"By one space": "By four\n spaces\n",
|
||||
"Flow style": ["By two", "Also by two", "Still by two"]
|
||||
}
|
||||
},
|
||||
"\\//||\\/||\n// || ||__\n",
|
||||
{
|
||||
"foo": [
|
||||
"a",
|
||||
{
|
||||
"key": "value"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"a": null,
|
||||
"b": null
|
||||
},
|
||||
"foo",
|
||||
{
|
||||
"a": "b",
|
||||
"": "a"
|
||||
},
|
||||
{
|
||||
"foo\nbar:baz\tx \\$%^&*()x": 23,
|
||||
"x\\ny:z\\tx $%^&*()x": 24
|
||||
},
|
||||
"Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n",
|
||||
" foo\nbar\nbaz ",
|
||||
{ "matches %": 20 },
|
||||
[
|
||||
"flow in block",
|
||||
"Block scalar\n",
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
{
|
||||
"a": "b",
|
||||
"c": 42,
|
||||
"e": "f",
|
||||
"g": "h",
|
||||
"23": false
|
||||
},
|
||||
"ab",
|
||||
" 1st non-empty\n2nd non-empty 3rd non-empty ",
|
||||
{
|
||||
"top1": {
|
||||
"key1": "one"
|
||||
},
|
||||
"top2": {
|
||||
"key2": "two"
|
||||
},
|
||||
"top3": {
|
||||
"key3": "three"
|
||||
},
|
||||
"top4": {
|
||||
"key4": "four"
|
||||
},
|
||||
"top5": {
|
||||
"key5": "five"
|
||||
},
|
||||
"top6": "six",
|
||||
"top7": "seven"
|
||||
},
|
||||
{
|
||||
"hr": ["Mark McGwire", "Sammy Sosa"],
|
||||
"rbi": ["Sammy Sosa", "Ken Griffey"]
|
||||
},
|
||||
"\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n",
|
||||
["word1", "word2"],
|
||||
{
|
||||
"a": null,
|
||||
"b": null,
|
||||
"c": null
|
||||
},
|
||||
{
|
||||
"nested sequences": [[[[]]], [[{}]]],
|
||||
"key1": [],
|
||||
"key2": {}
|
||||
},
|
||||
"---word1 word2",
|
||||
{
|
||||
"implicit block key": [
|
||||
{
|
||||
"implicit flow key": "value"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key ends with two colons::": "value"
|
||||
},
|
||||
[
|
||||
{
|
||||
"single line": null,
|
||||
"a": "b"
|
||||
},
|
||||
{
|
||||
"multi line": null,
|
||||
"a": "b"
|
||||
}
|
||||
],
|
||||
"a",
|
||||
{
|
||||
"key": ["item1", "item2"]
|
||||
},
|
||||
[
|
||||
"double quoted",
|
||||
"single quoted",
|
||||
"plain text",
|
||||
["nested"],
|
||||
{
|
||||
"single": "pair"
|
||||
}
|
||||
],
|
||||
["unicode anchor"],
|
||||
[
|
||||
{
|
||||
"key": "value",
|
||||
"key2": "value2"
|
||||
},
|
||||
{
|
||||
"key3": "value3"
|
||||
}
|
||||
],
|
||||
"trimmed\n\n\nas space",
|
||||
"Mark McGwire's year was crippled by a knee injury.\n",
|
||||
[
|
||||
{
|
||||
"single line": null,
|
||||
"a": "b"
|
||||
},
|
||||
{
|
||||
"multi line": null,
|
||||
"a": "b"
|
||||
}
|
||||
],
|
||||
{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": "d"
|
||||
},
|
||||
"e": {
|
||||
"f": "g"
|
||||
}
|
||||
},
|
||||
"h": "i"
|
||||
},
|
||||
{
|
||||
"foo": {
|
||||
"bar": "baz"
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"single line": "value"
|
||||
},
|
||||
{
|
||||
"multi line": "value"
|
||||
}
|
||||
],
|
||||
{
|
||||
"single": "text",
|
||||
"double": "text"
|
||||
},
|
||||
" 1st non-empty\n2nd non-empty 3rd non-empty ",
|
||||
[
|
||||
{
|
||||
"item": "Super Hoop",
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"item": "Basketball",
|
||||
"quantity": 4
|
||||
},
|
||||
{
|
||||
"item": "Big Shoes",
|
||||
"quantity": 1
|
||||
}
|
||||
],
|
||||
"a b c d\ne",
|
||||
{
|
||||
"a": ["b", ["c", "d"]]
|
||||
},
|
||||
{
|
||||
"strip": "text",
|
||||
"clip": "text\n",
|
||||
"keep": "text\n"
|
||||
},
|
||||
{
|
||||
"a": "b c",
|
||||
"d": "e f"
|
||||
},
|
||||
["single multiline - sequence entry"],
|
||||
{
|
||||
"1": [2, 3],
|
||||
"4": 5
|
||||
},
|
||||
[
|
||||
{
|
||||
"bla\"keks": "foo"
|
||||
},
|
||||
{
|
||||
"bla]keks": "foo"
|
||||
}
|
||||
],
|
||||
"folded text\n",
|
||||
"foo",
|
||||
{
|
||||
"key": {
|
||||
"a": "b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"adjacent": "value",
|
||||
"readable": "value",
|
||||
"empty": null
|
||||
},
|
||||
[
|
||||
{
|
||||
"a": "b"
|
||||
},
|
||||
{
|
||||
"c": "d"
|
||||
},
|
||||
{
|
||||
"e": "f"
|
||||
},
|
||||
{
|
||||
"g": "h"
|
||||
}
|
||||
],
|
||||
{
|
||||
"tab": "\tstring"
|
||||
},
|
||||
[
|
||||
{
|
||||
"foo bar": "baz"
|
||||
}
|
||||
],
|
||||
{
|
||||
"anchored": "value",
|
||||
"alias": "value"
|
||||
},
|
||||
["explicit indent and chomp", "chomp and explicit indent"],
|
||||
{
|
||||
"a": ["b", "c"]
|
||||
},
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
[
|
||||
"::vector",
|
||||
": - ()",
|
||||
"Up, up, and away!",
|
||||
-123,
|
||||
"http://example.com/foo#bar",
|
||||
[
|
||||
"::vector",
|
||||
": - ()",
|
||||
"Up, up and away!",
|
||||
-123,
|
||||
"http://example.com/foo#bar"
|
||||
]
|
||||
],
|
||||
{
|
||||
"a": "b",
|
||||
"seq": ["a"],
|
||||
"c": "d"
|
||||
},
|
||||
["foo", "bar", 42],
|
||||
"line1 # no comment line3\n",
|
||||
"\n\nliteral\n \n\ntext\n",
|
||||
{
|
||||
"a": "b"
|
||||
},
|
||||
{
|
||||
"k": ["a", "b"]
|
||||
},
|
||||
"a b c d\ne",
|
||||
"---word1 word2",
|
||||
["a", 2, 4, "d"],
|
||||
{
|
||||
"a": [
|
||||
"b",
|
||||
"c",
|
||||
{
|
||||
"d": ["e", "f"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"a": " more indented\nregular\n",
|
||||
"b": "\n\n more indented\nregular\n"
|
||||
},
|
||||
{
|
||||
"strip": "# text",
|
||||
"clip": "# text\n",
|
||||
"keep": "# text\n\n"
|
||||
},
|
||||
{
|
||||
"safe": "a!\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~ !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~",
|
||||
"safe question mark": "?foo",
|
||||
"safe colon": ":foo",
|
||||
"safe dash": "-foo"
|
||||
},
|
||||
"line1 line2 line3\n",
|
||||
["Mark McGwire", "Sammy Sosa", "Ken Griffey"],
|
||||
["a"],
|
||||
["a", ["b", "c"]],
|
||||
{
|
||||
"unicode": "Sosa did fine.☺",
|
||||
"control": "\b1998\t1999\t2000\n",
|
||||
"hex esc": "\r\n is \r\n",
|
||||
"single": "\"Howdy!\" he cried.",
|
||||
"quoted": " # Not a 'comment'.",
|
||||
"tie-fighter": "|\\-*-/|"
|
||||
},
|
||||
[["-", "-"]],
|
||||
"folded text\n",
|
||||
{
|
||||
"a": 13,
|
||||
"1.5": "d"
|
||||
},
|
||||
{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"text": "a\n \nb\n\nc\n\nd\n"
|
||||
},
|
||||
{
|
||||
"wanted": "love ♥ and peace ☮"
|
||||
},
|
||||
{
|
||||
"name": "Mark McGwire",
|
||||
"accomplishment": "Mark set a major league home run record in 1998.\n",
|
||||
"stats": "65 Home Runs\n0.278 Batting Average\n"
|
||||
},
|
||||
{
|
||||
"foo": "bar",
|
||||
"baz": "foo"
|
||||
},
|
||||
"1st non-empty\n2nd non-empty 3rd non-empty",
|
||||
{
|
||||
"quoted": "Quoted \t",
|
||||
"block": "void main() {\n\tprintf(\"Hello, world!\\n\");\n}\n"
|
||||
},
|
||||
{
|
||||
"foo": "blue",
|
||||
"bar": "arrr",
|
||||
"baz": "jazz"
|
||||
},
|
||||
[
|
||||
{
|
||||
"Mark McGwire": 65
|
||||
},
|
||||
{
|
||||
"Sammy Sosa": 63
|
||||
},
|
||||
{
|
||||
"Ken Griffy": 58
|
||||
}
|
||||
],
|
||||
{
|
||||
"1": 2,
|
||||
"3": 4
|
||||
},
|
||||
{
|
||||
"hr": ["Mark McGwire", "Sammy Sosa"],
|
||||
"rbi": ["Sammy Sosa", "Ken Griffey"]
|
||||
},
|
||||
"k:#foo &a !t s",
|
||||
{
|
||||
"block sequence": [
|
||||
"one",
|
||||
{
|
||||
"two": "three"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"First occurrence": "Value",
|
||||
"Second occurrence": "Value"
|
||||
},
|
||||
{
|
||||
"a true": "null d",
|
||||
"e 42": null
|
||||
},
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
["foo", "bar", 42],
|
||||
"trimmed\n\n\nas space",
|
||||
"scalar",
|
||||
{
|
||||
"strip": "",
|
||||
"clip": "",
|
||||
"keep": "\n"
|
||||
},
|
||||
{
|
||||
"foo": {
|
||||
"bar": 1
|
||||
},
|
||||
"baz": 2
|
||||
},
|
||||
{
|
||||
"a": 47,
|
||||
"c": "d"
|
||||
},
|
||||
{
|
||||
"implicit block key": [
|
||||
{
|
||||
"implicit flow key": "value"
|
||||
}
|
||||
]
|
||||
},
|
||||
["a", "b", "c", "c", ""],
|
||||
[
|
||||
["a", "b", "c"],
|
||||
{
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
"e": "f"
|
||||
},
|
||||
[]
|
||||
],
|
||||
{
|
||||
"implicit block key": [
|
||||
{
|
||||
"implicit flow key": "value"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"a": "ab\n\ncd\nef\n"
|
||||
},
|
||||
{
|
||||
"literal": "value\n",
|
||||
"folded": "value\n"
|
||||
},
|
||||
{
|
||||
"a": [
|
||||
"b",
|
||||
"c",
|
||||
{
|
||||
"d": ["e", "f"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"literal\n\ttext\n",
|
||||
"foo \n\n\t bar\n\nbaz\n",
|
||||
[
|
||||
{
|
||||
"a": "b"
|
||||
}
|
||||
],
|
||||
"ab",
|
||||
["plain", "double quoted", "single quoted", "block\n", "plain again"],
|
||||
{
|
||||
"a": " ",
|
||||
"b": " ",
|
||||
"c": " ",
|
||||
"d": " ",
|
||||
"e": "\n",
|
||||
"f": "\n",
|
||||
"g": "\n\n",
|
||||
"h": "\n\n"
|
||||
},
|
||||
{
|
||||
"key": "value with\ntabs"
|
||||
},
|
||||
{
|
||||
"": null
|
||||
},
|
||||
[
|
||||
{
|
||||
"single line": "value"
|
||||
},
|
||||
{
|
||||
"multi line": "value"
|
||||
}
|
||||
],
|
||||
"folded to a space,\nto a line feed, or \t \tnon-content",
|
||||
["literal\n", " folded\n", "keep\n\n", " strip"],
|
||||
{
|
||||
"key": "value"
|
||||
},
|
||||
{
|
||||
"american": ["Boston Red Sox", "Detroit Tigers", "New York Yankees"],
|
||||
"national": ["New York Mets", "Chicago Cubs", "Atlanta Braves"]
|
||||
},
|
||||
" 1st non-empty\n2nd non-empty 3rd non-empty ",
|
||||
{},
|
||||
[
|
||||
["a", "b"],
|
||||
{
|
||||
"a": "b"
|
||||
},
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
],
|
||||
"folded to a space,\nto a line feed, or \t \tnon-content",
|
||||
[
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
],
|
||||
["detected\n", "\n\n# detected\n", " explicit\n", "\t\ndetected\n"],
|
||||
{
|
||||
"top1": [
|
||||
"item1",
|
||||
{
|
||||
"key2": "value2"
|
||||
},
|
||||
"item3"
|
||||
],
|
||||
"top2": "value2"
|
||||
},
|
||||
{
|
||||
"foo": [42],
|
||||
"bar": [44]
|
||||
},
|
||||
{
|
||||
"23": "d",
|
||||
"a": 4.2
|
||||
},
|
||||
"Document",
|
||||
{
|
||||
"Date": "2001-11-23 15:03:17 -5",
|
||||
"User": "ed",
|
||||
"Fatal": "Unknown variable \"bar\"",
|
||||
"Stack": [
|
||||
{
|
||||
"file": "TopClass.py",
|
||||
"line": 23,
|
||||
"code": "x = MoreObject(\"345\\n\")\n"
|
||||
},
|
||||
{ "file": "MoreClass.py", "line": 58, "code": "foo = bar" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"plain key": "in-line value",
|
||||
"": null,
|
||||
"quoted key": ["entry"]
|
||||
},
|
||||
["12", 12, "12"],
|
||||
{
|
||||
"aaa": "bbb"
|
||||
},
|
||||
[":,"],
|
||||
{
|
||||
"sequence": ["one", "two"],
|
||||
"mapping": {
|
||||
"sky": "blue",
|
||||
"sea": "green"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": ["a", "b"]
|
||||
},
|
||||
"here's to \"quotes\"",
|
||||
{
|
||||
"hr": 65,
|
||||
"avg": 0.278,
|
||||
"rbi": 147
|
||||
},
|
||||
"\n\nliteral\n \n\ntext\n",
|
||||
" 1st non-empty\n2nd non-empty 3rd non-empty ",
|
||||
"literal\n\ttext\n",
|
||||
{
|
||||
"block mapping": {
|
||||
"key": "value"
|
||||
}
|
||||
},
|
||||
" foo\nbar\nbaz ",
|
||||
"ab cd\nef\n\ngh\n",
|
||||
"foo",
|
||||
{
|
||||
"top1": {
|
||||
"key1": "one"
|
||||
},
|
||||
"top2": {
|
||||
"key2": "two"
|
||||
},
|
||||
"top3": {
|
||||
"key3": "three"
|
||||
},
|
||||
"top4": {
|
||||
"key4": "four"
|
||||
},
|
||||
"top5": {
|
||||
"key5": "five"
|
||||
},
|
||||
"top6": "six",
|
||||
"top7": "seven"
|
||||
},
|
||||
[
|
||||
{
|
||||
"url": "http://example.org"
|
||||
}
|
||||
],
|
||||
{
|
||||
"sequence": ["one", "two"],
|
||||
"mapping": {
|
||||
"sky": "blue",
|
||||
"sea": "green"
|
||||
}
|
||||
},
|
||||
{
|
||||
"invoice": 34843,
|
||||
"date": "2001-01-23",
|
||||
"bill-to": {
|
||||
"given": "Chris",
|
||||
"family": "Dumars",
|
||||
"address": {
|
||||
"lines": "458 Walkman Dr.\nSuite #292\n",
|
||||
"city": "Royal Oak",
|
||||
"state": "MI",
|
||||
"postal": 48046
|
||||
}
|
||||
},
|
||||
"ship-to": {
|
||||
"given": "Chris",
|
||||
"family": "Dumars",
|
||||
"address": {
|
||||
"lines": "458 Walkman Dr.\nSuite #292\n",
|
||||
"city": "Royal Oak",
|
||||
"state": "MI",
|
||||
"postal": 48046
|
||||
}
|
||||
},
|
||||
"product": [
|
||||
{
|
||||
"sku": "BL394D",
|
||||
"quantity": 4,
|
||||
"description": "Basketball",
|
||||
"price": 450
|
||||
},
|
||||
{
|
||||
"sku": "BL4438H",
|
||||
"quantity": 1,
|
||||
"description": "Super Hoop",
|
||||
"price": 2392
|
||||
}
|
||||
],
|
||||
"tax": 251.42,
|
||||
"total": 4443.52,
|
||||
"comments": "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."
|
||||
},
|
||||
["a", "b", "a", "b"],
|
||||
[
|
||||
null,
|
||||
"block node\n",
|
||||
["one", "two"],
|
||||
{
|
||||
"one": "two"
|
||||
}
|
||||
],
|
||||
{
|
||||
"a": "scalar a",
|
||||
"b": "scalar a"
|
||||
},
|
||||
{
|
||||
"foo": "",
|
||||
"": "bar"
|
||||
},
|
||||
{
|
||||
"key": "value"
|
||||
},
|
||||
"scalar %YAML 1.2",
|
||||
{
|
||||
"Folding": "Empty line\nas a line feed",
|
||||
"Chomping": "Clipped empty lines\n"
|
||||
},
|
||||
{
|
||||
"key": "value"
|
||||
},
|
||||
[
|
||||
["name", "hr", "avg"],
|
||||
["Mark McGwire", 65, 0.278],
|
||||
["Sammy Sosa", 63, 0.288]
|
||||
],
|
||||
{
|
||||
"literal": "value\n",
|
||||
"folded": "value\n"
|
||||
},
|
||||
{
|
||||
"Mark McGwire": {
|
||||
"hr": 65,
|
||||
"avg": 0.278
|
||||
},
|
||||
"Sammy Sosa": {
|
||||
"hr": 63,
|
||||
"avg": 0.288
|
||||
}
|
||||
},
|
||||
{
|
||||
"a": "b",
|
||||
"c": "d"
|
||||
},
|
||||
{
|
||||
"key": [[["value"]]]
|
||||
},
|
||||
{
|
||||
"a": 1,
|
||||
"b": null,
|
||||
"c": 3
|
||||
},
|
||||
{
|
||||
"event": "outgoing HTTP response",
|
||||
"timestamp": "2021-01-21T18:44:57.116Z",
|
||||
"remoteAddress": "127.0.0.1",
|
||||
"deviceId": "202BC1-BM632w-000000",
|
||||
"connection": "2021-01-21T18:44:57.105Z",
|
||||
"statusCode": 200,
|
||||
"headers": {
|
||||
"content-length": 528,
|
||||
"server": "GenieACS/1.2.3+20210121000910",
|
||||
"soapserver": "GenieACS/1.2.3+20210121000910",
|
||||
"content-type": "text/xml; charset=\"utf-8\"",
|
||||
"set-cookie": "session=ea31d97ccf6832fb"
|
||||
},
|
||||
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soap-env:Envelope xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:cwmp=\"urn:dslforum-org:cwmp-1-0\"><soap-env:Header><cwmp:ID soap-env:mustUnderstand=\"1\">wdsx50vq</cwmp:ID></soap-env:Header><soap-env:Body><cwmp:InformResponse><MaxEnvelopes>1</MaxEnvelopes></cwmp:InformResponse></soap-env:Body></soap-env:Envelope>"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
import ava from "ava";
|
||||
import * as yaml from "yaml";
|
||||
import { stringify } from "../lib/common/yaml";
|
||||
|
||||
import testCases from "./yaml-tests.json";
|
||||
|
||||
ava("stringify", (t) => {
|
||||
for (const testCase of testCases) {
|
||||
let str = stringify(testCase);
|
||||
if (str.startsWith(">2")) str = ">3" + str.slice(2);
|
||||
if (str.startsWith("|2")) str = "|3" + str.slice(2);
|
||||
t.deepEqual(yaml.parse(yaml.stringify(testCase)), yaml.parse(str));
|
||||
}
|
||||
});
|
||||
@@ -22,6 +22,7 @@ import { m } from "../components";
|
||||
import * as store from "../store";
|
||||
import * as notifications from "../notifications";
|
||||
import { getIcon } from "../icons";
|
||||
import { stringify } from "../../lib/common/yaml";
|
||||
|
||||
const component: ClosureComponent = (): Component => {
|
||||
return {
|
||||
@@ -38,6 +39,7 @@ const component: ClosureComponent = (): Component => {
|
||||
"Channel",
|
||||
"Code",
|
||||
"Message",
|
||||
"Detail",
|
||||
"Retries",
|
||||
"Timestamp",
|
||||
].map((l) => m("th", l));
|
||||
@@ -48,7 +50,9 @@ const component: ClosureComponent = (): Component => {
|
||||
rows.push([
|
||||
m("td", f["channel"]),
|
||||
m("td", f["code"]),
|
||||
m("td", f["message"]),
|
||||
m("td", m("long-text", { text: f["message"] })),
|
||||
m("td", m("long-text", { text: stringify(f["detail"]) })),
|
||||
|
||||
m("td", f["retries"]),
|
||||
m("td", new Date(f["timestamp"]).toLocaleString()),
|
||||
m(
|
||||
|
||||
+6
-9
@@ -27,7 +27,7 @@ import * as notifications from "./notifications";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import { map, parse, stringify } from "../lib/common/expression-parser";
|
||||
import { loadYaml, yaml } from "./dynamic-loader";
|
||||
import { stringify as yamlStringify } from "../lib/common/yaml";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
@@ -76,13 +76,7 @@ export function init(
|
||||
|
||||
const sort = args.hasOwnProperty("sort") ? "" + args["sort"] : "";
|
||||
const filter = args.hasOwnProperty("filter") ? "" + args["filter"] : "";
|
||||
return new Promise((resolve, reject) => {
|
||||
loadYaml()
|
||||
.then(() => {
|
||||
resolve({ filter, sort });
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
return Promise.resolve({ filter, sort });
|
||||
}
|
||||
|
||||
export const component: ClosureComponent = (): Component => {
|
||||
@@ -147,8 +141,11 @@ export const component: ClosureComponent = (): Component => {
|
||||
return m("a", { href: deviceHref }, fault["device"]);
|
||||
}
|
||||
|
||||
if (attr.id === "message")
|
||||
return m("long-text", { text: fault["message"] });
|
||||
|
||||
if (attr.id === "detail")
|
||||
return m("long-text", { text: yaml.stringify(fault["detail"]) });
|
||||
return m("long-text", { text: yamlStringify(fault["detail"]) });
|
||||
|
||||
if (attr.id === "timestamp")
|
||||
return new Date(fault["timestamp"]).toLocaleString();
|
||||
|
||||
Reference in new issue
Block a user