Created
August 8, 2023 20:33
-
-
Save rjrodger/2de69753bb670316b4395c10bf4cd6b7 to your computer and use it in GitHub Desktop.
Proof of concept REPL for fastify
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Net = require('node:net') | |
const Repl = require('node:repl') | |
const Vm = require('node:vm') | |
const Fastify = require('fastify')({ logger: true }) | |
const Jsonic = require('@jsonic/jsonic-next') | |
Fastify | |
.get('/', function handler (request, reply) { | |
reply.send({ hello: 'world' }) | |
}) | |
.get('/foo', function handler (request, reply) { | |
reply.send('FOO') | |
}) | |
.post('/bar', function handler (request, reply) { | |
reply.send({...request.body, when:Date.now()}) | |
}) | |
.register(function repl(fastify, options, done) { | |
let server = Net.createServer(function (socket) { | |
socket.on('error', function (err) { | |
fastify.err('repl-socket', err) | |
}) | |
const input = socket | |
const output = socket | |
async function evaluate(cmdtext, context, filename, respond) { | |
cmdtext = cmdtext.trim() | |
let args = undefined | |
try { | |
args = Jsonic(cmdtext) | |
} | |
catch(err) { | |
// Probably JS code | |
} | |
let inject = undefined | |
let out = undefined | |
if(Array.isArray(args)) { | |
if('get' === args[0]) { | |
inject = { | |
method: 'GET', | |
url: args[1] | |
} | |
} | |
else if('post' === args[0]) { | |
inject = { | |
method: 'POST', | |
url: args[1], | |
body: args[2] | |
} | |
} | |
} | |
try { | |
if(inject) { | |
let res = await fastify.inject(inject) | |
out = { | |
statusCode: res.statusCode, | |
body: res.body, | |
} | |
} | |
else { | |
out = await Vm | |
.createScript(cmdtext, { | |
filename, | |
displayErrors: false, | |
}) | |
.runInContext(context, { | |
displayErrors: false, | |
}) | |
} | |
respond(undefined, out) | |
} | |
catch(err) { | |
respond(err) | |
} | |
} | |
const repl = Repl.start({ | |
prompt: `fastify-${fastify.version}> `, | |
socket, | |
socket, | |
terminal: false, | |
useGlobal: false, | |
eval: evaluate | |
}) | |
repl | |
.on('exit', () => { | |
input.end() | |
output.end() | |
}) | |
.on('error', (err) => { | |
fastify.error('repl', err) | |
}) | |
Object.assign(repl.context, { | |
fastify, | |
inject: async (...args ) => await fastify.inject(...args), | |
}) | |
}) | |
server | |
.on('error', function (err) { | |
fastify.error('repl-server', err) | |
}) | |
.on('listening', function () { | |
let address = server.address() | |
fastify.log.info('REPL listening on ' + address.address + ':' + address.port) | |
}) | |
.listen(31313, '127.0.0.1') | |
done() | |
}) | |
.listen({ port: 3000 }, (err) => { | |
if (err) { | |
fastify.log.error(err) | |
process.exit(1) | |
} | |
}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code is MIT licensed