April release - 2022

This release ships with integrated support for testing, improvements to the fakes API, pretty output for the list:routes command, and breaking changes .

You must update all the packages under @adonisjs scope to their latest version. You can run the npm update command or use the following command to upgrade packages manually.

npx npm-check-updates -i

First-class support for testing

AdonisJS now has first-class support for testing. Every new application comes pre-configured with Japa tests runner .

For existing projects, you will have to follow the following steps to configure the tests runner.

Before we get started, make sure to uninstall any Japa related packages you have self-installed in the past and start from scratch.

  1. Update all @adonisjs packages to their latest version.
  2. Run node ace generate:manifest to create a fresh index of the ace commands.
  3. Run node ace configure tests to configure Japa. This command will create all the required files and install Japa related packages.

If everything goes fine until step 3, you will have to make the following changes inside some existing files.

  1. Open the env.ts file and update the enum values for NODE_ENV.

    export default Env.rules({
    NODE_ENV: Env.schema.enum([
    'development',
    'production',
    'testing'
    'test'
    ] as const)
    })
  2. Open the config/shield.ts file (if it exists) and update the following line of code.

    export const csrf: ShieldConfig['csrf'] = {
    enabled: Env.get('NODE_ENV') !== 'testing'
    enabled: Env.get('NODE_ENV') !== 'test'
    }

That's all! You can run the node ace test command to execute the tests. Make sure to also reference the testing documentation .

Validator improvements

Some of the existing validator rules and the string schema type had some technical limitations when applying the sanitization rules.

In the following example, the maxLength rule is applied after the escape option. Since escaping the value can change the length of the string, it results in undesired behavior.

title: schema.string({ escape: true }, [
rules.maxLength(20)
])

It may seem like a straightforward fix, since the validator can apply the escape option after all other validation rules. However, this choice can conflict with other options like trim.

In the case of trimming whitespaces, you would want to be forgiving and trim all the whitespaces before applying the maxLength rule. In a nutshell, you would want

  • First apply the trim rule.
  • Then run all the validations.
  • Then apply the escape rule.
title: schema.string({
escape: true, // 3. and finally this
trim: true, // 1. apply this first
}, [
rules.maxLength(20) // 2. then this
])

As you can notice, the flow of executing rules and applying options is not predictable and neither configurable. Therefore, we have deprecated all the inline sanitization options in favor of equivalent rules.

Since rules are executed in the order they are defined, you have the flexibility to order them as per your application requirements.

trim

The trim option has been deprecated

title: schema.string({
trim: true
})

Instead use rules.trim rule

title: schema.string([
rules.trim()
])

escape

The escape option has been deprecated

title: schema.string({
escape: true
})

Instead use rules.escape rule

title: schema.string([
rules.escape()
])

email (sanitize)

The sanitize option has been deprecated

title: schema.string([
rules.email({
sanitize: {
lowerCase: true,
removeSubaddress: true
}
})
])

Instead use rules.normalizeEmail rule

title: schema.string([
rules.email(),
rules.normalizeEmail({
allLowercase: true,
gmailRemoveSubaddress: true,
})
])

url (ensureProtocol, stripWWW)

The ensureProtocol, and stripWWW options have been deprecated

title: schema.string([
rules.url({
stripWWW: true,
ensureProtocol: true
})
])

Instead use rules.normalizeUrl rule

title: schema.string([
rules.url(),
rules.normalizeUrl({
normalizeProtocol: true,
stripWWW: true,
forceHttps: true,
})
])

Pretty routes list

Julien Ripouteau earlier created a pretty-list-routes package, which has been merged to the core of the framework. The node ace list:routes output looks as follows.

You can still view the routes as a table by using --table flag.

node ace list:routes --table

Deprecate Event emitter traps

The Event.trap and Event.trapAll methods have been deprecated. We recommend you use Event fakes instead.

import Event from '@ioc:Adonis/Core/Event'
const fakeEmitter = Event.fake()
Event.emit('new:user')
fakeEmitter.exists('new:user')
Event.restore()

Breaking changes

This release introduce following breaking changes.

Remove Mail traps

We have removed the Mail.trap and Mail.trapAll methods. We recommend you use fakes instead.

import Mail from '@adonisjs/mail'
// Fake default mailer
const fakeMailer = Mail.fake()
// Fake "s3", "local" mailer
const fakeMailer = Mail.fake(['s3', 'local'])
// Send email
Mail.send()
fakeMailer.exists({ to: 'virk@adonisjs.com' })
fakeMailer.exists({ subject: 'Welcome to AdonisJS!' })
Mail.restore()
Mail.restore(['s3', 'local'])

Rename testing environment to test

Earlier the testing environment was created when the value NODE_ENV=testing. However, the Node ecosystem commonly uses the value test to detect the testing environment. Therefore, we decided to use test as well.

This change will require you to.

  • Update the NODE_ENV enum options inside env.ts file.

    export default Env.rules({
    NODE_ENV: Env.schema.enum([
    'development',
    'production',
    'testing'
    'test'
    ] as const)
    })
  • Update config/shield.ts file to check against the literal value test.

    export const csrf: ShieldConfig['csrf'] = {
    enabled: Env.get('NODE_ENV') !== 'testing'
    enabled: Env.get('NODE_ENV') !== 'test'
    }
  • Rename existing .env.testing file to .env.test.