@salesforce/core
Version:
Core libraries to interact with SFDX projects, orgs, and APIs.
253 lines (252 loc) • 10.4 kB
TypeScript
import { AnyJson } from '@salesforce/ts-types';
import { SfdxError } from './sfdxError';
export declare type Tokens = Array<string | boolean | number | null | undefined>;
/**
* A loader function to return messages.
*
* @param locale The local set by the framework.
*/
export declare type LoaderFunction<T extends string> = (locale: string) => Messages<T>;
export declare type StoredMessage = string | string[] | {
[s: string]: StoredMessage;
};
export declare type StoredMessageMap = Map<string, StoredMessage>;
/**
* 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 {@link Messages.importMessagesDirectory}. Message files must be the following formates.
*
* A `.json` file:
* ```json
* {
* "msgKey": "A message displayed in the user",
* "msgGroup": {
* "anotherMsgKey": "Another message displayed to the user"
* },
* "listOfMessage": ["message1", "message2"]
* }
* ```
*
* A `.js` file:
* ```javascript
* module.exports = {
* msgKey: 'A message displayed in the user',
* msgGroup: {
* anotherMsgKey: 'Another message displayed to the user'
* },
* listOfMessage: ['message1', 'message2']
* }
* ```
*
* A `.md` file:
* ```markdown
* # msgKey
* A message displayed in the user
*
* # msgGroup.anotherMsgKey
* Another message displayed to the user
*
* # listOfMessage
* - message1
* - message2
* ```
*
* The values support [util.format](https://nodejs.org/api/util.html#util_util_format_format_args) style strings
* that apply the tokens passed into {@link 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.
*
* ```typescript
* // Create loader functions for all files in the messages directory
* Messages.importMessagesDirectory(__dirname);
*
* // 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.load(packageName, bundleName);
*
* // Messages now contains all the message in the bundleName file.
* messages.getMessage('authInfoCreationError');
* ```
*/
export declare class Messages<T extends string> {
private messages;
private static loaders;
private static bundles;
/**
* The locale of the messages in this bundle.
*/
readonly locale: string;
/**
* The bundle name.
*/
readonly bundleName: string;
/**
* Create a new messages bundle.
*
* **Note:** Use {Messages.load} unless you are writing your own loader function.
*
* @param bundleName The bundle name.
* @param locale The locale.
* @param messages The messages. Can not be modified once created.
*/
constructor(bundleName: string, locale: string, messages: StoredMessageMap);
/**
* Internal readFile. Exposed for unit testing. Do not use util/fs.readFile as messages.js
* should have no internal dependencies.
*
* @param filePath read file target.
* @ignore
*/
static readFile: (filePath: string) => AnyJson;
/**
* Get the locale. This will always return 'en_US' but will return the
* machine's locale in the future.
*/
static getLocale(): string;
/**
* Set a custom loader function for a package and bundle that will be called on {@link Messages.load}.
*
* @param packageName The npm package name.
* @param bundle The name of the bundle.
* @param loader The loader function.
*/
static setLoaderFunction(packageName: string, bundle: string, loader: LoaderFunction<string>): void;
/**
* Generate a file loading function. Use {@link Messages.importMessageFile} unless
* overriding the bundleName is required, then manually pass the loader
* function to {@link Messages.setLoaderFunction}.
*
* @param bundleName The name of the bundle.
* @param filePath The messages file path.
*/
static generateFileLoaderFunction(bundleName: string, filePath: string): LoaderFunction<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.
*
* @param packageName The npm package name.
* @param filePath The path of the file.
*/
static importMessageFile(packageName: string, filePath: string): void;
/**
* Import all json and js files in a messages directory. Use the file name as the bundle key when
* {@link Messages.load} 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);
* ```
*
* @param moduleDirectoryPath The path to load the messages folder.
* @param truncateToProjectPath 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.
* @param packageName The npm package name. Figured out from the root directory's package.json.
*/
static importMessagesDirectory(moduleDirectoryPath: string, truncateToProjectPath?: boolean, packageName?: string): void;
/**
* Load messages for a given package and bundle. If the bundle is not already cached, use the loader function
* created from {@link Messages.setLoaderFunction} or {@link Messages.importMessagesDirectory}.
*
* **NOTE: Use {@link Messages.load} instead for safe message validation and usage.**
*
* ```typescript
* Messages.importMessagesDirectory(__dirname);
* const messages = Messages.load('packageName', 'bundleName');
* ```
*
* @param packageName The name of the npm package.
* @param bundleName The name of the bundle to load.
*/
static loadMessages(packageName: string, bundleName: string): Messages<string>;
/**
* Load messages for a given package and bundle. If the bundle is not already cached, use the loader function
* created from {@link Messages.setLoaderFunction} or {@link Messages.importMessagesDirectory}.
*
* The message keys that will be used must be passed in for validation. This prevents runtime errors if messages are used but not defined.
*
* **NOTE: This should be defined at the top of the file so validation is done at load time rather than runtime.**
*
* ```typescript
* Messages.importMessagesDirectory(__dirname);
* const messages = Messages.load('packageName', 'bundleName', [
* 'messageKey1',
* 'messageKey2',
* ]);
* ```
*
* @param packageName The name of the npm package.
* @param bundleName The name of the bundle to load.
* @param keys The message keys that will be used.
*/
static load<T extends string>(packageName: string, bundleName: string, keys: [T, ...T[]]): Messages<T>;
/**
* Check if a bundle already been loaded.
*
* @param packageName The npm package name.
* @param bundleName The bundle name.
*/
static isCached(packageName: string, bundleName: string): boolean;
/**
* Get a message using a message key and use the tokens as values for tokenization.
*
* If the key happens to be an array of messages, it will combine with OS.EOL.
*
* @param key The key of the message.
* @param tokens The values to substitute in the message.
*
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
*/
getMessage(key: T, tokens?: Tokens): string;
/**
* 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.
*
* ```json
* {
* "myKey": [ "message1", "message2" ]
* }
* ```
*
* ```markdown
* # myKey
* * message1
* * message2
* ```
*
* @param key The key of the messages.
* @param tokens The values to substitute in the message.
*
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
*/
getMessages(key: T, tokens?: Tokens): string[];
/**
* 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.
*
* @param key The key of the error message.
* @param tokens The error message tokens.
* @param actionTokens The action messages tokens.
* @param exitCodeOrCause The exit code which will be used by SfdxCommand or he underlying error that caused this error to be raised.
* @param cause The underlying error that caused this error to be raised.
*/
createError(key: T, tokens?: Tokens, actionTokens?: Tokens, exitCodeOrCause?: number | Error, cause?: Error): SfdxError;
private getMessageWithMap;
}