-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from agco/feature/GLBLAGCTWO-1147
Feature/glblagctwo 1147
- Loading branch information
Showing
22 changed files
with
1,647 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.iml | ||
.idea | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"version": "0.1.0", | ||
// List of configurations. Add new configurations or edit existing ones. | ||
"configurations": [ | ||
{ | ||
// Name of configuration; appears in the launch configuration drop down menu. | ||
"name": "Launch Mocha", | ||
// Type of configuration. | ||
"type": "node", | ||
// Workspace relative or absolute path to the program. | ||
"program": "node_modules/mocha/bin/_mocha", | ||
// Automatically stop program after launch. | ||
"stopOnEntry": false, | ||
// Command line arguments passed to the program. | ||
"args": ["--debug-brk", "--timeout", "10000"], | ||
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace. | ||
"cwd": ".", | ||
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH. | ||
"runtimeExecutable": null, | ||
// Optional arguments passed to the runtime executable. | ||
"runtimeArgs": ["--nolazy"], | ||
// Environment variables passed to the program. | ||
"env": { | ||
"NODE_ENV": "development" | ||
}, | ||
// Use JavaScript source maps (if they exist). | ||
"sourceMaps": false, | ||
// If JavaScript source maps are enabled, the generated code is expected in this directory. | ||
"outDir": null | ||
}, | ||
{ | ||
"name": "Attach", | ||
"type": "node", | ||
// TCP/IP address. Default is "localhost". | ||
"address": "localhost", | ||
// Port to attach to. | ||
"port": 5858, | ||
"sourceMaps": false | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require ('./lib/plugin') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES6", | ||
"module": "commonjs" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
'use strict' | ||
|
||
const Hapi = require('hapi') | ||
const _ = require('lodash') | ||
const Hoek = require('hoek') | ||
const mongoose = require('mongoose') | ||
const uuid = require('node-uuid') | ||
|
||
module.exports = function() { | ||
const toJsonApi = function (resources) { | ||
if (_.isArray(resources)) { | ||
return _.map(resources, (resource) => { | ||
return toJsonApiSingle(resource); | ||
}) | ||
} else { | ||
return toJsonApiSingle(resources); | ||
} | ||
|
||
function toJsonApiSingle(resource) { | ||
var mapped = _.mapKeys(resource, function (val, key) { | ||
if (key === '_id') return 'id' | ||
else return key | ||
}); | ||
return _.omit(mapped, '__v') | ||
} | ||
} | ||
|
||
const toMongooseModel = function (hhSchema) { | ||
|
||
const mongooseSchema = {} | ||
mongooseSchema._id = { | ||
type: String, | ||
default: () => { | ||
return uuid.v4() | ||
} | ||
} | ||
|
||
var schemaMap = { | ||
'string': String, | ||
'number': Number, | ||
'date': Date, | ||
'buffer': Buffer, | ||
'boolean': Boolean, | ||
'array': Array, | ||
'any': Object | ||
} | ||
|
||
mongooseSchema.type = 'string' | ||
mongooseSchema.attributes = | ||
_.mapValues(hhSchema.attributes, function (val) { | ||
Hoek.assert(val.isJoi, 'attribute values in the hh schema should be defined with Joi') | ||
return schemaMap[val._type] | ||
}) | ||
|
||
const schema = mongoose.Schema(mongooseSchema) | ||
return mongoose.model(hhSchema.type, schema) | ||
} | ||
|
||
const toMongoosePredicate = function(query) { | ||
const mappedToModel = _.mapKeys(query.filter, function (val, key) { | ||
if (key === 'id') return '_id' | ||
else return `attributes.${key}` | ||
}) | ||
|
||
return _.mapValues(mappedToModel, function (val, key) { | ||
const supportedComparators = ['lt', 'lte', 'gt', 'gte'] | ||
|
||
//if it's a normal value strig, do a $in query | ||
if (_.isString(val) && val.indexOf(',') !== -1) { | ||
return {$in: val.split(',')} | ||
} | ||
|
||
//if it's a comparator, translate to $gt, $lt etc | ||
const valueKey = _.keys(val)[0] | ||
if (_.contains(supportedComparators, valueKey)) { | ||
return {[`$${valueKey}`] : val[valueKey]} | ||
} | ||
|
||
else return val | ||
}) | ||
} | ||
|
||
const toMongooseSort = function(sort) { | ||
if (!sort) return {'_id' : -1} | ||
if(sort.indexOf('-') === 0) { | ||
return {[`attributes.${sort.substr(1)}`] : -1} | ||
} | ||
|
||
return {[`attributes.${sort}`] : 1} | ||
} | ||
|
||
return { toJsonApi, toMongooseModel, toMongoosePredicate, toMongooseSort } | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
'use strict' | ||
|
||
const Hapi = require('hapi') | ||
const Boom = require('boom') | ||
const _ = require('lodash') | ||
const mongoose = require('mongoose') | ||
const converters = require('./converters')() | ||
const utils = require('./utils')() | ||
|
||
mongoose.Promise = require('bluebird') | ||
|
||
module.exports = function (options) { | ||
|
||
const models = {} | ||
|
||
const connect = function(cb) { | ||
mongoose.connect(options.mongodbUrl, cb) | ||
} | ||
|
||
const disconnect = function(cb) { | ||
//clear out events | ||
mongoose.connection._events = {} | ||
mongoose.disconnect(cb) | ||
} | ||
|
||
mongoose.connection.on('error', connect) | ||
|
||
const find = function (type, req) { | ||
const model = models[type] | ||
const query = req.query | ||
const limit = (query.page && query.page.limit) || 1000 | ||
const skip = (query.page && query.page.offset) || 0 | ||
const sort = converters.toMongooseSort(query.sort) | ||
const sparse = query.fields && query.fields[type].split(',') | ||
var predicate = converters.toMongoosePredicate(query) | ||
return model.find(predicate).skip(skip).sort(sort).limit(limit).lean().exec() | ||
.then((resources)=> { | ||
let data = converters.toJsonApi(resources); | ||
if (sparse) { | ||
data = _.map(data, (datum) => { | ||
datum.attributes = _.pick(datum.attributes, sparse) | ||
return datum | ||
}) | ||
} | ||
|
||
return {data} | ||
}) | ||
} | ||
|
||
const findById = function(type, req) { | ||
|
||
const model = models[type] | ||
return model.findById(req.params.id).lean().exec() | ||
.then((resources) => { | ||
if (!resources) { | ||
return Boom.notFound() | ||
} | ||
return {data: converters.toJsonApi(resources)} | ||
}) | ||
} | ||
|
||
const create = function(type, req) { | ||
const model = models[type] | ||
var data = utils.getPayload(req) | ||
return model.create(data) | ||
.then((created) => { | ||
return {data: converters.toJsonApi(created.toObject())} | ||
}) | ||
} | ||
|
||
const update = function(type, req) { | ||
|
||
const model = models[type] | ||
var data = utils.getPayload(req) | ||
return model.findByIdAndUpdate(req.params.id, data) | ||
.then((resource) => { | ||
if (!resource) { | ||
return Boom.notFound() | ||
} | ||
return findById(type, req) | ||
}) | ||
} | ||
|
||
const del = function(type, req) { | ||
const model = models[type] | ||
var predicate = converters.toMongoosePredicate({id: req.params.id}) | ||
return model.remove(predicate) | ||
.then(() => { | ||
return {} | ||
}) | ||
} | ||
|
||
const processSchema = function(hhSchema) { | ||
|
||
if (!models[hhSchema.type]) { | ||
|
||
// clean up existing models and schemas | ||
delete mongoose.models[hhSchema.type] | ||
delete mongoose.modelSchemas[hhSchema.type] | ||
|
||
models[hhSchema.type] = converters.toMongooseModel(hhSchema) | ||
} | ||
return models[hhSchema.type] | ||
} | ||
|
||
return { | ||
connect, | ||
disconnect, | ||
find, | ||
findById, | ||
create, | ||
update, | ||
delete: del, | ||
models, | ||
processSchema | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use strict' | ||
|
||
const Hapi = require('hapi') | ||
const _ = require('lodash') | ||
const Hoek = require('hoek') | ||
const mongoose = require('mongoose') | ||
const uuid = require('node-uuid') | ||
|
||
module.exports = function() { | ||
const getPayload = function (req) { | ||
return (req.payload) ? req.payload.data : {} | ||
} | ||
|
||
return { getPayload } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
'use strict' | ||
|
||
const _ = require('lodash') | ||
const routes = require('./routes')() | ||
const adapterUtils = require('./utils/adapter')() | ||
const routeUtils = require('./utils/route')() | ||
|
||
exports.register = function (server, opts, next) { | ||
server.expose('version', require('../package.json').version); | ||
|
||
const adapter = opts.adapter; | ||
|
||
adapterUtils.checkValidAdapter(adapter); | ||
|
||
adapter.connect(() => { | ||
server.expose('adapter', adapter); | ||
next() | ||
}); | ||
|
||
const get = function (schema) { | ||
routeUtils.createOptionsRoute(server, schema) | ||
adapter.processSchema(schema) | ||
return _.merge(routes.get(schema), { | ||
handler: (req, reply) => { | ||
routeUtils.parseComparators(req) | ||
reply(adapter.find(schema.type, req)) | ||
} | ||
}) | ||
} | ||
|
||
const getById = function (schema) { | ||
routeUtils.createOptionsRoute(server, schema) | ||
adapter.processSchema(schema) | ||
return _.merge(routes.getById(schema), { | ||
handler: (req, reply) => { | ||
reply(adapter.findById(schema.type, req)) | ||
} | ||
}) | ||
} | ||
|
||
const post = function (schema) { | ||
routeUtils.createOptionsRoute(server, schema) | ||
adapter.processSchema(schema) | ||
return _.merge(routes.post(schema), { | ||
handler: (req, reply) => { | ||
reply(adapter.create(schema.type, req)).code(201) | ||
} | ||
}) | ||
} | ||
|
||
const patch = function (schema) { | ||
routeUtils.createOptionsRoute(server, schema) | ||
adapter.processSchema(schema) | ||
return _.merge(routes.patch(schema), { | ||
handler: (req, reply) => { | ||
reply(adapter.update(schema.type, req)) | ||
} | ||
}) | ||
} | ||
|
||
const del = function (schema) { | ||
routeUtils.createOptionsRoute(server, schema) | ||
adapter.processSchema(schema) | ||
return _.merge(routes.delete(schema), { | ||
handler: (req, reply) => { | ||
reply(adapter.delete(schema.type, req)).code(204) | ||
} | ||
}) | ||
} | ||
|
||
server.expose('routes', { | ||
get: get, | ||
getById: getById, | ||
post: post, | ||
patch: patch, | ||
delete: del | ||
}) | ||
|
||
server.ext('onPostStop', (server, next) => { | ||
adapter.disconnect(next) | ||
}) | ||
} | ||
|
||
exports.register.attributes = { | ||
pkg: require('../package.json') | ||
} | ||
|
||
exports.getAdapter = adapterUtils.getStandardAdapter; |
Oops, something went wrong.