124 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const inherits = require('inherits');
 | |
| 
 | |
| function Reporter(options) {
 | |
|   this._reporterState = {
 | |
|     obj: null,
 | |
|     path: [],
 | |
|     options: options || {},
 | |
|     errors: []
 | |
|   };
 | |
| }
 | |
| exports.Reporter = Reporter;
 | |
| 
 | |
| Reporter.prototype.isError = function isError(obj) {
 | |
|   return obj instanceof ReporterError;
 | |
| };
 | |
| 
 | |
| Reporter.prototype.save = function save() {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   return { obj: state.obj, pathLen: state.path.length };
 | |
| };
 | |
| 
 | |
| Reporter.prototype.restore = function restore(data) {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   state.obj = data.obj;
 | |
|   state.path = state.path.slice(0, data.pathLen);
 | |
| };
 | |
| 
 | |
| Reporter.prototype.enterKey = function enterKey(key) {
 | |
|   return this._reporterState.path.push(key);
 | |
| };
 | |
| 
 | |
| Reporter.prototype.exitKey = function exitKey(index) {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   state.path = state.path.slice(0, index - 1);
 | |
| };
 | |
| 
 | |
| Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   this.exitKey(index);
 | |
|   if (state.obj !== null)
 | |
|     state.obj[key] = value;
 | |
| };
 | |
| 
 | |
| Reporter.prototype.path = function path() {
 | |
|   return this._reporterState.path.join('/');
 | |
| };
 | |
| 
 | |
| Reporter.prototype.enterObject = function enterObject() {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   const prev = state.obj;
 | |
|   state.obj = {};
 | |
|   return prev;
 | |
| };
 | |
| 
 | |
| Reporter.prototype.leaveObject = function leaveObject(prev) {
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   const now = state.obj;
 | |
|   state.obj = prev;
 | |
|   return now;
 | |
| };
 | |
| 
 | |
| Reporter.prototype.error = function error(msg) {
 | |
|   let err;
 | |
|   const state = this._reporterState;
 | |
| 
 | |
|   const inherited = msg instanceof ReporterError;
 | |
|   if (inherited) {
 | |
|     err = msg;
 | |
|   } else {
 | |
|     err = new ReporterError(state.path.map(function(elem) {
 | |
|       return '[' + JSON.stringify(elem) + ']';
 | |
|     }).join(''), msg.message || msg, msg.stack);
 | |
|   }
 | |
| 
 | |
|   if (!state.options.partial)
 | |
|     throw err;
 | |
| 
 | |
|   if (!inherited)
 | |
|     state.errors.push(err);
 | |
| 
 | |
|   return err;
 | |
| };
 | |
| 
 | |
| Reporter.prototype.wrapResult = function wrapResult(result) {
 | |
|   const state = this._reporterState;
 | |
|   if (!state.options.partial)
 | |
|     return result;
 | |
| 
 | |
|   return {
 | |
|     result: this.isError(result) ? null : result,
 | |
|     errors: state.errors
 | |
|   };
 | |
| };
 | |
| 
 | |
| function ReporterError(path, msg) {
 | |
|   this.path = path;
 | |
|   this.rethrow(msg);
 | |
| }
 | |
| inherits(ReporterError, Error);
 | |
| 
 | |
| ReporterError.prototype.rethrow = function rethrow(msg) {
 | |
|   this.message = msg + ' at: ' + (this.path || '(shallow)');
 | |
|   if (Error.captureStackTrace)
 | |
|     Error.captureStackTrace(this, ReporterError);
 | |
| 
 | |
|   if (!this.stack) {
 | |
|     try {
 | |
|       // IE only adds stack when thrown
 | |
|       throw new Error(this.message);
 | |
|     } catch (e) {
 | |
|       this.stack = e.stack;
 | |
|     }
 | |
|   }
 | |
|   return this;
 | |
| };
 |