Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

micro

Package Overview
Dependencies
Maintainers
2
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

micro - npm Package Compare versions

Comparing version 7.2.2 to 7.3.0

64

bin/micro.js
#!/usr/bin/env node
// Native
const path = require('path')
const path = require('path');
// Packages
const updateNotifier = require('update-notifier')
const nodeVersion = require('node-version')
const args = require('args')
const isAsyncSupported = require('is-async-supported')
const updateNotifier = require('update-notifier');
const nodeVersion = require('node-version');
const args = require('args');
const isAsyncSupported = require('is-async-supported');
// Ours
const pkg = require('../package')
const pkg = require('../package');
// Throw an error if node version is too low
if (nodeVersion.major < 6) {
console.error(`Error! Micro requires at least version 6 of Node. Please upgrade!`)
process.exit(1)
console.error(
`Error! Micro requires at least version 6 of Node. Please upgrade!`
);
process.exit(1);
}

@@ -24,3 +26,3 @@

if (!process.env.NOW && pkg.dist) {
updateNotifier({pkg}).notify()
updateNotifier({ pkg }).notify();
}

@@ -31,3 +33,3 @@

.option(['H', 'host'], 'Host to listen on', '0.0.0.0')
.option(['s', 'silent'], 'Silent mode')
.option(['s', 'silent'], 'Silent mode');

@@ -41,12 +43,8 @@ const flags = args.parse(process.argv, {

},
boolean: [
'silent'
],
string: [
'host'
]
boolean: ['silent'],
string: ['host']
}
})
});
let file = args.sub[0]
let file = args.sub[0];

@@ -56,8 +54,8 @@ if (!file) {

// eslint-disable-next-line import/no-dynamic-require
const packageJson = require(path.resolve(process.cwd(), 'package.json'))
file = packageJson.main || 'index.js'
const packageJson = require(path.resolve(process.cwd(), 'package.json'));
file = packageJson.main || 'index.js';
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
console.error(`micro: Could not read \`package.json\`: ${err.message}`)
process.exit(1)
console.error(`micro: Could not read \`package.json\`: ${err.message}`);
process.exit(1);
}

@@ -68,24 +66,26 @@ }

if (!file) {
console.error('micro: Please supply a file.')
args.showHelp()
console.error('micro: Please supply a file.');
args.showHelp();
}
if (file[0] !== '/') {
file = path.resolve(process.cwd(), file)
file = path.resolve(process.cwd(), file);
}
if (!isAsyncSupported()) {
const asyncToGen = require('async-to-gen/register')
const asyncToGen = require('async-to-gen/register');
// Support for keywords "async" and "await"
const pathSep = process.platform === 'win32' ? '\\\\' : '/'
const directoryName = path.parse(path.join(__dirname, '..')).base
const pathSep = process.platform === 'win32' ? '\\\\' : '/';
const directoryName = path.parse(path.join(__dirname, '..')).base;
// This is required to make transpilation work on Windows
const fileDirectoryPath = path.parse(file).dir.split(path.sep).join(pathSep)
const fileDirectoryPath = path.parse(file).dir.split(path.sep).join(pathSep);
asyncToGen({
includes: new RegExp(`.*${directoryName}?${pathSep}(lib|bin)|${fileDirectoryPath}.*`),
includes: new RegExp(
`.*${directoryName}?${pathSep}(lib|bin)|${fileDirectoryPath}.*`
),
excludes: null,
sourceMaps: false
})
});
}

@@ -95,2 +95,2 @@

// If needed... Otherwise use the native implementation
require('../lib')(file, flags)
require('../lib')(file, flags);
// Packages
const detect = require('detect-port')
const detect = require('detect-port');
// Ours
const serve = require('./server')
const listening = require('./listening')
const getModule = require('./module')
const serve = require('./server');
const listening = require('./listening');
const getModule = require('./module');
module.exports = async (file, flags, module = getModule(file)) => {
const server = serve(module)
const server = serve(module);
let port = flags.port
let host = flags.host
let port = flags.port;
let host = flags.host;
const open = await detect(port)
let inUse = open !== port
const open = await detect(port);
let inUse = open !== port;
if (inUse) {
port = open
port = open;

@@ -24,7 +24,7 @@ inUse = {

open
}
};
}
if (host === '0.0.0.0') {
host = null
host = null;
}

