hapijs / glue Goto Github PK
View Code? Open in Web Editor NEWServer composer for hapi.js
License: Other
Server composer for hapi.js
License: Other
Hey, in all the examples for unit testing an API using the Lab library, they require their index.js file and use module.exports = server to get access to the server in their tests. However, with Glue we are handed back the server in the callback. How would it be possible to use these two libraries together?
I had occasion to pass environment variables in to my application via the manifest file, and wanted to do so in the same manner that you can specify the server port as $env.port for instance. I achieved this by specifying the environment variables as strings in the JSON file like $env.MY_CUSTOM_KEY and then after require
-ing the JSON file to create the manifest object, I looped over the area I had specified these values and pulled in the actual values using process.env() like so:
if (manifest.server.app.config) {
var value;
Object.keys(manifest.server.app.config).forEach(function (conf) {
value = manifest.server.app.config[conf];
if (value.indexOf('$env') !== -1) {
manifest.server.app.config[conf] = process.env[value.replace('$env.','')];
}
});
}
I'd like to propose having this functionality built in (implemented in a better fashion, naturally) but I'm not sure whether this should happen in Glue (because of the relevance of the manifest file to Glue) or in hapi itself (because the processing that pulls out the $env for port etc happens there).
Could someone provide guidance on this? Or kill the whole idea for a reason I'm not thinking of?
I'll fork and PR once I know the preferred location for this functionality, if any.
Thanks
Hey,
(I hope this issue is related to glue and not rejoice)
When installing rejoice globally, all glue plugin 'require' statements fail with such:
module.js:338
throw err;
^
Error: Cannot find module 'good'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.internals.parsePlugin (/Users/me/apps/node-v0.12.2-darwin-x64/lib/node_modules/rejoice/node_modules/glue/lib/index.js:218:23)
As it seems, the 'require' statement fails since the current directory is where rejoice was installed globally instead of the current one.
rejoice with -p also doesn't fix the problem.
Thanks.
Hapi noob here. Trying to use multiple instances of the mysql plugin to setup different db connection pools accessible to the same route (for doing federated queries). It's not immediately obvious where in the Glue manifest to put the attributes.multiple=true. And once it is set, what is the best way to reference a specific plugin instance being that they have the same plugin name?
Any tips would be appreciated.
thx,
Larry
Hi,
I'm configuring connections like this, but hapi is not creating an https listener correctly.
const tlsOptions = {
key: Fs.readFileSync(process.env.TLS_KEY),
cert: Fs.readFileSync(process.env.TLS_CERTIFICATE)
};
connections: [
{
port: 1111,
labels: ['service-proxy']
},
{
port: process.env.HOST_PORT,
labels: ['http']
},
{
port: process.env.TLS_PORT,
tls: tlsOptions,
labels: ['https']
}
]
I have no problem when setting the connection manually:
'use strict';
const Fs = require('fs');
const Hapi = require('hapi');
const tlsOptions = {
key: Fs.readFileSync('./ssl/selfsigned_server_key.pem'),
cert: Fs.readFileSync('./ssl/selfsigned_server_cert.pem')
};
// Create a server with a host and port
const server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8000,
tls: tlsOptions
});
glue
will call Hoek.clone
in the parsePlugin
method. This has the effect that some plugins stop working as expected when the values passed in the plugin options are objects or functions (in particular, streams).
Below is a simple demo that exhibits the problem. It just loads the good
plugin and passes an instance of a stream to the options (from good-console
). It should output some info about the server load every 1s, but an error is thrown:
Error: no writecb in Transform class
If we comment the Hoek.clone
call, it works as expected.
The problem will be present whenever the user needs to access the same value that is given in the plugin options (not a clone).
// npm install glue good good-console
const Glue = require('glue');
const GoodConsole = require('good-console');
const internals = {};
internals.goodOptions = {
ops: {
interval: 1000
},
reporters: {
'foo': [
new GoodConsole(),
'stdout'
]
}
};
internals.manifest = {
connections: [{ port: 8888 }],
registrations: [{
plugin: {
register: 'good',
options: internals.goodOptions
}
}]
};
Glue.compose(internals.manifest, (err, server) => {
server.start();
});
For the registrations array, reading the documentation:
It reads like the format is:
{
registrations: [{
plugin: 'pluginname',
options: {}
}]
}
however, according to the example, it reads:
{
registrations: [{
plugin: {
register: 'pluginname',
options: {}
},
}]
}
Since it appears that both formats work, is one deprecated?
Regarding the example format, it seems to me that it is redundant to say plugin
or is there something else that can be registered?
Glue restricts what is passed as options to new Hapi.Server(options), only allowing 'app', 'debug' and 'cache' members to the options.
It'd be useful to be able to define the full server options that are available.
If in manifest I do:
/* omitted for brevity */
plugins: [
{
'./app/api': {
routes: { prefix: '/api' }
}
}
]
routes in ./app/api
are registered without prefix.
But if I wrap in array, it does the right thing.
/* omitted for brevity */
plugins: [
{
'./app/api': [{ // ←←
routes: { prefix: '/api' }
}] // ←←
}
]
Needs clarifying the docs or fix to support both variants.
I noticed this note here about dependency registration order. And recently saw issues #34, #19, hapijs/hapi#2803 which made me think of this. I just wrote a library named hodgepodge that reorders a list of hapi plugins to respect their attributes.dependencies
. Perhaps it could be an option in glue to use this reordering.
I would otherwise suggest that a user choose to use hodgepodge on their own then pass the ordered plugin registrations to glue, but glue's manifest is not a standard plugin registrations list that could be passed to server.register()
.
It's just a thought to potentially make glue a little more deterministic– not sure if the community would genuinely find this useful, but figured it would be worth putting the option out there.
usinge hapi 10 with node 4 in ubuntu 14. keep getting this error when starting node server. It works on my colleague's mac but not on my ubuntu 14 (which I use inside a docker container base image ubuntu).
here's our server code:
var Glue = require('glue');
var routes = require('./config/routes/');
require('dotenv').load();
Glue.compose(require('./config/hapi.js'), function(err, server) {
// allow server to be used elsewhere
module.exports = server;
// setup authentication strategy
server.auth.strategy('jwt', 'jwt', 'required', {
key: process.env.JWT_SECRET,
validateFunc: require('./utils/auth/validateToken'),
verifyOptions: {
algorithms: ['HS256']
}
});
// register routes
server.route(routes.routes);
// start server
if (!module.parent) {
server.start(function(err) {
if (err) {
throw err;
}
server.log('Server running at:', server.info.uri);
});
}
});
I am using this boilerplate for a project.
This is the error I get when I run npm start
:
/Users/franzip/Work/project-api/node_modules/hapi/node_modules/hoek/lib/index.js:732
throw new Error(msgs.join(' ') || 'Unknown error');
^
Error: Invalid register options {
"data" [1]: {
"dir": "/Users/franzip/Work/project-api/lib",
"pattern": "fixtures.js"
},
"models" [2]: "/Users/franzip/Work/project-api/lib/models",
"adapters" [3]: {
"sails-mongo": {
"pkFormat": "string",
"syncable": true,
"defaults": {
"host": "localhost",
"database": "sails",
"port": 27017,
"user": null,
"password": null,
"schema": false,
"url": null,
"w": 1,
"wtimeout": 0,
"fsync": false,
"journal": false,
"readPreference": null,
"nativeParser": false,
"forceServerObjectId": false,
"recordQueryStats": false,
"retryMiliSeconds": 5000,
"numberOfRetries": 5,
"ssl": false,
"poolSize": 5,
"socketOptions": {
"noDelay": true,
"keepAlive": 0,
"connectTimeoutMS": 0,
"socketTimeoutMS": 0
},
"auto_reconnect": true,
"disableDriverBSONSizeCheck": false,
"reconnectInterval": 200,
"wlNext": {
"caseSensitive": false
}
},
"mongo": {},
"identity": "sails-mongo"
}
},
"connections" [4]: {
"mydb": {
"adapter": "sails-mongo",
"host": "localhost",
"port": 27017,
"database": "mydb"
}
}
}
[1] "connections" is not allowed
[2] "adapters" is not allowed
[3] "models" is not allowed
[4] "data" is not allowed
at Object.exports.contain.exports.reachTemplate.exports.assert.condition [as assert] (/Users/franzip/Work/project-api/node_modules/hapi/node_modules/hoek/lib/index.js:732:11)
at Object.exports.apply (/Users/franzip/Work/project-api/node_modules/hapi/lib/schema.js:17:10)
at module.exports.internals.Plugin.internals.Plugin.register.each [as register] (/Users/franzip/Work/project-api/node_modules/hapi/lib/plugin.js:180:22)
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:119:24
at iterate (/Users/franzip/Work/project-apinode_modules/glue/node_modules/items/lib/index.js:36:13)
at Object.exports.serial (/Users/franzip/Work/project-api/node_modules/glue/node_modules/items/lib/index.js:39:9)
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:117:19
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:129:9
at iterate (/Users/franzip/Work/project-api/node_modules/glue/node_modules/items/lib/index.js:36:13)
at done (/Users/franzip/Work/project-api/node_modules/glue/node_modules/items/lib/index.js:28:25)
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:101:13
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:129:9
at iterate (/Users/franzip/Work/project-api/node_modules/glue/node_modules/items/lib/index.js:36:13)
at done (/Users/franzip/Work/project-api/node_modules/glue/node_modules/items/lib/index.js:28:25)
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:92:9
at /Users/franzip/Work/project-api/node_modules/glue/lib/index.js:129:9
I have updated most of the dependencies and this is my package.json:
"dependencies": {
"bassmaster": "1.9.x",
"bedwetter": "1.8.x",
"boom": "3.1.x",
"dogwater": "1.1.x",
"glue": "3.1.x",
"hapi": "12.x.x",
"hapi-swagger": "3.3.x",
"hoek": "3.x.x",
"inert": "3.2.x",
"joi": "7.2.x",
"poop": "2.x.x",
"vision": "4.x.x",
"sails-mongo": "0.12.x"
}
My manifest object looks like this (in /server.js):
var config = require('./config');
...
manifest: {
server: {
...
},
connections: {
...
},
registrations: {
{
plugin: 'dogwater',
options: config.dogwater
},
{
plugin: 'poop',
options: config.poop
}
}
}
This is /config.js:
module.exports = {
...
dogwater: {
connections: {
mydb: {
adapter: 'sails-mongo',
host: 'localhost',
port: 27017,
database: 'mydb'
}
},
adapters: {
'sails-mongo': require('sails-mongo')
},
models: path.normalize(__dirname + '/lib/models'),
data: {
dir: path.normalize(__dirname + '/lib'),
pattern: 'fixtures.js'
}
},
poop: {
logPath: path.join(__dirname, 'poop.log')
}
};
The problem seems to be the object passed as option... passing an empty object makes poop registration works but not dogwater.
As stated in the docs, I'm passing the plugin name as a string and an object for the options... what am I doing wrong?
Thank you in advance!
Glue seems not to take the latest hapi-version as intended. To reproduce the behavior I set up a test project with the following package.json
and index.js
:
{
"name": "hapi-glue-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"glue": "^3.0.0",
"hapi": "^12.1.0"
}
}
'use strict';
const Glue = require('glue');
const manifest = {
connections: [{ port: 3000 }],
};
const options = {
relativeTo: __dirname,
};
Glue.compose(manifest, options, (err, server) => {
if (err) {
throw err;
}
server.start(function () {
console.log('Server (hapi v%s)running at: %s', server.version, server.info.uri);
});
})
If I run node index.js
, the output will look like
Server (hapi v11.1.4)running at: http://matthias.local:3000
This test ran on node v5.4.0 and npm 3.3.12. Can anyone confirm that behavior?
I guess glue's dependency "hapi": "11.x.x || 12.x.x"
might be the problem. I'm not sure, if I understand how that resolves. Is it like »Take the latest version of hapi that satisfies 11.x.x OR 12.x.x«?
Maybe it's a better idea to add a peer-dependency for hapi like `"hapi": ">=11 <13"?
When I run the plugin it throws this error:
/src/node_modules/glue/node_modules/hapi/lib/index.js:5
const Server = require('./server');
^^^^^
SyntaxError: Use of const in strict mode.
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/src/node_modules/glue/lib/index.js:4:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
I have a manifest that looks like the following,
module.exports = {
connections: [{
host: 'localhost',
port: 1337
}],
plugins: [
{
blipp: null
},
{
vision: null
},
{
'./lib/plugins/user': null
},
{
'./lib/plugins/admin': {
routes: {
prefix: '/admin'
}
}
}]
};
Both plugins adds a route that looks like this,
server.route([
{ method: 'GET', path: '/', config: indexConfig }
]);
I get Error: New route / conflicts with existing /
error.
Am I setting up the manifest wrong or are my expectations of how it should work wrong?
Not sure I'm doing everything right here, but while upgrading to v3 it seems I can't have other plugin options other than select. This is an example of what I'm trying to load:
{
"connections": [
{
"port": 8080,
"labels": ["http"]
}
],
"registrations": [
{
"plugin": "vision",
"options": {
"select": "http"
}
},
{
"plugin": "visionary",
"options": {
"select": "http",
"engines": {
"html": "handlebars"
},
"path": "/views"
}
}
]
}
I see there are no open issues and no open pull requests. I have an open PR in rejoice for upgrade to es6 type syntax but have been waiting on glue to be upgraded since I am relying on that and it seemed there would be breaking changes with the new version. Is there a timeline on this? If its going to be a long time I guess I'll have have to release again when it's finally done. I am trying to align with most of the other projects that have been upgraded already.
The plugin allows me to add options to server.register() but I can't set plugin specific options. You don't really support Hapi 15 if you don't allow that.
I'll make a PR.
Let me start by saying thanks for Glue - it's a great, really useful module.
One issue I have is with the compose
method. It has an optional callback which can be invoked sync or async depending if any plugins being registered are themselves async (they call their next
function asynchronously.)
This behaviour can cause astonishment and releases Zalgo
Would you consider forcing async behaviour with a little process.nextTick
? Apologies if this has already been discussed.
Related to #14
If I configure a vhost for routes in a plugin, the CORS options requests results in a 404 response.
It can be reproduced with the following example;
var Glue = require('glue'),
Hapi = require('hapi');
Config = require('./lib/config');
var manifest = {
connections: [
{
port: Config.port
}
],
plugins: {
'./web': [{
routes: {
vhost: 'example.com'
}
}],
'./plugins/rethink': Config.rethink,
'good': Config.monitor
}
};
var options = {
relativeTo: __dirname + '/lib'
};
Glue.compose(manifest, options, function (err, server) {
if (err) {
throw err;
}
server.start(function () {
console.log('Hapi days!');
});
});
If I comment out the vhost option, the CORS response is returned as expected.
outmoded/hapi-contrib#62 wants all hapji projects to update to node 4+ and es6 style guide and lab v7.
did Glue support scanning and register all js inside a folder, especially when there are no options to pass to this plugins. Something like :
registrations: [
{
plugins : './server/api/controllers/*.js'
},
....
]
Or is there another elegant solution to do that.
Within Glue.compose the server.info property points to null.
Hi guys,
I've noticed that in the package.json
the hapi-lts isn't set as a dependency nor is it used in code. Would you accept a PR for this to be added in? Apologies if I've missed something here.
Was wondering if there was any interest/plans in support for registering server methods in the Glue manifest? It's great to be able to register plugins in this fashion and similarly be great to handle server methods in a similar manner.
Registering some plugins is causing my composer to kill the server process but there is no explanation or errors. If I remove this plugin registration my server stays running as expected.
Given this registrations configuration:
registrations: [
{
plugin: {
register: 'lout'
}
}
]
Composer(function (err, server) {
if (err) {
throw err;
}
server.start(() => {
console.log('Server running at: ' + server.info.uri);
});
});
error returned
server starts with no error then silently quits.
I'm loading a local plugin with a dependency on h2o2, but seeing Unknown handler: proxy
error
Ref: https://gist.github.com/danielb2/78309eaf53d533407642
If I change the order of the manifest file (loading h2o2 first), the test will pass. I could use the array syntax for registering the plugins in the correct order, but the Glue documentation leads me to believe using server.dependency
will take care of it for me.
Am I missing something? I got this working just fine with 0.10.4 at one point
Whilst using glue I thought it might be good if there was a hook in the manifest for server.after like there is for preConnections and prePlugins.
Thanks
Simon
Joi of Jois, today when I deployed our API server it broke.
After digging around and some time debugging I found that plugins
is no longer a property we can use in a config file, but some kind of new registrations
array where you have to pass in each plugin as as an object, and a new options layout too.
Can you PLEASE document the Glue schema, and going forward advise of any changes as major is this.
Hi,
In the documentation it's stated, that we can pass options for server.register
when passing the plugin options as array, like this:
'./app/web/api/auth': [
{routes: {prefix: '/auth'}, options: {}}
],
However, I assume it should be somehow possible to do the same, when registering the plugin with object as options, something like this:
'./app/web/api/users': {routes: {prefix: '/users'}},
However, it doesn't work. Any thoughts if it's possible?
Regards,
I'm reading the Developing a Hapi Edge book, and wanted to try to get a basic HapiJS API server going using Glue, the JS is pretty much right from the book, and even took some of the plugins out, but it looks like it should work: http://pastebin.com/x6Wftvhd (Transpiled ES5 version: http://pastebin.com/PH9qiFut)
However, it returns an error in the console:
$ node dist/app.js
/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/index.js:141
throw error;
^
ValidationError: Invalid manifest {
"connections": [
{
"port": 8080,
"labels": [
"http"
]
},
{
"port": 8088,
"labels": [
"api"
]
}
],
"plugins" [1]: {
"good": {
"opsInterval": 5000,
"reporters": [
{
"reporter": "good-console",
"events": {
"ops": "*",
"log": "*"
}
}
]
}
}
}
[1] "plugins" is not allowed
at Object.internals.Err.toString.exports.process (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/errors.js:140:19)
at internals.Any.applyFunctionToChildren.internals.Any._validateWithOptions (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/any.js:654:27)
at root.validate (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/index.js:102:23)
at root.attempt (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/index.js:131:29)
at root.assert (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/node_modules/joi/lib/index.js:126:14)
at Object.exports.compose.steps.push.steps.push.steps.push.steps.push.Items.serial [as compose] (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/node_modules/glue/lib/index.js:43:9)
at Object.<anonymous> (/Users/me/Documents/scripts/js/node/test/hapi/hapi_server/dist/app.js:60:6)
at Module._compile (module.js:399:26)
at Object.Module._extensions..js (module.js:406:10)
at Module.load (module.js:345:32)
Any ideas?
hapi 15 is out, support it.
It's time.
This is my manifest.js :
'use strict';
let Database = require('../database/database');
const redis = require('../database/redis');
const database = Database.database;
module.exports = {
server: {
debug: {
request: ['info', 'error'],
log: ["error"]
},
cache: [{
// Omitted name so that this becomes the default
// cache client
engine: "catbox-redis",
host: "...",
partition: "def"
}]
},
connections: [
{
port: 8003,
labels: ["..."],
router: {
stripTrailingSlash: true
}
},
{
port: 8004,
labels: ["..."],
router: {
stripTrailingSlash: true
}
}
],
registrations: [
{
plugin: {
register: "./some-module",
options: {
database: database,
redis: redis
}
},
options: {
select: ['...']
}
},
...
}
]
};
Where can I pass the callback for a plugin??
In the classical method:
server.register(require('myplugin'), (err) => {
if (err) {
console.error('Failed to load plugin:', err);
}
});
I need this callback to execute some code
where can I specify this in manifest??
You can't use a relative path to require a module from inside a module that will be stored in the node_modules folder. If you have a manifest with a path ./my-plugin
, this will be resolved to require('<...>/node_modules/glue/my-plugin')
because relative path used with require() are relative to the __dirname.
The solution is to use join the process.cwd to the relative paths:
path = Path.join(process.cwd(), path);
Hi,
There are a couple of commits (e3b7da5 and 3c8c1e0) that introduced breaking changes when allowing hapi>=10
, since those versions require node>=4
.
Applications that depend on glue@2
but still run on [email protected]
(I know, enterprise) will break if re-installed, since the latest versions of hapi are using certain ES2015 features.
I would like to suggest bumping the major version and unpublishing those versions from npm.
Cheers!
It would be useful to pass function handlers in the Glue.compose() options in order to manipulate the server at each stage. Example:
var Glue = require('glue');
var options = {
relativeTo: __dirname,
preConnection: function (server, next) {
next();
},
preRegister: function (server, next) {
server.app.shared = someValue;
next();
},
};
Glue.compose(require("./manifest.json"), options, function (err, server) {
server.start();
});
The idea being that it would be possible to set up the server prior to loading plugins.
Is this something you'd consider supporting?
Thanks.
The last example in API.md is unreadable and doesn't follow the hapi style guide.
Return a promise for compose()
if callback is not provided.
Solved the issue, was declaring the options incorrectly.
Any chance of an alternate mechanism for glue to load a manifest into an existing server object? My use case is for a 'reusable' server that forces consistent log, ops, security, and documentation plugins. One way to do that might be to 'preload' a number of plugins into a server, and then load a manifest on top of the existing server. Composition of this 'standard' server would then consist of specific API plugins and their requirements. There are other ways to do this, but I thought I'd ask...
The rc3 and rc4 tags were not originally created as specified at https://github.com/hapijs/contrib/blob/master/Guidelines.md#releases
I've now recreated them as annotated tags and force pushed them. If you care, you can delete your local tags of those releases and re-fetch. No other tags are affected.
When I wasn't using glue to compose the server, the way I tested my code was pretty straight-forward. I exported the Hapi server instance from the index.js file and then, in the test modules, I required it and used the server.inject method to test the endpoints of my API.
However, using glue my index turned into something like this, with the server instance being available asynchronously:
index.js:
var Glue = require('glue');
var manifest = require('./config/manifest.json');
var options = {
relativeTo: process.cwd() + '/lib/modules'
};
Glue.compose(manifest, options, function (err, server) {
server.start(function () {
server.log('info', 'Server running at: ' + server.info.uri);
});
};
So now, trying to figure out how may be the best way to export that server variable to make it accessible to the test modules, I've come up with this solution. I don't know if I'm doing the right thing, so I'm seeking advice:
index.js:
var Glue = require('glue');
var manifest = require('./config/manifest.json');
var options = {
relativeTo: process.cwd() + '/lib/modules'
};
var compose = function (callback) {
Glue.compose(manifest, options, function (err, server) {
if (!module.parent) {
server.start(function () {
server.log('info', 'Server running at: ' + server.info.uri);
});
}
if (typeof callback !== 'undefined') {
callback(null, server);
}
});
};
// If this module is not being required by another one, compose the server.
if (!module.parent) {
compose();
}
module.exports = compose;
Then the index.js would be required from the tests this way:
test/whatever.js:
var composedServer;
require('../')(function (err, server) {
composedServer = server;
});
Any opinions would be very appreciated.
Thanks!
Matias
Using version: 3.2.0
I have the following manifest:
//manifest.js
var manifest = {
connections:[
{
host: appname.host,
port: appname.port.web,
labels: ['web']
},
{
host: appname.host,
port: appname.port.client,
labels: ['app-client']
}
],
registrations: [
{
plugin: {
register:'../services/app-client',
options: {
select: ['app-client']
}
}
}
]
};
I am getting an error in my plugin when trying to use server.listener
:
//services/app-client/index.js
var SocketIO = require('socket.io');
exports.register = function appClient(server, options, next){
var io = SocketIO(server.listener);
io.sockets.on('connection', function(socket){
console.log("new connection!");
socket.emit("app_connected", {
msg: "app client connected"
})
});
next();
}
Here's the error:
if ('object' == typeof srv && !srv.listen) {
TypeError: Cannot read property 'listen' of null
However, if I change the connection passed to SocketIO(server.select('app-client').listener)
, then everything works as expected. The point of select
in the registration options is so that you don't have to use select
inside your plugin, making it adaptable across your code.
While the existing tests do allow the select
option in the schema, I don't see that they actually test that the individual server.connection object is passed to the plugin. It looks like it still provides the entire server.settings
object to the plugin instead.
I am loading my manifest using glue. The plugins section of manifest looks like this
plugins: {
'hapi-auth-jwt':{},
'./server/api/index': {}
}
My api/index calls
server.auth.strategy('token', 'jwt' ....
This call fails sometimes with the message
Authentication strategy token uses unknown scheme: jwt
It seems that the load order of the plugins are not guaranteed which is causing my problem. Is there a recommended way to address this problem?
Have you thought about the logging reporters and the way they are loaded? For example:
'plugins': {
'good': {
'reporters': [{
'reporter': 'good-console',
'args':[{ 'log': '*' }]
}]
},
'./my-plugin': {}
}
The relativeTo
property is not taken into consideration when requiring the reporter, and you could be using be a reporter that's not available in the npm registry:
https://github.com/hapijs/good/blob/master/lib/monitor.js#L125
Therefore, you need to write:
'plugins': {
'good': {
'reporters': [{
'reporter': './plugins/my-reporter',
'args':[{ 'log': '*' }]
}]
},
'./my-plugin': {}
}
And it makes no sense to have a relativeTo
property because you are obligated to hardcode the relative path anyway. So, for me it's better to just ignore the 'relativeTo' property and always hardcode all the paths.
'plugins': {
'good': {
'reporters': [{
'reporter': './plugins/my-reporter',
'args':[{ 'log': '*' }]
}]
},
'./plugins/my-plugin': {}
}
Just sharing my thoughts. I don't find this property very useful, it obscures information if you simply read the json file. You need to know that the custom plugins are prefixed by a path that's hidden in the source code, when in fact this path it's used by a configuration file. I'd simply remove it and bump the version to 3.0.0.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.