actionhero

Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

APACHE-2.0 License

Downloads
14.5K
Stars
2.4K
Committers
127

Bot releases are visible (Hide)

actionhero - v19.0.1 Fix `actionhero generate`

Published by evantahler over 6 years ago

Fix actionhero generate

Fixes a bug introduced in v19.0.0 in which actionhero generate does not create a .gitignore file.

actionhero - v19.0.0 Jest and StuckWorkers

Published by evantahler over 6 years ago

Node Resque & Tasks

We've updated to Node-Resque v5.3.0, which includes support for automatically pruning old stuck or crashed worker processes. The setting which controls how long a worker has to be non-response for in actionhero is api.config.tasks.stuckWorkerTimeout

Lear more here: https://github.com/taskrabbit/node-resque/releases/tag/v5.3.0

Web Server

Capture full rawBody even if formidable fails

ActionHero Websocket

We noticed that the way that we were sharing session between WS and WEB connections (headers) was unlikely to work with some primus/websocket transports. We've changed to using query params which is what Priums recommends.

  • Added a new ActionHeroWebSocket option (generated automatically) cookieKey. This must now be added to your config files to share sessions between WEB and WEBSOCKET connections in the same browser.

Jest

ActionHero now uses jest for testing. We've removed mocha and and chai. You can continue to use these older tools in your projects, but all new projects will be generated with a jest-friendly layout.

Jest has a number of features which make it better than mocha:

  • interactive testing
  • test on file change
  • more popular
  • parallel testing

The project changes include:

  • all tests moved to __tests__, per Jest convention
  • update all test files to work with jest and jasmine-style matchers
  • removes the dev dependencies: mocha, chai, dirty-chai, and cross-env
  • adds the dev dependencies: jest, jest-environment-webdriver
  • updates the allowed global variables (for standard.js testing) as provided by jest
  • updates actionhero generate to use jasmine in new projects
  • adds chromedriver as a dev dependency; test cookies and sessions in a real browser with selenium
    • a guide on using chromedriver can be found here
  • Updated various configs to use process.env.JEST_WORKER_ID in tests to allow parallel testing without cross-pollution of redis, servers, etc.

Misc


Upgrade Guide

Configuration

  • in config/tasks.js add api.config.tasks.stuckWorkerTimeout = 3600000. This will be a 1 hour timeout for stuck/crashed worker processes
  • in config/servers/websocket.js add api.config.servers.websocket.client.cookieKey = api.config.servers.web.fingerprintOptions.cookieKey. This will instruct the ActionHero Websocket Clients to share the same cookie as the web server to share a fingerprint, which can be used to share session information.
  • If you plan to use Jest for your tests, and want to test in parallel, you will need to configure your server in the test environment to make use of process.env.JEST_WORKER_ID. Please view config/api.js, config/redis.js, config/servers/socket.js, and config/servers/web.js for more information
actionhero - v18.1.3: Generic error decoration and more!

Published by evantahler over 6 years ago

Generic error decoration hook for action errors

  • When an actions throws an error, we have a new error handler (defined in config/errors.js) to handle this case. The default is a no-op. This allows you to customize how you handle throw-ing errors from your actions.
  • by @chimmelb via https://github.com/actionhero/actionhero/pull/1180

allow "all" routes in api.routes.registerRoute

Update Required Packages

  • This includes major semver bumps to ws and standard. However, these changes produced no warnings in the ActionHero test suite, so we do not believe that a major version change to ActionHero is required.

Circle CI 2.0

We now test ActionHero with Circle.CI v2.0. We use the new workflow features. Thanks for supporting Open Source, Circle.CI!

actionhero - v18.1.2: WS IP addresses and connection.pipe

Published by evantahler over 6 years ago

Better detection for websocket client IP addresses behind a proxy

We now properly look for x-forward-for when looking for a websocket connection's remoteIp

connetion#pipe for web servers sending buffers or strings

solves https://github.com/actionhero/actionhero/issues/1142.

