noflo-nodejs
Version:
Command-line tool for running NoFlo programs on Node.js
121 lines (113 loc) • 3.27 kB
JavaScript
const http = require('http');
const https = require('https');
const url = require('url');
const fs = require('fs');
const querystring = require('querystring');
const websocket = require('noflo-runtime-websocket');
const WebRTCRuntime = require('noflo-runtime-webrtc');
exports.getUrl = (options) => {
if (options.protocol === 'webrtc') {
const signalUrl = url.parse(options.signaller);
signalUrl.hash = options.id;
return url.format(signalUrl);
}
let protocol = 'ws:';
if (options.tlsKey && options.tlsCert) {
protocol = 'wss:';
}
const rtUrl = {
protocol,
slashes: true,
hostname: options.host,
port: `${options.port}`,
pathname: '',
};
return url.format(rtUrl);
};
exports.liveUrl = (options, silent = false) => {
const liveUrl = url.parse(options.ide);
const rtUrl = url.parse(exports.getUrl(options));
liveUrl.pathname = liveUrl.pathname || '/';
if (rtUrl.protocol === 'ws:' && liveUrl.protocol === 'https:') {
if (!silent) {
console.log('Browsers will reject connections from HTTPS pages to unsecured WebSockets');
console.log('You can use insecure version of the IDE, or enable secure WebSockets with --tls-key and --tls-cert options');
}
liveUrl.protocol = 'http:';
}
const query = [
`protocol=${options.protocol}`,
`address=${url.format(rtUrl)}`,
`id=${options.id}`,
`secret=${options.secret}`,
].join('&');
liveUrl.hash = `#runtime/endpoint?${querystring.escape(query)}`;
return url.format(liveUrl);
};
function createRuntime(options, server, runtimeOptions) {
switch (options.protocol) {
case 'webrtc': {
return new WebRTCRuntime(exports.getUrl(options), runtimeOptions);
}
case 'websocket': {
return websocket(server, runtimeOptions);
}
default: {
throw new Error(`Unknown protocol ${options.protocol}. Use "websocket" or "webrtc"`);
}
}
}
exports.create = (options) => new Promise((resolve, reject) => {
const handleRequest = (req, res) => {
res.writeHead(302, {
Location: exports.liveUrl(options),
});
res.end();
};
let server = null;
if (options.tlsKey && options.tlsCert) {
server = https.createServer({
key: fs.readFileSync(options.tlsKey),
cert: fs.readFileSync(options.tlsCert),
}, handleRequest);
} else {
server = http.createServer(handleRequest);
}
const rt = createRuntime(options, server, {
baseDir: options.baseDir,
captureOutput: options.captureOutput,
catchExceptions: options.catchExceptions,
defaultPermissions: [],
permissions: options.permissions,
cache: options.cache,
id: options.id,
label: options.label,
namespace: options.namespace,
repository: options.repository,
});
rt.webServer = server;
rt.once('ready', () => {
resolve(rt);
});
rt.once('error', (err) => {
reject(err);
});
});
exports.start = (rt, options) => new Promise((resolve, reject) => {
rt.webServer.listen(options.port, (err) => {
if (err) {
reject(err);
return;
}
resolve(rt);
});
});
exports.stop = (rt) => new Promise((resolve, reject) => {
rt.webServer.close((err) => {
if (err) {
reject(err);
return;
}
resolve(null);
});
});