pino-devtools
Advanced tools
Comparing version 1.0.2 to 2.0.0
{ | ||
"name": "pino-devtools", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"description": "A transport for viewing the logs in your favorite browser devtools", | ||
@@ -30,2 +30,3 @@ "main": "index.js", | ||
"jest": "^23.4.2", | ||
"jest-fetch-mock": "^1.6.5", | ||
"prettier": "^1.14.0", | ||
@@ -35,4 +36,5 @@ "rimraf": "^2.6.2" | ||
"jest": { | ||
"setupTestFrameworkScriptFile": "<rootDir>/setupTests.js", | ||
"testURL": "http://localhost/" | ||
} | ||
} |
@@ -30,7 +30,32 @@ # pino-devtools | ||
- `--no-open`: do not automatically open the page in the browser | ||
- `--mode websocket`: the server mode, more information in the next section | ||
Note: the web socket port is `port + 1`. | ||
### Server modes | ||
The server can be started in one of these two modes: | ||
- `websocket`: the default mode, which opens a new tab in your browser and forwards the logs _via_ a websocket. There is nothing to configure in your application | ||
- `buffer`: a mode that does not open a new tab or use a websocket but uses a buffer to store all the logs and a client in your application to output those logs in the same console as your application | ||
#### `buffer` mode | ||
Use `pino-devtools` like so: | ||
``` | ||
$ node your-app.js | pino-devtools --mode buffer | ||
``` | ||
Update your application code to require the `pino-devtools` client and calls the `fetchBufferedLogs()` async function as early as possible: | ||
```js | ||
// index.js | ||
const { fetchBufferedLogs } = require('pino-devtools/src/client'); | ||
await fetchBufferedLogs(); | ||
``` | ||
## License | ||
pino-devtools is released under the Mozilla Public License Version 2.0. See the bundled [LICENSE](./LICENSE.txt) file for details. |
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
const PinoDevTools = (console, WebSocket, window) => { | ||
const { hostname, port } = window.location; | ||
const wsPort = parseInt(port, 10) + 1; | ||
(function () { | ||
const writeLog = ({ _console, data, prefix = null }) => { | ||
const logger = { | ||
10: _console.trace, | ||
20: _console.debug, | ||
30: _console.info, | ||
40: _console.warn, | ||
50: _console.error, | ||
60: _console.error | ||
}; | ||
const socket = new WebSocket(`ws://${hostname}:${wsPort}`); | ||
const logger = { | ||
10: console.trace, | ||
20: console.debug, | ||
30: console.info, | ||
40: console.warn, | ||
50: console.error, | ||
60: console.error | ||
}; | ||
socket.addEventListener('message', ({ data }) => { | ||
try { | ||
@@ -32,3 +27,4 @@ const _JSON$parse = JSON.parse(data), | ||
const message = `[${name}] ${msg || '<no message>'}`; | ||
const logName = prefix ? `${prefix}|${name}` : name; | ||
const message = `[${logName}] ${msg || '<no message>'}`; | ||
@@ -41,11 +37,53 @@ if (Object.keys(otherFields).length) { | ||
} catch (err) { | ||
console.debug('[pino-devtools] received non-JSON message:', data); | ||
_console.debug('[pino-devtools] could not write log:', data); | ||
} | ||
}); | ||
}; | ||
}; | ||
if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = PinoDevTools; | ||
} else { | ||
PinoDevTools(console, WebSocket, window); | ||
} | ||
const readWebSocketLogs = ({ | ||
_WebSocket = WebSocket, | ||
_console = console, | ||
_window = window | ||
} = {}) => { | ||
const { hostname, port } = _window.location; | ||
const wsPort = parseInt(port, 10) + 1; | ||
const socket = new _WebSocket(`ws://${hostname}:${wsPort}`); | ||
socket.addEventListener('message', ({ data }) => { | ||
writeLog({ data, _console }); | ||
}); | ||
}; | ||
const fetchBufferedLogs = ({ | ||
host = '127.0.0.1', | ||
port = 3010, | ||
_console = console | ||
} = {}) => { | ||
if (!host) { | ||
throw new Error('You must pass `host` to `fetchBufferedLogs()`.'); | ||
} | ||
if (!port) { | ||
throw new Error('You must pass `port` to `fetchBufferedLogs()`.'); | ||
} | ||
return fetch(`http://${host}:${port}/server-logs.json`).then(response => response.json()).then(({ logs, prefix }) => { | ||
logs.forEach(data => { | ||
writeLog({ _console, data, prefix }); | ||
}); | ||
}).catch(err => { | ||
_console.debug('[pino-devtools] error while fetching the logs:', { | ||
error: err.toString() | ||
}); | ||
}); | ||
}; | ||
if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = { | ||
fetchBufferedLogs, | ||
readWebSocketLogs | ||
}; | ||
} else { | ||
readWebSocketLogs(); | ||
} | ||
})(); |
@@ -0,1 +1,3 @@ | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
const fs = require('fs'); | ||
@@ -16,9 +18,19 @@ const http = require('http'); | ||
const MODE_BUFFER = 'buffer'; | ||
const MODE_WEBSOCKET = 'websocket'; | ||
const MODES = [MODE_BUFFER, MODE_WEBSOCKET]; | ||
const DEFAULT_OPTIONS = { | ||
host: '127.0.0.1', | ||
open: true, | ||
port: '3010' | ||
port: '3010', | ||
mode: MODE_WEBSOCKET, | ||
open: true | ||
}; | ||
const createTransformFunction = ({ options, wsServer }) => { | ||
let BUFFER = { | ||
logs: [], | ||
prefix: 'server' | ||
}; | ||
const createWebSocketTransformFunction = ({ options, wsServer }) => { | ||
return (record, enc, cb) => { | ||
@@ -30,25 +42,71 @@ wsServer.broadcast(record); | ||
const webSocketHandler = (req, res) => { | ||
let pathName = null; | ||
try { | ||
pathName = parseURL(req.url).pathname; | ||
} catch (e) {} | ||
if (pathName === '/client.js') { | ||
res.writeHead(200, { 'Content-Type': 'text/javascript' }); | ||
return res.end(clientJS); | ||
} | ||
res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
res.end(indexHTML); | ||
}; | ||
const createBufferTransformFunction = ({ options }) => { | ||
return (record, enc, cb) => { | ||
BUFFER = _extends({}, BUFFER, { | ||
logs: BUFFER.logs.concat(record) | ||
}); | ||
cb(); | ||
}; | ||
}; | ||
const bufferHandler = (req, res) => { | ||
const headers = { | ||
'Access-Control-Allow-Origin': '*' | ||
}; | ||
let pathName = null; | ||
try { | ||
pathName = parseURL(req.url).pathname; | ||
} catch (e) {} | ||
if (pathName !== '/server-logs.json') { | ||
res.writeHead(404, headers); | ||
return res.end(); | ||
} | ||
const json = JSON.stringify(BUFFER); | ||
headers['Content-Type'] = 'application/json'; | ||
// reset buffer once returned. | ||
BUFFER = _extends({}, BUFFER, { | ||
logs: [] | ||
}); | ||
res.writeHead(200, headers); | ||
return res.end(json); | ||
}; | ||
module.exports = () => { | ||
const options = parseOptions(process.argv.slice(2), DEFAULT_OPTIONS); | ||
const { host, port, open } = options; | ||
const { host, mode, port, open } = options; | ||
const httpPort = parseInt(port, 10) || parseInt(DEFAULT_OPTIONS.port, 10); | ||
const wsPort = httpPort + 1; | ||
const url = `http://${host}:${httpPort}/`; | ||
if (!MODES.includes(mode)) { | ||
console.error(`Invalid mode: "${mode}", choices: ${MODES.join(', ')}`); | ||
process.exit(1); | ||
} | ||
const server = http.createServer((req, res) => { | ||
let pathName = null; | ||
try { | ||
pathName = parseURL(req.url).pathname; | ||
} catch (e) {} | ||
let server; | ||
if (mode === MODE_BUFFER) { | ||
server = http.createServer(bufferHandler); | ||
} else { | ||
server = http.createServer(webSocketHandler); | ||
} | ||
if (pathName === '/client.js') { | ||
res.writeHead(200, { 'Content-Type': 'text/javascript' }); | ||
return res.end(clientJS); | ||
} | ||
const httpPort = parseInt(port, 10) || parseInt(DEFAULT_OPTIONS.port, 10); | ||
res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
res.end(indexHTML); | ||
}); | ||
server.listen({ | ||
@@ -58,25 +116,32 @@ port: httpPort, | ||
}, err => { | ||
const wsServer = new WebSocket.Server({ | ||
host: host, | ||
port: wsPort | ||
}); | ||
wsServer.broadcast = data => { | ||
wsServer.clients.forEach(client => { | ||
if (client.readyState === WebSocket.OPEN) { | ||
client.send(data); | ||
} | ||
let transport; | ||
if (mode === MODE_WEBSOCKET) { | ||
const url = `http://${host}:${httpPort}/`; | ||
const wsPort = httpPort + 1; | ||
const wsServer = new WebSocket.Server({ | ||
host: host, | ||
port: wsPort | ||
}); | ||
}; | ||
const devtoolsTransport = through.obj(createTransformFunction({ options, wsServer })); | ||
wsServer.broadcast = data => { | ||
wsServer.clients.forEach(client => { | ||
if (client.readyState === WebSocket.OPEN) { | ||
client.send(data); | ||
} | ||
}); | ||
}; | ||
pump(process.stdin, split(), devtoolsTransport); | ||
transport = createWebSocketTransformFunction({ options, wsServer }); | ||
if (open) { | ||
opn(url); | ||
if (open) { | ||
opn(url); | ||
} else { | ||
console.log(`Open your browser at: ${url}`); | ||
} | ||
} else { | ||
console.log(`Open your browser at: ${url}`); | ||
transport = createBufferTransformFunction({ options }); | ||
} | ||
pump(process.stdin, split(), through.obj(transport)); | ||
}); | ||
}; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
382614
207
61
7
2