"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.raw = exports.msgTag = exports.default = exports.custom = void 0; var _dateformat = _interopRequireDefault(require("dateformat")); var _prettyFormat = require("pretty-format"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // Generic builder for template literal tags const createTag = encode => function (stringParts) { for (var _len = arguments.length, substitutions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { substitutions[_key - 1] = arguments[_key]; } return substitutions.reduce((prev, cur, i) => prev + encode(cur) + stringParts[i + 1], stringParts[0]); }; // Version of `obj.hasOwnProperty()` that works regardless of prototype const hasOwnProperty = (obj, propName) => Object.prototype.hasOwnProperty.call(obj, propName); const customKey = Symbol('msg.custom'); const quote = value => `\`${value}\``; const formatObject = (obj, options) => { return (0, _prettyFormat.format)(obj, options).replace(/^Object /, ''); // Remove 'Object' tag }; const format = function (value) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (typeof value === 'object' && value && customKey in value) { if (value.type === 'raw') { return value.value; } if (typeof value.options === 'object' && value.options) { options = value.options; value = value.value; } } if (value === undefined) { return quote('undefined'); } else if (value === null) { return quote('null'); } else if (typeof value === 'boolean') { return quote(String(value)); } else if (typeof value === 'symbol') { return quote(value.toString()); // `Symbol()` } else if (typeof value === 'string') { return JSON.stringify(value); // Don't quote, just encode as a string literal } else if (typeof value === 'number') { if (isNaN(value)) { return 'NaN'; } else if (value === +Infinity) { return '+Infinity'; } else if (value === -Infinity) { return '-Infinity'; } return String(value); } else if (Array.isArray(value)) { // Currently just JSON encodes the entire array. We may want to format this a bit nicer. return quote(JSON.stringify(value)); } else if (typeof value === 'function') { return quote(value.toString()); } else if (value instanceof Date) { if (Number.isNaN(value.valueOf())) { return '[invalid Date]'; } else { // Note: `dateFormat` throws a TypeError if the given Date is invalid (i.e. value is NaN) return (0, _dateformat.default)(value, options.dateFormat || 'isoUtcDateTime'); } } else if (value instanceof RegExp) { return quote(value.toString()); } else if (value instanceof Error) { // For error messages, print the message raw. We expect the message to be already formatted // for display, so encoding it would mess up the formatting. return `[${value.constructor.name}] ${value.message}`; } else if (typeof value === 'object') { const proto = Object.getPrototypeOf(value); if (proto === null || proto === Object.prototype) { // Currently just JSON encodes the entire object. We may want to format this a bit nicer. return quote(formatObject(value, options.format)); } if (hasOwnProperty(proto, 'constructor') && typeof proto.constructor === 'function') { const constructor = proto.constructor; const tag = constructor.name || 'Unknown'; let stringRep; if ('toJSON' in value) { // Note: `toJSON` is not included in `Object.prototype`, so will only be present in types // that explicitly implement JSON encoding. stringRep = quote(formatObject(value, options.format)); } else if ('toString' in value && value.toString !== Object.prototype.toString) { // Note: `toString` is included in `Object.prototype`. However, the default implementation is // generally not very helpful (e.g. `[Object object]`). So we explicitly ignore it. stringRep = JSON.stringify(value.toString()); // Encode as string literal } else { // Fallback: take all enumerable properties and format as object stringRep = quote(formatObject({ ...value }, options.format)); } return `[${tag}] ${stringRep}`; } } // Fallback return JSON.stringify(value); }; const msgTag = options => createTag(value => format(value, options)); exports.msgTag = msgTag; const msg = msgTag({ format: { maxDepth: 4, min: true }, dateFormat: 'isoUtcDateTime' }); const raw = msg.raw = value => ({ [customKey]: true, type: 'raw', value }); exports.raw = raw; const custom = msg.custom = (options, value) => ({ [customKey]: true, options, value }); exports.custom = custom; var _default = msg; exports.default = _default; //# sourceMappingURL=message.cjs.map