routing-controllers-openapi
routing-controllers-openapi copied to clipboard
Testing code for stdin/stdout requests
This code is something I'm using as part of testing -- it reads JSON from stdin and writes responses back to stdout. The parent routing-controllers project has createExpressServer, but this project has the added decorations to make this more useful.
Using an OpenAPI decorated class:
const service = new api.Fetch();
const crypto = require("crypto");
const stream_in = process.stdin;
const stream_out = obj => process.stdout.write(JSON.stringify(obj));
const input = () => handle_input({stream_in, stream_out, service, crypto});
stream_in.on("readable", input);
stream_in.resume();
Splitting up input and parsing it as JSON; note the decorator is not used, as this code is incomplete (just calls one method as implied by the default):
function handle_input({stream_in, stream_out, service, crypto, operationId = "Fetch.fromCode"}) {
let chunk;
const MALFORMED_INPUT = { error: true, message: "MALFORMED_INPUT" };
while ((chunk = stream_in.read()) !== null) {
try {
let obj = JSON.parse(chunk);
if ("code" in obj) {
let requestId = crypto.randomBytes(3*4).toString('base64') ;
handle_output({requestId});
(requestId => service.fromCode(obj.code)
.then(output => handle_output({...output, requestId}))
.catch(output => handle_output({...output, requestId}))
)(requestId);
}
else handle_output(MALFORMED_INPUT);
} catch (e) {
console.error(e);
handle_output(MALFORMED_INPUT);
}
}
}
This was for ease of use, so I can just write {"code": "str"}
.
If the API has or needs headers then the combination of nock.back JSON, node-mocks-http and createExpressServer works pretty well.
tighter version with a json parsing package; shutdown function and MALFORMED_INPUT left to imagination.
// ctrl+c
process.on("SIGINT", shutdown);
// ctrl+d
process.stdin.on("end", shutdown);
process.stdin.resume();
// stdin
const crypto = require("crypto");
const {createParser} = require("json-stdio");
const service = new api.FetchPdb();
process.stdin.pipe(createParser()).on("data", data => {
const { operationId = "FetchPdb.fromCode" } = data;
const { requestId = crypto.randomBytes(3 * 4).toString("base64") } = data;
const write = data => output({ ...data, requestId });
write({ requestId });
const {code = ""} = data;
if(code.length) service
.fromCode(code)
.then(write)
.catch(write);
else write(MALFORMED_INPUT);
});