UNPKG

12.1 kBTypeScriptView Raw
1import { AnyJson } from '@salesforce/ts-types';
2import { SfError } from './sfError';
3export declare type Tokens = Array<string | boolean | number | null | undefined>;
4export declare type StructuredMessage = {
5 message: string;
6 name: string;
7 actions?: string[];
8};
9/**
10 * A loader function to return messages.
11 *
12 * @param locale The local set by the framework.
13 */
14export declare type LoaderFunction<T extends string> = (locale: string) => Messages<T>;
15export declare type StoredMessage = string | string[] | {
16 [s: string]: StoredMessage;
17};
18export declare type StoredMessageMap = Map<string, StoredMessage>;
19/**
20 * The core message framework manages messages and allows them to be accessible by
21 * all plugins and consumers of sfdx-core. It is set up to handle localization down
22 * the road at no additional effort to the consumer. Messages can be used for
23 * anything from user output (like the console), to error messages, to returned
24 * data from a method.
25 *
26 * Messages are loaded from loader functions. The loader functions will only run
27 * when a message is required. This prevents all messages from being loaded into memory at
28 * application startup. The functions can load from memory, a file, or a server.
29 *
30 * In the beginning of your app or file, add the loader functions to be used later. If using
31 * json or js files in a root messages directory (`<moduleRoot>/messages`), load the entire directory
32 * automatically with {@link Messages.importMessagesDirectory}. Message files must be the following formates.
33 *
34 * A `.json` file:
35 * ```json
36 * {
37 * "msgKey": "A message displayed in the user",
38 * "msgGroup": {
39 * "anotherMsgKey": "Another message displayed to the user"
40 * },
41 * "listOfMessage": ["message1", "message2"]
42 * }
43 * ```
44 *
45 * A `.js` file:
46 * ```javascript
47 * module.exports = {
48 * msgKey: 'A message displayed in the user',
49 * msgGroup: {
50 * anotherMsgKey: 'Another message displayed to the user'
51 * },
52 * listOfMessage: ['message1', 'message2']
53 * }
54 * ```
55 *
56 * A `.md` file:
57 * ```markdown
58 * # msgKey
59 * A message displayed in the user
60 *
61 * # msgGroup.anotherMsgKey
62 * Another message displayed to the user
63 *
64 * # listOfMessage
65 * - message1
66 * - message2
67 * ```
68 *
69 * The values support [util.format](https://nodejs.org/api/util.html#util_util_format_format_args) style strings
70 * that apply the tokens passed into {@link Message.getMessage}
71 *
72 * **Note:** When running unit tests individually, you may see errors that the messages aren't found.
73 * This is because `index.js` isn't loaded when tests run like they are when the package is required.
74 * To allow tests to run, import the message directory in each test (it will only
75 * do it once) or load the message file the test depends on individually.
76 *
77 * ```typescript
78 * // Create loader functions for all files in the messages directory
79 * Messages.importMessagesDirectory(__dirname);
80 *
81 * // Now you can use the messages from anywhere in your code or file.
82 * // If using importMessageDirectory, the bundle name is the file name.
83 * const messages: Messages = Messages.load(packageName, bundleName);
84 *
85 * // Messages now contains all the message in the bundleName file.
86 * messages.getMessage('authInfoCreationError');
87 * ```
88 */
89export declare class Messages<T extends string> {
90 private messages;
91 private static loaders;
92 private static bundles;
93 /**
94 * The locale of the messages in this bundle.
95 */
96 readonly locale: string;
97 /**
98 * The bundle name.
99 */
100 readonly bundleName: string;
101 /**
102 * Create a new messages bundle.
103 *
104 * **Note:** Use {Messages.load} unless you are writing your own loader function.
105 *
106 * @param bundleName The bundle name.
107 * @param locale The locale.
108 * @param messages The messages. Can not be modified once created.
109 */
110 constructor(bundleName: string, locale: string, messages: StoredMessageMap);
111 /**
112 * Internal readFile. Exposed for unit testing. Do not use util/fs.readFile as messages.js
113 * should have no internal dependencies.
114 *
115 * @param filePath read file target.
116 * @ignore
117 */
118 static readFile: (filePath: string) => AnyJson;
119 /**
120 * Get the locale. This will always return 'en_US' but will return the
121 * machine's locale in the future.
122 */
123 static getLocale(): string;
124 /**
125 * Set a custom loader function for a package and bundle that will be called on {@link Messages.load}.
126 *
127 * @param packageName The npm package name.
128 * @param bundle The name of the bundle.
129 * @param loader The loader function.
130 */
131 static setLoaderFunction(packageName: string, bundle: string, loader: LoaderFunction<string>): void;
132 /**
133 * Generate a file loading function. Use {@link Messages.importMessageFile} unless
134 * overriding the bundleName is required, then manually pass the loader
135 * function to {@link Messages.setLoaderFunction}.
136 *
137 * @param bundleName The name of the bundle.
138 * @param filePath The messages file path.
139 */
140 static generateFileLoaderFunction(bundleName: string, filePath: string): LoaderFunction<string>;
141 /**
142 * Add a single message file to the list of loading functions using the file name as the bundle name.
143 * The loader will only be added if the bundle name is not already taken.
144 *
145 * @param packageName The npm package name.
146 * @param filePath The path of the file.
147 */
148 static importMessageFile(packageName: string, filePath: string): void;
149 /**
150 * Import all json and js files in a messages directory. Use the file name as the bundle key when
151 * {@link Messages.load} is called. By default, we're assuming the moduleDirectoryPart is a
152 * typescript project and will truncate to root path (where the package.json file is). If your messages
153 * directory is in another spot or you are not using typescript, pass in false for truncateToProjectPath.
154 *
155 * ```
156 * // e.g. If your message directory is in the project root, you would do:
157 * Messages.importMessagesDirectory(__dirname);
158 * ```
159 *
160 * @param moduleDirectoryPath The path to load the messages folder.
161 * @param truncateToProjectPath Will look for the messages directory in the project root (where the package.json file is located).
162 * i.e., the module is typescript and the messages folder is in the top level of the module directory.
163 * @param packageName The npm package name. Figured out from the root directory's package.json.
164 */
165 static importMessagesDirectory(moduleDirectoryPath: string, truncateToProjectPath?: boolean, packageName?: string): void;
166 /**
167 * Load messages for a given package and bundle. If the bundle is not already cached, use the loader function
168 * created from {@link Messages.setLoaderFunction} or {@link Messages.importMessagesDirectory}.
169 *
170 * **NOTE: Use {@link Messages.load} instead for safe message validation and usage.**
171 *
172 * ```typescript
173 * Messages.importMessagesDirectory(__dirname);
174 * const messages = Messages.load('packageName', 'bundleName');
175 * ```
176 *
177 * @param packageName The name of the npm package.
178 * @param bundleName The name of the bundle to load.
179 */
180 static loadMessages(packageName: string, bundleName: string): Messages<string>;
181 /**
182 * Load messages for a given package and bundle. If the bundle is not already cached, use the loader function
183 * created from {@link Messages.setLoaderFunction} or {@link Messages.importMessagesDirectory}.
184 *
185 * The message keys that will be used must be passed in for validation. This prevents runtime errors if messages are used but not defined.
186 *
187 * **NOTE: This should be defined at the top of the file so validation is done at load time rather than runtime.**
188 *
189 * ```typescript
190 * Messages.importMessagesDirectory(__dirname);
191 * const messages = Messages.load('packageName', 'bundleName', [
192 * 'messageKey1',
193 * 'messageKey2',
194 * ]);
195 * ```
196 *
197 * @param packageName The name of the npm package.
198 * @param bundleName The name of the bundle to load.
199 * @param keys The message keys that will be used.
200 */
201 static load<T extends string>(packageName: string, bundleName: string, keys: [T, ...T[]]): Messages<T>;
202 /**
203 * Check if a bundle already been loaded.
204 *
205 * @param packageName The npm package name.
206 * @param bundleName The bundle name.
207 */
208 static isCached(packageName: string, bundleName: string): boolean;
209 /**
210 * Get a message using a message key and use the tokens as values for tokenization.
211 *
212 * If the key happens to be an array of messages, it will combine with OS.EOL.
213 *
214 * @param key The key of the message.
215 * @param tokens The values to substitute in the message.
216 *
217 * **See** https://nodejs.org/api/util.html#util_util_format_format_args
218 */
219 getMessage(key: T, tokens?: Tokens): string;
220 /**
221 * Get messages using a message key and use the tokens as values for tokenization.
222 *
223 * This will return all messages if the key is an array in the messages file.
224 *
225 * ```json
226 * {
227 * "myKey": [ "message1", "message2" ]
228 * }
229 * ```
230 *
231 * ```markdown
232 * # myKey
233 * * message1
234 * * message2
235 * ```
236 *
237 * @param key The key of the messages.
238 * @param tokens The values to substitute in the message.
239 *
240 * **See** https://nodejs.org/api/util.html#util_util_format_format_args
241 */
242 getMessages(key: T, tokens?: Tokens): string[];
243 /**
244 * Convenience method to create errors using message labels.
245 *
246 * `error.name` will be the upper-cased key, remove prefixed `error.` and will always end in Error.
247 * `error.actions` will be loaded using `${key}.actions` if available.
248 *
249 * @param key The key of the error message.
250 * @param tokens The error message tokens.
251 * @param actionTokens The action messages tokens.
252 * @param exitCodeOrCause The exit code which will be used by SfdxCommand or the underlying error that caused this error to be raised.
253 * @param cause The underlying error that caused this error to be raised.
254 */
255 createError(key: T, tokens?: Tokens, actionTokens?: Tokens, exitCodeOrCause?: number | Error, cause?: Error): SfError;
256 /**
257 * Convenience method to create warning using message labels.
258 *
259 * `warning.name` will be the upper-cased key, remove prefixed `warning.` and will always end in Warning.
260 * `warning.actions` will be loaded using `${key}.actions` if available.
261 *
262 * @param key The key of the warning message.
263 * @param tokens The warning message tokens.
264 * @param actionTokens The action messages tokens.
265 */
266 createWarning(key: T, tokens?: Tokens, actionTokens?: Tokens): StructuredMessage;
267 /**
268 * Convenience method to create info using message labels.
269 *
270 * `info.name` will be the upper-cased key, remove prefixed `info.` and will always end in Info.
271 * `info.actions` will be loaded using `${key}.actions` if available.
272 *
273 * @param key The key of the warning message.
274 * @param tokens The warning message tokens.
275 * @param actionTokens The action messages tokens.
276 */
277 createInfo(key: T, tokens?: Tokens, actionTokens?: Tokens): StructuredMessage;
278 /**
279 * Formats message contents given a message type, key, tokens and actions tokens
280 *
281 * `<type>.name` will be the upper-cased key, remove prefixed `<type>.` and will always end in 'Error | Warning | Info.
282 * `<type>.actions` will be loaded using `${key}.actions` if available.
283 *
284 * @param type The type of the message set must 'error' | 'warning' | 'info'.
285 * @param key The key of the warning message.
286 * @param tokens The warning message tokens.
287 * @param actionTokens The action messages tokens.
288 */
289 private formatMessageContents;
290 private getMessageWithMap;
291}