iproutejs 2.3.1 → 2.3.2
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.
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
* Robust parser for `ip -json` command output.
|
|
3
3
|
*
|
|
4
4
|
* Some iproute2 versions do not produce a valid JSON array but instead output
|
|
5
|
-
* objects separated by newlines (NDJSON),
|
|
6
|
-
* separated by newlines without commas
|
|
5
|
+
* objects separated by newlines (NDJSON), a JSON array where elements are
|
|
6
|
+
* separated by newlines without commas, or JSON interleaved with plain-text
|
|
7
|
+
* statistics (e.g. RX/TX tables from `-statistics`).
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* 2. NDJSON – `{...}\n{...}` or `[...]\n[...]`
|
|
10
|
-
* 3. Array w/o commas – `[{...}\n{...}]`
|
|
9
|
+
* This function tries four strategies in order:
|
|
11
10
|
*
|
|
12
|
-
*
|
|
11
|
+
* 1. Standard JSON – `[{...},{...}]`
|
|
12
|
+
* 2. Strip non-JSON lines – remove plain-text (RX/TX stats), retry JSON
|
|
13
|
+
* 3. NDJSON – `{...}\n{...}` or `[...]\n[...]`
|
|
14
|
+
* 4. Array w/o commas – `[{...}\n{...}]`
|
|
15
|
+
*
|
|
16
|
+
* Throws `SyntaxError` only if all four strategies fail.
|
|
13
17
|
*/
|
|
14
18
|
export declare function parseCommandOutput<T>(stdout: string): T;
|
|
@@ -5,14 +5,18 @@ exports.parseCommandOutput = void 0;
|
|
|
5
5
|
* Robust parser for `ip -json` command output.
|
|
6
6
|
*
|
|
7
7
|
* Some iproute2 versions do not produce a valid JSON array but instead output
|
|
8
|
-
* objects separated by newlines (NDJSON),
|
|
9
|
-
* separated by newlines without commas
|
|
8
|
+
* objects separated by newlines (NDJSON), a JSON array where elements are
|
|
9
|
+
* separated by newlines without commas, or JSON interleaved with plain-text
|
|
10
|
+
* statistics (e.g. RX/TX tables from `-statistics`).
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
* 2. NDJSON – `{...}\n{...}` or `[...]\n[...]`
|
|
13
|
-
* 3. Array w/o commas – `[{...}\n{...}]`
|
|
12
|
+
* This function tries four strategies in order:
|
|
14
13
|
*
|
|
15
|
-
*
|
|
14
|
+
* 1. Standard JSON – `[{...},{...}]`
|
|
15
|
+
* 2. Strip non-JSON lines – remove plain-text (RX/TX stats), retry JSON
|
|
16
|
+
* 3. NDJSON – `{...}\n{...}` or `[...]\n[...]`
|
|
17
|
+
* 4. Array w/o commas – `[{...}\n{...}]`
|
|
18
|
+
*
|
|
19
|
+
* Throws `SyntaxError` only if all four strategies fail.
|
|
16
20
|
*/
|
|
17
21
|
function parseCommandOutput(stdout) {
|
|
18
22
|
const trimmed = stdout.trim();
|
|
@@ -24,9 +28,26 @@ function parseCommandOutput(stdout) {
|
|
|
24
28
|
return JSON.parse(trimmed);
|
|
25
29
|
}
|
|
26
30
|
catch ( /* fall through */_a) { /* fall through */ }
|
|
27
|
-
// 2.
|
|
31
|
+
// 2. Strip non-JSON lines (e.g. RX/TX plain-text statistics from `ip -statistics`)
|
|
32
|
+
// and retry. JSON-relevant lines start with [ ] { } , or "
|
|
33
|
+
const stripped = trimmed
|
|
34
|
+
.split('\n')
|
|
35
|
+
.filter(line => {
|
|
36
|
+
const l = line.trim();
|
|
37
|
+
return !l || /^[\[{\]},"]/.test(l);
|
|
38
|
+
})
|
|
39
|
+
.join('\n')
|
|
40
|
+
.trim();
|
|
41
|
+
if (stripped && stripped !== trimmed) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(stripped);
|
|
44
|
+
}
|
|
45
|
+
catch ( /* fall through */_b) { /* fall through */ }
|
|
46
|
+
}
|
|
47
|
+
// 3. NDJSON — one JSON value per line (use stripped version if available)
|
|
48
|
+
const source = stripped || trimmed;
|
|
28
49
|
const fromLines = [];
|
|
29
|
-
for (const line of
|
|
50
|
+
for (const line of source.split('\n')) {
|
|
30
51
|
const l = line.trim();
|
|
31
52
|
if (!l)
|
|
32
53
|
continue;
|
|
@@ -34,17 +55,17 @@ function parseCommandOutput(stdout) {
|
|
|
34
55
|
const parsed = JSON.parse(l);
|
|
35
56
|
Array.isArray(parsed) ? fromLines.push(...parsed) : fromLines.push(parsed);
|
|
36
57
|
}
|
|
37
|
-
catch ( /* skip unparseable lines */
|
|
58
|
+
catch ( /* skip unparseable lines */_c) { /* skip unparseable lines */ }
|
|
38
59
|
}
|
|
39
60
|
if (fromLines.length > 0) {
|
|
40
61
|
return fromLines;
|
|
41
62
|
}
|
|
42
|
-
//
|
|
63
|
+
// 4. JSON array with missing commas between objects
|
|
43
64
|
try {
|
|
44
|
-
const fixed =
|
|
65
|
+
const fixed = source.replace(/\}\s*\n\s*\{/g, '},{');
|
|
45
66
|
return JSON.parse(fixed);
|
|
46
67
|
}
|
|
47
|
-
catch ( /* fall through */
|
|
68
|
+
catch ( /* fall through */_d) { /* fall through */ }
|
|
48
69
|
throw new SyntaxError(`parseCommandOutput: failed to parse ip command output: ${trimmed.slice(0, 300)}`);
|
|
49
70
|
}
|
|
50
71
|
exports.parseCommandOutput = parseCommandOutput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-output.js","sourceRoot":"","sources":["../../src/common/parse-output.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"parse-output.js","sourceRoot":"","sources":["../../src/common/parse-output.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,kBAAkB,CAAI,MAAc;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,EAAkB,CAAC;KAC3B;IAED,oCAAoC;IACpC,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC5B;IAAC,QAAQ,kBAAkB,IAApB,EAAE,kBAAkB,EAAE;IAE9B,mFAAmF;IACnF,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,OAAO;SACrB,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,IAAI,CAAC,EAAE;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;IAEV,IAAI,QAAQ,IAAI,QAAQ,KAAK,OAAO,EAAE;QACpC,IAAI;YACF,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;SAC7B;QAAC,QAAQ,kBAAkB,IAApB,EAAE,kBAAkB,EAAE;KAC/B;IAED,0EAA0E;IAC1E,MAAM,MAAM,GAAG,QAAQ,IAAI,OAAO,CAAC;IACnC,MAAM,SAAS,GAAc,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC5E;QAAC,QAAQ,4BAA4B,IAA9B,EAAE,4BAA4B,EAAE;KACzC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;QACxB,OAAO,SAAyB,CAAC;KAClC;IAED,oDAAoD;IACpD,IAAI;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;KAC1B;IAAC,QAAQ,kBAAkB,IAApB,EAAE,kBAAkB,EAAE;IAE9B,MAAM,IAAI,WAAW,CACnB,0DAA0D,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAClF,CAAC;AACJ,CAAC;AArDD,gDAqDC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iproutejs",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Show and manipulate network devices, addresses, routing, policy routing, tunnels, IP forwarding, address labels and other `iproute` objects.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"tuntap",
|
|
46
46
|
"maddress",
|
|
47
47
|
"mroute",
|
|
48
|
-
|
|
48
|
+
"batch"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"ajv": "^8.12.0",
|