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

trails

Package Overview
Dependencies
Maintainers
2
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

trails - npm Package Compare versions

Comparing version 3.0.3 to 3.2.0

.npmignore

148

index.js
/*eslint no-process-env: 0, no-console: 0 */
const merge = require('lodash.merge')
const EventEmitter = require('events').EventEmitter

@@ -16,3 +16,2 @@ const lib = require('./lib')

/**
* @param pkg The application package.json
* @param app.api The application api (api/ folder)

@@ -23,4 +22,5 @@ * @param app.config The application configuration (config/ folder)

* some necessary default configuration.
* @param app config to create Trails instance
*/
constructor (app) {
constructor(app) {
super()

@@ -38,7 +38,7 @@

app.api.models || (app.api.models = { })
app.api.services || (app.api.services = { })
app.api.resolvers || (app.api.resolvers = { })
app.api.policies || (app.api.policies = { })
app.api.controllers || (app.api.controllers = { })
app.api.models || (app.api.models = {})
app.api.services || (app.api.services = {})
app.api.resolvers || (app.api.resolvers = {})
app.api.policies || (app.api.policies = {})
app.api.controllers || (app.api.controllers = {})

@@ -71,7 +71,2 @@ if (!process.env.NODE_ENV) {

},
config: {
value: new lib.Configuration(app.config, processEnv),
configurable: true,
writable: false
},
api: {

@@ -87,23 +82,37 @@ value: app.api,

packs: {
value: { }
value: {}
}
})
this.setMaxListeners(this.config.get('main.maxListeners'))
let trailpacksConfig = {}
// instantiate trailpacks
if (app.config.main && app.config.main.packs) {
app.config.main.packs.forEach(Pack => {
try {
const pack = new Pack(this)
this.packs[pack.name] = pack
trailpacksConfig = merge(trailpacksConfig, pack.config)
lib.Core.mergeApi(this, pack)
lib.Core.bindTrailpackMethodListeners(this, pack)
}
catch (e) {
console.log(e.stack)
throw new TrailpackError(Pack, e, 'constructor')
}
})
}
// instantiate trailpacks
this.config.get('main.packs').forEach(Pack => {
try {
const pack = new Pack(this)
this.packs[pack.name] = pack
this.config.merge(pack.config)
lib.Core.mergeApi(this, pack)
lib.Core.bindTrailpackMethodListeners(this, pack)
Object.defineProperties(this, {
config: {
value: new lib.Configuration(trailpacksConfig, processEnv),
configurable: true,
writable: false
}
catch (e) {
console.log(e.stack)
throw new TrailpackError(Pack, e, 'constructor')
}
})
this.config.merge(app.config)
this.setMaxListeners(this.config.get('main.maxListeners'))
// instantiate resource classes and bind resource methods

@@ -116,2 +125,4 @@ this.controllers = lib.Core.bindMethods(this, 'controllers')

this.emit('trails:configured')
lib.Core.bindApplicationListeners(this)

@@ -126,3 +137,3 @@ lib.Core.bindTrailpackPhaseListeners(this, Object.values(this.packs))

*/
async start () {
async start() {
this.emit('trails:start')

@@ -137,13 +148,14 @@ await this.after('trails:ready')

*/
async stop () {
async stop() {
this.emit('trails:stop')
await Promise.all(Object.values(this.packs).map(pack => {
this.log.debug('Unloading trailpack', pack.name, '...')
return pack.unload()
}))
.then(() => {
this.log.debug('All trailpacks unloaded. Done.')
this.removeAllListeners()
})
await Promise
.all(Object.values(this.packs).map(pack => {
this.log.debug('Unloading trailpack', pack.name, '...')
return pack.unload()
}))
.then(() => {
this.log.debug('All trailpacks unloaded. Done.')
this.removeAllListeners()
})

@@ -158,3 +170,3 @@ return this

*/
async onceAny (events) {
async onceAny(events) {
if (!Array.isArray(events)) {

@@ -166,16 +178,17 @@ events = [events]

return Promise.race(events.map(eventName => {
return new Promise(resolve => {
resolveCallback = resolve
this.once(eventName, resolveCallback)
return Promise
.race(events.map(eventName => {
return new Promise(resolve => {
resolveCallback = resolve
this.once(eventName, resolveCallback)
})
}))
.then((...args) => {
events.forEach(eventName => this.removeListener(eventName, resolveCallback))
return args
})
}))
.then((...args) => {
events.forEach(eventName => this.removeListener(eventName, resolveCallback))
return args
})
.catch(err => {
this.log.error(err, 'handling onceAny events', events)
throw err
})
.catch(err => {
this.log.error(err, 'handling onceAny events', events)
throw err
})
}

@@ -189,21 +202,22 @@

*/
async after (events) {
async after(events) {
if (!Array.isArray(events)) {
events = [ events ]
events = [events]
}
return Promise.all(events.map(eventName => {
return new Promise(resolve => {
if (eventName instanceof Array){
resolve(this.onceAny(eventName))
}
else {
this.once(eventName, resolve)
}
return Promise
.all(events.map(eventName => {
return new Promise(resolve => {
if (eventName instanceof Array) {
resolve(this.onceAny(eventName))
}
else {
this.once(eventName, resolve)
}
})
}))
.catch(err => {
this.log.error(err, 'handling after events', events)
throw err
})
}))
.catch(err => {
this.log.error(err, 'handling after events', events)
throw err
})
}

@@ -215,5 +229,5 @@

*/
get log () {
get log() {
return this.logger
}
}
const merge = require('lodash.merge')
const path = require('path')
const joi = require('joi')
const schemas = require('./schemas')
const ConfigurationProxyHandler = {
get (target, key) {
get(target, key) {
if (target.has && target.has(key)) {

@@ -19,9 +17,7 @@ const value = target.immutable === true ? Object.freeze(target.get(key)) : target.get(key)

module.exports = class Configuration extends Map {
constructor (configTree = { }, processEnv = { }) {
const config = Configuration.buildConfig(configTree)
constructor(configTree = {}, processEnv = {}) {
const config = Configuration.buildConfig(configTree, processEnv.NODE_ENV)
const configEntries = Object.entries(Configuration.flattenTree(config))
super(configEntries)
this.validateConfig(config)
this.immutable = false

@@ -38,3 +34,3 @@ this.env = processEnv

set (key, value) {
set(key, value) {
if (this.immutable === true) {

@@ -47,8 +43,16 @@ throw new IllegalAccessError('Cannot set properties directly on config. Use .set(key, value) (immutable)')

/**
* Merge tree into this configuration. Return overwritten keys
* Merge tree into this configuration. Return overwritten keys
*/
merge (configTree) {
merge(configTree) {
const configEntries = Object.entries(Configuration.flattenTree(configTree))
return configEntries.map(([ key, value ]) => {
return configEntries.map(([key, value]) => {
const hasKey = this.has(key)
//if the key already exist and it's an object, we need to merge values before setting in on the map or we lose some data
if (hasKey) {
const currentValue = this.get(key)
if (typeof currentValue === 'object' && !Array.isArray(currentValue)) {
value = Object.assign({}, value, currentValue)
}
}
this.set(key, value)

@@ -63,3 +67,3 @@

*/
freeze () {
freeze() {
this.immutable = true

@@ -71,3 +75,3 @@ }

*/
unfreeze () {
unfreeze() {
this.immutable = false

@@ -79,6 +83,6 @@ }

*/
static flattenTree (tree = { }) {
const toReturn = { }
static flattenTree(tree = {}) {
const toReturn = {}
Object.entries(tree).forEach(([ k, v ]) => {
Object.entries(tree).forEach(([k, v]) => {
if (typeof v === 'object' && v !== null) {

@@ -99,6 +103,6 @@ const flatObject = Configuration.flattenTree(v)

*/
static buildConfig (initialConfig = { }, nodeEnv) {
static buildConfig(initialConfig = {}, nodeEnv) {
const root = path.resolve(path.dirname(require.main.filename))
const temp = path.resolve(root, '.tmp')
const envConfig = initialConfig.env && initialConfig.env[nodeEnv]
const envConfig = initialConfig.env && initialConfig.env[nodeEnv] || {}

@@ -108,3 +112,3 @@ const configTemplate = {

maxListeners: 128,
packs: [ ],
packs: [],
paths: {

@@ -116,30 +120,10 @@ root: root,

},
timeouts: {
start: 10000,
stop: 10000
},
freezeConfig: true,
createPaths: true
},
log: { }
}
}
const mergedConfig = merge(configTemplate, initialConfig, (envConfig || { }))
mergedConfig.env = nodeEnv
return mergedConfig
return merge(configTemplate, initialConfig, envConfig, { env: nodeEnv })
}
/**
* Validate the structure and prerequisites of the configuration object. Throw
* an Error if invalid; invalid configurations are unrecoverable and require
* that the programmer fix them.
*/
validateConfig (config) {
const result = joi.validate(config, schemas.config)
if (result.error) {
throw new ValidationError('Project Configuration Error', result.error.details)
}
}
}

@@ -5,3 +5,2 @@ /*eslint no-console: 0 */

const mkdirp = require('mkdirp')
const mapValues = require('lodash.mapvalues')
const lib = require('./')

@@ -60,11 +59,15 @@

bindMethods (app, resource) {
return mapValues(app.api[resource], (Resource, resourceName) => {
const obj = new Resource(app)
return Object.entries(app.api[resource])
.map(([ resourceName, Resource ]) => {
const obj = new Resource(app)
obj.methods = Core.getClassMethods(obj)
Object.entries(obj.methods).forEach(([ _, method ]) => {
obj[method] = obj[method].bind(obj)
obj.methods = Core.getClassMethods(obj)
Object.entries(obj.methods).forEach(([ _, method ]) => {
obj[method] = obj[method].bind(obj)
})
return [ resourceName, obj ]
})
return obj
})
.reduce((result, [ resourceName, resource ]) => Object.assign(result, {
[resourceName]: resource
}), { })
},

@@ -71,0 +74,0 @@

exports.Errors = require('./errors')
exports.Schemas = require('./schemas')

@@ -4,0 +3,0 @@ exports.Configuration = require('./Configuration')

{
"name": "trails",
"version": "3.0.3",
"version": "3.2.0",
"description": "Modern Web Application Framework for Node.js",

@@ -21,3 +21,3 @@ "keywords": [

"scripts": {
"test": "eslint --ignore-path .gitignore . && nyc mocha",
"test": "eslint --ignore-path .gitignore index.js lib/ test/ && nyc mocha",
"test-performance": "eslint --ignore-path .gitignore . && mocha test-performance",

@@ -72,6 +72,2 @@ "ci": "cd .. && ci"

"dependencies": {
"joi": "13.0.2",
"lodash.defaultsdeep": "4.6.0",
"lodash.isplainobject": "4.0.6",
"lodash.mapvalues": "4.6.0",
"lodash.merge": "4.6.0",

@@ -81,11 +77,10 @@ "mkdirp": "0.5.1"

"devDependencies": {
"eslint": "^3",
"eslint": "^4.15.0",
"eslint-config-trails": "^3",
"mocha": "^4",
"nyc": "^11.0.2",
"pre-commit": "^1.1.3",
"proxyquire": "^1.7.11",
"nyc": "^11.4.1",
"pre-commit": "^1.2.2",
"proxyquire": "^1.8.0",
"smokesignals": "^3",
"trailpack": "^3",
"winston": "^2.1.1"
"trailpack": "^3"
},

@@ -92,0 +87,0 @@ "eslintConfig": {

@@ -37,2 +37,10 @@ const path = require('path')

},
testpack: {
override: 'ok',
defaultArray: ['ko'],
defaultArrayWithDuplicates: ['ko', 'test'],
defaultObject: {
override: 'ok'
}
},
i18n: {

@@ -39,0 +47,0 @@ lng: 'en',

@@ -8,2 +8,14 @@ const Trailpack = require('trailpack')

name: 'testpack'
},
config: {
testpack: {
defaultValue: 'default',
override: 'ko',
defaultArray: ['ok'],
defaultArrayWithDuplicates: ['test'],
defaultObject: {
test: 'ok',
override: 'ko'
}
}
}

@@ -10,0 +22,0 @@ })

@@ -14,3 +14,3 @@ const fs = require('fs')

it('should be able to start and stop many instances in a single node process', () => {
const cycles = [ ]
const cycles = []
for (let i = 0; i < 10; ++i) {

@@ -63,2 +63,15 @@ cycles.push(new TrailsApp(testAppDefinition).start())

})
it('should set default config value if not configured explicitly by user', () => {
assert.equal(global.app.config.get('testpack.defaultValue'), 'default')
assert.equal(global.app.config.get('testpack.defaultObject.test'), 'ok')
})
it('should override config if configured explicitly by user', () => {
assert.equal(global.app.config.get('testpack.defaultValue'), 'default')
assert.equal(global.app.config.get('testpack.override'), 'ok')
assert.equal(global.app.config.get('testpack.defaultObject.override'), 'ok')
assert.equal(global.app.config.get('testpack.defaultObject.test'), 'ok')
assert.equal(global.app.config.testpack.defaultObject.test, 'ok')
assert.deepEqual(global.app.config.get('testpack.defaultArray'), ['ko'])
assert.deepEqual(global.app.config.get('testpack.defaultArrayWithDuplicates'), ['ko', 'test'])
})
})

@@ -73,3 +86,3 @@

const def = {
pkg: { },
pkg: {},
config: {

@@ -99,4 +112,4 @@ main: {

const def = {
api: { },
pkg: { },
api: {},
pkg: {},
config: {

@@ -106,3 +119,3 @@ main: {

class Failpack extends Trailpack {
constructor (app) {
constructor(app) {
super(app)

@@ -122,7 +135,7 @@ }

const def = {
api: { },
api: {},
config: {
main: { }
main: {}
},
pkg: { }
pkg: {}
}

@@ -139,7 +152,7 @@ const app = new TrailsApp(def)

const def = {
pkg: { },
api: { },
pkg: {},
api: {},
config: {
main: {
packs: [ Testpack ]
packs: [Testpack]
},

@@ -161,7 +174,7 @@ foo: 'bar'

const def = {
pkg: { },
api: { },
pkg: {},
api: {},
config: {
main: {
packs: [ Testpack ]
packs: [Testpack]
},

@@ -173,3 +186,3 @@ foo: 'bar'

assert.equal(app.config.get('foo'), 'bar')
app.config = { }
app.config = {}
assert.equal(app.config.get('foo'), 'bar')

@@ -187,3 +200,3 @@ })

it('should invoke listener when listening for a single event', () => {
const eventPromise = app.after([ 'test1' ])
const eventPromise = app.after(['test1'])
app.emit('test1')

@@ -198,3 +211,3 @@ return eventPromise

it('should invoke listener when listening for multiple events', () => {
const eventPromise = app.after([ 'test3', 'test4', 'test5' ])
const eventPromise = app.after(['test3', 'test4', 'test5'])
app.emit('test3')

@@ -201,0 +214,0 @@ app.emit('test4')

@@ -196,18 +196,2 @@ const assert = require('assert')

})
describe('#validateConfig', () => {
it('should throw ValidationError if main.packs contains an "undefined" trailpack', () => {
const testConfig = {
main: {
packs: [
undefined
]
},
log: {
logger: new smokesignals.Logger('silent')
}
}
assert.throws(() => new lib.Configuration(testConfig), lib.Errors.ValidationError)
})
})
describe('#get', () => {

@@ -214,0 +198,0 @@ it('should return nested config value if it exists', () => {

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