main
js 56 lines 1.68 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 // Takes a format string (first argument to console) and returns a normalized
11 // string that has the exact number of arguments as the args. That way it's safe
12 // to prepend or append to it.
13 export default function normalizeConsoleFormat(
14 formatString: string,
15 args: $ReadOnlyArray<mixed>,
16 firstArg: number,
17 ): string {
18 let j = firstArg;
19 let normalizedString = '';
20 let last = 0;
21 for (let i = 0; i < formatString.length - 1; i++) {
22 if (formatString.charCodeAt(i) !== 37 /* "%" */) {
23 continue;
24 }
25 switch (formatString.charCodeAt(++i)) {
26 case 79 /* "O" */:
27 case 99 /* "c" */:
28 case 100 /* "d" */:
29 case 102 /* "f" */:
30 case 105 /* "i" */:
31 case 111 /* "o" */:
32 case 115 /* "s" */: {
33 if (j < args.length) {
34 // We have a matching argument.
35 j++;
36 } else {
37 // We have more format specifiers than arguments.
38 // So we need to escape this to print the literal.
39 normalizedString += formatString.slice(last, (last = i)) + '%';
40 }
41 }
42 }
43 }
44 normalizedString += formatString.slice(last, formatString.length);
45 // Pad with extra format specifiers for the rest.
46 while (j < args.length) {
47 if (normalizedString !== '') {
48 normalizedString += ' ';
49 }
50 // Not every environment has the same default.
51 // This seems to be what Chrome DevTools defaults to.
52 normalizedString += typeof args[j] === 'string' ? '%s' : '%o';
53 j++;
54 }
55 return normalizedString;
56 }