All Versions
55
Latest Version
Avg Release Cycle
8 days
Latest Release
1228 days ago

Changelog History
Page 1

  • v25.0.0-alpha.5 Changes

    December 08, 2020
    • ๐Ÿ‘‰ Use Commander for Actionhero CLI (#1670)
      • Much simpler and clearer running of Actionhero CLI commands
      • [BREAKING CHANGE] Commands now have optional initialize and start options, so you can opt-into initializing or starting your server as needed for your CLI command. The default is to initialize initialize=true but not start (start=false)
      • [BREAKING CHANGE] Command names with spaces now have -. IE: actionhero generate action is now actionhero generate-action, etc.
  • v25.0.0-alpha.4 Changes

    December 07, 2020
    • โœ… Test mode still continues to use Typescript #1669
      • Fixes a bug introduced in #1668 - we want to still default to testing Typescript files
  • v25.0.0-alpha.3 Changes

    December 07, 2020
    • โœ… Replace ACTIONHERO_TEST_FILE_EXTENSION with ACTIONHERO_TYPESCRIPT_MODE (boolean) #1668
      • [Breaking Change] - Replaces the old process.env.ACTIONHERO_TEST_FILE_EXTENSION with process.env.ACTIONHERO_TYPESCRIPT_MODE to more declaratively state if we should load typescript files or not.
  • v25.0.0-alpha.2 Changes

    December 05, 2020
    • 0๏ธโƒฃ Default action logging output to match action result returned to web client (#1661)
      • [BREAKING] - The default HTTP response code if an Action throws is now 500, configured by a new config setting, config.servers.web.defaultErrorStatusCode (default 500). This option is only effective if the status code has not been set by the action.
      • [BREAKING] - Error log message format has changed
    • โฌ†๏ธ Upgrade to Node Resque v8.2.0 (#1667)
  • v25.0.0-alpha.1 Changes

    November 18, 2020

    Pre-Release: v25.0.0-alpha.1

    • ๐Ÿคก Actionhero can be run with ioredis-mock (Redis is always enabled) (#1653)
    • โœ… Browser tests with Puppeteer rather than Selenium (#1562)

    ๐Ÿš€ Install pre-releases with npm install actionhero@next

  • v24.0.4 Changes

    November 16, 2020
    • Replace up to 5 params in routes for swagger with Swagger param paths (#1643)
    • โšก๏ธ Update docs (#1648), c25bc2d
    • โž• Add a Dedication to the Readme (#1642)
    • โšก๏ธ Update dependencies
  • v24.0.3 Changes

    November 04, 2020

    ๐Ÿ‘ท Suppress "Job already enqueued at this time with same arguments" errors with recurring tasks #1641

    โž• Adds an option to task.enqueueAt() and task.enqueueIn() to suppress errors if there is a duplicate task at the same time with the same arguments. We use this new setting when (re)enqueueing periodic tasks.

    /\*\* \* Enqueue a task to be performed in the background, at a certain time in the future. \* Will throw an error if redis cannot be reached. \* \* Inputs: \* \* taskName: The name of the task. \* \* inputs: inputs to pass to the task. \* \* queue: (Optional) Which queue/priority to run this instance of the task on. \* \* suppressDuplicateTaskError: (optional) Suppress errors when the same task with the same arguments are double-enqueued for the same time \*/export async function enqueueAt(timestamp: number,taskName: string,inputs: TaskInputs,queue: string = api.tasks.tasks[taskName].queue,suppressDuplicateTaskError = false) {await validateInput(taskName, inputs);return api.resque.queue.enqueueAt(timestamp,queue,taskName,[inputs],suppressDuplicateTaskError);}/\*\* \* Enqueue a task to be performed in the background, at a certain number of ms from now. \* Will throw an error if redis cannot be reached. \* \* Inputs: \* \* timestamp: At what time the task is able to be run. Does not guarantee that the task will be run at this time. (in ms) \* \* taskName: The name of the task. \* \* inputs: inputs to pass to the task. \* \* queue: (Optional) Which queue/priority to run this instance of the task on. \* \* suppressDuplicateTaskError: (optional) Suppress errors when the same task with the same arguments are double-enqueued for the same time \*/export async function enqueueIn(time: number,taskName: string,inputs: TaskInputs,queue: string = api.tasks.tasks[taskName].queue,suppressDuplicateTaskError = false) {await validateInput(taskName, inputs);return api.resque.queue.enqueueIn(time,queue,taskName,[inputs],suppressDuplicateTaskError);}
    

    ๐Ÿ”€ Merges in the changes from Node Resque:

    WS client state back to 'connected' on reconnect event #1639

  • v24.0.2 Changes

    October 31, 2020
    • โšก๏ธ Update Dependencies (#1637)
  • v24.0.1 Changes

    October 26, 2020

    Prefer the end command when disconnecting from redis #1635

    With ioredis "quit" will try to reconnect now. We want to "end" the connections when shutting down.

    ๐Ÿ‘€ If you are seeing timeouts when completing your jest tests or errors like Jest did not exit one second after the test run has completed. this may be the culprit

    Actions can be called in-line #1628

    This PR introduces action.run() which allows Actions to be run arbitrarily from elsewhere in the codebase. With this, you can have one Action call another, have a Task run Action, etc. Middleware for the the Action will be run. action.run() creates a new proxy connection with only the arguments you provide to the method.

    import { action } from "actionhero"const nameOfAction = 'myAction'const actionVersion = 'v1' // or leave null to use the latest versionconst params = {key: 'value'} // the params which would be parsed from the clientconst connectionProperties = {} // special properties on the connection which may be expected by the action or middleware. Perhaps "session.id" or "authenticated = true" depending on your middlewareconst response = await action.run(nameOfAction, actionVersion, params, connectionProperties);
    

    So, if you wanted an Action which combines the responses of 2 other Actions:

    import { Action, action } from "actionhero";export class RecursiveAction extends Action {constructor() {super();this.name = "recursiveAction";this.description = "I am an action that runs 2 other actions";this.outputExample = {};}async run() {const localResponse = { local: true };const firstActionResponse = await action.run("otherAction");const secondActionResponse = await action.run("anotherAction");return Object.assign(firstActionResponse, secondActionResponse, localResponse);}}
    

    Future work:

    • Type the responses of action.run() according the run method's return types.

    โšก๏ธ Update dependencies

  • v24.0.0 Changes

    October 11, 2020

    ๐Ÿš€ A new major release with lots of new features!

    What's New

    node-resque v8 (#1606)

    โฑ This new version of node-resque did a lot of work to make your tasks more idempotent. It's now harder to loose jobs if your application crashes. Be sure to set config.tasks.retryStuckJobs (boolean) to enable the automatic-retrying of stuck tasks by the resque scheduler.

    From actionhero/node-resque#453

    ๐Ÿ“‡ > This PR moves to use a Lua script to atomically (within the redis srerver) both pop the job from the list and write it to the Worker's metadata.

    ๐Ÿ“ฆ > Due to the sematics of how ioredis loads and uses lua commands, this is a breaking change as this may break users who do not use the ioredis package

    Redis version >= 2.6.0 is now required

    โž• Add automaticRoutes, Remove query and simple routing (#1607)

    ๐ŸŒ Per the discussion in #1579, Actionhero is removing the options config.servers.web.simpleRouting and config.servers.web.queryRouting. These options were confusing, and generally conflicted with the config/routes.ts file. We want to be clear to new users that the "right" way to define the routes for your Actionhero APIs is in /config/routes.ts.

    ๐Ÿš€ That said, there are times when you may need to quickly build routes automatically from your actions, like when testing or deploying this core Actionhero project directly ๐Ÿ˜. For those cases, this PR adds a new option, config.servers.web.automaticRoutes. This new option is similar-ish to the old automaticRoutes option, but differs in a few key ways:

    • 0๏ธโƒฃ disabled by default. New users will not get confused about why actions are showing up automatically
    • ๐Ÿ‘ can support some/many HTTP verbs. The verb(s) you want are now declarative, ie:
      • config.servers.web.automaticRoutes = ['get']
      • config.servers.web.automaticRoutes = ['get', 'post', 'head']

    For newly generated Actionhero Projects, we will start with your config/routes.ts file including a get entry for the Status, Swagger, and CreateChatRoom actions, so the examples continue to work

    Actions can return responses to determine response types (#1610)

    ๐Ÿ— The preferred way to describe an Action's run method is now by returning an object which you want to send to your consumers. By doing this, you are building up a Typescript type which can then be used in your API to type-check API responses!

    For example:

    // src/actions/randomNumber.tsimport { Action } from "actionhero";export class RandomNumber extends Action {constructor() {super();this.name = "randomNumber";this.description = "I am an API method which will generate a random number";this.outputExample = { randomNumber: 0.123 };}async run({ connection }) {const randomNumber = Math.random();const stringRandomNumber: string = connection.localize(["Your random number is {{randomNumber}}",{ randomNumber },]);return { randomNumber, stringRandomNumber };}}
    

    Now, you can load in the action and inspect the run method's return type:

    const { RandomNumber } = await import("../../src/actions/randomNumber");type ResponseType = UnwrapPromise\<typeof RandomNumber.prototype.run\>;// now that we know the types, we can enforce that new objects match the type// this is OK!const responsePayload: ResponseType = {randomNumber: 1,stringRandomNumber: "some string",};// this fails compilation (missing stringRandomNumber):const responsePayload: ResponseType = {randomNumber: 1,};
    

    The type information is also available to your IDE

    Screen Shot 2020-10-06 at 4 33 30 PM

    Setting data.response in the action is still possible, but now it will be discouraged by the class Action, which expects the run method to return an object or null.

    Actionhero now includes the helper types <UnwrapPromise> and <AssertEqualType> for these types of use cases.

    โšก๏ธ Other Updates:

    • cache.keys can be provided an optionalScopePrefix (#1612)
    • Do not load routes from Actionhero core (#1613)
    • Replace require with await import where possible (#1614)

    Migration Path

    ๐Ÿ†• New Config Options which should be added:

    • ๐ŸŒ config.servers.web.automaticRoutes = []
    • ๐Ÿ‘ท config.tasks.retryStuckJobs = false

    ๐Ÿšš Config Options which should be removed:

    • ๐ŸŒ config.servers.web.simpleRouting (spiritually replaced with config.servers.web.automaticRoutes)
    • ๐ŸŒ config.servers.web.queryRouting (depreciated)

    ๐Ÿšš And if you want to use the new Typescript features, change your Actions to return the response you want to send rather than using data.response. data.response will be removed in a future version of Actionhero.