The core message framework manages messages and allows them to be accessible by all plugins and consumers of sfdx-core. It is set up to handle localization down the road at no additional effort to the consumer. Messages can be used for anything from user output (like the console), to error messages, to returned data from a method.

Messages are loaded from loader functions. The loader functions will only run when a message is required. This prevents all messages from being loaded into memory at application startup. The functions can load from memory, a file, or a server.

In the beginning of your app or file, add the loader functions to be used later. If using json or js files in a root messages directory (<moduleRoot>/messages), load the entire directory automatically with Messages.importMessagesDirectory. Message files must be the following formates.

A .json file:

{
"msgKey": "A message displayed in the user",
"msgGroup": {
"anotherMsgKey": "Another message displayed to the user"
},
"listOfMessage": ["message1", "message2"]
}

A .js file:

module.exports = {
msgKey: 'A message displayed in the user',
msgGroup: {
anotherMsgKey: 'Another message displayed to the user'
},
listOfMessage: ['message1', 'message2']
}

A .md file:

# msgKey
A message displayed in the user

# msgGroup.anotherMsgKey
Another message displayed to the user

# listOfMessage
- message1
- message2

The values support util.format style strings that apply the tokens passed into Message.getMessage

Note: When running unit tests individually, you may see errors that the messages aren't found. This is because index.js isn't loaded when tests run like they are when the package is required. To allow tests to run, import the message directory in each test (it will only do it once) or load the message file the test depends on individually.

// Create loader functions for all files in the messages directory
Messages.importMessagesDirectory(__dirname);

// or, for ESM code
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)

// Now you can use the messages from anywhere in your code or file.
// If using importMessageDirectory, the bundle name is the file name.
const messages: Messages = Messages.loadMessages(packageName, bundleName);

// Messages now contains all the message in the bundleName file.
messages.getMessage('authInfoCreationError');

Type Parameters

  • T extends string

Constructors

  • Create a new messages bundle.

    Note: Use {Messages.loadMessages} unless you are writing your own loader function.

    Type Parameters

    • T extends string

    Parameters

    • bundleName: string

      The bundle name.

    • locale: string

      The locale.

    • messages: StoredMessageMap

      The messages. Can not be modified once created.

    Returns Messages<T>

Properties

bundleName: string

The bundle name.

locale: string

The locale of the messages in this bundle.

The messages. Can not be modified once created.

Methods

  • Convenience method to create errors using message labels.

    error.name will be the upper-cased key, remove prefixed error. and will always end in Error. error.actions will be loaded using ${key}.actions if available.

    Parameters

    • key: T

      The key of the error message.

    • tokens: Tokens = []

      The error message tokens.

    • actionTokens: Tokens = []

      The action messages tokens.

    • Optional exitCodeOrCause: number | Error

      The exit code which will be used by SfdxCommand or the underlying error that caused this error to be raised.

    • Optional cause: Error

      The underlying error that caused this error to be raised.

    Returns SfError<AnyJson>

  • Convenience method to create info using message labels.

    info.name will be the upper-cased key, remove prefixed info. and will always end in Info. info.actions will be loaded using ${key}.actions if available.

    Parameters

    • key: T

      The key of the warning message.

    • tokens: Tokens = []

      The warning message tokens.

    • actionTokens: Tokens = []

      The action messages tokens.

    Returns StructuredMessage

  • Convenience method to create warning using message labels.

    warning.name will be the upper-cased key, remove prefixed warning. and will always end in Warning. warning.actions will be loaded using ${key}.actions if available.

    Parameters

    • key: T

      The key of the warning message.

    • tokens: Tokens = []

      The warning message tokens.

    • actionTokens: Tokens = []

      The action messages tokens.

    Returns StructuredMessage

  • Get messages using a message key and use the tokens as values for tokenization.

    This will return all messages if the key is an array in the messages file.

    {
    "myKey": [ "message1", "message2" ]
    }
    # myKey
    * message1
    * message2

    Parameters

    Returns string[]

  • Get the locale. This will always return 'en_US' but will return the machine's locale in the future.

    Returns string

  • Add a single message file to the list of loading functions using the file name as the bundle name. The loader will only be added if the bundle name is not already taken.

    Parameters

    • packageName: string

      The npm package name.

    • filePath: string

      The path of the file.

    Returns void

  • Import all json and js files in a messages directory. Use the file name as the bundle key when Messages.loadMessages is called. By default, we're assuming the moduleDirectoryPart is a typescript project and will truncate to root path (where the package.json file is). If your messages directory is in another spot or you are not using typescript, pass in false for truncateToProjectPath.

    // e.g. If your message directory is in the project root, you would do:
    Messages.importMessagesDirectory(__dirname);

    Parameters

    • moduleDirectoryPath: string

      The path to load the messages folder.

    • truncateToProjectPath: boolean = true

      Will look for the messages directory in the project root (where the package.json file is located). i.e., the module is typescript and the messages folder is in the top level of the module directory.

    • Optional packageName: string

      The npm package name. Figured out from the root directory's package.json.

    Returns void

  • Support ESM plugins who can't use __dirname

    Parameters

    • metaUrl: string

      pass in import.meta.url

    • truncateToProjectPath: boolean = true

      Will look for the messages directory in the project root (where the package.json file is located). i.e., the module is typescript and the messages folder is in the top level of the module directory.

    • Optional packageName: string

      The npm package name. Figured out from the root directory's package.json.

    Returns void

  • Check if a bundle already been loaded.

    Parameters

    • packageName: string

      The npm package name.

    • bundleName: string

      The bundle name.

    Returns boolean

  • Load messages for a given package and bundle. If the bundle is not already cached, use the loader function created from Messages.setLoaderFunction or Messages.importMessagesDirectory.

    Messages.importMessagesDirectory(__dirname);
    const messages = Messages.loadMessages('packageName', 'bundleName');

    Parameters

    • packageName: string

      The name of the npm package.

    • bundleName: string

      The name of the bundle to load.

    Returns Messages<string>

  • Set a custom loader function for a package and bundle that will be called on Messages.loadMessages.

    Parameters

    • packageName: string

      The npm package name.

    • bundle: string

      The name of the bundle.

    • loader: LoaderFunction<string>

      The loader function.

    Returns void