-
Notifications
You must be signed in to change notification settings - Fork 29
/
post.js
116 lines (91 loc) · 2.73 KB
/
post.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/** @format */
const NEWLINE = 0xa;
const utf8Decoder = new TextDecoder();
function fromByteArray(data) {
let u8Array = new Uint8Array(data);
// Ignore trailing newline:
if (u8Array[u8Array.length - 1] === NEWLINE) {
u8Array = new Uint8Array(u8Array.buffer, 0, u8Array.length - 1);
}
return utf8Decoder.decode(u8Array);
}
// takes a string as input and returns a string
// like `echo <jsonstring> | jq <filter>`, returning the value of STDOUT
function raw(jsonstring, filter, flags) {
outBuffer = [];
errBuffer = [];
// window.FS=FS
flags = flags || []
let mainErr, stdout, stderr, exitCode;
// Emscripten 3.1.31 neglects to free its argv, so we’ll do it here.
// This should be safe to do even if Emscripten fixes that.
const stackBefore = stackSave();
// Emscripten, as of 3.1.31, mucks with process.exitCode, which
// makes no sense.
let preExitCode;
if (typeof process !== "undefined") {
preExitCode = process.exitCode;
}
FS.writeFile("inputString", jsonstring);
try {
exitCode = Module.callMain(flags.concat(filter, "inputString")); // induce c main open it
} catch (e) {
mainErr = e;
}
if (preExitCode !== undefined) {
process.exitCode = preExitCode;
}
stackRestore(stackBefore);
// make sure closed & clean up fd
FS.streams.forEach( stream => stream && FS.close(stream) );
if (FS.streams.length>3) FS.streams = FS.streams.slice(0, 3);
// calling main closes stdout, so we reopen it here:
FS.streams[0] = FS.open('/dev/stdin', "r")
FS.streams[1] = FS.open('/dev/stdout', 577, 0)
FS.streams[2] = FS.open('/dev/stderr', 577, 0)
if (errBuffer.length) {
stderr = fromByteArray(errBuffer).trim();
}
if (outBuffer.length) {
stdout = fromByteArray(outBuffer);
}
try {
if (mainErr) {
throw mainErr;
} else if (exitCode) {
let errMsg = `Non-zero exit code: ${exitCode}`;
if (stderr) errMsg += `\n${stderr}`;
const err = new Error(errMsg);
err.exitCode = exitCode;
if (stderr) err.stderr += stderr;
throw err;
} else if (stderr) {
console.warn('%cstderr%c: %c%s', 'background:red;color:black', '', 'color:red', stderr);
}
} catch (e) {
if (stderr) e.stderr = stderr;
throw e;
}
return stdout;
}
// takes an object as input and tries to return objects.
function json(json, filter) {
var jsonstring = JSON.stringify(json)
var result = raw(jsonstring, filter, ['-c']).trim()
if (result.indexOf('\n') !== -1) {
return result
.split('\n')
.filter(function(x) {
return x
})
.reduce(function(acc, line) {
return acc.concat(JSON.parse(line))
}, [])
} else {
return JSON.parse(result)
}
}
Object.assign(
Module,
{ json, raw },
);