const {Action} = require('actionhero')

module.exports = class StringResponse extends Action {
  constructor () {
    super()
    this.name = 'stringResponse'
    this.description = 'I send a string to the client as if it were a file'
  }

  async run (data) {
    data.toRun = false
    data.connection.pipe('my response', {'content-type': 'text/plain'})
  }
}

Adds connection.pipe(string-or-buffer, headers) which can be used in your actions for web clients. This is a helper method which is the same as:

data.connection.setHeader('Content-Type', 'application/xml; charset=utf-8')
data.connection.rawConnection.res.end(fileBuffer)

data.toRender = false is still needed within the Action's run method.

Parse locally scoped IPv6 addresses (web and websocket servers)

Misc

actionhero - v17.1.2: Work with node.js v9.x

Published by evantahler almost 7 years ago

This release brings the changes from ActionHero v18.1.1 back to v17, adding support for node.js v9.

actionhero - v18.1.1: Allow node v9

Published by evantahler almost 7 years ago

Allow node.js v9

  • Update the engines directive in ActionHero's package.json to allow any node.js version >=8.0.0

Solve an Issue with unclosed file descriptors in the web server

If the web server sends a status code 304 response, then the fileStream handle may not have been closed.

actionhero - v18.1.0: Node.JS v9.x and better action validators.

Published by evantahler almost 7 years ago

Support for Node.js v9.x

