Helpers

Helpers reference

AdonisJS bundles the utilities the framework uses into the helpers module and makes them available to your application code. Since these utilities are already installed and used by the framework, the helpers module does not add any additional bloat to your node_modules.

The helper methods are exported from the following modules.

import is from '@adonisjs/helpers/is'
import * as helpers from '@adonisjs/core/helpers'
import string from '@adonisjs/core/helpers/string'

escapeHTML

Escape HTML entities in a string value. Under the hood, we use the he package.

import string from '@adonisjs/core/helpers/string'
string.escapeHTML('<p> foo © bar </p>')
// &lt;p&gt; foo © bar &lt;/p&gt;

Optionally, you can encode non-ASCII symbols using the encodeSymbols option.

import string from '@adonisjs/core/helpers/string'
string.escapeHTML('<p> foo © bar </p>', {
encodeSymbols: true,
})
// &lt;p&gt; foo &#xA9; bar &lt;/p&gt;

encodeSymbols

You may encode non-ASCII symbols in a string value using the encodeSymbols helper. Under the hood, we use he.encode method.

import string from '@adonisjs/core/helpers/string'
string.encodeSymbols('foo © bar ≠ baz 𝌆 qux')
// 'foo &#xA9; bar &#x2260; baz &#x1D306; qux'

prettyHrTime

Pretty print the diff of process.hrtime method.

import { hrtime } from 'node:process'
import string from '@adonisjs/core/helpers/string'
const startTime = hrtime()
await someOperation()
const endTime = hrtime(startTime)
console.log(string.prettyHrTime(endTime))

isEmpty

Check if a string value is empty.

import string from '@adonisjs/core/helpers/string'
string.isEmpty('') // true
string.isEmpty(' ') // true

truncate

Truncate a string at a given number of characters.

import string from '@adonisjs/core/helpers/string'
string.truncate('This is a very long, maybe not that long title', 12)
// Output: This is a ve...

By default, the string is truncated exactly at the given index. However, you can instruct the method to wait for the words to complete.

string.truncate('This is a very long, maybe not that long title', 12, {
completeWords: true,
})
// Output: This is a very...

You can customize the suffix using the suffix option.

string.truncate('This is a very long, maybe not that long title', 12, {
completeWords: true,
suffix: '... <a href="/1"> Read more </a>',
})
// Output: This is a very... <a href="/1"> Read more </a>

excerpt

The excerpt method is identical to the truncate method. However, it strips the HTML tags from the string.

import string from '@adonisjs/core/helpers/string'
string.excerpt('<p>This is a <strong>very long</strong>, maybe not that long title</p>', 12, {
completeWords: true,
})
// Output: This is a very...

slug

Generate slug for a string value. The method is exported from the slugify package; therefore, consult its documentation for available options.

import string from '@adonisjs/core/helpers/string'
console.log(string.slug('hello ♥ world'))
// hello-love-world

You can add custom replacements for Unicode values as follows.

string.slug.extend({ '': 'radioactive' })
console.log(string.slug('unicode ♥ is ☢'))
// unicode-love-is-radioactive

interpolate

Interpolate variables inside a string. The variables must be inside double curly braces.

import string from '@adonisjs/core/helpers/string'
string.interpolate('hello {{ user.username }}', {
user: {
username: 'virk'
}
})
// hello virk

Curly braces can be escaped using the \\ prefix.

string.interpolate('hello \\{{ users.0 }}', {})
// hello {{ users.0 }}

plural

Convert a word to its plural form. The method is exported from the pluralize package.

import string from '@adonisjs/core/helpers/string'
string.plural('test')
// tests

isPlural

Find if a word already is in plural form.

import string from '@adonisjs/core/helpers/string'
string.isPlural('tests') // true

pluralize

This method combines the singular and the plural methods and uses one or the other based on the count. For example:

import string from '@adonisjs/core/helpers/string'
string.pluralize('box', 1) // box
string.pluralize('box', 2) // boxes
string.pluralize('box', 0) // boxes
string.pluralize('boxes', 1) // box
string.pluralize('boxes', 2) // boxes
string.pluralize('boxes', 0) // boxes