@@ -34,8 +34,10 @@

if (err) {
console.error('micro:', err.stack)
process.exit(1)
console.error('micro:', err.stack);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}
return listening(server, inUse, flags.silent)
})
}
return listening(server, inUse, flags.silent);
});
};
// Packages
const {write: copy} = require('clipboardy')
const ip = require('ip')
const chalk = require('chalk')
const boxen = require('boxen')
const { write: copy } = require('clipboardy');
const ip = require('ip');
const chalk = require('chalk');
const boxen = require('boxen');
const copyToClipboard = async text => {
try {
await copy(text)
return true
await copy(text);
return true;
} catch (err) {
return false
return false;
}
}
};
module.exports = async (server, inUse, silent) => {
const details = server.address()
const ipAddress = ip.address()
const url = `http://${ipAddress}:${details.port}`
const details = server.address();
const ipAddress = ip.address();
const url = `http://${ipAddress}:${details.port}`;
const isTTY = process.stdout.isTTY
const isTTY = process.stdout.isTTY;
process.on('SIGINT', () => {
server.close()
process.exit(0)
})
server.close();
process.exit(0);
});
if (!(silent || process.env.NOW)) {
let message = chalk.green('Micro is running!')
let message = chalk.green('Micro is running!');
if (inUse) {
message += ' ' + chalk.red(`(on port ${inUse.open},` +
` because ${inUse.old} is already in use)`)
message += ' ' +
chalk.red(
`(on port ${inUse.open}, because ${inUse.old} is already in use)`
);
}
message += '\n\n'
message += '\n\n';
const localURL = `http://localhost:${details.port}`
const localURL = `http://localhost:${details.port}`;
message += `• ${chalk.bold('Local: ')} ${localURL}\n`
message += `• ${chalk.bold('On Your Network: ')} ${url}\n\n`
message += `• ${chalk.bold('Local: ')} ${localURL}\n`;
message += `• ${chalk.bold('On Your Network: ')} ${url}\n\n`;
if (isTTY) {
const copied = await copyToClipboard(localURL)
const copied = await copyToClipboard(localURL);
if (copied) {
message += `${chalk.grey('Copied local address to clipboard!')}`
message += `${chalk.grey('Copied local address to clipboard!')}`;
}
}
console.log(boxen(message, {
padding: 1,
borderColor: 'green',
margin: 1
}))
console.log(
boxen(message, {
padding: 1,
borderColor: 'green',
margin: 1
})
);
}
}
};
module.exports = file => {
let mod
let mod;
try {
// eslint-disable-next-line import/no-dynamic-require
mod = require(file)
mod = require(file);
if (mod && typeof mod === 'object') {
mod = mod.default
mod = mod.default;
}
} catch (err) {
console.error(`micro: Error when importing ${file}: ${err.stack}`)
process.exit(1)
console.error(`micro: Error when importing ${file}: ${err.stack}`);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}
if (typeof mod !== 'function') {
console.error(`micro: "${file}" does not export a function.`)
process.exit(1)
console.error(`micro: "${file}" does not export a function.`);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}
return mod
}
return mod;
};
// Native
const server = require('http').Server
const server = require('http').Server;
// Packages
const getRawBody = require('raw-body')
const typer = require('media-typer')
const isStream = require('isstream')
const Promise = require('bluebird')
const getRawBody = require('raw-body');
const typer = require('media-typer');
const isStream = require('isstream');
const Promise = require('bluebird');
const DEV = process.env.NODE_ENV === 'development'
const TESTING = process.env.NODE_ENV === 'test'
const DEV = process.env.NODE_ENV === 'development';
const TESTING = process.env.NODE_ENV === 'test';
const serve = fn => server((req, res) => exports.run(req, res, fn))
const serve = fn => server((req, res) => exports.run(req, res, fn));
module.exports = serve
exports = serve
module.exports = serve;
exports = serve;
exports.send = send
exports.sendError = sendError
exports.createError = createError
exports.send = send;
exports.sendError = sendError;
exports.createError = createError;

