/** * asyncer * Run groups of (a)sync functions. * * @name asyncer * @function * @param {Array|Object} tasks The tasks to run in parallel or one by one. * @param {Function} cb The callback function. */ function asyncer (tasks, cb) { cb = cb || noop6; if (typpy(tasks, Function)) { if (tasks.length >= 1) { return tasks(cb); } return fnResult(tasks, cb); } let normalize = tsks => tsks.map(c => { if (typpy(c, Function) && c.length >= 1) { return c; } return done => { asyncer(c, done) }; }); if (typpy(tasks, Object)) { tasks = normalize(tasks.parallel || tasks.p); sameTime(tasks, cb); return; } if (typpy(tasks, Array)) { tasks = normalize(tasks); oneByOne(tasks, cb); return; } throw new TypeError("The tasks should be an array or an object."); };
/** * * @name parseType * @function * @param {Value} value inputed value * @param {Type} type inputed type * @return {Value} parsed type * */ function parseType (value, type) { /** * Currently they send a string - handle String or Number or Boolean? */ if ((value && value.constructor === type) || typpy(value, type)) { return value } var typeName = type /** * Convert the constructor into a string */ if (type && type.name) { typeName = type.name.toLowerCase() } typeName = stripTrimLower(typeName) switch (typeName) { case 'string': if (typeof value === 'object') return JSON.stringify(value) return String(value) case 'function': if (typpy(value, Function)) { return value } return function (cb) { if (typeof cb === 'function') { cb(value) } return value } case 'date': return new Date(value) case 'object': var jsonParsed try { jsonParsed = JSON.parse(value) } catch (e) {} if (typpy(jsonParsed, Object) || typpy(jsonParsed, Array)) { return autoParse(jsonParsed) } else if (!typpy(jsonParsed, 'undefined')) { return {} } return parseObject(value) case 'boolean': return toBoolean(value) case 'number': return Number(value) case 'undefined': return undefined case 'null': return null case 'array': return [value] default: if (typeof type === 'function') { return new type(value) // eslint-disable-line } throw new Error('Unsupported type.') } }
GitStats.prototype.initConfig = function (input, callback) { var self = this; if (Typpy(input, Function)) { callback = input; input = null; } input = input || CONFIG_PATH; // Handle object input if (Typpy(input, Object)) { this.config = Ul.deepMerge(input, GitStats.DEFAULT_CONFIG); callback && callback(null, this.config); return this.config; } if (callback) { this.getConfig(function (err, data) { if (err) { return callback(err); } self.initConfig(data, callback); }); } else { this.initConfig(this.getConfig()); } };
iterateObj(cOpt.data, (v, n) => { v = normalizeOpt(v); let $elm = $items.eq(i); if (v.selector) { $elm = $elm.find(v.selector) } if (typpy(v.eq, Number)) { $elm = $elm.eq(v.eq); } let value = null; if (v.listItem) { v.name = "_"; value = scrapeIt.scrapeCheerio($elm, v, $)._.map(c => c._); } else { value = typpy(v.how, Function) ? v.how($elm, cDoc) : $elm[v.how](); } if (v.convert) { value = v.convert(value); } if (v.trimValue && typpy(value, String)) { value = value.trim(); } cDoc[n] = value; });
constructor (error, code, data) { // Err({ message: "...", code: "...", ... }); if (typpy(error, Object)) { data = error; error = data.message; delete data.message; code = data.code; } // Err(message, code, data); // Err(message, data); if (typpy(data, Object)) { data.code = code; } else if (typpy(code, Object)) { data = code; code = undefined; } else if (!typpy(code, undefined)) { data = { code: code }; } if (typeof error === "string") { error = barbe(error, ["<", ">"], data); } // Create the error super(error); if (data) { iterateObject(data, (v, n) => { this[n] = v; }); } }
GitStats.prototype.record = function (data, callback) { var self = this; // Validate data callback = callback || function (err) { if (err) throw err; }; data = Object(data); if (typeof data.date === "string") { data.date = new Moment(new Date(data.date)); } if (!/^moment|date$/.test(Typpy(data.date))) { callback(new Error("The date field should be a string or a date object.")); return GitStats; } else if (Typpy(data.date, Date)) { data.date = Moment(data.date); } if (typeof data.hash !== "string" || !data.hash) { callback(new Error("Invalid hash.")); return GitStats; } // This is not used, but remains here just in case we need // it in the future if (typeof data.url !== "string" || !data.url) { delete data.url; } function modify (err, stats) { var commits = stats.commits , day = data.date.format(DATE_FORMAT) , today = commits[day] = Object(commits[day]) ; today[data.hash] = 1; if (data.save === false) { callback(null, stats); } else { self.save(stats, callback); } return stats; } // Check if we have input data if (data._data) { return modify(null, data._data); } else { // Get stats self.get(modify); } return self; };
GitStats.prototype.removeCommit = function (data, callback) { var self = this; // Validate data callback = callback || function (err) { if (err) throw err; }; data = Object(data); if (typeof data.date === "string") { data.date = new Moment(new Date(data.date)); } if (!/^moment|date$/.test(Typpy(data.date))) { data.date = null; } else if (Typpy(data.date, Date)) { data.date = Moment(data.date); } if (typeof data.hash !== "string" || !data.hash) { callback(new Error("Invalid hash.")); return GitStats; } function modify (err, stats) { if (err) { return callback(err); } if (!data.date) { IterateObject(stats.commits, function (todayObj) { delete todayObj[data.hash]; }); } else { var commits = stats.commits , day = data.date.format(DATE_FORMAT) , today = commits[day] = Object(commits[day]) ; delete today[data.hash]; } if (data.save === false) { callback(null, stats); } else { self.save(stats, callback); } return stats; } // Check if we have input data if (data._data) { return modify(null, data._data); } else { // Get stats self.get(modify); } return self; };
/** * position * Sets the element position. * * @name position * @function * @param {Number} x The x coordinate. * @param {Number} y The y coordinate. */ position (x, y) { if (typpy(x, Number) && typpy(y, Number)) { return this.position({ x: x, y: y }); } if (!typpy(x, Object) || !typpy(x.x, Number) || !typpy(x.y, Number)) { return this.pos; } this.pos = x; }
let getListener = (eventObj, instanceNode) => { if (!eventObj) { return null; } if (typpy(eventObj, String)) { return instanceNode.subelms[new SubElmId("listener", eventObj, instanceNode)]; } if (typpy(eventObj, "listener")) { return instanceNode.subelms[new SubElm(eventObj, instanceNode).id]; } return getListener(eventObj.event, this.nodes[new NodeId({ name: eventObj.to })]); };
/** * Couleurs * * @name Couleurs * @function * @param {Boolean|undefined} setStringProto If `true`, the prototype of String * class will be modified. * @param {String|Array} fg An optional foreground color. * @return {String|Object} The colored string if the `fg` argument was provided * or an object containing the following methods: * * - `proto` * - `toString` * - `fg` * - `bg` * - `bold` * - `italic` * - `underline` * - `inverse` * - `strike` * */ function Couleurs(text, fg) { if (!typpy(this, Couleurs) || typpy(this, undefined)) { if (typpy(fg, Array) || typpy(fg, String)) { return Couleurs.fg(text, fg); } return new Couleurs(text, fg); } this.text = text; this.styles = []; }
/** * convertTo * Converts an input into a class instance. * * @name convertTo * @function * @param {Class} classConst The class to convert to. * @param {Object|Array} input The object info. * @param {Object} opts The options object (optional). * @returns {TildaAction|TildaOption} The input converted into a class instance. */ static convertTo (classConst, input, opts) { if (typpy(input, classConst)) { return input; } if (typpy(input, Array)) { return input.map(x => new classConst(x, opts)); } return new classConst(input, opts); }
/** * log * Displays debug messages by providing the type. * * Usage: * * ```js * CuteLogger.log("Some info message") * CuteLogger.log(new Error("Interesting error")) * ``` * * The config object can be modified to make this module to act diferently. * Defaults are shown: * * ```js * CuteLogger.config = { * // The error type * error: { * color: [192, 57, 43] * , text: "error" * , level: 1 * } * // The warning type * , warn: { * color: [241, 196, 15] * , text: "warn " * , level: 2 * } * // The info type * , info: { * color: [52, 152, 219] * , text: "info " * , level: 3 * } * // Display date * , date: false * // Log level * , level: 4 * * // Output streams * , stdout: process.stdout * , stderr: process.stderr * * // The options passed to `util.inspect` * , inspectOptions: { colors: true } * } * ```` * * @name log * @function * @param {Object} message The debug message that should be displayed. If * `message` is an object, it will show the inspected object. * @param {String} type The message type (e.g. "error", "info" etc). Default is * computed (`"error"` if the message is an `Error`) or `"info"` if the provided * `type` is invalid. * @return {Object} The `CuteLogger` instance. */ static log (message, type) { if (Array.isArray(message)) { message.forEach(c => { this.log(c, type) }) return CuteLogger } let logMessage = "" type = Deffy(type, Typpy(message)) if (type === "error" && message && message.message) { message = message.message } if (Typpy(CuteLogger.config[type]) === "undefined") { type = "info" } // Get type from config type = CuteLogger.config[type] if (type.level > CuteLogger.config.level) { return CuteLogger } // Build message logMessage += Couleurs(type.text).bold().fg(type.color) + " " if (CuteLogger.config.date) { logMessage += Couleurs(CuteLogger.getDate()).bold() + " " } if (typeof message === "object") { message = util.inspect(message, CuteLogger.config.inspectOptions) } // Add message logMessage += message // Where should the message go? const str = CuteLogger.config.streams[type.stream] || CuteLogger.config.streams.out // No fun when the stream is not TTY if (!str.isTTY) { logMessage = AnsiParser.removeAnsi(logMessage) } // Print message str.write(logMessage + "\n") return CuteLogger }
iterateObj(data, function (cOpt, optName) { cOpt = normalizeOpt(cOpt); cOpt.name = optName; var $cContext = $context === $ ? undefined : $context; if (!$cContext && !cOpt.selector && !cOpt.listItem) { throw new Err("There is no element selected for the '<option.name>' field. Please provide a selector, list item or use nested object structure.", { option: cOpt, code: "NO_ELEMENT_SELECTED" }); } var $elm = cOpt.selector ? $(cOpt.selector, $cContext) : $cContext; // Handle lists if (cOpt.listItem) { var docs = pageData[cOpt.name] = [], $items = $(cOpt.listItem, $cContext), isEmpty = emptyObj(cOpt.data); if (isEmpty) { cOpt.data.___raw = {}; } for (var i = 0; i < $items.length; ++i) { var cDoc = handleDataObj(cOpt.data, $items.eq(i)); docs.push(cDoc.___raw || cDoc); } } else { if (typpy(cOpt.eq, Number)) { $elm = $elm.eq(cOpt.eq); } if (!emptyObj(cOpt.data)) { pageData[cOpt.name] = handleDataObj(cOpt.data, $elm); return pageData; } var value = typpy(cOpt.how, Function) ? cOpt.how($elm) : $elm[cOpt.how](); if (cOpt.trimValue && typpy(value, String)) { value = value.trim(); } if (cOpt.convert) { value = cOpt.convert(value); } pageData[cOpt.name] = value; } });
/** * Couleurs * * @name Couleurs * @function * @param {Boolean|undefined} setStringProto If `true`, the prototype of String * class will be modified. * @param {String|Array} fg An optional foreground color. * @return {String|Object} The colored string if the `fg` argument was provided * or an object containing the following methods: * * - `proto` * - `toString` * - `fg` * - `bg` * - `bold` * - `italic` * - `underline` * - `inverse` * - `strike` * */ function Couleurs(text, fg) { var self = this; if (!Typpy(self, Couleurs) || Typpy(self, undefined)) { if (/array|string/.test(Typpy(fg))) { return Couleurs.fg(text, fg); } return new Couleurs(text, fg); } self.text = text; self.styles = []; }
function parseObject (value) { if (typpy(value, Array)) { return _.map(value, function (n, key) { return parse(n) }) } else if (typpy(value, Object)) { return _.forIn(value, function (n, key) { value[key] = parse(n) }) } return {} }
/** * * @name parseObject * @function * @param {Value} value parse object * @return {Value} parsed object * */ function parseObject (value) { if (typpy(value, Array)) { return value.map(function (n, key) { return autoParse(n) }) } else if (typpy(value, Object)) { for (var n in value) { value[n] = autoParse(value[n]) } return value } return {} }
/** * add * Adds a new function. * * There are three levels where the functions are added to be executed: * * Parallel: | <0: [.............................................]> * Unordered (don't wait): | <4a: [........]> * + <4b: [....]> * + <4c: [......]> * Ordered (wait): | <1: [...]> <2: [.]> <3:[.....]> <5: [....]> * * @name add * @function * @param {Function|Transformer} fn The function to add. Note you can add * an existing transformer instance as well. * @param {TransformerType} type One of the following: * * - `Transformer.PARALLEL`: Used to append on the parallel timeline. * - `Transformer.UNORDERED`: Grouped, but unordered. * - `Transformer.ORDERED`: Grouped, but ordered. * * @return {Transformer} The current Transformer instance. * */ add (fn, type) { if (typeof type === "string") { type = Transformer[type]; if (typeof type !== "number") { throw new Error("Invalid type."); } } if (typpy(fn, Array)) { fn.forEach(c => this.add(c, type)); return this; } type = deffy(type, Transformer.ORDERED); if (typpy(fn, Transformer)) { let tr = fn; tr.autostart = false; fn = (data, cb) => { tr.start(data, cb); }; } fn = this._wrapFn(fn); switch (type) { case Transformer.PARALLEL: this._parallel.push(fn); break; case Transformer.UNORDERED: if (this._lastFn.type !== Transformer.UNORDERED) { this._cUnordered = []; this._ordered.push({ parallel: this._cUnordered }); } this._cUnordered.push(fn); break; case Transformer.ORDERED: this._ordered.push(fn); break; } this._lastFn = { fn: fn , type: type }; this._ordered.push(); return this; }
/** * addLine * Adds a new line. * * @name addLine * @function * @param {Line|Object} line The line to add. * @return {Line} The added line. */ addLine (line) { line = new LineElm(line); if (typpy(line.source, SubElm)) { line.source.lines[line.id] = line; } return (this.lines[line.id] = this.ids[line.id] = line); }
iterateObject(input, value => { if (typpy(value.types, String)) { value.types = { normal: [value.types] }; } else if (typpy(value.types, Array)) { value.types = { normal: value.types }; } value.types = Object(value.types); mapObject(value.types, (value, name) => { return { char: value[0] , icon: value[1] && ("&#x" + value[1]) }; }); });
let normalize = tsks => tsks.map(c => { if (typpy(c, Function) && c.length >= 1) { return c; } return done => { asyncer(c, done) }; });
iterateObj(cOpt, (v, n) => { v = normalizeOpt(v); let $elm = $(v.selector); if (typpy(v.eq, Number)) { $elm = $elm.eq(v.eq); } let value = typpy(v.how, Function) ? v.how($elm) : $elm[v.how](); if (v.convert) { value = v.convert(value); } if (v.trimValue && typpy(value, String)) { value = value.trim(); } pageData[n] = value; });
iterateObj(data, (cOpt, optName) => { cOpt = normalizeOpt(cOpt); cOpt.name = optName; let $cContext = $context === $ ? undefined : $context , $elm = cOpt.selector ? $(cOpt.selector, $cContext) : $cContext ; // Handle lists if (cOpt.listItem) { let docs = pageData[cOpt.name] = [] , $items = $(cOpt.listItem, $cContext) , isEmpty = emptyObj(cOpt.data) ; if (isEmpty) { cOpt.data.___raw = {}; } for (let i = 0; i < $items.length; ++i) { let cDoc = handleDataObj(cOpt.data, $items.eq(i)); docs.push(cDoc.___raw || cDoc); } } else { if (typpy(cOpt.eq, Number)) { $elm = $elm.eq(v.eq); } let value = typpy(cOpt.how, Function) ? cOpt.how($elm) : $elm[cOpt.how](); if (cOpt.convert) { value = cOpt.convert(value); } if (cOpt.trimValue && typpy(value, String)) { value = value.trim(); } pageData[cOpt.name] = value; } });
, normalizeOpt = v => { if (typpy(v, String)) { v = { selector: v }; } objDef(v, "how", "text", true); if (v.attr) { v.how = $elm => $elm.attr(v.attr); } objDef(v, "trimValue", true); return v; }
return function (str, r, g, b) { var res = prepareHandler.apply(this, arguments); if (Typpy(this.text) === "string") { this.styles.push([ start , end , res ]); return this; } return toStr(start, res.color, res.text, end); }
constructor (input) { if (typpy(input, String)) { input = { name: input }; } this.name = input.name; this.description = input.desc || input.description || ""; this.type = input.type; this.stdin = input.stdin || false; this.prompt = input.prompt; }
function prepareHandler(text, r, g, b) { if (Typpy(this.text) === "string") { r = text; text = this.text; } var res = { color: "" , text: text }; if (Typpy(r, Array)) { res.color = colorConvert.rgb.hex(r); } else if (Typpy(r, Number)) { res.color = colorConvert.rgb.hex(r, g, b); } else { res.color = r; } return res; }
var normalizeOpt = function normalizeOpt(v) { if (typpy(v, String)) { v = { selector: v }; } objDef(v, "data", {}); objDef(v, "how", "text", true); if (v.attr) { v.how = function ($elm) { return $elm.attr(v.attr); }; } objDef(v, "trimValue", true); return v; },
iterateObject(values, (c, i) => { let arg = action._args[i]; if (!arg.type) { return; } if (arg.type) { c = values[i] = autoparse(values[i], arg.type); } if (arg.type && !typpy(c, arg.type)) { return this.exit({ code: "INVALID_ARG_VALUE" , exe: this.name , arg: arg }); } });
module.exports = function (_input, instName) { var input = Ul.clone(_input); if (Typpy(input, String)) { input = [input]; } var pInput = parseCommand(input[0]); if (pInput.error) { // TODO Not sure how to handle such errors throw pInput.error; } pInput.instance = deffy(pInput.instance, instName); switch (pInput.type.func) { case flowTypes.DataHandler: case flowTypes.StreamHandler: return new pInput.type.func( pInput.command , { to: pInput.instance , once: pInput.type.type === "once" , leaking: pInput.type.type === "leaking" } , input[1] ); case flowTypes.Emit: pInput.instance = deffy(input[1] && input[1].to, pInput.instance) return new flowTypes.Emit( pInput.command , { to: pInput.instance , net: pInput.type.type === "net" , leaking: pInput.type.type === "leaking" } ); default: throw new Error("Unsupported type."); } };
module.exports = function getListener (event, index, instance, isServer) { if (Typpy(event, Object)) { return getListener(event.name, event.index, index, event.server); } var flow = Deffy(isServer ? instance.flow : Object(instance.client).flow, []) , result = null ; IterateObject(flow, function (value) { if (value[0] === event) { --index; } if (index === -1) { result = value; return false; } }); return result; };