ActionHero now support node.js v9.x, and we are running testing all new releases against it. The only change required was to support a change in how node handled parsedURL.search ( https://github.com/actionhero/actionhero/pull/1152).

Action validators which return nothing are valid

ActionHero changed the behavior of action's param validators to only mark a param as invalid if they return false or throw an error. Previously, validators which did not return (or returned null) would be marked as failing.

Fro example, these validators which return null (they don't return) on a passing param would mark the email and password {email: '[email protected]', password: 'password123'} valid:

const {Action} = require('actionhero')

class ValidatedAction extends Action {
  constructor () {
    super()
    this.inputs = {
      email: {
        required: true,
        validator: this.emailValidator
      },
      password: {
        required: true,
        validator: this.passwordValidator
      }
    }
  }

  emailValidator (param) {
    if (param.indexOf('@') < 0) {
      throw new Error('that is not a valid email address')
    }
  }

  passwordValidator (param) {
    if (param.length < 4) {
      throw new Error('password should be at least 3 letters long')
    }
  }

  run (data) { 
    // ...
  } 
}

by @evantahler via https://github.com/actionhero/actionhero/pull/1158

connection.setStatusCode for web clients

  • Added a helper for the web type of connection to more easily set a custom status code in your actions. Remember that if you don't want to sent data back to the client, to use data.toRender = false:
// actions/custom404.js

const {Action} = require('./../index.js')

module.exports = class Custom404 extends Action {
  constructor () {
    super()
    this.name = 'custom 404 message'
    this.description = 'I return a 404 with a sassy message'
    this.outputExample = {}
  }

  async run ({connection, response}) {
    response.message = 'nope.'
    connection.setStatusCode(404)
  }
}

Increased verbosity for fatal error on handleMethod

If there was a fatal exception loading an initializer, you can now see what file & line number caused the problem

actionhero - v18.0.2: False Validators

Published by evantahler almost 7 years ago

Validators returning false now emit a generic error

To simplify the developer experience, any Action's valuator which returns false will now fail, and return an error to the client.

You can now have simple "1-liner" validators like:

const {Action} = require('actionhero')

module.exports = class ValidationTest extends Action {
  constructor () {
    super()
    this.name = 'validationTest'
    this.description = 'I will test action input validators.'
    this.outputExample = { string: 'imAString!' }
  }

  inputs () {
    return {
      string: {
        required: true,
        validator: param => { return typeof param === 'string' }
      }
    }
  }

  run ({params, response}) {
    response.string = params.string
  }
}
actionhero - v17.1.1: v17 Docs and Websocket Race Condition Fix

Published by evantahler almost 7 years ago

Documentation!

As promised, we now have documented all the public methods of ActionHero v17 using JSdoc. You can view these on docs.actionherojs.com (just choose the version at the bottom of the page), and in your own ActionHero projects. Just run npm run docs to build the documentation pages locally. This replaces the old documentation which used to be on the www.actionherojs.com website.

A huge thank you to @gcoonrod for this work (via https://github.com/actionhero/actionhero/pull/1126 and https://github.com/actionhero/actionhero/pull/1144)!

Fix race condition in websocket server

Fixes a v17 bug in which a websocket connection could send 2 parallel requests .... one action request and one "verb" (like 'roomAdd', 'roomLeave' or 'roomView') in the following constellation:

  1. send verb roomLeave request
    -> connection.messageNumber++ (now 1)
  2. send action request (action takes a little longer ~500ms)
    -> connection.messageNumber++ (now 2)
  3. answer received from roomLeave request (messageCount send back from actionhero: 2(!!!))
  4. answer received fromaction request (messageCount send back from actionhero: 2(!!!))

The response payloads would be assigned the wrong response ID. This is now fixed.

actionhero - v18.0.1: Documentation and Task Scope

Published by evantahler about 7 years ago

Update this scope in Task#run.

Prior to this update, this in the run method of a task was a node-resque worker rather than the task itself. Now that it is updated, you can do things like the following:

module.exports = class SomeTask extends ActionHero.Task {
  constructor () {
    super()
    this.name = 'someTask'
    this.description = '...'
    this.frequency = 0
    this.queue = 'default'
    this.middleware = []
  }

  async stepOne (params) {
    ...
  }

  async stepTwo (params) {
    ...
  }

  async run (params) {
    let resOne = await this.stepOne()
    let resTwo = await this.stepTwo()
    ...
  }
}

While this is might be a breaking change for some exotic uses of tasks, the previous scope of a task was never documented. Now, we've defined and tested this behavior to ensure that it persists.

Update Redis Connection in SpecHelper#runFullTask

This is a fixes a problem running unit-tests with a non-standard redis configuration. E.g.

REDIS_HOST=192.168.99.100 npm test -- test/core/tasks.js

Documemtation

Various updates to the documentation have been added, and mistakes corrected. The docs site also looks much nicer now! Thanks to @gcoonrod, @rakhnin, and @evantahler

actionhero - v18.0.0 Async/Await

Published by evantahler about 7 years ago

ActionHero v18: Async/Await

Introduction

ActionHero has been entirely re-written to use the new async/await features available in Node.JS version 8.

If you don't know about writing javascript code in the async/await style, there are many resources online, but this is my favorite: Explaining Async/Await in 7 seconds (you have time for this one!). There are no more callbacks and no more promise chains. You use try/catch to deal with errors. You can use normal for and while loops to work on async methods. The world is so much more pleasant! Code is more readable, and bugs are far easier to find and test.

With the newer versions of node, we also get access to real class methods, which make extending and sharing code much easier.

For example, the run method of an action using api.cache used to look like:

exports.cacheTest = {
  name: 'cacheTest',
  description: 'I will test the internal cache functions of the API',
  inputs: {
    key: {
      required: true,
      formatter: function (s) { return String(s) }
    },
    value: {
      required: true,
      formatter: function (s) { return String(s) },
      validator: function (s) {
        if (s.length < 3) {
          return '`value` should be at least 3 letters long'
        } else { return true }
      }
    }
  },

  run: function (api, data, next) {
    const key = 'cacheTest_' + data.params.key
    const value = data.params.value

    data.response.cacheTestResults = {}

    api.cache.save(key, value, 5000, function (error, resp) {
      if (error) { return next(error) }
      data.response.cacheTestResults.saveResp = resp
      api.cache.size(function (error, numberOfCacheObjects) {
        if (error) { return next(error) }
        data.response.cacheTestResults.sizeResp = numberOfCacheObjects
        api.cache.load(key, function (error, resp, expireTimestamp, createdAt, readAt) {
          if (error) { return next(error) }
          data.response.cacheTestResults.loadResp = {
            key: key,
            value: resp,
            expireTimestamp: expireTimestamp,
            createdAt: createdAt,
            readAt: readAt
          }
          api.cache.destroy(key, function (error, resp) {
            data.response.cacheTestResults.deleteResp = resp
            next(error)
          })
        })
      })
    })
  }

}

But now, can be written simply as:

const {Action, api} = require('actionhero')

module.exports = class CacheTest extends Action {
  constructor () {
    super()
    this.name = 'cacheTest'
    this.description = 'I will test the internal cache functions of the API'
  }

  inputs () {
    return {
      key: {
        required: true,
        formatter: this.stringFormatter,
        validator: this.stringValidator
      },

      value: {
        required: true,
        formatter: this.stringFormatter,
        validator: this.stringValidator
      }
    }
  }

  stringFormatter (s) {
    return String(s)
  }

  stringValidator (s) {
    if (s.length < 3) {
      throw new Error('inputs should be at least 3 letters long')
    } else {
      return true
    }
  }

  async run ({params, response}) {
    const key = 'cacheTest_' + params.key
    const value = params.value

    response.cacheTestResults = {
      saveResp: await api.cache.save(key, value, 5000),
      sizeResp: await api.cache.size(),
      loadResp: await api.cache.load(key),
      deleteResp: await api.cache.destroy(key)
    }
  }
}

The Many Breaking Changes

The ActionHero Core Team had to make a hard decision with this release. This marks the first version we've released that does not work with all active LTS versions of Node.JS. Until now, this was our policy. However, We felt the gains in legibility, productivity, and debugging were so important that leaving 'legacy' users behind was the correct tradeoff.

However, to continue to support ActionHero users on v17, we will break with our other policy of only supporting "master". We've cut a v17 branch, and will continue to accept patches and updates to it until March of 2018. We will also port any security fixes from master back to v17. We know that upgrading to v18 (and perhaps a new version of Node.JS) will be the most difficult ActionHero migration to date, but I assure you it will be worth it!

I've also discussed these thoughts on the first "Always bet on Node podcast" with @dshaw and @mikeal and in this blog post.

API changes and Documentation: docs.actionherojs.com

To ease the upgrade process (and help new users), we have annotated all public APIs, methods and classes within the ActionHero codebase with jsDOC. This allows for a few wonderful things to happen:

  • When viewing the source code, you can see documentation right next to where the method is defined!
  • We can call out which methods are public, and expected to have a stable API (these are the documented ones), and which ones are private (@priavte or not documetned at all).
  • We can build a new docs.actionherojs.com website AUTOMATICALLY from the source code, and always ensure that it is up-to-date.
  • The above site will be included into the releases of ActionHero, and therefore you will always have access to the documentation for your version of ActionHero, even offline.

@gcoonrod has offered to back-port the new JSdoc documentation to the v17 branch of ActionHero, which is one of the ways we have committed to supporting this version of the project.


In a nutshell, the API changes can be described as follows:

Node.js v8.0.0+ is required.

Using these new features requires node V8.x.x and later. ActionHero will no longer be supporting node v4.x.x and v6.x.x. In the future, we can investigate using Babel to transpile for earlier versions, but today, that is not supported.

There are no more callbacks.

Anything that used to have a callback, is now an async method which returns a response, and throws and error. This includes the run method within actions and tasks.

Example:

//old
await api.cache.load('myKey', (error, value) => {
  if (error) { return handleError(error) }  
  //...
})

// new
try {
  let value = await api.cache.load('myKey')
} catch (error) {
  api.log(error)
}

You Extend ActionhHero

ll modules of ActionHero (Actions, Tasks, Initializers, Servers and, CLI commands) are all now classes which extend some a similarly named module from ActionHero.

Actions

const {Action, api} = require('actionhero')

module.exports = class MyAction extends Action {
  constructor () {
    super()
    this.name = 'myAction'
    this.description = 'myAction'
    this.outputExample = {}
  }

  async run (data) {
    api.log('yay')
    // your logic here
  }
}

Tasks

const {Task, api} = require('actionhero')

module.exports = class MyTask extends Task {
  constructor () {
    super()
    this.name = 'myTask'
    this.description = 'myTask'
    this.frequency = 0
  }

  async run (data) {
    api.log('yay')
    // your logic here
  }
}

This allows you to create your own classes which might share common inputs, middleware, or helper functions, ie: MyAction extends AuthenticatedAction, where AuthenticatedAction extends ActionHero.Action.

You require the api object

Every method which used to supply the api object as an argument no longer does. You now const api = require('actionhero').api wherever you need it. This is helpful for a few reasons:

  • Method signatures get cleaned up.
  • You can require the api object once in an class, and use it for every method (no need to pass it between functions, or set this.api = api).
  • You can reach the api object from helper files now.

No more fakeredis

Support fakeredis is dropped. In fact, the maintainer has stoped supporting it. ioredis is now a required dependent package. That said, if you don't need any of the redis features (cache, chat, pub/sub, tasks), you can disable them all with api.config.redis.enabled = false configuration option, and you can still boot an ActionHero server without redis.

How to require plugins has changed

Remove actionhero link (and actionhero unlink) in favor of config/plugins.js

Using linkfiles was brittle. It didn't work with namespaced NPM packages, and struggled on windows computers. We are returning to using a configuration file to define plugins which your application will load.

// config/plugins.js

// If you want to use plugins in your application, include them here:
return {
  'myPlugin': { path: __dirname + '/../node_modules/myPlugin' }
}

// You can also toggle on or off sections of a plugin to include (default true for all sections):
return {
  'myPlugin': {
    path: __dirname + '/../node_modules/myPlugin',
    actions: true,
    tasks: true,
    initializers: true,
    servers: true,
    public: true
  }
}

This also makes testing plugins much easier, as you can boot up an ActionHero server from within your plugin (if actionhero is a devDependancy) with the following:

const path = require('path')
process.env.PROJECT_ROOT = path.join(__dirname, '..', 'node_modules', 'actionhero')
const ActionHero = require('actionhero')
const actionhero = new ActionHero.Process()
let api

describe('My Plugin', () => {
  before(async () => {
    let configChanges = {
      plugins: {
        'testPlugin': { path: path.join(__dirname, '..') }
      }
    }

    api = await actionhero.start({configChanges})
  })

  after(async () => { await actionhero.stop() })

  it('does stuff', async () => {
    //...
  })
})

Add actionhero generate plugin

A helper which you can use in an empty directory which will create a template plugin project

Remove api.utils.recursiveDirectoryGlob in favor of the nom glob package.

We can use the standard package now that we no longer need to traverse custom ActionHero link files

Other notes

  • All dependent packages have been updated to their latest versions.
  • ActionHero will no longer throw an error and exit if you override a core (or existing) initializer, action, task, etc. We now log an error and allow it.
  • A related change to Node Resque https://github.com/taskrabbit/node-resque/pull/212 is part of this update.
    A related change to Browser Fingerprint https://github.com/actionhero/browser_fingerprint/releases/tag/v1.0.1 is part of this update.
  • ActionheroClient (the included client library for browser websocket clients) as been named a more clear ActionheroWebsocketClient to avoid ambiguity. The node sever-sever package has been renamed actionhero-node-client to help clear up any confusion.

Thank you.

Thank you to everyone who helped make this release possible, especially @gcoonrod and @crrobinson14.

actionhero -

Published by evantahler about 7 years ago

actionhero -

Published by evantahler about 7 years ago

actionhero -

Published by evantahler about 7 years ago

actionhero - v17.1.0: Raw HTTP body and JSON param filtering

Published by evantahler about 7 years ago

Store connection.rawConnection.params.rawBody on web connections

Some APIs ask you to compare checksums of the body of a request (https://github.com/actionhero/actionhero/issues/1081) to ensure their origin. Until now, ActionHero did not allow you access to the raw POST/PUT body of an http request. A new config option, api.config.servers.web.saveRawBody can be toggled to true to save the body of your requests as a Buffer.

Please note that enabling this feature may increase the memory requirements of each of your actions.

Use dot-prop package with api.config.general.filteredParams to allow for filtering of JSON params

Uses the dot-prop package to allow for filtering parameters using a dot notation.

Added to api.utils.filterObjectForLogging since I wanted the filter for my own logging messages as well (not just action logs)

//example, as filled from config/api.js
filteredParams: [ 'p4', 'o1.p3' ],

//example, as used in initializers/actionProcessor.js
var params = { p1 : 1, o1 : { p2: 'ok', p3: 'secret' }, p4: 'long string that clogs logs' }
var filteredParams = api.utils.filterObjectForLogging( params)
//filteredParams --> { p1 : 1, o1 : { p2: 'ok', p3: '[FILTERED]' }, p4: '[FILTERED]' }

Misc

  • All dependent packages updated to their latest versions
  • Updated worker log messages to start with to [ worker ] (rather than worker: ) to match [ action ]
actionhero - v17.0.3: Server Custom Methods

Published by evantahler over 7 years ago

Server Custom Methods

  • You can now create custom methods on your connections!
  • The first of these, which is included within ActionHero by popular request, is connection.setHeader, which is a proxy for connection.rawConnection.res.setHeader
  • You can create you own extensions to servers with a middleware:
//Initializer
 module.exports = {
   startPriority: 1000,
   start: function (api, next) {
     let webServer = api.servers.servers.web
     webServer.connectionCustomMethods = webServer.connectionCustomMethods || {}
     webServer.connectionCustomMethods.requestHeaders = function (connection) {
       return connection.rawConnection.req.headers
     }
   }
 }

 //Action
 module.exports = {
   name: 'logHeaders',
   description 'Log Web Request Headers',
   run: function (api, data, next) {
     let headers = data.connection.requestHeaders()
     api.log('Headers:', 'debug', headers)
     next()
   }
 }
  • Note that the type of connection determines the server, which then sets the custom methods. The above example of connection.setHeader only works for web connections.
  • by @evantahler and @gcoonrod via https://github.com/actionhero/actionhero/pull/1080

Config option to disable access to internal CLI commands

  • Using the new api.config.general.cliIncludeInternal option, you can prevent use of the ActionHero CLI commands in your project from including the internal methods, like generate and generateAction
  • This is helpful if you are shipping an application with your own CLI commands
  • bu @evantahler via https://github.com/actionhero/actionhero/pull/1076

Fix memory leak for actions with data.toRender: false

ClusterPidfile Cleanup

New ActionHero Website

Misc

  • Commit NPM package-lock.json
  • Update integration tests to run on node v8
  • Move test runner to circle.ci from travis.ci
actionhero - v17.0.2: Redis Priority and Dependency Updates

Published by evantahler over 7 years ago

Update Redis stop priority to be last

The Reids initializer is likely to be relied on by many other parts of the system. To that end, the 'stop' priority of redis is now 99999

Update Major versions of dependancies

  • cross-env now at v5.0.x
  • ws now at v3.0.x
  • ioredis now at v3.0.x
actionhero - v17.0.1: revert to use recursiveDirectoryGlob for link following

Published by evantahler over 7 years ago

Revert to use recursiveDirectoryGlob for link following

We have reverted to bring back api.utils.recursiveDirectoryGlob for link following. Perviously, v17.0.0 did not follow ActionHero's link files properly

Catch Exceptions in Initializers

via @S3bb1 via https://github.com/actionhero/actionhero/pull/1045

actionhero - v17.0.0 Localization and Custom CLI Commands

Published by evantahler over 7 years ago

Saner Localization

  • clarify the usage of i18n and connection.localize by converting all localizations to use mustache-style strings. IE: data.connection.localize(['hello {{name}}', {name: 'Evan'}]) rather than data.connection.localize(['hello %s', 'Evan'])
  • [BREAKING CAHNGE] Stop localizing all internal and logging messages
    • this feature was rarely used and added complexity. This also slowed down the logging of message from the server as it required 2 interpolation passes each time
    • convert all internal message interpolation into es6 interpolation, ie: a log ${message}. Now that we required node v4+, this is OK
  • [BREAKTING CHANGE] move all user-visible strings from actionhero into the locale file. This creates a single file which can be used to modify ActionHero strings
  • ensure that by default, calling either api.i18n.localize or connection.localize on an unknown string will not cause an error, and this string will be added to the locale file properly
  • by @evantahler via https://github.com/actionhero/actionhero/pull/1036

Custom CLI Commands

Allow actionhero developers to create new files in ./bin which can be run via the CLI. These commands will have access to a the ActionHero api and CLI arguments object within a run method.

For example, a file in ./bin/redis/keys would be run via ./node_modules/.bin/actionhero redis keys --prefix actionhero

'use strict'

module.exports = {
  name: 'redis keys',
  description: 'I list all the keys in redis',
  example: 'actionhero keys --prefix actionhero',

  inputs: {
    prefix: {
      requried: true,
      default: 'actionhero',
      note: 'the redis prefix for searching keys'
    }
  },

  run: function (api, data, next) {
    api.redis.clients.client.keys(data.params.prefix, (error, keys) => {
      if (error) { throw error }

      api.log(`Found ${keys.length} keys:`)
      keys.forEach((k) => { api.log(k) })

      return next(null, true)
    })
  }
}
  • [breaking change]: ActionHero projects will now be generated with a ./bin directory.
  • [breaking change]: ./config/api.js now defines api.config.general.paths.cli, which defaults to path.join(__dirname, '/../bin'). This is where the actionhero script runner sources its files.

ActionHero CLI commands have:

  • name
  • description
  • example

Inputs for CLI commands have

  • required (true/false)
  • default (string only)
  • note

These are sourced by actionhero help, and the example above would return:

* redis keys
  description: I list all the keys in redis
  example: actionhero keys --prefix actionhero
  inputs:
    [prefix] (optional)
      note: the redis prefix for searching keys
      default: actionhero

This PR includes a refactor of all CLI commands

Replace api.utils.recursiveDirectoryGlob with the glob package


Breaking Changes and How to Overcome Them:

  • Localization (i18n)
    • In ./config/i18n.js be sure to enable objectNotation, or else the new locale file will be gibberish to ActionHero
    • As of this release, ActionHero no longer localizes its log messages. This is done to simplify and speed up the logger methods. There is not mitigation path here without overwriting the api.log() method.
    • Any use of % interpolation should be removed from your logger strings. Favor native JS string templates.
  • ActionHero now ships with locale files by default.
    • You will need to acquire the default locale file and copy it into ./locales/en.json within your project.
    • The error reporters have all been changed to use these new locale file and mustache-style syntax.
      Update your from the default errors file
    • The welcomeMessage and goodbyeMessage are removed from the config files and ActionHero now refrences the locale files for these strings. Update yours accodingly.
      utils
  • api.utils.recursiveDirectoryGlob has been removed in favor of the glob package. Use this instead.
actionhero - v16.0.5: Connection Internal Errors

Published by evantahler over 7 years ago

This minor release ensures that connections return error objects internally when attempting to use a not-found verb. This also ensure that the socket server responds with the error string in the same manner it used to maintain backwards compatibility.

by @evantahler via https://github.com/actionhero/actionhero/commit/dbef734459212635c5838d11009cff4ac9adfb01