core.cjs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. 'use strict';
  2. const LogLevels = {
  3. silent: Number.NEGATIVE_INFINITY,
  4. fatal: 0,
  5. error: 0,
  6. warn: 1,
  7. log: 2,
  8. info: 3,
  9. success: 3,
  10. fail: 3,
  11. ready: 3,
  12. start: 3,
  13. box: 3,
  14. debug: 4,
  15. trace: 5,
  16. verbose: Number.POSITIVE_INFINITY
  17. };
  18. const LogTypes = {
  19. // Silent
  20. silent: {
  21. level: -1
  22. },
  23. // Level 0
  24. fatal: {
  25. level: LogLevels.fatal
  26. },
  27. error: {
  28. level: LogLevels.error
  29. },
  30. // Level 1
  31. warn: {
  32. level: LogLevels.warn
  33. },
  34. // Level 2
  35. log: {
  36. level: LogLevels.log
  37. },
  38. // Level 3
  39. info: {
  40. level: LogLevels.info
  41. },
  42. success: {
  43. level: LogLevels.success
  44. },
  45. fail: {
  46. level: LogLevels.fail
  47. },
  48. ready: {
  49. level: LogLevels.info
  50. },
  51. start: {
  52. level: LogLevels.info
  53. },
  54. box: {
  55. level: LogLevels.info
  56. },
  57. // Level 4
  58. debug: {
  59. level: LogLevels.debug
  60. },
  61. // Level 5
  62. trace: {
  63. level: LogLevels.trace
  64. },
  65. // Verbose
  66. verbose: {
  67. level: LogLevels.verbose
  68. }
  69. };
  70. function isObject(value) {
  71. return value !== null && typeof value === "object";
  72. }
  73. function _defu(baseObject, defaults, namespace = ".", merger) {
  74. if (!isObject(defaults)) {
  75. return _defu(baseObject, {}, namespace, merger);
  76. }
  77. const object = Object.assign({}, defaults);
  78. for (const key in baseObject) {
  79. if (key === "__proto__" || key === "constructor") {
  80. continue;
  81. }
  82. const value = baseObject[key];
  83. if (value === null || value === void 0) {
  84. continue;
  85. }
  86. if (merger && merger(object, key, value, namespace)) {
  87. continue;
  88. }
  89. if (Array.isArray(value) && Array.isArray(object[key])) {
  90. object[key] = [...value, ...object[key]];
  91. } else if (isObject(value) && isObject(object[key])) {
  92. object[key] = _defu(
  93. value,
  94. object[key],
  95. (namespace ? `${namespace}.` : "") + key.toString(),
  96. merger
  97. );
  98. } else {
  99. object[key] = value;
  100. }
  101. }
  102. return object;
  103. }
  104. function createDefu(merger) {
  105. return (...arguments_) => (
  106. // eslint-disable-next-line unicorn/no-array-reduce
  107. arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
  108. );
  109. }
  110. const defu = createDefu();
  111. function isPlainObject(obj) {
  112. return Object.prototype.toString.call(obj) === "[object Object]";
  113. }
  114. function isLogObj(arg) {
  115. if (!isPlainObject(arg)) {
  116. return false;
  117. }
  118. if (!arg.message && !arg.args) {
  119. return false;
  120. }
  121. if (arg.stack) {
  122. return false;
  123. }
  124. return true;
  125. }
  126. let paused = false;
  127. const queue = [];
  128. class Consola {
  129. constructor(options = {}) {
  130. const types = options.types || LogTypes;
  131. this.options = defu(
  132. {
  133. ...options,
  134. defaults: { ...options.defaults },
  135. level: _normalizeLogLevel(options.level, types),
  136. reporters: [...options.reporters || []]
  137. },
  138. {
  139. types: LogTypes,
  140. throttle: 1e3,
  141. throttleMin: 5,
  142. formatOptions: {
  143. date: true,
  144. colors: false,
  145. compact: true
  146. }
  147. }
  148. );
  149. for (const type in types) {
  150. const defaults = {
  151. type,
  152. ...this.options.defaults,
  153. ...types[type]
  154. };
  155. this[type] = this._wrapLogFn(defaults);
  156. this[type].raw = this._wrapLogFn(
  157. defaults,
  158. true
  159. );
  160. }
  161. if (this.options.mockFn) {
  162. this.mockTypes();
  163. }
  164. this._lastLog = {};
  165. }
  166. get level() {
  167. return this.options.level;
  168. }
  169. set level(level) {
  170. this.options.level = _normalizeLogLevel(
  171. level,
  172. this.options.types,
  173. this.options.level
  174. );
  175. }
  176. prompt(message, opts) {
  177. if (!this.options.prompt) {
  178. throw new Error("prompt is not supported!");
  179. }
  180. return this.options.prompt(message, opts);
  181. }
  182. create(options) {
  183. const instance = new Consola({
  184. ...this.options,
  185. ...options
  186. });
  187. if (this._mockFn) {
  188. instance.mockTypes(this._mockFn);
  189. }
  190. return instance;
  191. }
  192. withDefaults(defaults) {
  193. return this.create({
  194. ...this.options,
  195. defaults: {
  196. ...this.options.defaults,
  197. ...defaults
  198. }
  199. });
  200. }
  201. withTag(tag) {
  202. return this.withDefaults({
  203. tag: this.options.defaults.tag ? this.options.defaults.tag + ":" + tag : tag
  204. });
  205. }
  206. addReporter(reporter) {
  207. this.options.reporters.push(reporter);
  208. return this;
  209. }
  210. removeReporter(reporter) {
  211. if (reporter) {
  212. const i = this.options.reporters.indexOf(reporter);
  213. if (i >= 0) {
  214. return this.options.reporters.splice(i, 1);
  215. }
  216. } else {
  217. this.options.reporters.splice(0);
  218. }
  219. return this;
  220. }
  221. setReporters(reporters) {
  222. this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];
  223. return this;
  224. }
  225. wrapAll() {
  226. this.wrapConsole();
  227. this.wrapStd();
  228. }
  229. restoreAll() {
  230. this.restoreConsole();
  231. this.restoreStd();
  232. }
  233. wrapConsole() {
  234. for (const type in this.options.types) {
  235. if (!console["__" + type]) {
  236. console["__" + type] = console[type];
  237. }
  238. console[type] = this[type].raw;
  239. }
  240. }
  241. restoreConsole() {
  242. for (const type in this.options.types) {
  243. if (console["__" + type]) {
  244. console[type] = console["__" + type];
  245. delete console["__" + type];
  246. }
  247. }
  248. }
  249. wrapStd() {
  250. this._wrapStream(this.options.stdout, "log");
  251. this._wrapStream(this.options.stderr, "log");
  252. }
  253. _wrapStream(stream, type) {
  254. if (!stream) {
  255. return;
  256. }
  257. if (!stream.__write) {
  258. stream.__write = stream.write;
  259. }
  260. stream.write = (data) => {
  261. this[type].raw(String(data).trim());
  262. };
  263. }
  264. restoreStd() {
  265. this._restoreStream(this.options.stdout);
  266. this._restoreStream(this.options.stderr);
  267. }
  268. _restoreStream(stream) {
  269. if (!stream) {
  270. return;
  271. }
  272. if (stream.__write) {
  273. stream.write = stream.__write;
  274. delete stream.__write;
  275. }
  276. }
  277. pauseLogs() {
  278. paused = true;
  279. }
  280. resumeLogs() {
  281. paused = false;
  282. const _queue = queue.splice(0);
  283. for (const item of _queue) {
  284. item[0]._logFn(item[1], item[2]);
  285. }
  286. }
  287. mockTypes(mockFn) {
  288. const _mockFn = mockFn || this.options.mockFn;
  289. this._mockFn = _mockFn;
  290. if (typeof _mockFn !== "function") {
  291. return;
  292. }
  293. for (const type in this.options.types) {
  294. this[type] = _mockFn(type, this.options.types[type]) || this[type];
  295. this[type].raw = this[type];
  296. }
  297. }
  298. _wrapLogFn(defaults, isRaw) {
  299. return (...args) => {
  300. if (paused) {
  301. queue.push([this, defaults, args, isRaw]);
  302. return;
  303. }
  304. return this._logFn(defaults, args, isRaw);
  305. };
  306. }
  307. _logFn(defaults, args, isRaw) {
  308. if ((defaults.level || 0) > this.level) {
  309. return false;
  310. }
  311. const logObj = {
  312. date: /* @__PURE__ */ new Date(),
  313. args: [],
  314. ...defaults,
  315. level: _normalizeLogLevel(defaults.level, this.options.types)
  316. };
  317. if (!isRaw && args.length === 1 && isLogObj(args[0])) {
  318. Object.assign(logObj, args[0]);
  319. } else {
  320. logObj.args = [...args];
  321. }
  322. if (logObj.message) {
  323. logObj.args.unshift(logObj.message);
  324. delete logObj.message;
  325. }
  326. if (logObj.additional) {
  327. if (!Array.isArray(logObj.additional)) {
  328. logObj.additional = logObj.additional.split("\n");
  329. }
  330. logObj.args.push("\n" + logObj.additional.join("\n"));
  331. delete logObj.additional;
  332. }
  333. logObj.type = typeof logObj.type === "string" ? logObj.type.toLowerCase() : "log";
  334. logObj.tag = typeof logObj.tag === "string" ? logObj.tag : "";
  335. const resolveLog = (newLog = false) => {
  336. const repeated = (this._lastLog.count || 0) - this.options.throttleMin;
  337. if (this._lastLog.object && repeated > 0) {
  338. const args2 = [...this._lastLog.object.args];
  339. if (repeated > 1) {
  340. args2.push(`(repeated ${repeated} times)`);
  341. }
  342. this._log({ ...this._lastLog.object, args: args2 });
  343. this._lastLog.count = 1;
  344. }
  345. if (newLog) {
  346. this._lastLog.object = logObj;
  347. this._log(logObj);
  348. }
  349. };
  350. clearTimeout(this._lastLog.timeout);
  351. const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;
  352. this._lastLog.time = logObj.date;
  353. if (diffTime < this.options.throttle) {
  354. try {
  355. const serializedLog = JSON.stringify([
  356. logObj.type,
  357. logObj.tag,
  358. logObj.args
  359. ]);
  360. const isSameLog = this._lastLog.serialized === serializedLog;
  361. this._lastLog.serialized = serializedLog;
  362. if (isSameLog) {
  363. this._lastLog.count = (this._lastLog.count || 0) + 1;
  364. if (this._lastLog.count > this.options.throttleMin) {
  365. this._lastLog.timeout = setTimeout(
  366. resolveLog,
  367. this.options.throttle
  368. );
  369. return;
  370. }
  371. }
  372. } catch {
  373. }
  374. }
  375. resolveLog(true);
  376. }
  377. _log(logObj) {
  378. for (const reporter of this.options.reporters) {
  379. reporter.log(logObj, {
  380. options: this.options
  381. });
  382. }
  383. }
  384. }
  385. function _normalizeLogLevel(input, types = {}, defaultLevel = 3) {
  386. if (input === void 0) {
  387. return defaultLevel;
  388. }
  389. if (typeof input === "number") {
  390. return input;
  391. }
  392. if (types[input] && types[input].level !== void 0) {
  393. return types[input].level;
  394. }
  395. return defaultLevel;
  396. }
  397. Consola.prototype.add = Consola.prototype.addReporter;
  398. Consola.prototype.remove = Consola.prototype.removeReporter;
  399. Consola.prototype.clear = Consola.prototype.removeReporter;
  400. Consola.prototype.withScope = Consola.prototype.withTag;
  401. Consola.prototype.mock = Consola.prototype.mockTypes;
  402. Consola.prototype.pause = Consola.prototype.pauseLogs;
  403. Consola.prototype.resume = Consola.prototype.resumeLogs;
  404. function createConsola(options = {}) {
  405. return new Consola(options);
  406. }
  407. exports.Consola = Consola;
  408. exports.LogLevels = LogLevels;
  409. exports.LogTypes = LogTypes;
  410. exports.createConsola = createConsola;