@flexshopper/hapi-methods
Advanced tools
Comparing version 1.0.4 to 2.0.0
'use strict'; | ||
const Gulp = require('gulp'); | ||
const Notify = require('gulp-notify'); | ||
const Eslint = require('gulp-eslint'); | ||
const Path = require('path'); | ||
const eslint = require('gulp-eslint'); | ||
const paths = { | ||
js: [ | ||
Path.join(__dirname, 'test/**/*.js'), | ||
Path.join(__dirname, 'tests/**/*.js'), | ||
Path.join(__dirname, 'lib/**/*.js'), | ||
Path.join(__dirname, 'config/**/*.js'), | ||
Path.join(__dirname, 'gulpfile.js') | ||
@@ -18,11 +19,9 @@ ] | ||
return Gulp.src(paths.js) | ||
.pipe(Eslint({ | ||
config: '.eslintrc', | ||
rules: { | ||
'keyword-spacing': 0 | ||
} | ||
.pipe(eslint({ | ||
config: '.eslintrc' | ||
})) | ||
.pipe(Eslint.format()) | ||
.pipe(Eslint.failAfterError()) | ||
.on('error', Notify.onError((error) => { | ||
.pipe(eslint.format()) | ||
.pipe(eslint.failAfterError()) | ||
.on('error', (error) => { | ||
return { | ||
@@ -32,3 +31,3 @@ title: 'ESLint Error', | ||
}; | ||
})); | ||
}); | ||
}); | ||
@@ -35,0 +34,0 @@ |
132
lib/index.js
'use strict'; | ||
const Joi = require('joi'); | ||
const Hoek = require('hoek'); | ||
const Joi = require('joi'); | ||
const Async = require('async'); | ||
const Filesystem = require('fs'); | ||
const Glob = require('glob'); | ||
const CastArray = require('cast-array'); | ||
const Path = require('path'); | ||
const internals = module.exports = {}; | ||
/** | ||
* Register function required by Hapi. | ||
* @param {object} server - the server object the plugin is being registered to. | ||
* @param {object} options - an options object passed to the plugin during registration. | ||
* @param {function} next - a callback method the function must call to return control back to the framework to complete the registration process with signature function(err). | ||
* @return {*} | ||
*/ | ||
internals.register = (server, options, next) => { | ||
const validate = Joi.validate(options, internals._defaults.options); | ||
const globSchema = Joi.object().keys({ | ||
includes: Joi.array().items(Joi.string()).default([]), | ||
options: Joi.object().keys({ | ||
nodir: Joi.boolean().default(true), | ||
strict: Joi.boolean().default(true), | ||
cwd: Joi.string().default(process.cwd()), | ||
ignore: Joi.array().items(Joi.string()).default([]) | ||
}) | ||
}); | ||
if (validate.error) { | ||
return next(validate.error); | ||
} | ||
internals.register = function (server, options, next) { | ||
options = Hoek.applyToDefaults(validate.value, options); | ||
const methods = {}; | ||
let preRequirements = {}; | ||
CastArray(options.methods).forEach((pattern) => { | ||
const files = Glob.sync(pattern, options.glob); | ||
files.forEach((file) => { | ||
const path = options.glob.cwd + '/' + file; | ||
const module = require(path); | ||
Async.auto({ | ||
glob: (callback) => { | ||
server.method(module.name, module.method, module.options || {}); | ||
}); | ||
}); | ||
Joi.validate({ | ||
includes: options.includes, | ||
options: { | ||
cwd: options.relativeTo, | ||
ignore: options.ignore | ||
} | ||
}, globSchema, callback); | ||
}, | ||
relativeTo: ['glob', (data, callback) => { | ||
server.log(internals._defaults.info, 'is been loaded successfully.'); | ||
if (!options.relativeTo) { | ||
return callback(null, null); | ||
} | ||
return next(); | ||
Filesystem.stat(options.relativeTo, (err, stats) => { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (!stats.isDirectory()) { | ||
return callback(new Error('relativeTo must be an valid directory.')); | ||
} | ||
return callback(null, options.relativeTo); | ||
}); | ||
}], | ||
files: ['relativeTo', (data, callback) => { | ||
const glob = data.glob; | ||
let files = []; | ||
for (let i = glob.includes.length - 1; i >= 0; i--) { | ||
const pattern = glob.includes[i]; | ||
files = Hoek.merge(files, Glob.sync(pattern, glob.options)); | ||
} | ||
return callback(null, files); | ||
}], | ||
register: ['files', (data, callback) => { | ||
const glob = data.glob; | ||
const files = data.files; | ||
files.map((file) => { | ||
const methodPath = Path.join(glob.options.cwd, file); | ||
const methodFile = require(methodPath); | ||
const methods = Object.keys(methodFile); | ||
for (let i = 0; i < methods.length; ++i) { | ||
const methodName = methods[i]; | ||
const method = methodFile[methodName]; | ||
const chain = Path.basename(file).replace(/.js/, '') + '.' + methodName; | ||
server.method(chain, method.method, method.options); | ||
} | ||
}); | ||
return callback(null, null); | ||
}] | ||
}, next); | ||
}; | ||
/** | ||
* Attributes object required by Hapi. | ||
* @type {{pkg}} | ||
* @private | ||
*/ | ||
internals.register.attributes = { | ||
pkg: require('../package') | ||
pkg: require('../package.json') | ||
}; | ||
/** | ||
* Private defaults values. | ||
* @type {{ options: @Joi, info: Array, error: Array }} | ||
*/ | ||
internals._defaults = { | ||
options: Joi.object().keys({ | ||
methods: Joi.alternatives().try( | ||
Joi.array().items(Joi.string()), | ||
Joi.string() | ||
).required(), | ||
glob: Joi.object().keys({ | ||
nodir: Joi.boolean().default(true), | ||
strict: Joi.boolean().default(true), | ||
cwd: Joi.string().default(process.cwd()), | ||
ignore: Joi.string().allow('').default(null) | ||
}).default() | ||
}), | ||
info: ['plugin', 'info', internals.register.attributes.pkg.name], | ||
error: ['plugin', 'error', internals.register.attributes.pkg.name] | ||
}; |
{ | ||
"name": "@flexshopper/hapi-methods", | ||
"description": "Hapi plugin to autoload methods.", | ||
"version": "1.0.4", | ||
"version": "2.0.0", | ||
"author": "Angel Ramirez <angel.ramirez@flexshopper.com>", | ||
@@ -10,19 +10,19 @@ "bugs": { | ||
"dependencies": { | ||
"cast-array": "^1.0.1", | ||
"async": "^2.0.0-rc.6", | ||
"glob": "^7.0.3", | ||
"hoek": "^3.0.4", | ||
"joi": "^8.0.4" | ||
"hoek": "^4.0.1", | ||
"joi": "^8.4.2" | ||
}, | ||
"devDependencies": { | ||
"code": "^2.1.0", | ||
"eslint": "^2.4.0", | ||
"eslint-config-flexshopper": "github:flexShopper/eslint-config", | ||
"@flexshopper/eslint-config-flexshopper": "^3.0.3", | ||
"code": "^2.3.0", | ||
"eslint": "^2.10.2", | ||
"eslint-config-yandex": "^1.0.6", | ||
"estraverse-fb": "^1.3.1", | ||
"fixpack": "^2.3.0", | ||
"fixpack": "^2.3.1", | ||
"gulp": "^3.9.1", | ||
"gulp-eslint": "^1.1.1", | ||
"gulp-notify": "^2.2.0", | ||
"hapi": "^13.0.0", | ||
"lab": "^8.2.0" | ||
"gulp-eslint": "^2.0.0", | ||
"hapi": "^13.4.0", | ||
"lab": "^10.5.1", | ||
"nodemon": "^1.9.2" | ||
}, | ||
@@ -29,0 +29,0 @@ "homepage": "https://github.com/FlexShopper/hapi-methods#readme", |
@@ -20,13 +20,32 @@ # @flexshopper/hapi-methods | ||
### Examples | ||
### Registering | ||
Kraken service style: | ||
``` manifest.js | ||
```javascript | ||
const server = new Hapi.Server(); | ||
server.connection(); | ||
server.register({ | ||
register: require('hapi-methods'), | ||
options: { | ||
relativeTo: proccess.cwd() + '/methods', | ||
includes: ['path/to/**/*methods.js'], | ||
ignore: ['*.git'], | ||
} | ||
}, (err) => { | ||
// continue application | ||
}); | ||
``` | ||
manifest style: | ||
```javascript | ||
registrations: [ | ||
.... | ||
... | ||
{ | ||
plugin: { | ||
register: '@flexshopper/hapi-methods', | ||
register: 'hapi-methods', | ||
options: { | ||
methods: 'methods/*.js' | ||
relativeTo: proccess.cwd() + '/methods', | ||
includes: ['path/to/**/*methods.js'], | ||
ignore: ['*.git'], | ||
} | ||
@@ -38,16 +57,51 @@ } | ||
#### Options Object | ||
### Options | ||
##### includes | ||
*Required* <br/> | ||
Type: `array` | ||
The [glob](https://github.com/isaacs/node-glob) pattern you would like to include | ||
##### ignore | ||
Type: `array` | ||
The pattern or an array of patterns to exclude | ||
##### relativeTo | ||
Type: `string` | ||
The current working directory in which to search (defaults to `process.cwd()`) | ||
#### Route Signature | ||
```javascript | ||
'use strict'; | ||
const internals = module.exports = {}; | ||
internals.myNewMethod = { | ||
method: (next) => { | ||
return next(); | ||
}, | ||
options: { | ||
cache: { | ||
expiresIn: 60000, | ||
generateTimeout: 60000 | ||
} | ||
} | ||
}; | ||
internals.anotherMethod = { | ||
method: (next) => { | ||
return next(); | ||
} | ||
}; | ||
// This methods would be available as: | ||
server.methods.methodFileName.myNewMethod(); | ||
server.methods.methodFileName.anotherMethod(); | ||
``` | ||
const options = Joi.object().keys({ | ||
methods: Joi.alternatives().try( | ||
Joi.array().items(Joi.string()), | ||
Joi.string() | ||
).required(), | ||
glob: Joi.object().keys({ | ||
nodir: Joi.boolean().default(true), | ||
strict: Joi.boolean().default(true), | ||
cwd: Joi.string().default(process.cwd()), | ||
ignore: Joi.string().allow('').default(null) | ||
}).default() | ||
}) | ||
``` |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
7050
106
4
106
2
+ Addedasync@^2.0.0-rc.6
+ Addedasync@2.6.4(transitive)
+ Addedlodash@4.17.21(transitive)
- Removedcast-array@^1.0.1
- Removedcast-array@1.0.1(transitive)
- Removedhoek@3.0.4(transitive)
- Removedisarray@0.0.1(transitive)
Updatedhoek@^4.0.1
Updatedjoi@^8.4.2