The pluralize property exports additional methods to register custom uncountable, irregular, plural, and singular rules.

import string from '@adonisjs/core/helpers/string'
string.pluralize.addUncountableRule('paper')
string.pluralize.addSingularRule(/singles$/i, 'singular')

singular

Convert a word to its singular form. The method is exported from the pluralize package.

import string from '@adonisjs/core/helpers/string'
string.singular('tests')
// test

isSingular

Find if a word is already in a singular form.

import string from '@adonisjs/core/helpers/string'
string.isSingular('test') // true

camelCase

Convert a string value to camelcase.

import string from '@adonisjs/core/helpers/string'
string.camelCase('user_name') // userName

Following are some of the conversion examples.

InputOutput
'test''test'
'test string''testString'
'Test String''testString'
'TestV2''testV2'
'foo_bar''fooBar'
'version 1.2.10''version1210'
'version 1.21.0''version1210'

capitalCase

Convert a string value to a capital case.

import string from '@adonisjs/core/helpers/string'
string.capitalCase('helloWorld') // Hello World

Following are some of the conversion examples.

InputOutput
'test''Test'
'test string''Test String'
'Test String''Test String'
'TestV2''Test V 2'
'version 1.2.10''Version 1.2.10'
'version 1.21.0''Version 1.21.0'

dashCase

Convert a string value to a dash case.

import string from '@adonisjs/core/helpers/string'
string.dashCase('helloWorld') // hello-world

Optionally, you can capitalize the first letter of each word.

string.dashCase('helloWorld', { capitalize: true }) // Hello-World

Following are some of the conversion examples.

InputOutput
'test''test'
'test string''test-string'
'Test String''test-string'
'Test V2''test-v2'
'TestV2''test-v-2'
'version 1.2.10''version-1210'
'version 1.21.0''version-1210'

dotCase

Convert a string value to a dot case.

import string from '@adonisjs/core/helpers/string'
string.dotCase('helloWorld') // hello.World

Optionally, you can convert the first letter of all the words to lowercase.

string.dotCase('helloWorld', { lowerCase: true }) // hello.world

Following are some of the conversion examples.

InputOutput
'test''test'
'test string''test.string'
'Test String''Test.String'
'dot.case''dot.case'
'path/case''path.case'
'TestV2''Test.V.2'
'version 1.2.10''version.1210'
'version 1.21.0''version.1210'

noCase

Remove all sorts of casing from a string value.

import string from '@adonisjs/core/helpers/string'
string.noCase('helloWorld') // hello world

Following are some of the conversion examples.

InputOutput
'test''test'
'TEST''test'
'testString''test string'
'testString123''test string123'
'testString_1_2_3''test string 1 2 3'
'ID123String''id123 string'
'foo bar123''foo bar123'
'a1bStar''a1b star'
'CONSTANT_CASE ''constant case'
'CONST123_FOO''const123 foo'
'FOO_bar''foo bar'
'XMLHttpRequest''xml http request'
'IQueryAArgs''i query a args'
'dot.case''dot case'
'path/case''path case'
'snake_case''snake case'
'snake_case123''snake case123'
'snake_case_123''snake case 123'
'"quotes"''quotes'
'version 0.45.0''version 0 45 0'
'version 0..78..9''version 0 78 9'
'version 4_99/4''version 4 99 4'
' test ''test'
'something_2014_other''something 2014 other'
'amazon s3 data''amazon s3 data'
'foo_13_bar''foo 13 bar'

pascalCase

Convert a string value to a Pascal case. Great for generating JavaScript class names.

import string from '@adonisjs/core/helpers/string'
string.pascalCase('user team') // UserTeam

Following are some of the conversion examples.

InputOutput
'test''Test'
'test string''TestString'
'Test String''TestString'
'TestV2''TestV2'
'version 1.2.10''Version1210'
'version 1.21.0''Version1210'

sentenceCase

Convert a value to a sentence.

