UNPKG

baset-baseliner-json

Version:

JSON baseliner plugin for BaseT project.

181 lines 7.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const baset_core_1 = require("baset-core"); const path_1 = __importDefault(require("path")); const rxEscapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; function normalizeStackTrace(trace) { const filePathRegex = path_1.default.sep === '\\' ? /([a-z]|[A-Z]):\\[^:]*:/g : /\/[^:]*:/g; return trace.replace(filePathRegex, absPath => path_1.default.relative(process.cwd(), absPath) .replace(/\\/g, '/')); } // table of character substitutions class Meta { constructor() { this['\b'] = '\\b'; this['\t'] = '\\t'; this['\n'] = '\\n'; this['\f'] = '\\f'; this['\r'] = '\\r'; this['"'] = '\\"'; this['\\'] = '\\\\'; } } const meta = new Meta(); let gap; let indent; let rep; let shouldReplaceZeroIndex = false; function quote(value) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. rxEscapable.lastIndex = 0; return rxEscapable.test(value) ? `"${value.replace(rxEscapable, a => { const c = meta[a]; return typeof c === 'string' ? c : `\\u${(`0000${a}`.charCodeAt(0).toString(16)).slice(-4)}`; })}"` : `"${value}"`; } // tslint:disable-next-line:cyclomatic-complexity function str(key, holder, limit) { // Produce a string from holder[key]. const mind = gap; const originalValue = holder[key]; const jsonValue = (originalValue && typeof originalValue === 'object' && typeof originalValue.toJSON === 'function') ? originalValue.toJSON(key) : originalValue; const value = (typeof rep === 'function') ? rep.call(holder, key, jsonValue) : jsonValue; // What happens next depends on the value's type. switch (typeof value) { case 'string': return quote(value); case 'number': return isFinite(value) ? String(value) : 'Infinity'; case 'boolean': return String(value); case 'object': // Due to a specification blunder in ECMAScript, typeof null is 'object', // so watch out for that case. if (!value) return 'null'; if (value && value[baset_core_1.circularReference]) { return (shouldReplaceZeroIndex) ? value[baset_core_1.circularReference].replace(/^exports\[0\]/, 'exports') : value[baset_core_1.circularReference]; } if (value && value[baset_core_1.dataTypes.error]) { return `Throws: ${value[baset_core_1.dataTypes.error].stack ? normalizeStackTrace(value[baset_core_1.dataTypes.error].stack) : value[baset_core_1.dataTypes.error]}`; } // Make an array to hold the partial results of stringifying this object value. gap += indent; const partial = []; // Is the value an array? if (Array.isArray(value)) { // The value is an array. Stringify every element. Use null as a placeholder // for non-JSON values. for (let i = 0, length = value.length; i < length; i += 1) { partial[i] = str(i, value, limit) || 'null'; } // Join all of the elements together, separated with commas, and wrap them in // brackets. const v = partial.length === 0 ? '[]' : gap ? (gap.length + partial.join(', ').length + 4 > limit) ? `[\n${gap}${partial.join(`,\n${gap}`)}\n${mind}]` : `[ ${partial.join(', ')} ]` : `[${partial.join(', ')}]`; gap = mind; return v; } // If the replacer is an array, use it to select the members to be stringified. if (rep instanceof Array) { for (let i = 0, length = rep.length; i < length; i += 1) { if (typeof rep[i] === 'string') { const k = rep[i]; const v = str(k, value, limit); if (v) { partial.push(`${quote(k)}${gap ? ': ' : ':'}${v}`); } } } } else { // Otherwise, iterate through all of the keys in the object. for (const k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { const v = str(k, value, limit); if (v) { partial.push(`${quote(k)}${gap ? ': ' : ':'}${v}`); } } } } // Join all of the member texts together, separated with commas, // and wrap them in braces. const result = partial.length === 0 ? '{}' : gap ? (gap.length + partial.join(', ').length + 4 > limit) ? `{\n${gap}${partial.join(`,\n${gap}`)}\n${mind}}` : `{ ${partial.join(', ')} }` : `{${partial.join(', ')}}`; gap = mind; return result; default: return ''; } } function beautify(value, replacer, space, limit, isExportSingle = false) { shouldReplaceZeroIndex = isExportSingle; // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function // that can replace values, or an array of strings that will select the keys. // A default replacer method can be provided. Use of the space parameter can // produce text that is more easily readable. gap = ''; indent = ''; if (!limit) limit = 0; if (typeof limit !== 'number') { throw new Error('beaufifier: limit must be a number'); } // If the space parameter is a number, make an indent string containing that // many spaces. if (typeof space === 'number') { for (let i = 0; i < space; i += 1) { indent += ' '; } // If the space parameter is a string, it will be used as the indent string. } else if (typeof space === 'string') { indent = space; } // If there is a replacer, it must be a function or an array. // Otherwise, throw an error. rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { throw new Error('beautifier: wrong replacer parameter'); } // Make a fake root object containing our value under the key of ''. // Return the result of stringifying the value. return str('', { '': value }, limit); } exports.beautify = beautify; //# sourceMappingURL=beautifier.js.map