@@ -26,56 +26,68 @@ exports.run = (req, res, fn) =>

if (val === null) {
send(res, 204, null)
return
send(res, 204, null);
return;
}
// Return a undefined-null value -> send
// Send value if it is not undefined, otherwise assume res.end
// will be called later
if (undefined !== val) {
send(res, res.statusCode || 200, val)
send(res, res.statusCode || 200, val);
}
})
.catch(err => sendError(req, res, err))
.catch(err => sendError(req, res, err));
// Maps requests to buffered raw bodies so that
// multiple calls to `json` work as expected
const rawBodyMap = new WeakMap()
const rawBodyMap = new WeakMap();
const parseJSON = str => {
try {
return JSON.parse(str)
return JSON.parse(str);
} catch (err) {
throw createError(400, 'Invalid JSON', err)
throw createError(400, 'Invalid JSON', err);
}
}
};
exports.json = (req, {limit = '1mb'} = {}) => Promise.resolve().then(() => {
const type = req.headers['content-type']
const length = req.headers['content-length']
const encoding = typer.parse(type).parameters.charset
exports.buffer = (req, { limit = '1mb', encoding } = {}) =>
Promise.resolve().then(() => {
const type = req.headers['content-type'] || 'text/plain';
const length = req.headers['content-length'];
encoding = encoding === undefined
? typer.parse(type).parameters.charset
: encoding;
let str = rawBodyMap.get(req)
const body = rawBodyMap.get(req);
if (str) {
return parseJSON(str)
}
if (body) {
return body;
}
return getRawBody(req, {limit, length, encoding}).then(buf => {
str = buf
rawBodyMap.set(req, str)
return getRawBody(req, { limit, length, encoding })
.then(buf => {
rawBodyMap.set(req, buf);
return buf;
})
.catch(err => {
if (err.type === 'entity.too.large') {
throw createError(413, `Body exceeded ${limit} limit`, err);
} else {
throw createError(400, 'Invalid body', err);
}
});
});
return parseJSON(str)
}).catch(err => {
if (err.type === 'entity.too.large') {
throw createError(413, `Body exceeded ${limit} limit`, err)
} else {
throw createError(400, 'Invalid body', err)
}
})
})
exports.text = (req, { limit, encoding } = {}) =>
exports
.buffer(req, { limit, encoding })
.then(body => body.toString(encoding));
exports.json = (req, opts) =>
exports.text(req, opts).then(body => parseJSON(body));
function send(res, code, obj = null) {
res.statusCode = code
res.statusCode = code;
if (obj === null) {
res.end()
return
res.end();
return;
}

@@ -85,8 +97,8 @@

if (!res.getHeader('Content-Type')) {
res.setHeader('Content-Type', 'application/octet-stream')
res.setHeader('Content-Type', 'application/octet-stream');
}
res.setHeader('Content-Length', obj.length)
res.end(obj)
return
res.setHeader('Content-Length', obj.length);
res.end(obj);
return;
}

@@ -96,10 +108,10 @@

if (!res.getHeader('Content-Type')) {
res.setHeader('Content-Type', 'application/octet-stream')
res.setHeader('Content-Type', 'application/octet-stream');
}
obj.pipe(res)
return
obj.pipe(res);
return;
}
let str = obj
let str = obj;