import string from '@adonisjs/core/helpers/string'
string.sentenceCase('getting-started-with-adonisjs')
// Getting started with adonisjs

Following are some of the conversion examples.

InputOutput
'test''Test'
'test string''Test string'
'Test String''Test string'
'TestV2''Test v2'
'version 1.2.10''Version 1 2 10'
'version 1.21.0''Version 1 21 0'

snakeCase

Convert value to snake case.

import string from '@adonisjs/core/helpers/string'
string.snakeCase('user team') // user_team

Following are some of the conversion examples.

InputOutput
'_id''id'
'test''test'
'test string''test_string'
'Test String''test_string'
'Test V2''test_v2'
'TestV2''test_v_2'
'version 1.2.10''version_1210'
'version 1.21.0''version_1210'

titleCase

Convert a string value to the title case.

import string from '@adonisjs/core/helpers/string'
string.titleCase('small word ends on')
// Small Word Ends On

Following are some of the conversion examples.

InputOutput
'one. two.''One. Two.'
'a small word starts''A Small Word Starts'
'small word ends on''Small Word Ends On'
'we keep NASA capitalized''We Keep NASA Capitalized'
'pass camelCase through''Pass camelCase Through'
'follow step-by-step instructions''Follow Step-by-Step Instructions'
'this vs. that''This vs. That'
'this vs that''This vs That'
'newcastle upon tyne''Newcastle upon Tyne'
'newcastle *upon* tyne''Newcastle *upon* Tyne'

random

Generate a cryptographically secure random string of a given length. The output value is a URL-safe base64 encoded string.

import string from '@adonisjs/core/helpers/string'
string.random(32)
// 8mejfWWbXbry8Rh7u8MW3o-6dxd80Thk

sentence

Convert an array of words to a comma-separated sentence.

import string from '@adonisjs/core/helpers/string'
string.sentence(['routes', 'controllers', 'middleware'])
// routes, controllers, and middleware

You can replace the and with an or by specifying the options.lastSeparator property.

string.sentence(['routes', 'controllers', 'middleware'], {
lastSeparator: ', or ',
})

In the following example, the two words are combined using the and separator, not the comma (usually advocated in English). However, you can use a custom separator for a pair of words.

string.sentence(['routes', 'controllers'])
// routes and controllers
string.sentence(['routes', 'controllers'], {
pairSeparator: ', and ',
})
// routes, and controllers

condenseWhitespace

Remove multiple whitespaces from a string to a single whitespace.

import string from '@adonisjs/core/helpers/string'
string.condenseWhitespace('hello world')
// hello world
string.condenseWhitespace(' hello world ')
// hello world

seconds

Parse a string-based time expression to seconds.

import string from '@adonisjs/core/helpers/string'
string.seconds.parse('10h') // 36000
string.seconds.parse('1 day') // 86400

Passing a numeric value to the parse method is returned as it is, assuming the value is already in seconds.

string.seconds.parse(180) // 180

You can format seconds to a pretty string using the format method.

string.seconds.format(36000) // 10h
string.seconds.format(36000, true) // 10 hours

milliseconds

Parse a string-based time expression to milliseconds.

import string from '@adonisjs/core/helpers/string'
string.milliseconds.parse('1 h') // 3.6e6
string.milliseconds.parse('1 day') // 8.64e7

Passing a numeric value to the parse method is returned as it is, assuming the value is already in milliseconds.

string.milliseconds.parse(180) // 180

Using the format method, you can format milliseconds to a pretty string.

string.milliseconds.format(3.6e6) // 1h
string.milliseconds.format(3.6e6, true) // 1 hour

bytes

Parse a string-based unit expression to bytes.

import string from '@adonisjs/core/helpers/string'
string.bytes.parse('1KB') // 1024
string.bytes.parse('1MB') // 1048576

Passing a numeric value to the parse method is returned as it is, assuming the value is already in bytes.

string.bytes.parse(1024) // 1024

Using the format method, you can format bytes to a pretty string. The method is exported directly from the bytes package. Please reference the package README for available options.

