Comparing version 1.0.0-alpha.30 to 1.0.0-alpha.31
@@ -20,3 +20,3 @@ # Middleware | ||
Context is the only parameter that middleware receives and we'll call it `ctx`. It represents all the information known at this point. It can appear at several points, but the most important one is as the only middleware parameter. | ||
Context is the only parameter that middleware receives and we'll call it `ctx`. It represents all the information known at this point. It can appear at several points, but the most important one is as a middleware parameter. | ||
@@ -23,0 +23,0 @@ In this situation it has, among others, the properties `req`, `res` (from express) and `options`: |
@@ -11,2 +11,3 @@ # Options | ||
|[`engine`](#engine) |`'pug'` |`ENGINE=pug` |String, Object | | ||
|[`views`](#views)\* |`'./views'` |`VIEWS=./views` |String | | ||
|[`env`](#env)\* |`'development'` |**`NODE_ENV=development`** |String | | ||
@@ -16,3 +17,3 @@ |[`ssl`](#ssl)\* |`false` |`???` |Object | | ||
\*not yet documented ([help us?](https://github.com/franciscop/server/tree/master/docs/documentation/options)) | ||
\*not yet documented ([help us editing this?](https://github.com/franciscop/server/tree/master/docs/documentation/options)) | ||
@@ -35,7 +36,7 @@ | ||
### Environment | ||
## Environment | ||
Environment variables are *not commited in your version control* but instead they are provided by the machine or Node.js process. In this way these options can be different in your machine and in the remote server(s). | ||
Environment variables are *not commited in your version control* but instead they are provided by the machine or Node.js process. In this way these options can be different in your machine and in testing, production or other type of servers. | ||
They are uppercase and can be set through a file called `.env` ([or other ways](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)): | ||
They are uppercase and they can be set through a file called `.env` in your computer: | ||
@@ -52,7 +53,9 @@ ``` | ||
To set them in remote server it will depend on the hosting that you use ([see Heroku example](https://devcenter.heroku.com/articles/config-vars)). | ||
## Parameter | ||
The alternative to the environment variables is to pass them **as the first parameter** when calling `server()`. Each option is a combination of key/value in the object and they all go in lowercase. See it with the defaults: | ||
The alternative to the environment variables is to pass them **as the first parameter** when calling `server()`. Each option is a combination of key/value in the object and they all go in lowercase. See some options with their defaults: | ||
@@ -67,3 +70,3 @@ ```js | ||
engine: 'pug', | ||
env: 'development' // Remember this is "env" and not "node_env" | ||
env: 'development' // Remember this is "env" and not "node_env" here | ||
}); | ||
@@ -73,4 +76,32 @@ ``` | ||
## Special cases | ||
As a general rule, an option that is an object becomes a `_` separated string in uppercase for the `.env` file. For example, for the SSL we have to pass an object such as: | ||
```js | ||
server({ | ||
port: 3000, | ||
ssl: { | ||
key: 'test/fixtures/keys/agent2-key.pem', | ||
cert: 'test/fixtures/keys/agent2-cert.cert' | ||
} | ||
}); | ||
``` | ||
So if we want to put this in the environment variable we'd set it up such as: | ||
``` | ||
PORT=3000 | ||
SSL_KEY=test/fixtures/keys/agent2-key.pem | ||
SSL_CERT=test/fixtures/keys/agent2-cert.cert | ||
``` | ||
The converse is not true; a `_` separated string in the `.env` does not necessarily become an object as a parameter. You'll have to read the documentation of each option and plugin for the specific details. | ||
## Available options | ||
Description of all the available options, their defaults and how to use them. | ||
### Port | ||
@@ -96,3 +127,3 @@ | ||
It is **highly recommended** that you set this in your environment variable for both development and production before you start coding. It should be a random and long string. It will be used by several middleware for storing secrets and keeping cookies/sessions: | ||
It is [**highly recommended**](https://github.com/franciscop/server/issues/3) that you set this in your environment variable for both development and production before you start coding. It should be a random and long string. It will be used by several middleware for storing secrets and keeping cookies/sessions: | ||
@@ -99,0 +130,0 @@ ``` |
{ | ||
"name": "server", | ||
"version": "1.0.0-alpha.30", | ||
"version": "1.0.0-alpha.31", | ||
"description": "A modern and powerful server for Node.js", | ||
@@ -5,0 +5,0 @@ "main": "server.js", |
@@ -11,3 +11,3 @@ // External libraries used | ||
// Local helpers and data | ||
const empty = ctx => ctx.res.send(); | ||
const empty = ctx => ctx.res.send('Hello 世界'); | ||
const tests = __dirname + '/../../tests'; | ||
@@ -49,3 +49,3 @@ const favicon = tests + '/logo.png'; | ||
const routes = [ | ||
get('/a', setSession, ctx => ctx.res.end()), | ||
get('/a', setSession, ctx => ctx.res.send('')), | ||
get('/b', ctx => ctx.res.send(ctx.req.session.page)), | ||
@@ -52,0 +52,0 @@ ]; |
@@ -22,3 +22,3 @@ // External libraries used | ||
expect(content(ctx)).toBe('application/x-www-form-urlencoded'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}; | ||
@@ -32,3 +32,3 @@ return poster(middle, data, nocsrf); | ||
expect(content(ctx)).toBe('application/json'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}; | ||
@@ -44,3 +44,3 @@ | ||
expect(ctx.req.files.logo.size).toBe(10151); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
} | ||
@@ -53,3 +53,3 @@ return handler(middle, { method: 'POST', formData: { logo } }, nocsrf); | ||
it('cookieParser', () => { | ||
const middle = ctx => ctx.res.cookie('place', '世界').send(); | ||
const middle = ctx => ctx.res.cookie('place', '世界').send('Hello 世界'); | ||
return poster(middle, { place: '世界' }, nocsrf).then(res => { | ||
@@ -69,3 +69,3 @@ const cookieheader = res.headers['set-cookie']; | ||
expect(ctx.req.originalMethod).toBe('POST'); | ||
ctx.res.send('世界'); | ||
ctx.res.send('Hello 世界'); | ||
} | ||
@@ -87,3 +87,3 @@ const headers = { 'X-HTTP-Method-Override': 'PUT' }; | ||
expect(ctx.req.headers['content-type']).toBe('application/x-www-form-urlencoded'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}; | ||
@@ -99,3 +99,3 @@ return poster(middle, data, { parser: { body: false }, connect: { csrf: false } }); | ||
expect(ctx.req.body).toBe(undefined); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}; | ||
@@ -102,0 +102,0 @@ return poster(middle, data, { parser: false, connect: { csrf: false } }); |
@@ -77,2 +77,2 @@ # **Server** for Node.js | ||
You can also [sponsor the project](/sponsor), get your logo in here and some other perks with tons of ♥ | ||
You can also [sponsor the project](https://serverjs.io/sponsor), get your logo in here and some other perks with tons of ♥ |
@@ -26,3 +26,7 @@ // server for Node.js (https://serverjs.io/) | ||
let ctx = {}; | ||
// Proxify it to use the server if a method is not in context | ||
// Useful for things like ctx.close() | ||
const ctx = new Proxy({}, { | ||
get: (orig, k) => orig[k] || orig.server[k] | ||
}); | ||
@@ -57,2 +61,3 @@ // First parameter can be: | ||
// PLUGIN middleware | ||
@@ -65,9 +70,6 @@ middle = join(hook(ctx, 'before'), middle, hook(ctx, 'after'), final); | ||
// Different listening methods | ||
await Promise.all(hook(ctx, 'listen').map(listen => listen(ctx))); | ||
// Proxify it to use the server if a method is not in context | ||
// Useful for things like ctx.close() | ||
ctx = new Proxy(ctx, { get: (orig, k) => orig[k] || orig.server[k] }); | ||
// After launching it (already proxified) | ||
@@ -91,2 +93,3 @@ for (let launch of hook(ctx, 'launch')) { | ||
require('./plugins/log'), | ||
require('./plugins/socket'), | ||
]; |
const extend = require('extend'); // deep clone, not like shallow Object.assign | ||
const config = require('./defaults'); | ||
const errors = require('./errors'); | ||
require('dotenv').config({ silent: true }); | ||
const env = require('./env'); | ||
// Check if a variable is numeric even if string | ||
const is = { | ||
numeric: num => !isNaN(num), | ||
boolean: b => b === true || b === false || | ||
(typeof b === 'string' && ['true', 'false'].includes(b.toLowerCase())) | ||
}; | ||
module.exports = (user = {}, plugins = []) => { | ||
module.exports = (user = {}, plugins = false, app = false) => { | ||
// If it's a number it's the port | ||
@@ -23,24 +16,12 @@ if (typeof user === 'number') { | ||
// Load the options from the plugin array, namespaced with the plugin name | ||
if (plugins) { | ||
plugins.forEach(plugin => { | ||
const valuify = cb => cb instanceof Function ? cb(options) : cb; | ||
const obj = { [plugin.name]: valuify(plugin.options) }; | ||
options = extend(true, {}, options, obj); | ||
}); | ||
} | ||
plugins.forEach(({ name, options: opts = {}} = {}) => { | ||
if (opts instanceof Function) { | ||
opts = opts(options[name] || {}, options); | ||
} | ||
extend(true, options, { [name]: opts }); | ||
}); | ||
extend(true, options, user); | ||
// Overwrite with the env variables if set | ||
for (let key in options) { | ||
if (key.toUpperCase().replace(/\s/g, '_') in process.env) { | ||
let env = process.env[key.toUpperCase().replace(/\s/g, '_')]; | ||
// Convert it to Number if it's numeric | ||
if (is.numeric(env)) env = +env; | ||
if (is.boolean(env)) env = typeof env === 'string' ? env === 'true' : env; | ||
options[key] = env; | ||
} | ||
} | ||
// TODO: these notifications should not be here | ||
if (options.secret === 'your-random-string-here') { | ||
@@ -58,3 +39,14 @@ throw errors.NotSoSecret(); | ||
return options; | ||
return new Proxy(options, { | ||
get: (orig, key) => { | ||
// If it is set in the environment some other way | ||
if (typeof env[key] !== 'undefined') { | ||
return env[key]; | ||
} | ||
// It was set in the options | ||
return options[key]; | ||
} | ||
}); | ||
}; |
const server = require('../../server'); | ||
const { getter, throws } = require('../../tests/helpers'); | ||
const request = require('request-promises'); | ||
@@ -19,2 +20,7 @@ describe('final', () => { | ||
}); | ||
it('testing', async () => { | ||
const res = await getter(ctx => 'Hello 世界'); | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
}); |
// Final error handler | ||
const handler = () => {}; | ||
const handler = ctx => { | ||
if (!ctx.res.headersSent) { | ||
ctx.res.send(ctx.ret || ''); | ||
} | ||
}; | ||
handler.error = ctx => { | ||
@@ -4,0 +8,0 @@ if (ctx.options.verbose) { |
@@ -22,4 +22,7 @@ const load = require('loadware'); | ||
if (ret instanceof Function) { | ||
await ret(ctx); | ||
ret = await ret(ctx); | ||
} | ||
if (/^(string|number)$/i.test(typeof ret)) { | ||
ctx.ret = ret; | ||
} | ||
return ctx; | ||
@@ -26,0 +29,0 @@ }); |
@@ -56,1 +56,12 @@ // Perform the routing required | ||
}; | ||
exports.join = join; | ||
// Allow for calling to routers that do not exist yet | ||
module.exports = new Proxy(exports, { | ||
get: (orig, key) => { | ||
if (orig[key]) return orig[key]; | ||
return (path, ...middle) => ctx => ctx.router[key](path, ...middle); | ||
} | ||
}); |
@@ -103,3 +103,3 @@ // Unit - test the router on its own | ||
expect(ctx.error.message).toBe('Hi there 1'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}); | ||
@@ -114,3 +114,3 @@ return getter([generate, handle], {}, { errors }); | ||
expect(ctx.error.message).toBe('Hi there ABC'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}); | ||
@@ -125,3 +125,3 @@ return getter([generate, handle], {}, { errors }); | ||
expect(ctx.error.message).toBe('generic error'); | ||
ctx.res.send(); | ||
ctx.res.send('Hello 世界'); | ||
}); | ||
@@ -128,0 +128,0 @@ return getter([generate, handle], {}, { errors }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
1151145
128
1938
6