@@ -115,27 +127,27 @@ if (typeof obj === 'object' || typeof obj === 'number') {

if (DEV) {
str = JSON.stringify(obj, null, 2)
str = JSON.stringify(obj, null, 2);
} else {
str = JSON.stringify(obj)
str = JSON.stringify(obj);
}
if (!res.getHeader('Content-Type')) {
res.setHeader('Content-Type', 'application/json')
res.setHeader('Content-Type', 'application/json');
}
}
res.setHeader('Content-Length', Buffer.byteLength(str))
res.end(str)
res.setHeader('Content-Length', Buffer.byteLength(str));
res.end(str);
}
function sendError(req, res, {statusCode, status, message, stack}) {
statusCode = statusCode || status
function sendError(req, res, { statusCode, status, message, stack }) {
statusCode = statusCode || status;
if (statusCode) {
send(res, statusCode, DEV ? stack : message)
send(res, statusCode, DEV ? stack : message);
} else {
send(res, 500, DEV ? stack : 'Internal Server Error')
send(res, 500, DEV ? stack : 'Internal Server Error');
}
if (!TESTING) {
console.error(stack)
console.error(stack);
}

@@ -145,6 +157,6 @@ }

function createError(code, msg, orig) {
const err = new Error(msg)
err.statusCode = code
err.originalError = orig
return err
const err = new Error(msg);
err.statusCode = code;
err.originalError = orig;
return err;
}
{
"name": "micro",
"version": "7.2.2",
"version": "7.3.0",
"description": "Asynchronous HTTP microservices",

@@ -11,3 +11,3 @@ "main": "./lib/server.js",

"scripts": {
"precommit": "npm run lint",
"precommit": "lint-staged",
"lint": "xo",

@@ -17,12 +17,14 @@ "test": "npm run lint && NODE_ENV=test nyc ava"

"xo": {
"esnext": true,
"space": true,
"semicolon": false,
"ignores": [
"examples/**/*"
],
"rules": {
"unicorn/no-process-exit": 0
}
"extends": "prettier"
},
"lint-staged": {
"*.js": [
"npm run lint",
"prettier --single-quote --write",
"git add"
]
},
"bin": {

@@ -51,4 +53,7 @@ "micro": "./bin/micro.js"

"coveralls": "2.12.0",
"eslint-config-prettier": "1.5.0",
"husky": "0.13.3",
"lint-staged": "3.4.0",
"nyc": "10.1.2",
"prettier": "0.22.0",
"request": "2.81.0",

@@ -59,6 +64,6 @@ "request-promise": "4.2.0",

"then-sleep": "1.0.1",
"xo": "0.18.0"
"xo": "0.18.1"
},
"dependencies": {
"args": "2.3.0",
"args": "2.4.0",
"async-to-gen": "1.3.2",

@@ -65,0 +70,0 @@ "bluebird": "3.5.0",

@@ -100,10 +100,16 @@ ![](https://raw.githubusercontent.com/zeit/art/31913be3107827adf10e1f491ec61480f63e19af/micro/logo.png)

For parsing the incoming request body we included an async function `json`
For parsing the incoming request body we included an async functions `buffer`, `text` and `json`
```js
const {json} = require('micro')
const {buffer, text, json} = require('micro')
module.exports = async (req, res) => {
const data = await json(req)
console.log(data.price)
const buf = await buffer(req)
console.log(buf)
// <Buffer 7b 22 70 72 69 63 65 22 3a 20 39 2e 39 39 7d>
const txt = await text(req)
// '{"price": 9.99}'
const js = await json(req)
// { price: 9.99 }
console.log(js.price)
return ''

@@ -115,5 +121,6 @@ }

**`json(req, { limit = '1mb' })`**
##### `buffer(req, { limit = '1mb', encoding = 'utf8' })`
##### `text(req, { limit = '1mb', encoding = 'utf8' })`
##### `json(req, { limit = '1mb', encoding = 'utf8' })`
- Use `require('micro').json`.
- Buffers and parses the incoming body and returns it.

@@ -144,3 +151,3 @@ - Exposes an `async` function that can be run with `await`.

**`send(res, statusCode, data = null)`**
##### `send(res, statusCode, data = null)`

@@ -174,3 +181,3 @@ - Use `require('micro').send`.

**`micro(fn)`**
##### micro(fn)

@@ -255,3 +262,3 @@ - This function is exposed as the `default` export.

**`sendError(req, res, error)`**
##### sendError(req, res, error)

@@ -265,3 +272,3 @@ - Use `require('micro').sendError`.

**`createError(code, msg, orig)`**
##### createError(code, msg, orig)

@@ -268,0 +275,0 @@ - Use `require('micro').createError`.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc