/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ // Takes a format string (first argument to console) and returns a normalized // string that has the exact number of arguments as the args. That way it's safe // to prepend or append to it. export default function normalizeConsoleFormat( formatString: string, args: $ReadOnlyArray, firstArg: number, ): string { let j = firstArg; let normalizedString = ''; let last = 0; for (let i = 0; i < formatString.length - 1; i++) { if (formatString.charCodeAt(i) !== 37 /* "%" */) { continue; } switch (formatString.charCodeAt(++i)) { case 79 /* "O" */: case 99 /* "c" */: case 100 /* "d" */: case 102 /* "f" */: case 105 /* "i" */: case 111 /* "o" */: case 115 /* "s" */: { if (j < args.length) { // We have a matching argument. j++; } else { // We have more format specifiers than arguments. // So we need to escape this to print the literal. normalizedString += formatString.slice(last, (last = i)) + '%'; } } } } normalizedString += formatString.slice(last, formatString.length); // Pad with extra format specifiers for the rest. while (j < args.length) { if (normalizedString !== '') { normalizedString += ' '; } // Not every environment has the same default. // This seems to be what Chrome DevTools defaults to. normalizedString += typeof args[j] === 'string' ? '%s' : '%o'; j++; } return normalizedString; }