string.bytes.format(1048576) // 1MB
string.bytes.format(1024 * 1024 * 1000) // 1000MB
string.bytes.format(1024 * 1024 * 1000, { thousandsSeparator: ',' }) // 1,000MB

ordinal

Get the ordinal letter for a given number.

import string from '@adonisjs/core/helpers/string'
string.ordinal(1) // 1st
string.ordinal(2) // '2nd'
string.ordinal(3) // '3rd'
string.ordinal(4) // '4th'
string.ordinal(23) // '23rd'
string.ordinal(24) // '24th'

safeEqual

Check if two buffer or string values are the same. This method does not leak any timing information and prevents timing attack.

Under the hood, this method uses Node.js crypto.timeSafeEqual method, with support for comparing string values. (crypto.timeSafeEqual does not support string comparison)

import { safeEqual } from '@adonisjs/core/helpers'
/**
* The trusted value, it might be saved inside the db
*/
const trustedValue = 'hello world'
/**
* Untrusted user input
*/
const userInput = 'hello'
if (safeEqual(trustedValue, userInput)) {
// both are the same
} else {
// value mismatch
}

cuid

Create a secure, collision-resistant ID optimized for horizontal scaling and performance. This method uses the @paralleldrive/cuid2 package under the hood.

import { cuid } from '@adonisjs/core/helpers'
const id = cuid()
// tz4a98xxat96iws9zmbrgj3a

You can use the isCuid method to check if a value is a valid CUID.

import { cuid, isCuid } from '@adonisjs/core/helpers'
const id = cuid()
isCuid(id) // true

compose

The compose helper allows you to use TypeScript class mixins with a cleaner API. Following is an example of mixin usage without the compose helper.

class User extends UserWithAttributes(UserWithAge(UserWithPassword(UserWithEmail(BaseModel)))) {}

Following is an example with the compose helper.

  • There is no nesting.
  • The order of mixins is from (left to right/top to bottom). Whereas earlier, it was inside out.
import { compose } from '@adonisjs/core/helpers'
class User extends compose(
BaseModel,
UserWithEmail,
UserWithPassword,
UserWithAge,
UserWithAttributes
) {}

base64

Utility methods to base64 encode and decode values.

import { base64 } from '@adonisjs/core/helpers'
base64.encode('hello world')
// aGVsbG8gd29ybGQ=

Like the encode method, you can use the urlEncode to generate a base64 string safe to pass in a URL.

The urlEncode method performs the following replacements.

  • Replace + with -.
  • Replace / with _.
  • And remove the = sign from the end of the string.
base64.urlEncode('hello world')
// aGVsbG8gd29ybGQ

You can use the decode and the urlDecode methods to decode a previously encoded base64 string.

base64.decode(base64.encode('hello world'))
// hello world
base64.urlDecode(base64.urlEncode('hello world'))
// hello world

The decode and the urlDecode methods return null when the input value is an invalid base64 string. You can turn on the strict mode to raise an exception instead.

base64.decode('hello world') // null
base64.decode('hello world', 'utf-8', true) // raises exception

fsReadAll

Get a list of all the files from a directory. The method recursively fetches files from the main and the sub-folders. The dotfiles are ignored implicitly.

import { fsReadAll } from '@adonisjs/core/helpers'
const files = await fsReadAll(new URL('./config', import.meta.url), { pathType: 'url' })
await Promise.all(files.map((file) => import(file)))

You can also pass the options along with the directory path as the second argument.

type Options = {
ignoreMissingRoot?: boolean
filter?: (filePath: string, index: number) => boolean
sort?: (current: string, next: string) => number
pathType?: 'relative' | 'unixRelative' | 'absolute' | 'unixAbsolute' | 'url'
}
const options: Partial<Options> = {}
await fsReadAll(location, options)
ArgumentDescription
ignoreMissingRootBy default, an exception is raised when the root directory is missing. Setting ignoreMissingRoot to true will not result in an error, and an empty array is returned.
filterDefine a filter to ignore certain paths. The method is called on the final list of files.
sortDefine a custom method to sort file paths. By default, the files are sorted using natural sort.
pathTypeDefine how to return the collected paths. By default, OS-specific relative paths are returned. If you want to import the collected files, you must set thepathType = 'url'

