logHelper.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. /**
  3. * Copyright 2022 Google LLC.
  4. * Copyright (c) Microsoft Corporation.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. Object.defineProperty(exports, "__esModule", { value: true });
  19. exports.getRemoteValuesText = exports.logMessageFormatter = void 0;
  20. const specifiers = ['%s', '%d', '%i', '%f', '%o', '%O', '%c'];
  21. function isFormmatSpecifier(str) {
  22. return specifiers.some((spec) => str.includes(spec));
  23. }
  24. /**
  25. * @param args input remote values to be format printed
  26. * @return parsed text of the remote values in specific format
  27. */
  28. function logMessageFormatter(args) {
  29. let output = '';
  30. const argFormat = args[0].value.toString();
  31. const argValues = args.slice(1, undefined);
  32. const tokens = argFormat.split(new RegExp(specifiers.map((spec) => `(${spec})`).join('|'), 'g'));
  33. for (const token of tokens) {
  34. if (token === undefined || token === '') {
  35. continue;
  36. }
  37. if (isFormmatSpecifier(token)) {
  38. const arg = argValues.shift();
  39. // raise an exception when less value is provided
  40. if (arg === undefined) {
  41. throw new Error(`Less value is provided: "${getRemoteValuesText(args, false)}"`);
  42. }
  43. if (token === '%s') {
  44. output += stringFromArg(arg);
  45. }
  46. else if (token === '%d' || token === '%i') {
  47. if (arg.type === 'bigint' ||
  48. arg.type === 'number' ||
  49. arg.type === 'string') {
  50. output += parseInt(arg.value.toString(), 10);
  51. }
  52. else {
  53. output += 'NaN';
  54. }
  55. }
  56. else if (token === '%f') {
  57. if (arg.type === 'bigint' ||
  58. arg.type === 'number' ||
  59. arg.type === 'string') {
  60. output += parseFloat(arg.value.toString());
  61. }
  62. else {
  63. output += 'NaN';
  64. }
  65. }
  66. else {
  67. // %o, %O, %c
  68. output += toJson(arg);
  69. }
  70. }
  71. else {
  72. output += token;
  73. }
  74. }
  75. // raise an exception when more value is provided
  76. if (argValues.length > 0) {
  77. throw new Error(`More value is provided: "${getRemoteValuesText(args, false)}"`);
  78. }
  79. return output;
  80. }
  81. exports.logMessageFormatter = logMessageFormatter;
  82. /**
  83. * @param arg input remote value to be parsed
  84. * @return parsed text of the remote value
  85. *
  86. * input: {"type": "number", "value": 1}
  87. * output: 1
  88. *
  89. * input: {"type": "string", "value": "abc"}
  90. * output: "abc"
  91. *
  92. * input: {"type": "object", "value": [["id", {"type": "number", "value": 1}]]}
  93. * output: '{"id": 1}'
  94. *
  95. * input: {"type": "object", "value": [["font-size", {"type": "string", "value": "20px"}]]}
  96. * output: '{"font-size": "20px"}'
  97. */
  98. function toJson(arg) {
  99. // arg type validation
  100. if (arg.type !== 'array' &&
  101. arg.type !== 'bigint' &&
  102. arg.type !== 'date' &&
  103. arg.type !== 'number' &&
  104. arg.type !== 'object' &&
  105. arg.type !== 'string') {
  106. return stringFromArg(arg);
  107. }
  108. if (arg.type === 'bigint') {
  109. return `${arg.value.toString()}n`;
  110. }
  111. if (arg.type === 'number') {
  112. return arg.value.toString();
  113. }
  114. if (['date', 'string'].includes(arg.type)) {
  115. return JSON.stringify(arg.value);
  116. }
  117. if (arg.type === 'object') {
  118. return `{${arg.value
  119. .map((pair) => {
  120. return `${JSON.stringify(pair[0])}:${toJson(pair[1])}`;
  121. })
  122. .join(',')}}`;
  123. }
  124. if (arg.type === 'array') {
  125. return `[${arg.value?.map((val) => toJson(val)).join(',') ?? ''}]`;
  126. }
  127. throw Error(`Invalid value type: ${arg.toString()}`);
  128. }
  129. function stringFromArg(arg) {
  130. if (!Object.hasOwn(arg, 'value')) {
  131. return arg.type;
  132. }
  133. switch (arg.type) {
  134. case 'string':
  135. case 'number':
  136. case 'boolean':
  137. case 'bigint':
  138. return String(arg.value);
  139. case 'regexp':
  140. return `/${arg.value.pattern}/${arg.value.flags ?? ''}`;
  141. case 'date':
  142. return new Date(arg.value).toString();
  143. case 'object':
  144. return `Object(${arg.value?.length ?? ''})`;
  145. case 'array':
  146. return `Array(${arg.value?.length ?? ''})`;
  147. case 'map':
  148. return `Map(${arg.value.length})`;
  149. case 'set':
  150. return `Set(${arg.value.length})`;
  151. case 'node':
  152. return 'node';
  153. default:
  154. return arg.type;
  155. }
  156. }
  157. function getRemoteValuesText(args, formatText) {
  158. const arg = args[0];
  159. if (!arg) {
  160. return '';
  161. }
  162. // if args[0] is a format specifier, format the args as output
  163. if (arg.type === 'string' &&
  164. isFormmatSpecifier(arg.value.toString()) &&
  165. formatText) {
  166. return logMessageFormatter(args);
  167. }
  168. // if args[0] is not a format specifier, just join the args with \u0020 (unicode 'SPACE')
  169. return args
  170. .map((arg) => {
  171. return stringFromArg(arg);
  172. })
  173. .join('\u0020');
  174. }
  175. exports.getRemoteValuesText = getRemoteValuesText;
  176. //# sourceMappingURL=logHelper.js.map