cborg 1.4.2 → 1.5.3
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/cjs/browser-test/node-test-bin.js +133 -50
- package/cjs/browser-test/test-0uint.js +1 -1
- package/cjs/browser-test/test-1negint.js +1 -1
- package/cjs/browser-test/test-2bytes.js +1 -1
- package/cjs/browser-test/test-3string.js +1 -1
- package/cjs/browser-test/test-4array.js +1 -1
- package/cjs/browser-test/test-5map.js +1 -1
- package/cjs/browser-test/test-6tag.js +1 -1
- package/cjs/browser-test/test-7float.js +1 -1
- package/cjs/browser-test/test-bl.js +1 -1
- package/cjs/browser-test/test-cbor-vectors.js +1 -1
- package/cjs/browser-test/test-decode-errors.js +1 -1
- package/cjs/browser-test/test-fuzz.js +1 -1
- package/cjs/lib/bin.js +100 -37
- package/cjs/node-test/node-test-bin.js +133 -50
- package/cjs/node-test/test-0uint.js +1 -1
- package/cjs/node-test/test-1negint.js +1 -1
- package/cjs/node-test/test-2bytes.js +1 -1
- package/cjs/node-test/test-3string.js +1 -1
- package/cjs/node-test/test-4array.js +1 -1
- package/cjs/node-test/test-5map.js +1 -1
- package/cjs/node-test/test-6tag.js +1 -1
- package/cjs/node-test/test-7float.js +1 -1
- package/cjs/node-test/test-bl.js +1 -1
- package/cjs/node-test/test-cbor-vectors.js +1 -1
- package/cjs/node-test/test-decode-errors.js +1 -1
- package/cjs/node-test/test-fuzz.js +1 -1
- package/esm/browser-test/node-test-bin.js +131 -48
- package/esm/lib/bin.js +99 -36
- package/esm/node-test/node-test-bin.js +131 -48
- package/lib/bin.js +125 -40
- package/package.json +1 -1
- package/test/node-test-bin.js +155 -50
- package/types/lib/common.d.ts +1 -1
- package/types/lib/common.d.ts.map +1 -1
package/esm/lib/bin.js
CHANGED
|
@@ -5,51 +5,114 @@ import {
|
|
|
5
5
|
} from '../cborg.js';
|
|
6
6
|
import { tokensToDiagnostic } from './diagnostic.js';
|
|
7
7
|
import {
|
|
8
|
-
fromHex,
|
|
8
|
+
fromHex as _fromHex,
|
|
9
9
|
toHex
|
|
10
10
|
} from './byte-utils.js';
|
|
11
|
-
const cmd = process.argv[2];
|
|
12
11
|
function usage(code) {
|
|
13
12
|
console.error('Usage: cborg <command> <args>');
|
|
14
13
|
console.error('Valid commands:');
|
|
15
|
-
console.error('\thex2diag
|
|
16
|
-
console.error('\
|
|
17
|
-
console.error('\
|
|
14
|
+
console.error('\thex2diag [hex input]');
|
|
15
|
+
console.error('\thex2bin [hex input]');
|
|
16
|
+
console.error('\thex2json [--pretty] [hex input]');
|
|
17
|
+
console.error('\tbin2hex [binary input]');
|
|
18
|
+
console.error('\tbin2diag [binary input]');
|
|
19
|
+
console.error('\tbin2json [--pretty] [binary input]');
|
|
20
|
+
console.error('\tjson2hex \'[json input]\'');
|
|
21
|
+
console.error('\tjson2diag \'[json input]\'');
|
|
22
|
+
console.error('\tjson2bin \'[json input]\'');
|
|
23
|
+
console.error('Input may either be supplied as an argument or piped via stdin');
|
|
18
24
|
process.exit(code || 0);
|
|
19
25
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const pretty = argv.length !== process.argv.length;
|
|
25
|
-
if (argv.length < 4) {
|
|
26
|
-
console.error('hex2json requires a hexadecimal input string');
|
|
27
|
-
usage(1);
|
|
28
|
-
}
|
|
29
|
-
const bin = fromHex(argv[3]);
|
|
30
|
-
console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined));
|
|
31
|
-
} else if (cmd === 'hex2diag') {
|
|
32
|
-
if (process.argv.length < 4) {
|
|
33
|
-
console.error('hex2diag requires a hexadecimal input string');
|
|
34
|
-
usage(1);
|
|
26
|
+
async function fromStdin() {
|
|
27
|
+
const chunks = [];
|
|
28
|
+
for await (const chunk of process.stdin) {
|
|
29
|
+
chunks.push(chunk);
|
|
35
30
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
console.error('json2hex requires a JSON input string');
|
|
43
|
-
usage(1);
|
|
31
|
+
return Buffer.concat(chunks);
|
|
32
|
+
}
|
|
33
|
+
function fromHex(str) {
|
|
34
|
+
str = str.replace(/\r?\n/g, '');
|
|
35
|
+
if (!/^([0-9a-f]{2})*$/i.test(str)) {
|
|
36
|
+
throw new Error('Input string is not hexadecimal format');
|
|
44
37
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
return _fromHex(str);
|
|
39
|
+
}
|
|
40
|
+
function argvPretty() {
|
|
41
|
+
const argv = process.argv.filter(s => s !== '--pretty');
|
|
42
|
+
const pretty = argv.length !== process.argv.length;
|
|
43
|
+
return {
|
|
44
|
+
argv,
|
|
45
|
+
pretty
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function run() {
|
|
49
|
+
const cmd = process.argv[2];
|
|
50
|
+
switch (cmd) {
|
|
51
|
+
case 'help': {
|
|
52
|
+
return usage(0);
|
|
53
|
+
}
|
|
54
|
+
case 'hex2json': {
|
|
55
|
+
const {argv, pretty} = argvPretty();
|
|
56
|
+
const bin = fromHex(argv.length < 4 ? (await fromStdin()).toString() : argv[3]);
|
|
57
|
+
return console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined));
|
|
58
|
+
}
|
|
59
|
+
case 'hex2diag': {
|
|
60
|
+
const bin = fromHex(process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3]);
|
|
61
|
+
for (const line of tokensToDiagnostic(bin)) {
|
|
62
|
+
console.log(line);
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
case 'hex2bin': {
|
|
67
|
+
const bin = fromHex(process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3]);
|
|
68
|
+
return process.stdout.write(bin);
|
|
69
|
+
}
|
|
70
|
+
case 'bin2hex': {
|
|
71
|
+
const bin = process.argv.length < 4 ? await fromStdin() : new TextEncoder().encode(process.argv[3]);
|
|
72
|
+
return console.log(toHex(bin));
|
|
73
|
+
}
|
|
74
|
+
case 'bin2json': {
|
|
75
|
+
const {argv, pretty} = argvPretty();
|
|
76
|
+
const bin = argv.length < 4 ? await fromStdin() : new TextEncoder().encode(argv[3]);
|
|
77
|
+
return console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined));
|
|
78
|
+
}
|
|
79
|
+
case 'bin2diag': {
|
|
80
|
+
const bin = process.argv.length < 4 ? await fromStdin() : new TextEncoder().encode(process.argv[3]);
|
|
81
|
+
for (const line of tokensToDiagnostic(bin)) {
|
|
82
|
+
console.log(line);
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
case 'json2hex': {
|
|
87
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3];
|
|
88
|
+
const obj = JSON.parse(inp);
|
|
89
|
+
return console.log(toHex(encode(obj)));
|
|
90
|
+
}
|
|
91
|
+
case 'json2diag': {
|
|
92
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3];
|
|
93
|
+
const obj = JSON.parse(inp);
|
|
94
|
+
for (const line of tokensToDiagnostic(encode(obj))) {
|
|
95
|
+
console.log(line);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
case 'json2bin': {
|
|
100
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3];
|
|
101
|
+
const obj = JSON.parse(inp);
|
|
102
|
+
return process.stdout.write(encode(obj));
|
|
103
|
+
}
|
|
104
|
+
default: {
|
|
105
|
+
if (process.argv.findIndex(a => a.endsWith('mocha')) === -1) {
|
|
106
|
+
if (cmd) {
|
|
107
|
+
console.error(`Unknown command: '${ cmd }'`);
|
|
108
|
+
}
|
|
109
|
+
usage(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
53
112
|
}
|
|
54
113
|
}
|
|
114
|
+
run().catch(err => {
|
|
115
|
+
console.error(err);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
|
55
118
|
export default true;
|
|
@@ -6,9 +6,12 @@ import { fileURLToPath } from 'url';
|
|
|
6
6
|
import bin from '../lib/bin.js';
|
|
7
7
|
const {assert} = chai;
|
|
8
8
|
const binPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../lib/bin.js');
|
|
9
|
-
|
|
9
|
+
function fromHex(hex) {
|
|
10
|
+
return new Uint8Array(hex.split('').map((c, i, d) => i % 2 === 0 ? `0x${ c }${ d[i + 1] }` : '').filter(Boolean).map(e => parseInt(e, 16)));
|
|
11
|
+
}
|
|
12
|
+
async function execBin(cmd, stdin) {
|
|
10
13
|
return new Promise((resolve, reject) => {
|
|
11
|
-
exec(`"${ process.execPath }" "${ binPath }" ${ cmd }`, (err, stdout, stderr) => {
|
|
14
|
+
const cp = exec(`"${ process.execPath }" "${ binPath }" ${ cmd }`, (err, stdout, stderr) => {
|
|
12
15
|
if (err) {
|
|
13
16
|
err.stdout = stdout;
|
|
14
17
|
err.stderr = stderr;
|
|
@@ -19,6 +22,12 @@ async function execBin(cmd) {
|
|
|
19
22
|
stderr
|
|
20
23
|
});
|
|
21
24
|
});
|
|
25
|
+
if (stdin != null) {
|
|
26
|
+
cp.on('spawn', () => {
|
|
27
|
+
cp.stdin.write(stdin);
|
|
28
|
+
cp.stdin.end();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
22
31
|
});
|
|
23
32
|
}
|
|
24
33
|
describe('Bin', () => {
|
|
@@ -30,9 +39,16 @@ describe('Bin', () => {
|
|
|
30
39
|
assert.strictEqual(e.stdout, '');
|
|
31
40
|
assert.strictEqual(e.stderr, `Usage: cborg <command> <args>
|
|
32
41
|
Valid commands:
|
|
33
|
-
\thex2diag
|
|
34
|
-
\
|
|
35
|
-
\
|
|
42
|
+
\thex2diag [hex input]
|
|
43
|
+
\thex2bin [hex input]
|
|
44
|
+
\thex2json [--pretty] [hex input]
|
|
45
|
+
\tbin2hex [binary input]
|
|
46
|
+
\tbin2diag [binary input]
|
|
47
|
+
\tbin2json [--pretty] [binary input]
|
|
48
|
+
\tjson2hex '[json input]'
|
|
49
|
+
\tjson2diag '[json input]'
|
|
50
|
+
\tjson2bin '[json input]'
|
|
51
|
+
Input may either be supplied as an argument or piped via stdin
|
|
36
52
|
`);
|
|
37
53
|
}
|
|
38
54
|
});
|
|
@@ -45,9 +61,16 @@ Valid commands:
|
|
|
45
61
|
assert.strictEqual(e.stderr, `Unknown command: 'blip'
|
|
46
62
|
Usage: cborg <command> <args>
|
|
47
63
|
Valid commands:
|
|
48
|
-
\thex2diag
|
|
49
|
-
\
|
|
50
|
-
\
|
|
64
|
+
\thex2diag [hex input]
|
|
65
|
+
\thex2bin [hex input]
|
|
66
|
+
\thex2json [--pretty] [hex input]
|
|
67
|
+
\tbin2hex [binary input]
|
|
68
|
+
\tbin2diag [binary input]
|
|
69
|
+
\tbin2json [--pretty] [binary input]
|
|
70
|
+
\tjson2hex '[json input]'
|
|
71
|
+
\tjson2diag '[json input]'
|
|
72
|
+
\tjson2bin '[json input]'
|
|
73
|
+
Input may either be supplied as an argument or piped via stdin
|
|
51
74
|
`);
|
|
52
75
|
}
|
|
53
76
|
});
|
|
@@ -56,27 +79,31 @@ Valid commands:
|
|
|
56
79
|
assert.strictEqual(stdout, '');
|
|
57
80
|
assert.strictEqual(stderr, `Usage: cborg <command> <args>
|
|
58
81
|
Valid commands:
|
|
59
|
-
\thex2diag
|
|
60
|
-
\
|
|
61
|
-
\
|
|
82
|
+
\thex2diag [hex input]
|
|
83
|
+
\thex2bin [hex input]
|
|
84
|
+
\thex2json [--pretty] [hex input]
|
|
85
|
+
\tbin2hex [binary input]
|
|
86
|
+
\tbin2diag [binary input]
|
|
87
|
+
\tbin2json [--pretty] [binary input]
|
|
88
|
+
\tjson2hex '[json input]'
|
|
89
|
+
\tjson2diag '[json input]'
|
|
90
|
+
\tjson2bin '[json input]'
|
|
91
|
+
Input may either be supplied as an argument or piped via stdin
|
|
62
92
|
`);
|
|
63
93
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await execBin('hex2json');
|
|
70
|
-
assert.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const {stdout, stderr} = await execBin('hex2json --pretty a3616101616282020365736d696c6564f09f9880');
|
|
78
|
-
assert.strictEqual(stderr, '');
|
|
79
|
-
assert.strictEqual(stdout, `{
|
|
94
|
+
for (const stdin of [
|
|
95
|
+
true,
|
|
96
|
+
false
|
|
97
|
+
]) {
|
|
98
|
+
it(`hex2json${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
99
|
+
const {stdout, stderr} = stdin ? await execBin('hex2json a3616101616282020365736d696c6564f09f9880') : await execBin('hex2json', 'a3616101616282020365736d696c6564f09f9880');
|
|
100
|
+
assert.strictEqual(stderr, '');
|
|
101
|
+
assert.strictEqual(stdout, '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}\n');
|
|
102
|
+
});
|
|
103
|
+
it(`hex2json pretty${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
104
|
+
const {stdout, stderr} = stdin ? await execBin('hex2json --pretty a3616101616282020365736d696c6564f09f9880') : await execBin('hex2json --pretty', 'a3616101616282020365736d696c6564f09f9880');
|
|
105
|
+
assert.strictEqual(stderr, '');
|
|
106
|
+
assert.strictEqual(stdout, `{
|
|
80
107
|
"a": 1,
|
|
81
108
|
"b": [
|
|
82
109
|
2,
|
|
@@ -85,11 +112,11 @@ Valid commands:
|
|
|
85
112
|
"smile": "😀"
|
|
86
113
|
}
|
|
87
114
|
`);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
115
|
+
});
|
|
116
|
+
it(`hex2diag${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
117
|
+
const {stdout, stderr} = stdin ? await execBin('hex2diag a4616101616282020363627566440102036165736d696c6564f09f9880') : await execBin('hex2diag', 'a4616101616282020363627566440102036165736d696c6564f09f9880');
|
|
118
|
+
assert.strictEqual(stderr, '');
|
|
119
|
+
assert.strictEqual(stdout, `a4 # map(4)
|
|
93
120
|
61 # string(1)
|
|
94
121
|
61 # "a"
|
|
95
122
|
01 # uint(1)
|
|
@@ -107,24 +134,80 @@ Valid commands:
|
|
|
107
134
|
64 f09f # string(2)
|
|
108
135
|
f09f9880 # "😀"
|
|
109
136
|
`);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assert.strictEqual(
|
|
115
|
-
|
|
116
|
-
}
|
|
137
|
+
});
|
|
138
|
+
it(`hex2bin${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
139
|
+
const {stdout, stderr} = stdin ? await execBin('hex2bin a3616101616282020365736d696c6564f09f9880') : await execBin('hex2bin', 'a3616101616282020365736d696c6564f09f9880');
|
|
140
|
+
assert.strictEqual(stderr, '');
|
|
141
|
+
assert.strictEqual(stdout, new TextDecoder().decode(fromHex('a3616101616282020365736d696c6564f09f9880')));
|
|
142
|
+
});
|
|
143
|
+
it(`json2hex${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
144
|
+
const {stdout, stderr} = stdin ? await execBin('json2hex "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2hex', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
|
|
145
|
+
assert.strictEqual(stderr, '');
|
|
146
|
+
assert.strictEqual(stdout, 'a3616101616282020365736d696c6564f09f9880\n');
|
|
147
|
+
});
|
|
148
|
+
it(`json2bin${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
149
|
+
const {stdout, stderr} = stdin ? await execBin('json2bin "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2bin', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
|
|
150
|
+
assert.strictEqual(stderr, '');
|
|
151
|
+
assert.strictEqual(stdout, new TextDecoder().decode(fromHex('a3616101616282020365736d696c6564f09f9880')));
|
|
152
|
+
});
|
|
153
|
+
it(`json2diag${ stdin ? ' (stdin)' : '' }`, async () => {
|
|
154
|
+
const {stdout, stderr} = stdin ? await execBin('json2diag "{\\"a\\":1,\\"b\\":[2,3],\\"smile\\":\\"\uD83D\uDE00\\"}"') : await execBin('json2diag', '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}');
|
|
155
|
+
assert.strictEqual(stderr, '');
|
|
156
|
+
assert.strictEqual(stdout, `a3 # map(3)
|
|
157
|
+
61 # string(1)
|
|
158
|
+
61 # "a"
|
|
159
|
+
01 # uint(1)
|
|
160
|
+
61 # string(1)
|
|
161
|
+
62 # "b"
|
|
162
|
+
82 # array(2)
|
|
163
|
+
02 # uint(2)
|
|
164
|
+
03 # uint(3)
|
|
165
|
+
65 # string(5)
|
|
166
|
+
736d696c65 # "smile"
|
|
167
|
+
64 f09f # string(2)
|
|
168
|
+
f09f9880 # "😀"
|
|
169
|
+
`);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
it('bin2diag (stdin)', async () => {
|
|
173
|
+
const {stdout, stderr} = await execBin('bin2diag', fromHex('a3616101616282020365736d696c6564f09f9880'));
|
|
174
|
+
assert.strictEqual(stderr, '');
|
|
175
|
+
assert.strictEqual(stdout, `a3 # map(3)
|
|
176
|
+
61 # string(1)
|
|
177
|
+
61 # "a"
|
|
178
|
+
01 # uint(1)
|
|
179
|
+
61 # string(1)
|
|
180
|
+
62 # "b"
|
|
181
|
+
82 # array(2)
|
|
182
|
+
02 # uint(2)
|
|
183
|
+
03 # uint(3)
|
|
184
|
+
65 # string(5)
|
|
185
|
+
736d696c65 # "smile"
|
|
186
|
+
64 f09f # string(2)
|
|
187
|
+
f09f9880 # "😀"
|
|
188
|
+
`);
|
|
189
|
+
});
|
|
190
|
+
it('bin2json (stdin)', async () => {
|
|
191
|
+
const {stdout, stderr} = await execBin('bin2json', fromHex('a3616101616282020365736d696c6564f09f9880'));
|
|
192
|
+
assert.strictEqual(stderr, '');
|
|
193
|
+
assert.strictEqual(stdout, '{"a":1,"b":[2,3],"smile":"\uD83D\uDE00"}\n');
|
|
194
|
+
});
|
|
195
|
+
it('bin2json pretty (stdin)', async () => {
|
|
196
|
+
const {stdout, stderr} = await execBin('bin2json --pretty', fromHex('a3616101616282020365736d696c6564f09f9880'));
|
|
197
|
+
assert.strictEqual(stderr, '');
|
|
198
|
+
assert.strictEqual(stdout, `{
|
|
199
|
+
"a": 1,
|
|
200
|
+
"b": [
|
|
201
|
+
2,
|
|
202
|
+
3
|
|
203
|
+
],
|
|
204
|
+
"smile": "😀"
|
|
205
|
+
}
|
|
206
|
+
`);
|
|
117
207
|
});
|
|
118
|
-
it('
|
|
119
|
-
const {stdout, stderr} = await execBin('
|
|
208
|
+
it('bin2hex (stdin)', async () => {
|
|
209
|
+
const {stdout, stderr} = await execBin('bin2hex', fromHex('a3616101616282020365736d696c6564f09f9880'));
|
|
120
210
|
assert.strictEqual(stderr, '');
|
|
121
211
|
assert.strictEqual(stdout, 'a3616101616282020365736d696c6564f09f9880\n');
|
|
122
|
-
try {
|
|
123
|
-
await execBin('json2hex');
|
|
124
|
-
assert.fail('should have errored');
|
|
125
|
-
} catch (e) {
|
|
126
|
-
assert.strictEqual(e.stdout, '');
|
|
127
|
-
assert.isTrue(e.stderr.startsWith('json2hex requires a JSON input string\nUsage: '));
|
|
128
|
-
}
|
|
129
212
|
});
|
|
130
213
|
});
|
package/lib/bin.js
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
import process from 'process'
|
|
4
4
|
import { decode, encode } from '../cborg.js'
|
|
5
5
|
import { tokensToDiagnostic } from './diagnostic.js'
|
|
6
|
-
import { fromHex, toHex } from './byte-utils.js'
|
|
7
|
-
|
|
8
|
-
const cmd = process.argv[2]
|
|
6
|
+
import { fromHex as _fromHex, toHex } from './byte-utils.js'
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* @param {number} code
|
|
@@ -13,50 +11,137 @@ const cmd = process.argv[2]
|
|
|
13
11
|
function usage (code) {
|
|
14
12
|
console.error('Usage: cborg <command> <args>')
|
|
15
13
|
console.error('Valid commands:')
|
|
16
|
-
console.error('\thex2diag
|
|
17
|
-
console.error('\
|
|
18
|
-
console.error('\
|
|
14
|
+
console.error('\thex2diag [hex input]')
|
|
15
|
+
console.error('\thex2bin [hex input]')
|
|
16
|
+
console.error('\thex2json [--pretty] [hex input]')
|
|
17
|
+
console.error('\tbin2hex [binary input]')
|
|
18
|
+
console.error('\tbin2diag [binary input]')
|
|
19
|
+
console.error('\tbin2json [--pretty] [binary input]')
|
|
20
|
+
console.error('\tjson2hex \'[json input]\'')
|
|
21
|
+
console.error('\tjson2diag \'[json input]\'')
|
|
22
|
+
console.error('\tjson2bin \'[json input]\'')
|
|
23
|
+
console.error('Input may either be supplied as an argument or piped via stdin')
|
|
19
24
|
process.exit(code || 0)
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const pretty = argv.length !== process.argv.length
|
|
27
|
-
if (argv.length < 4) {
|
|
28
|
-
console.error('hex2json requires a hexadecimal input string')
|
|
29
|
-
usage(1)
|
|
30
|
-
}
|
|
31
|
-
const bin = fromHex(argv[3])
|
|
32
|
-
console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined))
|
|
33
|
-
} else if (cmd === 'hex2diag') {
|
|
34
|
-
if (process.argv.length < 4) {
|
|
35
|
-
console.error('hex2diag requires a hexadecimal input string')
|
|
36
|
-
usage(1)
|
|
37
|
-
}
|
|
38
|
-
const bin = fromHex(process.argv[3])
|
|
39
|
-
for (const line of tokensToDiagnostic(bin)) {
|
|
40
|
-
console.log(line)
|
|
27
|
+
async function fromStdin () {
|
|
28
|
+
const chunks = []
|
|
29
|
+
for await (const chunk of process.stdin) {
|
|
30
|
+
chunks.push(chunk)
|
|
41
31
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
return Buffer.concat(chunks)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} str
|
|
37
|
+
* @returns {Uint8Array}
|
|
38
|
+
*/
|
|
39
|
+
function fromHex (str) {
|
|
40
|
+
str = str.replace(/\r?\n/g, '') // let's be charitable
|
|
41
|
+
/* c8 ignore next 3 */
|
|
42
|
+
if (!(/^([0-9a-f]{2})*$/i).test(str)) {
|
|
43
|
+
throw new Error('Input string is not hexadecimal format')
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
return _fromHex(str)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function argvPretty () {
|
|
49
|
+
const argv = process.argv.filter((s) => s !== '--pretty')
|
|
50
|
+
const pretty = argv.length !== process.argv.length
|
|
51
|
+
return { argv, pretty }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function run () {
|
|
55
|
+
const cmd = process.argv[2]
|
|
56
|
+
|
|
57
|
+
switch (cmd) {
|
|
58
|
+
case 'help': {
|
|
59
|
+
return usage(0)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case 'hex2json': {
|
|
63
|
+
const { argv, pretty } = argvPretty()
|
|
64
|
+
const bin = fromHex(argv.length < 4 ? (await fromStdin()).toString() : argv[3])
|
|
65
|
+
return console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
case 'hex2diag': {
|
|
69
|
+
const bin = fromHex(process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3])
|
|
70
|
+
for (const line of tokensToDiagnostic(bin)) {
|
|
71
|
+
console.log(line)
|
|
72
|
+
}
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
case 'hex2bin': {
|
|
77
|
+
// this is really nothing to do with cbor.. just handy
|
|
78
|
+
const bin = fromHex(process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3])
|
|
79
|
+
return process.stdout.write(bin)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case 'bin2hex': {
|
|
83
|
+
// this is really nothing to do with cbor.. just handy
|
|
84
|
+
/* c8 ignore next 1 */
|
|
85
|
+
const bin = process.argv.length < 4 ? (await fromStdin()) : new TextEncoder().encode(process.argv[3])
|
|
86
|
+
return console.log(toHex(bin))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
case 'bin2json': {
|
|
90
|
+
const { argv, pretty } = argvPretty()
|
|
91
|
+
/* c8 ignore next 1 */
|
|
92
|
+
const bin = argv.length < 4 ? (await fromStdin()) : new TextEncoder().encode(argv[3])
|
|
93
|
+
return console.log(JSON.stringify(decode(bin), undefined, pretty ? 2 : undefined))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
case 'bin2diag': {
|
|
97
|
+
/* c8 ignore next 1 */
|
|
98
|
+
const bin = process.argv.length < 4 ? (await fromStdin()) : new TextEncoder().encode(process.argv[3])
|
|
99
|
+
for (const line of tokensToDiagnostic(bin)) {
|
|
100
|
+
console.log(line)
|
|
101
|
+
}
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case 'json2hex': {
|
|
106
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3]
|
|
107
|
+
const obj = JSON.parse(inp)
|
|
108
|
+
return console.log(toHex(encode(obj)))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
case 'json2diag': {
|
|
112
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3]
|
|
113
|
+
const obj = JSON.parse(inp)
|
|
114
|
+
for (const line of tokensToDiagnostic(encode(obj))) {
|
|
115
|
+
console.log(line)
|
|
116
|
+
}
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
case 'json2bin': {
|
|
121
|
+
const inp = process.argv.length < 4 ? (await fromStdin()).toString() : process.argv[3]
|
|
122
|
+
const obj = JSON.parse(inp)
|
|
123
|
+
return process.stdout.write(encode(obj))
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
default: { // no, or unknown cmd
|
|
127
|
+
// this is a dirty hack to allow import of this package by the tests
|
|
128
|
+
// for inclusion in ipjs bundling, but to silently ignore it so we don't
|
|
129
|
+
// print usage and exit(1).
|
|
130
|
+
if (process.argv.findIndex((a) => a.endsWith('mocha')) === -1) {
|
|
131
|
+
if (cmd) {
|
|
132
|
+
console.error(`Unknown command: '${cmd}'`)
|
|
133
|
+
}
|
|
134
|
+
usage(1)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
58
137
|
}
|
|
59
138
|
}
|
|
60
139
|
|
|
140
|
+
run().catch((err) => {
|
|
141
|
+
/* c8 ignore next 2 */
|
|
142
|
+
console.error(err)
|
|
143
|
+
process.exit(1)
|
|
144
|
+
})
|
|
145
|
+
|
|
61
146
|
// for ipjs, to get it to compile
|
|
62
147
|
export default true
|