fsImportAll

The fsImportAll method imports all the files recursively from a given directory and sets the exported value from each module on an object.

import { fsImportAll } from '@adonisjs/core/helpers'
const collection = await fsImportAll(new URL('./config', import.meta.url))
console.log(collection)
  • Collection is an object with a tree of key-value pairs.
  • The key is the nested object created from the file path.
  • Value is the exported values from the module. Only the default export is used if a module has both default and named exports.

The second param is the option to customize the import behavior.

type Options = {
ignoreMissingRoot?: boolean
filter?: (filePath: string, index: number) => boolean
sort?: (current: string, next: string) => number
transformKeys? (keys: string[]) => string[]
}
const options: Partial<Options> = {}
await fsImportAll(location, options)
ArgumentDescription
ignoreMissingRootBy default, an exception is raised when the root directory is missing. Setting ignoreMissingRoot to true will not result in an error, and an empty object will be returned.
filterDefine a filter to ignore certain paths. By default, only files ending with .js, .ts, .json, .cjs, and .mjs are imported.
sortDefine a custom method to sort file paths. By default, the files are sorted using natural sort.
transformKeysDefine a callback method to transform the keys for the final object. The method receives an array of nested keys and must return an array.

String builder

The StringBuilder class offers a fluent API to perform transformations on a string value. You may get an instance of string builder using the string.create method.

import string from '@adonisjs/core/helpers/string'
const value = string
.create('userController')
.removeSuffix('controller') // user
.plural() // users
.snakeCase() // users
.suffix('_controller') // users_controller
.ext('ts') // users_controller.ts
.toString()

Message builder

The MessageBuilder class offers an API to serialize JavaScript data types with an expiry and purpose. You can either store the serialized output in safe storage like your application database or encrypt it (to avoid tampering) and share it publicly.

In the following example, we serialize an object with the token property and set its expiry to be 1 hour.

import { MessageBuilder } from '@adonisjs/core/helpers'
const builder = new MessageBuilder()
const encoded = builder.build(
{
token: string.random(32),
},
'1 hour',
'email_verification'
)
/**
* {
* "message": {
* "token":"GZhbeG5TvgA-7JCg5y4wOBB1qHIRtX6q"
* },
* "purpose":"email_verification",
* "expiryDate":"2022-10-03T04:07:13.860Z"
* }
*/

Once you have the JSON string with the expiry and the purpose, you can encrypt it (to prevent tampering) and share it with the client.

During the token verification, you can decrypt the previously encrypted value and use the MessageBuilder to verify the payload and convert it to a JavaScript object.

import { MessageBuilder } from '@adonisjs/core/helpers'
const builder = new MessageBuilder()
const decoded = builder.verify(value, 'email_verification')
if (!decoded) {
return 'Invalid payload'
}
console.log(decoded.token)

Secret

The Secret class lets you hold sensitive values within your application without accidentally leaking them inside logs and console statements.

For example, the appKey value defined inside the config/app.ts file is an instance of the Secret class. If you try to log this value to the console, you will see [redacted] and not the original value.

For demonstration, let's fire up a REPL session and try it.

node ace repl
> (js) config = await import('./config/app.js')
# [Module: null prototype] {
# appKey: [redacted],
# http: {
# }
# }
> (js) console.log(config.appKey)
# [redacted]

You can call the config.appKey.release method to read the original value. The purpose of the Secret class is not to prevent your code from accessing the original value. Instead, it provides a safety net from exposing sensitive data inside logs.

Using the Secret class

You can wrap custom values inside the Secret class as follows.

import { Secret } from '@adonisjs/core/helpers'
const value = new Secret('some-secret-value')
console.log(value) // [redacted]
console.log(value.release()) // some-secret-value

Types detection

We export the @sindresorhus/is module from the helpers/is import path, and you may use it to perform the type detection in your apps.

import is from '@adonisjs/helpers/is'
is.object({}) // true
is.object(null) // false