-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathpost.js
138 lines (110 loc) · 3.31 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/** @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);
let files = [];
try {
for (let i = 0; i < flags.length; i++) {
if (flags[i] !== "--argjson") {
continue;
}
const fileIndex = i + 2;
const argName = '$' + flags[i + 1];
const fileName = 'file_'+ fileIndex;
flags[i] = "--slurpfile";
if (typeof filter === 'string') {
filter = filter.replaceAll(argName, argName + '[0]');
}
FS.writeFile(fileName, flags[fileIndex]);
files.push(fileName);
flags[fileIndex] = "file_" + fileIndex;
}
exitCode = Module.callMain(flags.concat(filter, "inputString")); // induce c main open it
} catch (e) {
mainErr = e;
} finally {
files.forEach(file => FS.unlink(file));
files = [];
}
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 },
);