<commit_before>var utils = require('./utils');
var sockets = {};
var streams = {};

if (typeof engine !== 'undefined') {
    engine.sockets = sockets;
}

exports.setup = setupSocket;
exports.stream = setupStream;

/**
 * Setup a stream to write over a socket.
 *
 * @public
 * @param {object} The stream object.
 * @param {string} The destination URL.
 */
function setupStream (stream, url) {

    // append parsed url on stream
    if (typeof url === 'string' && !(url = parseUrl(url))) {
        return console.error('Invalid socket url.');
    }

    // create stream id
    stream.id = stream.id || utils.uid(3);

    // save url data
    stream.url = url;

    // create or get a socket
    stream.socket = stream.socket || getSocket(url.host);

    // save session on stream
    stream.session = stream.socket.session;

    // send data to socket on data
    stream.data(send);

    // append custom end handler
    stream._end = end;

    // save stream in cache
    streams[stream.id] = stream;

    // save stream on socket, to end stream on socket end
    stream.socket.streams[stream.id] = stream;

    return stream;
}

/**
 * Get or create a new client Socket.
 *
 * @public
 * @param {string} The target host.
 */
function getSocket (host) {

    // get socket from cached connections
    if (sockets[host]) {
        return sockets[host];
    }

    // create new websocket connection
    var socket = sockets[host] = new WebSocket('ws://' + host + '/');
    socket._cacheKey = host;

    // setup and return socket
    return setupSocket(socket);
}

/**
 * Setup socket with handlers.
 *
 * @public
 * @param {object} The socket.
 */
function setupSocket (socket) {

    // stream refs
    socket.streams = {};
    socket._buffer = [];

    // session
    socket.session = socket.session || {};

    // setup socket handlers
    socket.onclose = closeHandler;
    socket.onerror = errorHandler;
    socket.onmessage = parseMessage;
    socket.onopen = openHandler;

    return socket;
}

/**
 * Parse a socket URL string.
 *
 * @public
 * @param {string} The destination URL.
 */
function parseUrl (url) {

    url = url.split('/');
    if (url.length < 2) {
        return;
    }

    var urlObject = {};
    if (url.length < 3) {
        urlObject = {
            // TODO server default host??
            host: global.location.host,
            inst: url[0],
            emit: url[1]
        };
    } else {
        urlObject = {
            host: url[0],
            inst: url[1],
            emit: url[2]
        };
    }

    return urlObject;
}

/**
 * Create and send a websocket message.
 *
 * @private
 * @param {object} The error object.
 * @param {object} The data object.
 */
function send (err, data, end) {

    // create message
    var message = [end ? 0 : 1, this.url.inst, this.url.emit, this.id, err ? err.toString() : 0];

    // add the data to the message
    if (typeof data !== 'undefined') {
        message[5] = data;
    }

    // encode message (string)
    try {
        message = JSON.stringify(message);
    } catch (err) {
        return console.error(err);
    }

    // buffer writes if socket is not ready yet
    if (this.socket.readyState !== 1) {
        return this.socket._buffer.push(message);
    }

    // send message over socket
    this.socket.send(message);
}

/**
 * Custom end handler.
 *
 * @private
 */
function end (err, data) {

    // send end signal
    this.send(err, data, true);

    // remove stream from cache
    delete streams[this.id];

    // remove stream from socket
    delete this.socket.streams[this.id];
}

/**
 * Prase websocket messages.
 *
 * @public
 * @param {object} The message event object.
 */
function parseMessage (messageEvent) {

    var socket = messageEvent.target;
    var message = messageEvent.data;
    var role = (socket.session || {})[engine.session_role];

    // parse message
    // protocoll: [type, instance, event, id, err, data]

    // TODO broadcast (grouped connections)
    /*
      - how to define/create groups?
      - get group by name
      - get group by session id
      - get group by regexp pattern?
      - get group by role?
      - check group access with session
      - public groups
    */

    try {
        message = JSON.parse(message);
    } catch (error) {
        return console.error(error);
    }

    // extract data from parsed message
    var type = message[0];
    var instance = message[1];
    var event = message[2];
    var id = message[3];
    var err = message[4];
    var data = message[5];

    // check mandatory message values
    if (!event || !instance || !id) {

        // send error back
        message[4] = 'Invalid message.';
        message[5] = 0;
        return socket.send(JSON.stringify(message));
    }

    // get the link object
    var stream = streams[id];

    // write data to stream on write message
    if (type) {

        // create a new stream and emit to flow handlers
        if (!stream) {

            // get module instance
            if (!(instance = engine.instances[instance])) {

                // load an instance
                // TODO buffer messages for this instance (pause)
                engine.load(message[1], role, function (err, instance) {

                    if (err) {
                        // send error back
                        message[4] = err;
                        message[5] = 0;
                        return socket.send(JSON.stringify(message));
                    }

                    // create a new stream and save it in cache and write data
                    createStream(instance, event, id, socket, message[1]).write(err, data);
                });
                return;

            // check role and event access on server module instance
            } else if (!(utils.eventAccess(instance, role, event))) {

                // send error back
                message[4] = 'Access denied to instance: ' + message[1];
                message[5] = 0;
                return socket.send(JSON.stringify(message));
            }

            // create a new stream and save it in cache and write data
            stream = createStream(instance, event, id, socket, message[1]);
        }

        stream.write(err, data);

    // end stream on end message
    } else if (stream) {
        stream.end(err, data);
    }
}

function createStream (instance, event, id, socket, instanceName) {

    // create stream and save it to cache
    sockets[id] = setupStream(instance.flow(event, {
        id: id,
        socket: socket
    }), {
        inst: instanceName,
        emit: event
    });

    return sockets[id];
}

/**
 * Write bufferd data when a socket is connected.
 *
 * @public
 * @param {object} The open event object.
 */
function openHandler (openEvent) {
    var socket = openEvent.target;

    // send buffered writes to socket
    if (socket._buffer.length) {
        for (var i = 0, l = socket._buffer.length; i < l; ++i) {
            socket.send(socket._buffer[i]);
        }

        // empty buffer
        socket._buffer = [];
    }
}

/**
 * Remove socket from cache and end streams.
 *
 * @public
 * @param {object} The close event object.
 */
function closeHandler (closeEvent) {
    var socket = closeEvent.target;

    // remove socket from sockets cache
    delete sockets[socket._cacheKey];

    // end all streams on socket
    for (var stream in socket.streams) {
        socket.streams[stream].end();
    }
}

/**
 * Write socket errors to streams.
 *
 * @public
 * @param {object} The error event object.
 */
function errorHandler (errorEvent) {
    var socket = errorEvent.target;
    for (var stream in socket.streams) {
        stream.write(errorEvent.data);
    }
}
<commit_msg>send is not on readable stream<commit_after>var utils = require('./utils');
var sockets = {};
var streams = {};

if (typeof engine !== 'undefined') {
    engine.sockets = sockets;
}

exports.setup = setupSocket;
exports.stream = setupStream;

/**
 * Setup a stream to write over a socket.
 *
 * @public
 * @param {object} The stream object.
 * @param {string} The destination URL.
 */
function setupStream (stream, url) {

    // append parsed url on stream
    if (typeof url === 'string' && !(url = parseUrl(url))) {
        return console.error('Invalid socket url.');
    }

    // create stream id
    stream.id = stream.id || utils.uid(3);

    // save url data
    stream.url = url;

    // create or get a socket
    stream.socket = stream.socket || getSocket(url.host);

    // save session on stream
    stream.session = stream.socket.session;

    // send data to socket on data
    stream.data(send);

    // append custom end handler
    stream._end = end;

    // save stream in cache
    streams[stream.id] = stream;

    // save stream on socket, to end stream on socket end
    stream.socket.streams[stream.id] = stream;

    return stream;
}

/**
 * Get or create a new client Socket.
 *
 * @public
 * @param {string} The target host.
 */
function getSocket (host) {

    // get socket from cached connections
    if (sockets[host]) {
        return sockets[host];
    }

    // create new websocket connection
    var socket = sockets[host] = new WebSocket('ws://' + host + '/');
    socket._cacheKey = host;

    // setup and return socket
    return setupSocket(socket);
}

/**
 * Setup socket with handlers.
 *
 * @public
 * @param {object} The socket.
 */
function setupSocket (socket) {

    // stream refs
    socket.streams = {};
    socket._buffer = [];

    // session
    socket.session = socket.session || {};

    // setup socket handlers
    socket.onclose = closeHandler;
    socket.onerror = errorHandler;
    socket.onmessage = parseMessage;
    socket.onopen = openHandler;

    return socket;
}

/**
 * Parse a socket URL string.
 *
 * @public
 * @param {string} The destination URL.
 */
function parseUrl (url) {

    url = url.split('/');
    if (url.length < 2) {
        return;
    }

    var urlObject = {};
    if (url.length < 3) {
        urlObject = {
            // TODO server default host??
            host: global.location.host,
            inst: url[0],
            emit: url[1]
        };
    } else {
        urlObject = {
            host: url[0],
            inst: url[1],
            emit: url[2]
        };
    }

    return urlObject;
}

/**
 * Create and send a websocket message.
 *
 * @private
 * @param {object} The error object.
 * @param {object} The data object.
 */
function send (err, data, end) {

    // create message
    var message = [end ? 0 : 1, this.url.inst, this.url.emit, this.id, err ? err.toString() : 0];

    // add the data to the message
    if (typeof data !== 'undefined') {
        message[5] = data;
    }

    // encode message (string)
    try {
        message = JSON.stringify(message);
    } catch (err) {
        return console.error(err);
    }

    // buffer writes if socket is not ready yet
    if (this.socket.readyState !== 1) {
        return this.socket._buffer.push(message);
    }

    // send message over socket
    this.socket.send(message);
}

/**
 * Custom end handler.
 *
 * @private
 */
function end (err, data) {

    // send end signal
    send.call(this, err, data, true);

    // remove stream from cache
    delete streams[this.id];

    // remove stream from socket
    delete this.socket.streams[this.id];
}

/**
 * Prase websocket messages.
 *
 * @public
 * @param {object} The message event object.
 */
function parseMessage (messageEvent) {

    var socket = messageEvent.target;
    var message = messageEvent.data;
    var role = (socket.session || {})[engine.session_role];

    // parse message
    // protocoll: [type, instance, event, id, err, data]

    // TODO broadcast (grouped connections)
    /*
      - how to define/create groups?
      - get group by name
      - get group by session id
      - get group by regexp pattern?
      - get group by role?
      - check group access with session
      - public groups
    */

    try {
        message = JSON.parse(message);
    } catch (error) {
        return console.error(error);
    }

    // extract data from parsed message
    var type = message[0];
    var instance = message[1];
    var event = message[2];
    var id = message[3];
    var err = message[4];
    var data = message[5];

    // check mandatory message values
    if (!event || !instance || !id) {

        // send error back
        message[4] = 'Invalid message.';
        message[5] = 0;
        return socket.send(JSON.stringify(message));
    }

    // get the link object
    var stream = streams[id];

    // write data to stream on write message
    if (type) {

        // create a new stream and emit to flow handlers
        if (!stream) {

            // get module instance
            if (!(instance = engine.instances[instance])) {

                // load an instance
                // TODO buffer messages for this instance (pause)
                engine.load(message[1], role, function (err, instance) {

                    if (err) {
                        // send error back
                        message[4] = err;
                        message[5] = 0;
                        return socket.send(JSON.stringify(message));
                    }

                    // create a new stream and save it in cache and write data
                    createStream(instance, event, id, socket, message[1]).write(err, data);
                });
                return;

            // check role and event access on server module instance
            } else if (!(utils.eventAccess(instance, role, event))) {

                // send error back
                message[4] = 'Access denied to instance: ' + message[1];
                message[5] = 0;
                return socket.send(JSON.stringify(message));
            }

            // create a new stream and save it in cache and write data
            stream = createStream(instance, event, id, socket, message[1]);
        }

        stream.write(err, data);

    // end stream on end message
    } else if (stream) {
        stream.end(err, data);
    }
}

function createStream (instance, event, id, socket, instanceName) {

    // create stream and save it to cache
    sockets[id] = setupStream(instance.flow(event, {
        id: id,
        socket: socket
    }), {
        inst: instanceName,
        emit: event
    });

    return sockets[id];
}

/**
 * Write bufferd data when a socket is connected.
 *
 * @public
 * @param {object} The open event object.
 */
function openHandler (openEvent) {
    var socket = openEvent.target;

    // send buffered writes to socket
    if (socket._buffer.length) {
        for (var i = 0, l = socket._buffer.length; i < l; ++i) {
            socket.send(socket._buffer[i]);
        }

        // empty buffer
        socket._buffer = [];
    }
}

/**
 * Remove socket from cache and end streams.
 *
 * @public
 * @param {object} The close event object.
 */
function closeHandler (closeEvent) {
    var socket = closeEvent.target;

    // end all streams on socket
    for (var stream in socket.streams) {
        socket.streams[stream].end();
    }

    // remove socket from sockets cache
    delete sockets[socket._cacheKey];
}

/**
 * Write socket errors to streams.
 *
 * @public
 * @param {object} The error event object.
 */
function errorHandler (errorEvent) {
    var socket = errorEvent.target;
    for (var stream in socket.streams) {
        stream.write(errorEvent.data);
    }
}
<|endoftext|>


<commit_before>import Ember from 'ember';

const {
  RSVP: { Promise },
  run
} = Ember;

export const next = () => new Promise(resolve => run.next(resolve));
<commit_msg>test helper<commit_after>import Ember from 'ember';

const {
  RSVP: { Promise },
  run
} = Ember;

export const next = () => new Promise(resolve => run.next(resolve));
export const later = delay => new Promise(resolve => run.later(resolve, delay));
<|endoftext|>


<commit_before>'use strict';

var React = require('react');

var allTypes = [
    'Html', 'HtmlBlock', 'Text', 'Paragraph', 'Header', 'Softbreak', 'Hardbreak',
    'Link', 'Image', 'Emph', 'Code', 'CodeBlock', 'BlockQuote', 'List', 'Item',
    'Strong', 'HorizontalRule', 'Document'
];

function tag(node, name, attrs, children) {
    node.react = {
        tag: name,
        props: attrs,
        children: children || []
    };
}

function isGrandChildOfList(node) {
    var grandparent = node.parent.parent;
    return (
        grandparent &&
        grandparent.type === 'List' &&
        grandparent.listTight
    );
}

function addChild(node, child) {
    var parent = node;
    do {
        parent = parent.parent;
    } while (!parent.react);

    parent.react.children.push(child);
}

function createElement(tagName, props, children) {
    var args = [tagName, props].concat(children);
    var child = React.createElement.apply(React, args);
    return child;
}

function renderNodes(block) {
    var walker = block.walker();
    var sourcePos = this.sourcePos;
    var escapeHtml = this.escapeHtml;
    var skipHtml = this.skipHtml;
    var infoWords;

    // Softbreaks are usually treated as newlines, but in HTML we might want explicit linebreaks
    var softBreak = (
        this.softBreak === 'br' ?
        React.createElement('br') :
        this.softBreak
    );

    var e, node, entering, leaving, attrs, doc;
    while ((e = walker.next())) {
        entering = e.entering;
        leaving = !entering;
        node = e.node;
        attrs = {};

        // If we have not assigned a document yet, assume the current node is just that
        if (!doc) {
            doc = node;
            node.react = { children: [] };
        }

        // `sourcePos` is true if the user wants source information (line/column info from markdown source)
        if (sourcePos && node.sourcepos) {
            var pos = node.sourcepos;
            attrs['data-sourcepos'] = [
                pos[0][0], ':', pos[0][1], '-',
                pos[1][0], ':', pos[1][1]
            ].map(String).join('');
        }

        // In HTML, we don't want paragraphs inside of list items
        if (node.type === 'Paragraph' && isGrandChildOfList(node)) {
            continue;
        }

        if (leaving) {
            // Commonmark treats image description as children. We just want the text
            if (node.type === 'Image') {
                node.react.props.alt = node.react.children[0];
                node.react.children = [];
            }

            // `allowNode` is validated to be a function if it exists
            if (node !== doc && this.allowNode && !this.allowNode({
                type: node.type,
                tag: node.react.tag,
                props: node.react.props,
                children: node.react.children
            })) {
                continue;
            }

            // `allowedTypes` is an array containing the allowed types
            var nodeIsAllowed = this.allowedTypes.indexOf(node.type) !== -1;
            if (node !== doc && nodeIsAllowed) {
                addChild(node, createElement(
                    node.react.tag,
                    node.react.props,
                    node.react.children
                ));
            }

            continue;
        }

        // Entering a new node
        switch (node.type) {
            case 'Html':
            case 'HtmlBlock':
                if (escapeHtml) {
                    addChild(node, node.literal);
                } else if (!skipHtml) {
                    attrs.dangerouslySetInnerHTML = {
                        __html: node.literal
                    };

                    addChild(node, createElement(
                        node.type === 'Html' ? 'span' : 'div',
                        attrs
                    ));
                }
                break;
            case 'Text':
                addChild(node, node.literal);
                break;
            case 'Paragraph':
                tag(node, 'p', attrs);
                break;
            case 'Header':
                tag(node, 'h' + node.level, attrs);
                break;
            case 'Softbreak':
                addChild(node, softBreak);
                break;
            case 'Hardbreak':
                addChild(node, React.createElement('br'));
                break;
            case 'Strong':
                tag(node, 'strong', attrs);
                break;
            case 'Link':
                attrs.href = node.destination;
                if (node.title) {
                    attrs.title = node.title;
                }
                tag(node, 'a', attrs);
                break;
            case 'Image':
                attrs.src = node.destination;
                if (node.title) {
                    attrs.title = node.title;
                }
                tag(node, 'img', attrs);
                break;
            case 'Emph':
                tag(node, 'em', attrs);
                break;
            case 'Code':
                addChild(node, createElement(
                    'code',
                    attrs,
                    [node.literal]
                ));
                break;
            case 'CodeBlock':
                infoWords = node.info ? node.info.split(/ +/) : [];
                if (infoWords.length > 0 && infoWords[0].length > 0) {
                    attrs.className = 'language-' + infoWords[0];
                }

                var code = createElement('code', attrs, [node.literal]);
                addChild(node, createElement('pre', {}, [code]));
                break;
            case 'BlockQuote':
                tag(node, 'blockquote', attrs);
                break;
            case 'List':
                var start = node.listStart;
                if (start !== null && start !== 1) {
                    attrs.start = start.toString();
                }
                tag(node, node.listType === 'Bullet' ? 'ul' : 'ol', attrs);
                break;
            case 'Item':
                tag(node, 'li', attrs);
                break;
            case 'HorizontalRule':
                addChild(node, createElement('hr', attrs));
                break;
            case 'Document':
                break;
            default:
                throw new Error('Unknown node type "' + node.type + '"');
        }
    }

    return doc.react.children;
}

function ReactRenderer(options) {
    var opts = options || {};

    if (opts.allowedTypes && opts.disallowedTypes) {
        throw new Error('Only one of `allowedTypes` and `disallowedTypes` should be defined');
    }

    if (opts.allowedTypes && !Array.isArray(opts.allowedTypes)) {
        throw new Error('`allowedTypes` must be an array');
    }

    if (opts.disallowedTypes && !Array.isArray(opts.disallowedTypes)) {
        throw new Error('`disallowedTypes` must be an array');
    }

    if (opts.allowNode && typeof opts.allowNode !== 'function') {
        throw new Error('`allowNode` must be a function');
    }

    var allowedTypes = opts.allowedTypes || allTypes;
    if (opts.disallowedTypes) {
        allowedTypes = allowedTypes.filter(function(type) {
            return opts.disallowedTypes.indexOf(type) === -1;
        });
    }

    return {
        sourcePos: opts.sourcePos,
        softBreak: opts.softBreak || '\n',
        escapeHtml: Boolean(opts.escapeHtml),
        skipHtml: Boolean(opts.skipHtml),
        allowNode: opts.allowNode,
        allowedTypes: allowedTypes,
        render: renderNodes
    };
}

module.exports = ReactRenderer;
<commit_msg>Adding index-based keys to generated elements<commit_after>'use strict';

var React = require('react');

var allTypes = [
    'Html', 'HtmlBlock', 'Text', 'Paragraph', 'Header', 'Softbreak', 'Hardbreak',
    'Link', 'Image', 'Emph', 'Code', 'CodeBlock', 'BlockQuote', 'List', 'Item',
    'Strong', 'HorizontalRule', 'Document'
];

function tag(node, name, attrs, children) {
    node.react = {
        tag: name,
        props: attrs,
        children: children || []
    };
}

function isGrandChildOfList(node) {
    var grandparent = node.parent.parent;
    return (
        grandparent &&
        grandparent.type === 'List' &&
        grandparent.listTight
    );
}

function addChild(node, child) {
    var parent = node;
    do {
        parent = parent.parent;
    } while (!parent.react);

    parent.react.children.push(child);
}

function createElement(tagName, props, children) {
    var args = [tagName, props].concat(children);
    var child = React.createElement.apply(React, args);
    return child;
}

function renderNodes(block) {
    var walker = block.walker();
    var sourcePos = this.sourcePos;
    var escapeHtml = this.escapeHtml;
    var skipHtml = this.skipHtml;
    var infoWords;

    // Softbreaks are usually treated as newlines, but in HTML we might want explicit linebreaks
    var softBreak = (
        this.softBreak === 'br' ?
        React.createElement('br') :
        this.softBreak
    );

    var e, node, entering, leaving, attrs, doc, key;
    while ((e = walker.next())) {
        entering = e.entering;
        leaving = !entering;
        node = e.node;
        key = !e.node.prev ? 0 : e.node.prev.reactKey + 1;
        attrs = { key: key };

        // Assigning a key to the node
        node.reactKey = key;

        // If we have not assigned a document yet, assume the current node is just that
        if (!doc) {
            doc = node;
            node.react = { children: [] };
        }

        // `sourcePos` is true if the user wants source information (line/column info from markdown source)
        if (sourcePos && node.sourcepos) {
            var pos = node.sourcepos;
            attrs['data-sourcepos'] = [
                pos[0][0], ':', pos[0][1], '-',
                pos[1][0], ':', pos[1][1]
            ].map(String).join('');
        }

        // In HTML, we don't want paragraphs inside of list items
        if (node.type === 'Paragraph' && isGrandChildOfList(node)) {
            continue;
        }

        if (leaving) {
            // Commonmark treats image description as children. We just want the text
            if (node.type === 'Image') {
                node.react.props.alt = node.react.children[0];
                node.react.children = [];
            }

            // `allowNode` is validated to be a function if it exists
            if (node !== doc && this.allowNode && !this.allowNode({
                type: node.type,
                tag: node.react.tag,
                props: node.react.props,
                children: node.react.children
            })) {
                continue;
            }

            // `allowedTypes` is an array containing the allowed types
            var nodeIsAllowed = this.allowedTypes.indexOf(node.type) !== -1;
            if (node !== doc && nodeIsAllowed) {
                addChild(node, createElement(
                    node.react.tag,
                    node.react.props,
                    node.react.children
                ));
            }

            continue;
        }

        // Entering a new node
        switch (node.type) {
            case 'Html':
            case 'HtmlBlock':
                if (escapeHtml) {
                    addChild(node, node.literal);
                } else if (!skipHtml) {
                    attrs.dangerouslySetInnerHTML = {
                        __html: node.literal
                    };

                    addChild(node, createElement(
                        node.type === 'Html' ? 'span' : 'div',
                        attrs
                    ));
                }
                break;
            case 'Text':
                addChild(node, node.literal);
                break;
            case 'Paragraph':
                tag(node, 'p', attrs);
                break;
            case 'Header':
                tag(node, 'h' + node.level, attrs);
                break;
            case 'Softbreak':
                addChild(node, softBreak);
                break;
            case 'Hardbreak':
                addChild(node, React.createElement('br'));
                break;
            case 'Strong':
                tag(node, 'strong', attrs);
                break;
            case 'Link':
                attrs.href = node.destination;
                if (node.title) {
                    attrs.title = node.title;
                }
                tag(node, 'a', attrs);
                break;
            case 'Image':
                attrs.src = node.destination;
                if (node.title) {
                    attrs.title = node.title;
                }
                tag(node, 'img', attrs);
                break;
            case 'Emph':
                tag(node, 'em', attrs);
                break;
            case 'Code':
                addChild(node, createElement(
                    'code',
                    attrs,
                    [node.literal]
                ));
                break;
            case 'CodeBlock':
                infoWords = node.info ? node.info.split(/ +/) : [];
                if (infoWords.length > 0 && infoWords[0].length > 0) {
                    attrs.className = 'language-' + infoWords[0];
                }

                var code = createElement('code', attrs, [node.literal]);
                addChild(node, createElement('pre', {}, [code]));
                break;
            case 'BlockQuote':
                tag(node, 'blockquote', attrs);
                break;
            case 'List':
                var start = node.listStart;
                if (start !== null && start !== 1) {
                    attrs.start = start.toString();
                }
                tag(node, node.listType === 'Bullet' ? 'ul' : 'ol', attrs);
                break;
            case 'Item':
                tag(node, 'li', attrs);
                break;
            case 'HorizontalRule':
                addChild(node, createElement('hr', attrs));
                break;
            case 'Document':
                break;
            default:
                throw new Error('Unknown node type "' + node.type + '"');
        }
    }

    return doc.react.children;
}

function ReactRenderer(options) {
    var opts = options || {};

    if (opts.allowedTypes && opts.disallowedTypes) {
        throw new Error('Only one of `allowedTypes` and `disallowedTypes` should be defined');
    }

    if (opts.allowedTypes && !Array.isArray(opts.allowedTypes)) {
        throw new Error('`allowedTypes` must be an array');
    }

    if (opts.disallowedTypes && !Array.isArray(opts.disallowedTypes)) {
        throw new Error('`disallowedTypes` must be an array');
    }

    if (opts.allowNode && typeof opts.allowNode !== 'function') {
        throw new Error('`allowNode` must be a function');
    }

    var allowedTypes = opts.allowedTypes || allTypes;
    if (opts.disallowedTypes) {
        allowedTypes = allowedTypes.filter(function(type) {
            return opts.disallowedTypes.indexOf(type) === -1;
        });
    }

    return {
        sourcePos: opts.sourcePos,
        softBreak: opts.softBreak || '\n',
        escapeHtml: Boolean(opts.escapeHtml),
        skipHtml: Boolean(opts.skipHtml),
        allowNode: opts.allowNode,
        allowedTypes: allowedTypes,
        render: renderNodes
    };
}

module.exports = ReactRenderer;
<|endoftext|>


<commit_before>require('../support')
import { mocks, helpers } from '../../support'
import CommunityJoinLinkHandler from '../../../src/containers/community/CommunityJoinLinkHandler.js'
import { renderIntoDocument } from 'react-addons-test-utils'
import { NAVIGATE } from '../../../src/actions'
const { createElement } = helpers

describe('CommunityJoinLinkHandler', () => {
  var store, redirectUrl

  const setup = props => {
    const component = createElement(CommunityJoinLinkHandler, props, {store})
    renderIntoDocument(component).getWrappedInstance()
  }

  beforeEach(() => {
    store = mocks.redux.store({
      people: {current: {id: 42}},
      errors: {}
    })
    store.transformAction(NAVIGATE, action => redirectUrl = action.payload)
  })

  it('redirects to onboarding with new membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'}
    }]
    setup({params: {id: 'foomunity', tagName: 'bar'}})
    // this is to compensate for the setTimeout in CommunityJoinLinkHandler
    setTimeout(() => {
      expect(redirectUrl).to.equal('/c/foomunity/onboarding')
      done()
    }, 10)
  })

  it('redirects to community profile with existing membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'},
      preexisting: true
    }]
    setup({params: {id: 'foomunity'}})
    // this is to compensate for the setTimeout in CommunityJoinLinkHandler
    setTimeout(() => {
      expect(redirectUrl).to.equal('/c/foomunity')
      done()
    }, 10)
  })

  it('redirects to tag page with tagName param existing membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'},
      preexisting: true
    }]
    setup({params: {id: 'foomunity', tagName: 'bar'}})
    // this is to compensate for the setTimeout in CommunityJoinLinkHandler
    setTimeout(() => {
      expect(redirectUrl).to.equal('/c/foomunity/tag/bar')
      done()
    }, 10)
  })
})
<commit_msg>move setTimeout into setup<commit_after>require('../support')
import { mocks, helpers } from '../../support'
import CommunityJoinLinkHandler from '../../../src/containers/community/CommunityJoinLinkHandler.js'
import { renderIntoDocument } from 'react-addons-test-utils'
import { NAVIGATE } from '../../../src/actions'
const { createElement } = helpers

describe.only('CommunityJoinLinkHandler', () => {
  var store, redirectUrl

  const renderAndWait = (props, callback) => {
    const component = createElement(CommunityJoinLinkHandler, props, {store})
    renderIntoDocument(component).getWrappedInstance()
    setTimeout(callback, 10)
  }

  beforeEach(() => {
    store = mocks.redux.store({
      people: {current: {id: 42}},
      errors: {}
    })
    store.transformAction(NAVIGATE, action => redirectUrl = action.payload)
  })

  it('redirects to onboarding with new membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'}
    }]
    renderAndWait({params: {id: 'foomunity', tagName: 'bar'}}, () => {
      expect(redirectUrl).to.equal('/c/foomunity/onboarding')
      done()
    })
    // this is to compensate for the setTimeout in CommunityJoinLinkHandler
  })

  it('redirects to community profile with existing membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'},
      preexisting: true
    }]
    renderAndWait({params: {id: 'foomunity'}}, () => {
      expect(redirectUrl).to.equal('/c/foomunity')
      done()
    })
  })

  it('redirects to tag page with tagName param existing membership', done => {
    store.getState().people.current.memberships = [{
      community: {id: '1', name: 'Foomunity', slug: 'foomunity'},
      preexisting: true
    }]
    renderAndWait({params: {id: 'foomunity', tagName: 'bar'}}, () => {
      expect(redirectUrl).to.equal('/c/foomunity/tag/bar')
      done()
    })
  })
})
<|endoftext|>


<commit_before>"use strict";

exports.name = "TaskTests";

var assert = require('assert'),
    _und = require('underscore'),
    Task = require('../lib/Task');

describe( exports.name, function(){

    describe('#create()', function(){
        it('creates a new task instance provided required options', function(done){
            var task = Task.create({ type: 'testType', scheduledFor: (new Date().getTime()), message: 'testMsg', recipients: 'all' });

            assert.ok( task instanceof Task );
            assert.ok( _und.isNumber( task.scheduledFor ) );
            assert.ok( task.message === 'testMsg' );
            done();
        });
        it('fails to create a new task when missing a type attribute', function(done){
            var task = Task.create({ scheduledFor: (new Date().getTime()), message: 'testMsg', recipients: 'all' });

            assert.ok( !(task instanceof Task) );
            assert.ok( !task );
            assert.ok( !_und.isNumber( task.scheduledFor ) );
            assert.ok( task.message !== 'testMsg' );
            done();
        });
    });

});
<commit_msg>Add tests for Task.create.<commit_after>"use strict";

exports.name = "TaskTests";

var assert = require('assert'),
    _und = require('underscore'),
    Task = require('../lib/Task');

describe( exports.name, function(){

    describe('#create()', function(){
        it('creates a new task instance provided required options', function(done){
            var task = Task.create({ type: 'testType', scheduledFor: (new Date().getTime()), message: 'testMsg', recipients: 'all' });

            assert.ok( task instanceof Task );
            assert.ok( _und.isNumber( task.scheduledFor ) );
            assert.ok( task.message === 'testMsg' );
            done();
        });
        it('creates a new task instance provided a date string in scheduledFor', function(done){
            var task = Task.create({ type: 'testType', scheduledFor: 'December 17, 1995 03:24:00', message: 'testMsg', recipients: 'all' });

            assert.ok( task instanceof Task );
            assert.ok( _und.isNumber( task.scheduledFor ) );
            assert.ok( task.message === 'testMsg' );
            done();
        });
        it('creates a new task with current time given a Date value in scheduledFor', function(done){
            var task = Task.create({ type: 'testType', scheduledFor: new Date(), message: 'testMsg', recipients: 'all' });

            assert.ok( task instanceof Task );
            assert.ok( _und.isNumber( task.scheduledFor ) );
            assert.ok( task.message === 'testMsg' );
            done();
        });
        it('creates a new task instance when passed two args', function(done){
            var taskAttr = {
                type: 'testType',
                scheduledFor: (new Date().getTime()),
                message: 'testMsg',
                recipients: 'all'
            };
            Task.create(taskAttr, function (err, task) {
                assert.ok( task instanceof Task );
                assert.ok( _und.isNumber( task.scheduledFor ) );
                assert.ok( task.message === 'testMsg' );
                done();
            });

        });
        it('creates a new task instance when passed three args', function(done){
            var taskAttr = {
                type: 'testType',
                scheduledFor: (new Date().getTime()),
                message: 'testMsg',
                recipients: 'all'
            };
            var opts = {
                someOption: true
            };
            Task.create(taskAttr, opts, function (err, task) {
                assert.ok( task instanceof Task );
                assert.ok( _und.isNumber( task.scheduledFor ) );
                assert.ok( task.message === 'testMsg' );
                done();
            });

        });
        it('fails to create a new task when it fails schema validation', function(done){
            var taskAttr = {
                scheduledFor: (new Date().getTime()),
                message: 'testMsg',
                recipients: 'all'
            };
            var opts = {
                someOption: true
            };
            Task.create(taskAttr, opts, function (err, task) {
                assert(err, 'Task.create throws an error');
                assert.equal('InvalidTask', err.name);
                assert.ok(!task, 'No task is created');
                done();
            });

        });
        it('fails to create a new task when it fails validation with a custom schema', function(done){
            var taskAttr = {
                scheduledFor: (new Date().getTime()),
                message: 'testMsg',
                recipients: 'all'
            };
            var opts = {
                schema: {
                    properties: {
                        newProperty: {
                            description: "A new property in a custom schema",
                            type: 'string',
                            required: true
                        }
                    }
                }
            };
            Task.create(taskAttr, opts, function (err, task) {
                assert(err, 'Task.create throws an error');
                assert.equal('InvalidTask', err.name);
                assert.ok(!task, 'No task is created');
                done();
            });

        });
        it('fails to create a new task when missing a type attribute', function(done){
            var task = Task.create({ scheduledFor: (new Date().getTime()), message: 'testMsg', recipients: 'all' });

            assert.ok( !(task instanceof Task) );
            assert.ok( !task );
            assert.ok( !_und.isNumber( task.scheduledFor ) );
            assert.ok( task.message !== 'testMsg' );
            done();
        });
    });

});
<|endoftext|>


<commit_before>export const helpIconSvg = `<svg preserveAspectRatio="xMidYMid meet" width="50%" viewBox="0 0 12 19" class='icon'
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
  <title>help</title>
  <desc>Created with Sketch.</desc>
  <defs></defs>
  <g id="icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
      <path d="M6,1.42108547e-14 C2.69142857,1.42108547e-14 0,2.77582739 0,6.18742 C0,6.66684952 0.384,7.05595173 0.857142857,7.05595173 C1.33028571,7.05595173 1.71428571,6.66684952 1.71428571,6.18742 C1.71428571,3.77463887 3.67714286,1.73706345 6,1.73706345 C8.36228571,1.73706345 10.2857143,3.66172975 10.2857143,6.02761017 C10.2857143,8.39175352 8.36228571,10.3164198 6,10.3164198 C5.52685714,10.3164198 5.14285714,10.705522 5.14285714,11.1849515 L5.14285714,13.3545438 C5.14285714,13.8339733 5.52685714,14.2230755 6,14.2230755 C6.47314286,14.2230755 6.85714286,13.8339733 6.85714286,13.3545438 L6.85714286,11.992686 C9.76114286,11.5740538 12,9.05878588 12,6.02761017 C12,2.70287073 9.30857143,1.42108547e-14 6,1.42108547e-14 Z M6,19 C6.94677386,19 7.71428571,18.2222902 7.71428571,17.2629366 C7.71428571,16.3035829 6.94677386,15.5258731 6,15.5258731 C5.05322614,15.5258731 4.28571429,16.3035829 4.28571429,17.2629366 C4.28571429,18.2222902 5.05322614,19 6,19 Z" id="help" fill="#000000"></path>
  </g>
</svg>`

// after this point icons from https://useiconic.com/open
export const infoIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M3 0c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-1.5 2.5c-.83 0-1.5.67-1.5 1.5h1c0-.28.22-.5.5-.5s.5.22.5.5-1 1.64-1 2.5c0 .86.67 1.5 1.5 1.5s1.5-.67 1.5-1.5h-1c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-.36 1-1.84 1-2.5 0-.81-.67-1.5-1.5-1.5z" transform="translate(2)"
  />
</svg>`
<commit_msg>feat(icons): added a few extra icons<commit_after>export const helpIconSvg = `<svg preserveAspectRatio="xMidYMid meet" width="50%" viewBox="0 0 12 19" class='icon'
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
  <title>help</title>
  <desc>Created with Sketch.</desc>
  <defs></defs>
  <g id="icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
      <path d="M6,1.42108547e-14 C2.69142857,1.42108547e-14 0,2.77582739 0,6.18742 C0,6.66684952 0.384,7.05595173 0.857142857,7.05595173 C1.33028571,7.05595173 1.71428571,6.66684952 1.71428571,6.18742 C1.71428571,3.77463887 3.67714286,1.73706345 6,1.73706345 C8.36228571,1.73706345 10.2857143,3.66172975 10.2857143,6.02761017 C10.2857143,8.39175352 8.36228571,10.3164198 6,10.3164198 C5.52685714,10.3164198 5.14285714,10.705522 5.14285714,11.1849515 L5.14285714,13.3545438 C5.14285714,13.8339733 5.52685714,14.2230755 6,14.2230755 C6.47314286,14.2230755 6.85714286,13.8339733 6.85714286,13.3545438 L6.85714286,11.992686 C9.76114286,11.5740538 12,9.05878588 12,6.02761017 C12,2.70287073 9.30857143,1.42108547e-14 6,1.42108547e-14 Z M6,19 C6.94677386,19 7.71428571,18.2222902 7.71428571,17.2629366 C7.71428571,16.3035829 6.94677386,15.5258731 6,15.5258731 C5.05322614,15.5258731 4.28571429,16.3035829 4.28571429,17.2629366 C4.28571429,18.2222902 5.05322614,19 6,19 Z" id="help" fill="#000000"></path>
  </g>
</svg>`

// after this point icons from https://useiconic.com/open
export const infoIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M3 0c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-1.5 2.5c-.83 0-1.5.67-1.5 1.5h1c0-.28.22-.5.5-.5s.5.22.5.5-1 1.64-1 2.5c0 .86.67 1.5 1.5 1.5s1.5-.67 1.5-1.5h-1c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-.36 1-1.84 1-2.5 0-.81-.67-1.5-1.5-1.5z" transform="translate(2)"
  />
</svg>`

export const printerIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M.34 0c-.18 0-.34.16-.34.34v7.31c0 .18.16.34.34.34h6.31c.18 0 .34-.16.34-.34v-7.31c0-.18-.16-.34-.34-.34h-6.31zm.66 1h5v5h-5v-5zm2.5 5.5c.38 0 .63.42.44.75s-.68.33-.88 0c-.19-.33.05-.75.44-.75z" />
</svg>`

export const videoIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M.5 0c-.28 0-.5.23-.5.5v4c0 .28.23.5.5.5h5c.28 0 .5-.22.5-.5v-1.5l1 1h1v-3h-1l-1 1v-1.5c0-.28-.22-.5-.5-.5h-5z" transform="translate(0 1)" />
</svg>`

export const pauseIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M0 0v6h2v-6h-2zm4 0v6h2v-6h-2z" transform="translate(1 1)" />
</svg>`

export const playIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M0 0v6l6-3-6-3z" transform="translate(1 1)" />
</svg>`

export const lockLockedIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M3 0c-1.1 0-2 .9-2 2v1h-1v4h6v-4h-1v-1c0-1.1-.9-2-2-2zm0 1c.56 0 1 .44 1 1v1h-2v-1c0-.56.44-1 1-1z" transform="translate(1)" />
</svg>`

export const lockUnlockedIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
  <path d="M3 0c-1.1 0-2 .9-2 2h1c0-.56.44-1 1-1s1 .44 1 1v2h-4v4h6v-4h-1v-2c0-1.1-.9-2-2-2z" transform="translate(1)" />
</svg>`
<|endoftext|>


<commit_before>define(['marionette', 'backbone'], function (marionette, backbone) {

	var app = new marionette.Application();

	app.addRegions({
		regionContent: "#region-page-content"
	});

	app.setContentView = function(view) {
		app.regionContent.show(view);
	};

	app.addTile = function (def, options) {

		var optionsJson = JSON.stringify(options);

		$.post('/api/webui/tiles/add', { def: def, options: optionsJson })
			.done(function () {
				app.navigate('tiles');
			});
	};

	app.navigate = function (route) {

		if (route) {

			var args = Array.prototype.slice.call(arguments, 1);

			require([route], function (obj) {

				obj.start.apply(obj, args);

				if (args && args.length) {
					//encodeURIComponent('edg/fwegw/e&wegewg/we/g')
					route += '?' + args.join('/');
				}

				backbone.history.navigate(route);
			});
		}
	};

	app.router = new marionette.AppRouter({
		appRoutes: { '*path(?*args)': 'loadPage' },
		controller: {
			loadPage: function (route, args) {

				//decodeURIComponent("edg%2Ffwegw%2Fe%26wegewg%2Fwe%2Fg");
				var x = args === null || args === undefined
					? [route]
					: [route].concat(args.split('/'));;

				app.navigate.apply(this, x);
			}
		}
	});

	app.on('page:load', app.navigate);

	app.on('initialize:after', function () {

		if (backbone.history) {
			backbone.history.start();

			if (Backbone.history.fragment === '') {
				app.navigate('tiles');
			}
		}
	});

	return app;
});<commit_msg>- рефакторинг обработки параметров URL + экранирование служебных символов URL;<commit_after>define(['marionette', 'backbone'], function (marionette, backbone) {

	var app = new marionette.Application();

	app.addRegions({
		regionContent: "#region-page-content"
	});

	app.setContentView = function(view) {
		app.regionContent.show(view);
	};

	app.addTile = function (def, options) {

		var optionsJson = JSON.stringify(options);

		$.post('/api/webui/tiles/add', { def: def, options: optionsJson })
			.done(function () {
				app.navigate('tiles');
			});
	};

	var api = {
		parseParameters: function(queryString) {

			var result = [];

			if (queryString !== null && queryString !== undefined) {

				var params = (queryString + '').split('/');

				for (var i = 0; i < params.length; i++) {

					var decodedValue = decodeURIComponent(params[i]);
					result.push(decodedValue);
				}
			}

			return result;
		},

		loadRoute: function(route, args) {

			require([route], function (obj) {

				obj.start.apply(obj, args);

				if (args && args.length) {

					var encoded = [];

					for (var i = 0; i < args.length; i++) {
						encoded.push(encodeURIComponent(args[i]));
					}

					route += '?' + encoded.join('/');
				}

				backbone.history.navigate(route);
			});
		}
	};

	app.navigate = function (route) {

		if (route) {

			var args = Array.prototype.slice.call(arguments, 1);
			api.loadRoute.call(this, route, args);
		}
	};

	app.router = new marionette.AppRouter({
		appRoutes: { '*path': 'loadPage' },
		controller: {
			loadPage: function (route, queryString) {

				var args = api.parseParameters(queryString);
				api.loadRoute.call(this, route, args);
			}
		}
	});

	app.on('page:load', app.navigate);

	app.on('initialize:after', function () {

		if (backbone.history) {
			backbone.history.start();

			if (Backbone.history.fragment === '') {
				app.navigate('tiles');
			}
		}
	});

	return app;
});<|endoftext|>


<commit_before>var raven = require('./client');
var crypto = require('crypto');
var fs = require('fs');
var url = require('url');
var transports = require('./transports');
var path = require('path');

var protocolMap = {
    'http': 80,
    'https': 443
};

module.exports.constructChecksum = function constructChecksum(kwargs) {
    var checksum = crypto.createHash('md5');
    checksum.update(kwargs['message'] || '');
    return checksum.digest('hex');
};

module.exports.getAuthHeader = function getAuthHeader(timestamp, api_key, project_id) {
    var header = ['Sentry sentry_version=2.0'];
    header.push('sentry_timestamp='+timestamp);
    header.push('sentry_client=raven-node/'+raven.version);
    header.push('sentry_key='+api_key);
    header.push('project_id='+project_id);
    return header.join(', ');
};

module.exports.parseDSN = function parseDSN(dsn) {
    if(!dsn) {
        // Let a falsey value return false explicitly
        return false;
    }
    try {
        var parsed = url.parse(dsn),
            response = {
              protocol: parsed.protocol.slice(0, -1),
              public_key: parsed.auth.split(':')[0],
              private_key: parsed.auth.split(':')[1],
              host: parsed.host.split(':')[0]
          };

        if(~response.protocol.indexOf('+'))
            response.protocol = response.protocol.split('+')[1];

        if(!transports.hasOwnProperty(response.protocol))
            throw new Error('Invalid transport');

        var path = parsed.path.substr(1),
            index = path.lastIndexOf('/');
        response.path = path.substr(0, index);
        response.project_id = ~~path.substr(index+1);
        response.port = ~~parsed.port || protocolMap[response.protocol] || 443;
        return response;
    } catch(e) {
        throw new Error('Invalid Sentry DSN: ' + dsn);
    }
};

var module_cache;
module.exports.getModules = function getModules() {
    if(module_cache) {
        return module_cache;
    }

    module_cache = {};
    require.main.paths.forEach(function(path_dir) {
        if (!(fs.existsSync || path.existsSync)(path_dir)) {
            return;
        }

        var modules = fs.readdirSync(path_dir).filter(function(name) {
            return name.charAt(0) !== '.';
        });

        modules.forEach(function(module) {
            var pkg_json = path.join(path_dir, module, 'package.json');

            try {
                var json = require(pkg_json);
                module_cache[json.name] = json.version;
            } catch(e) {}
        });
    });

    return module_cache;
};

var LINES_OF_CONTEXT = 7;

function getFunction(line) {
    return line.getFunctionName() ||
           line.getTypeName() + '.' + (line.getMethodName() || '<anonymous>');
}

function parseStack(stack, cb) {
    var frames = [],
        cache = {},
        callbacks;

    // check to make sure that the stack is what we need it to be.
    if (!stack || !Array.isArray(stack) || !stack.length || !stack[0].getFileName) {
        // lol, stack is fucked
        return cb(frames);
    }

    callbacks = stack.length;

    stack.forEach(function(line, index) {
        var frame = {
            filename: line.getFileName() || '',
            lineno: line.getLineNumber(),
            'function': getFunction(line)
        }, isInternal = line.isNative() ||
                        (frame.filename[0] !== '/' &&
                         frame.filename[0] !== '.');

        // in_app is all that's not an internal Node function or a module within node_modules
        frame.in_app = !isInternal && !~frame.filename.indexOf('node_modules/');

        // internal Node files are not full path names. Ignore them.
        if (isInternal) {
            frames[index] = frame;
            if (--callbacks === 0) cb(frames);
            return;
        }

        if (frame.filename in cache) {
            parseLines(cache[frame.filename]);
            if (--callbcaks === 0) cb(frames);
            return;
        }

        fs.readFile(frame.filename, function(err, file) {
            if (!err) {
                file = file.toString().split('\n');
                cache[frame.filename] = file;
                parseLines(file, frame);
            }
            frames[index] = frame;
            if (--callbacks === 0) cb(frames);
        });

        function parseLines(lines) {
            frame.pre_context = lines.slice(Math.max(0, frame.lineno-(LINES_OF_CONTEXT+1)), frame.lineno-1);
            frame.context_line = lines[frame.lineno-1];
            frame.post_context = lines.slice(frame.lineno, frame.lineno+LINES_OF_CONTEXT);
        }

        // console.log(line.getThis());
        // console.log(line.getTypeName());
        // console.log(line.getFunction().caller);
        // console.log(line.getFunction()+'');
        // console.log(line.getFunctionName());
        // console.log(line.getMethodName());
        // console.log(line.getFileName());
        // console.log(line.getLineNumber());
        // console.log(line.getColumnNumber());
        // console.log(line.getEvalOrigin());
        // console.log(line.isToplevel());
        // console.log(line.isNative());
        // console.log(line.isConstructor());
    });
}

module.exports.parseStack = parseStack;
<commit_msg>Mask an exception with 'use strict'<commit_after>var raven = require('./client');
var crypto = require('crypto');
var fs = require('fs');
var url = require('url');
var transports = require('./transports');
var path = require('path');

var protocolMap = {
    'http': 80,
    'https': 443
};

module.exports.constructChecksum = function constructChecksum(kwargs) {
    var checksum = crypto.createHash('md5');
    checksum.update(kwargs['message'] || '');
    return checksum.digest('hex');
};

module.exports.getAuthHeader = function getAuthHeader(timestamp, api_key, project_id) {
    var header = ['Sentry sentry_version=2.0'];
    header.push('sentry_timestamp='+timestamp);
    header.push('sentry_client=raven-node/'+raven.version);
    header.push('sentry_key='+api_key);
    header.push('project_id='+project_id);
    return header.join(', ');
};

module.exports.parseDSN = function parseDSN(dsn) {
    if(!dsn) {
        // Let a falsey value return false explicitly
        return false;
    }
    try {
        var parsed = url.parse(dsn),
            response = {
              protocol: parsed.protocol.slice(0, -1),
              public_key: parsed.auth.split(':')[0],
              private_key: parsed.auth.split(':')[1],
              host: parsed.host.split(':')[0]
          };

        if(~response.protocol.indexOf('+'))
            response.protocol = response.protocol.split('+')[1];

        if(!transports.hasOwnProperty(response.protocol))
            throw new Error('Invalid transport');

        var path = parsed.path.substr(1),
            index = path.lastIndexOf('/');
        response.path = path.substr(0, index);
        response.project_id = ~~path.substr(index+1);
        response.port = ~~parsed.port || protocolMap[response.protocol] || 443;
        return response;
    } catch(e) {
        throw new Error('Invalid Sentry DSN: ' + dsn);
    }
};

var module_cache;
module.exports.getModules = function getModules() {
    if(module_cache) {
        return module_cache;
    }

    module_cache = {};
    require.main.paths.forEach(function(path_dir) {
        if (!(fs.existsSync || path.existsSync)(path_dir)) {
            return;
        }

        var modules = fs.readdirSync(path_dir).filter(function(name) {
            return name.charAt(0) !== '.';
        });

        modules.forEach(function(module) {
            var pkg_json = path.join(path_dir, module, 'package.json');

            try {
                var json = require(pkg_json);
                module_cache[json.name] = json.version;
            } catch(e) {}
        });
    });

    return module_cache;
};

var LINES_OF_CONTEXT = 7;

function getFunction(line) {
    try {
        return line.getFunctionName() ||
               line.getTypeName() + '.' + (line.getMethodName() || '<anonymous>');
    } catch(e) {
        // This seems to happen sometimes when using 'use strict',
        // stemming from `getTypeName`.
        // [TypeError: Cannot read property 'constructor' of undefined]
        return '<anonymous>';
    }
}

function parseStack(stack, cb) {
    var frames = [],
        cache = {},
        callbacks;

    // check to make sure that the stack is what we need it to be.
    if (!stack || !Array.isArray(stack) || !stack.length || !stack[0].getFileName) {
        // lol, stack is fucked
        return cb(frames);
    }

    callbacks = stack.length;

    stack.forEach(function(line, index) {
        var frame = {
            filename: line.getFileName() || '',
            lineno: line.getLineNumber(),
            'function': getFunction(line)
        }, isInternal = line.isNative() ||
                        (frame.filename[0] !== '/' &&
                         frame.filename[0] !== '.');

        // in_app is all that's not an internal Node function or a module within node_modules
        frame.in_app = !isInternal && !~frame.filename.indexOf('node_modules/');

        // internal Node files are not full path names. Ignore them.
        if (isInternal) {
            frames[index] = frame;
            if (--callbacks === 0) cb(frames);
            return;
        }

        if (frame.filename in cache) {
            parseLines(cache[frame.filename]);
            if (--callbcaks === 0) cb(frames);
            return;
        }

        fs.readFile(frame.filename, function(err, file) {
            if (!err) {
                file = file.toString().split('\n');
                cache[frame.filename] = file;
                parseLines(file, frame);
            }
            frames[index] = frame;
            if (--callbacks === 0) cb(frames);
        });

        function parseLines(lines) {
            frame.pre_context = lines.slice(Math.max(0, frame.lineno-(LINES_OF_CONTEXT+1)), frame.lineno-1);
            frame.context_line = lines[frame.lineno-1];
            frame.post_context = lines.slice(frame.lineno, frame.lineno+LINES_OF_CONTEXT);
        }

        // console.log(line.getThis());
        // console.log(line.getTypeName());
        // console.log(line.getFunction().caller);
        // console.log(line.getFunction()+'');
        // console.log(line.getFunctionName());
        // console.log(line.getMethodName());
        // console.log(line.getFileName());
        // console.log(line.getLineNumber());
        // console.log(line.getColumnNumber());
        // console.log(line.getEvalOrigin());
        // console.log(line.isToplevel());
        // console.log(line.isNative());
        // console.log(line.isConstructor());
    });
}

module.exports.parseStack = parseStack;
<|endoftext|>


<commit_before>var CloudCmd, Util, DOM;

(function(CloudCmd, Util, DOM){
    'use strict';

    CloudCmd.Upload = UploadProto;

    function UploadProto() {
        var Images      = DOM.Images,
            Files       = DOM.Files,

            Upload      = this;

        function init() {
            Images.showLoad({
                top: true
            });

            Util.exec.series([
                CloudCmd.View,
                Upload.show
            ]);
        }

        this.show                       = function() {
            Images.showLoad({
                top: true
            });

            Files.get('upload', function(error, data) {
                CloudCmd.View.show(data, {
                    autoSize    : true,
                    afterShow   : afterShow
                });
            });

            DOM.load.style({
                id      : 'js-upload',
                inner   : '[data-name=js-upload-file-button] {'                                         +
                              'font-family: "Droid Sans Mono", "Ubuntu Mono", "Consolas", monospace;'   +
                                  'font-size: 20px;'                                                    +
                        '}'
            });

        };

        this.hide                       = function() {
            CloudCmd.View.hide();
        };

        function afterShow() {
            var button = DOM.getByDataName('js-upload-file-button');

            Images.hide();

            DOM.Events.add('change', button, function(event) {
                var files = event.target.files;

                Upload.hide();

                DOM.uploadFiles(files);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM);
<commit_msg>feature(upload) js-upload -> upload-css<commit_after>var CloudCmd, Util, DOM;

(function(CloudCmd, Util, DOM){
    'use strict';

    CloudCmd.Upload = UploadProto;

    function UploadProto() {
        var Images      = DOM.Images,
            Files       = DOM.Files,

            Upload      = this;

        function init() {
            Images.showLoad({
                top: true
            });

            Util.exec.series([
                CloudCmd.View,
                Upload.show
            ]);
        }

        this.show                       = function() {
            Images.showLoad({
                top: true
            });

            Files.get('upload', function(error, data) {
                CloudCmd.View.show(data, {
                    autoSize    : true,
                    afterShow   : afterShow
                });
            });

            DOM.load.style({
                id      : 'upload-css',
                inner   : '[data-name=js-upload-file-button] {'                                         +
                              'font-family: "Droid Sans Mono", "Ubuntu Mono", "Consolas", monospace;'   +
                                  'font-size: 20px;'                                                    +
                        '}'
            });

        };

        this.hide                       = function() {
            CloudCmd.View.hide();
        };

        function afterShow() {
            var button = DOM.getByDataName('js-upload-file-button');

            Images.hide();

            DOM.Events.add('change', button, function(event) {
                var files = event.target.files;

                Upload.hide();

                DOM.uploadFiles(files);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM);
<|endoftext|>


<commit_before>'use strict';

var fs      = require('fs-extra');
var Promise = require('../../lib/ext/promise');
var remove  = Promise.denodeify(fs.remove);
var root    = process.cwd();

module.exports.setup = function(path) {
  process.chdir(root);

  return remove(path)
    .then(function() {
      fs.mkdirsSync(path);
    });
};

module.exports.teardown = function(path) {
  process.chdir(root);

  if (fs.existsSync(path)) {
    return remove(path);
  } else {
    return Promise.resolve();
  }
};
<commit_msg>Update tmp.js<commit_after>'use strict';

var fs      = require('fs-extra');
var existsSync  = require('exists-sync');
var Promise = require('../../lib/ext/promise');
var remove  = Promise.denodeify(fs.remove);
var root    = process.cwd();

module.exports.setup = function(path) {
  process.chdir(root);

  return remove(path)
    .then(function() {
      fs.mkdirsSync(path);
    });
};

module.exports.teardown = function(path) {
  process.chdir(root);

  if (existsSync(path)) {
    return remove(path);
  } else {
    return Promise.resolve();
  }
};
<|endoftext|>


<commit_before>'use strict'
describe('property', function () {
  var Observable = require('../../../../../../lib/observable')
  var lastData
  beforeEach(function () {
    lastData = []
  })
  var A = new Observable({
    key: 'a',
    on: {
      property (data) {
        lastData.push(data)
      }
    },
    ChildConstructor: 'Constructor'
  }).Constructor
  var b
  var c

  it('passes added fields for new properties', function () {
    b = new A({
      key: 'b',
      field3: 'field3'
    })
    expect(lastData[0])
      .to.have.property('added')
      .which.deep.equals(['field3'])
  })

  it('passes added fields for new properties', function () {
    // double check this
    c = new b.Constructor({
      key: 'c',
      field: 'field',
      field2: 'field2'
    })
    expect(lastData).to.deep.equal([{
      added: [ 'field', 'field2' ]
    }])
  })

  it('passes removed fields on remove', function () {
    c.field2.remove()
    expect(lastData).to.deep.equal([{ removed: [ 'field2' ] }])
  })

  it('passes removed fields on remove using set object', function () {
    c.set({ field: null })
    expect(lastData).to.deep.equal([{ removed: [ 'field' ] }])
  })

  it('passes removed fields on constructor remove using set object', function () {
    b.set({ field3: null })
    expect(lastData).to.deep.equal([
      { removed: [ 'field3' ] },
      { removed: [ 'field3' ] }
    ])
  })

  it('resets context after emitting', function () {
    console.clear()
    var paths = []
    var datas = []
    var d = new Observable({
      key: 'd',
      field: {
        on: {
          data (data) {
            datas.push(data)
            paths.push(this.path.join('.'))
          }
        }
      }
    })

    var e = new d.Constructor({
      key: 'e'
    })

    var f = new e.Constructor({ //eslint-disable-line
      key: 'f'
    })

    e.set({ field: 'bla' })
    expect(paths).to.deep.equal([ 'e.field', 'f.field' ])
    expect(datas).to.deep.equal([ 'bla', 'bla' ])
  })
})
<commit_msg>exect context5 getter<commit_after>'use strict'
describe('property', function () {
  var Observable = require('../../../../../../lib/observable')
  var lastData
  beforeEach(function () {
    lastData = []
  })
  var A = new Observable({
    key: 'a',
    on: {
      property (data) {
        lastData.push(data)
      }
    },
    ChildConstructor: 'Constructor'
  }).Constructor
  var b
  var c

  it('passes added fields for new properties', function () {
    b = new A({
      key: 'b',
      field3: 'field3'
    })
    expect(lastData[0])
      .to.have.property('added')
      .which.deep.equals(['field3'])
  })

  it('passes added fields for new properties', function () {
    // double check this
    c = new b.Constructor({
      key: 'c',
      field: 'field',
      field2: 'field2'
    })
    expect(lastData).to.deep.equal([{
      added: [ 'field', 'field2' ]
    }])
  })

  it('passes removed fields on remove', function () {
    c.field2.remove()
    expect(lastData).to.deep.equal([{ removed: [ 'field2' ] }])
  })

  it('passes removed fields on remove using set object', function () {
    c.set({ field: null })
    expect(lastData).to.deep.equal([{ removed: [ 'field' ] }])
  })

  it('passes removed fields on constructor remove using set object', function () {
    b.set({ field3: null })
    expect(lastData).to.deep.equal([
      { removed: [ 'field3' ] },
      { removed: [ 'field3' ] }
    ])
  })

  it('resets context after emitting', function () {
    console.clear()
    var paths = []
    var datas = []
    var d = new Observable({
      key: 'd',
      field: {
        on: {
          data (data) {
            datas.push(data)
            paths.push(this.path.join('.'))
          }
        }
      }
    })
    var e = new d.Constructor({
      key: 'e'
    })
    var f = new e.Constructor({ //eslint-disable-line
      key: 'f'
    })
    expect(e).to.have.property('_field')
    e.set({ field: 'bla' })
    expect(paths).to.deep.equal([ 'e.field', 'f.field' ])
    expect(datas).to.deep.equal([ 'bla', 'bla' ])
  })
})
<|endoftext|>


<commit_before>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  hasOwnProperty,
  toString
} = Object.prototype;

function _isNullProtoObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isNullProtoObject(val)) ?
    'Object(proto:Null)' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (val instanceof Object) {
    if (val.constructor) {
      if (val.constructor.name) {
        if (val.constructor.name !== t) {
          let name = val.constructor.name;

          if (t === 'Object') {
            t = name;
          } else if (name !== 'Object') {
            if (t.indexOf(name) >= 0) {
              //t = t;
            } else if (name.indexOf(t) >= 0) {
              t = name;
            } else {
              if (!t.endsWith('Prototype')) {
                t = `${t}(ctor:${name})`;
              }
            }
          }
        }
      } else {
        if (!t.endsWith('Prototype')) {
          t = `${t}(ctor:Anonymous)`;
        }
      }
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

const _noop = () => {};
const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    v !== Promise.prototype && typeof v.catch === 'function' &&
      v.catch(_noop)),
  v
);

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      if (k === SymbolVpropEntries) {
        v = _vpropEntries(leaf);
      } else {
        v = _swallowPromiseRejection(leaf[k]);
      }
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

function memberInfo(val, k, seen) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  let iSeen = -1;
  let sSeen;
  let st;
  let v;
  let sv = '';

  try {
    if (!skip.includes(k)) {
      if (k === SymbolVpropEntries) {
        v = _vpropEntries(val);
      } else {
        v = _swallowPromiseRejection(val[k]);
      }
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  iSeen = seen.findIndex(kv => v === kv[1]);
  sSeen = (iSeen >= 0) ? `->${seen[iSeen][0]}` : '';
  st = typeStr(v, k);
  sv = valueStr(v);

  return {
    v,
    s: `${sk}{${sd}}${sSeen}: ${st}${(sv) ? `:${sv}` : ''}`,
    seen: iSeen >= 0
  };
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

//const MaxVpropEntries = 200;
const MaxVpropEntries = Infinity;
//const DescVpropEntries = `vprop_entries(max:${MaxVpropEntries})`;
const DescVpropEntries = `vprop_entries`;
const SymbolVpropEntries = Symbol(DescVpropEntries);

//const _isVpropEntriesType = val => val[Symbol.iterator] && (
//  !(typeof val === 'string' ||
//    Array.isArray(val) ||
//    (typeof NodeList !== 'undefined' && val instanceof NodeList) ||
//    (typeof HTMLCollection !== 'undefined' && val instanceof HTMLCollection) ||
//    (typeof NamedNodeMap !== 'undefined' && val instanceof NamedNodeMap)
//  ) && !hasOwnProperty.call(val, 'constructor')
//);
const _isVpropEntriesType = val =>
  val instanceof Set || val instanceof Map;

const _take = (iterator, max = Infinity) => {
  let result = [];

  for (let iter = iterator.next(), i = 0;
    !iter.done && i < max;
    iter = iterator.next(), i++
  ) {
    let entry = iter.value;

    result.push(
      (Array.isArray(entry) && entry.length === 2) ?
        {key: entry[0], value: entry[1]} :
        entry
    );
  }

  return result;
};

const _vpropEntries = val => _take(
  val[Symbol.iterator](),
  MaxVpropEntries
);

const members = val => (
  ( !(val === undefined || val === null) && _isVpropEntriesType(val) ) ?
    [SymbolVpropEntries] :
    []
).
  concat(_symbols(val), _names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

const _trackedReference = v =>
  (typeof v === 'object' && v !== null &&
    v !== _getterTagDummy) ||
  typeof v === 'function';
const _descendableObject = v =>
  typeof v === 'object' && v !== null &&
    v !== _getterTagDummy;
const _maybeConstructor = v =>
  // Assumes typeof v === 'function'
  hasOwnProperty.call(v, 'prototype') &&
    v.name && v.name.match(/^[A-Z]/);
const _descendableFunctionWhitelist = v =>
  // Assumes typeof v === 'function'
  v === Proxy ||
  (typeof _ === 'function' && v === _) ||
  (typeof $ === 'function' && v === $);
const _descendableFunction = v =>
  typeof v === 'function' &&
    (_maybeConstructor(v) || _descendableFunctionWhitelist(v));

const _shouldDescend = (k, v, level) =>
  (_descendableObject(v) || _descendableFunction(v));

function _inspectStr(val, k,
  indent = '  ', level = 1,
  seen = [['ROOT', val]], path = []
) {
  let mi = memberInfo(val, k, seen);
  let v = mi.v;
  let result = [`${indent.repeat(level)}${mi.s}`];

  if (!mi.seen && _trackedReference(v)) {
    path.push(String(k));
    seen.push([path.join('.'), v]);

    if (_shouldDescend(k, v, level)) {
      members(v).forEach(_k => result.push(
        _inspectStr(v, _k, indent, level + 1, seen, path)
      ));
    }

    path.pop();
  }

  return result.join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);
  let result = [`${st}${(sv) ? `:${sv}` : ''}`];
  let seen = [['ROOT', val]];

  members(val).forEach(k => result.push(
    _inspectStr(val, k, indent, 1, seen)
  ));

  return result.join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    member(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        memberStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'member'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<commit_msg>Add function to _descendableFunctionWhitelist<commit_after>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  hasOwnProperty,
  toString
} = Object.prototype;

function _isNullProtoObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isNullProtoObject(val)) ?
    'Object(proto:Null)' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (val instanceof Object) {
    if (val.constructor) {
      if (val.constructor.name) {
        if (val.constructor.name !== t) {
          let name = val.constructor.name;

          if (t === 'Object') {
            t = name;
          } else if (name !== 'Object') {
            if (t.indexOf(name) >= 0) {
              //t = t;
            } else if (name.indexOf(t) >= 0) {
              t = name;
            } else {
              if (!t.endsWith('Prototype')) {
                t = `${t}(ctor:${name})`;
              }
            }
          }
        }
      } else {
        if (!t.endsWith('Prototype')) {
          t = `${t}(ctor:Anonymous)`;
        }
      }
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

const _noop = () => {};
const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    v !== Promise.prototype && typeof v.catch === 'function' &&
      v.catch(_noop)),
  v
);

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      if (k === SymbolVpropEntries) {
        v = _vpropEntries(leaf);
      } else {
        v = _swallowPromiseRejection(leaf[k]);
      }
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

function memberInfo(val, k, seen) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  let iSeen = -1;
  let sSeen;
  let st;
  let v;
  let sv = '';

  try {
    if (!skip.includes(k)) {
      if (k === SymbolVpropEntries) {
        v = _vpropEntries(val);
      } else {
        v = _swallowPromiseRejection(val[k]);
      }
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  iSeen = seen.findIndex(kv => v === kv[1]);
  sSeen = (iSeen >= 0) ? `->${seen[iSeen][0]}` : '';
  st = typeStr(v, k);
  sv = valueStr(v);

  return {
    v,
    s: `${sk}{${sd}}${sSeen}: ${st}${(sv) ? `:${sv}` : ''}`,
    seen: iSeen >= 0
  };
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

//const MaxVpropEntries = 200;
const MaxVpropEntries = Infinity;
//const DescVpropEntries = `vprop_entries(max:${MaxVpropEntries})`;
const DescVpropEntries = `vprop_entries`;
const SymbolVpropEntries = Symbol(DescVpropEntries);

//const _isVpropEntriesType = val => val[Symbol.iterator] && (
//  !(typeof val === 'string' ||
//    Array.isArray(val) ||
//    (typeof NodeList !== 'undefined' && val instanceof NodeList) ||
//    (typeof HTMLCollection !== 'undefined' && val instanceof HTMLCollection) ||
//    (typeof NamedNodeMap !== 'undefined' && val instanceof NamedNodeMap)
//  ) && !hasOwnProperty.call(val, 'constructor')
//);
const _isVpropEntriesType = val =>
  val instanceof Set || val instanceof Map;

const _take = (iterator, max = Infinity) => {
  let result = [];

  for (let iter = iterator.next(), i = 0;
    !iter.done && i < max;
    iter = iterator.next(), i++
  ) {
    let entry = iter.value;

    result.push(
      (Array.isArray(entry) && entry.length === 2) ?
        {key: entry[0], value: entry[1]} :
        entry
    );
  }

  return result;
};

const _vpropEntries = val => _take(
  val[Symbol.iterator](),
  MaxVpropEntries
);

const members = val => (
  ( !(val === undefined || val === null) && _isVpropEntriesType(val) ) ?
    [SymbolVpropEntries] :
    []
).
  concat(_symbols(val), _names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

const _trackedReference = v =>
  (typeof v === 'object' && v !== null &&
    v !== _getterTagDummy) ||
  typeof v === 'function';
const _descendableObject = v =>
  typeof v === 'object' && v !== null &&
    v !== _getterTagDummy;
const _maybeConstructor = v =>
  // Assumes typeof v === 'function'
  hasOwnProperty.call(v, 'prototype') &&
    v.name && v.name.match(/^[A-Z]/);
const _descendableFunctionWhitelist = v =>
  // Assumes typeof v === 'function'
  v === Proxy ||
  (typeof _ === 'function' && v === _) ||
  (typeof $ === 'function' && v === $) ||
  (typeof p === 'function' && v === p);
const _descendableFunction = v =>
  typeof v === 'function' &&
    (_maybeConstructor(v) || _descendableFunctionWhitelist(v));

const _shouldDescend = (k, v, level) =>
  (_descendableObject(v) || _descendableFunction(v));

function _inspectStr(val, k,
  indent = '  ', level = 1,
  seen = [['ROOT', val]], path = []
) {
  let mi = memberInfo(val, k, seen);
  let v = mi.v;
  let result = [`${indent.repeat(level)}${mi.s}`];

  if (!mi.seen && _trackedReference(v)) {
    path.push(String(k));
    seen.push([path.join('.'), v]);

    if (_shouldDescend(k, v, level)) {
      members(v).forEach(_k => result.push(
        _inspectStr(v, _k, indent, level + 1, seen, path)
      ));
    }

    path.pop();
  }

  return result.join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);
  let result = [`${st}${(sv) ? `:${sv}` : ''}`];
  let seen = [['ROOT', val]];

  members(val).forEach(k => result.push(
    _inspectStr(val, k, indent, 1, seen)
  ));

  return result.join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    member(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        memberStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'member'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<|endoftext|>


<commit_before>// api.js
// User-Facing API for public data

var accounts = require('../database/accounts');
var shows = require('../database/shows');

var express = require('express');
var router = express.Router();

function checkPublic(show) {
	return show.public;
};

router.get('/show/:id', function(req, res) {
	shows.getShowById(req.params.id, function(err, o) {
		if (o && o.public) {
			res.json(o);
		}
		else {
			res.status(400).send(err);
		}
	});
});

router.get('/schedule', function(req, res) {
	shows.getAllShows(function(err, o) {
		if (o) {
			res.json({shows: o.filter(checkPublic)});
		}
		else {
			res.status(400).send(err);
		}
	});
});

router.get('/nowplaying', function(req, res) {
	var info = getTimeAndDay();

	shows.getShowByTimeslotAndDay(info.time, info.day, function(err, blurb) {
		if (blurb && blurb.public) {
			res.setHeader('Content-Type', 'application/json');
			res.send(JSON.stringify(blurb));
		}
		else {
			res.send(JSON.stringify({status: "no show playing"}));
		}
	});
});

// router.get('/dj/:id', function(req, res) {
// 	shows.getShowById(req.params.id, function(err, o) {
// 		if (o) {
// 			res.json(o);
// 		}
// 		else {
// 			res.status(400).send(err);
// 		}
// 	});
// });

router.get('/djs', function(req, res) {
	accounts.getAllUsers(function(err, o) {
		if (o) {
			res.json({djs: o});
		}
		else {
			res.status(400).send(err);
		}
	});
});

/* Helper Functions */

function getTimeAndDay() {
	var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
	var date = new Date();

	var day = days[date.getDay()];
	var time = date.getHours();

	//Change the time into the format our db is expecting
	//AKA 12pm, 10am, 1pm: hour followed by am or pm
	if (time === 0) {
		time = '12am';
	} else if (time < 12) {
		time += 'am';
	} else if (time == 12) {
		time = '12pm';
	} else {
		time -= 12;
		time += 'pm';
	}

	return {
		day: day,
		time: time
	};
}

module.exports = router;
<commit_msg>add route for giveaway description<commit_after>// api.js
// User-Facing API for public data

var accounts = require('../database/accounts');
var shows = require('../database/shows');

var express = require('express');
var router = express.Router();

function checkPublic(show) {
	return show.public;
};

router.get('/show/:id', function(req, res) {
	shows.getShowById(req.params.id, function(err, o) {
		if (o && o.public) {
			res.json(o);
		}
		else {
			res.status(400).send(err);
		}
	});
});

router.get('/schedule', function(req, res) {
	shows.getAllShows(function(err, o) {
		if (o) {
			res.json({shows: o.filter(checkPublic)});
		}
		else {
			res.status(400).send(err);
		}
	});
});

router.get('/nowplaying', function(req, res) {
	var info = getTimeAndDay();

	shows.getShowByTimeslotAndDay(info.time, info.day, function(err, blurb) {
		if (blurb && blurb.public) {
			res.setHeader('Content-Type', 'application/json');
			res.send(JSON.stringify(blurb));
		}
		else {
			res.send(JSON.stringify({status: "no show playing"}));
		}
	});
});

// router.get('/dj/:id', function(req, res) {
// 	shows.getShowById(req.params.id, function(err, o) {
// 		if (o) {
// 			res.json(o);
// 		}
// 		else {
// 			res.status(400).send(err);
// 		}
// 	});
// });

router.get('/djs', function(req, res) {
	accounts.getAllUsers(function(err, o) {
		if (o) {
			res.json({djs: o});
		}
		else {
			res.status(400).send(err);
		}
	});
});

router.get('/giveawayDescription', function(req, res) {
	res.json({info: "We give a lot of tickets away to our listeners.. Tune in and follow us on Facebook and Instagram for your chance to see these shows!"});
})

/* Helper Functions */

function getTimeAndDay() {
	var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
	var date = new Date();

	var day = days[date.getDay()];
	var time = date.getHours();

	//Change the time into the format our db is expecting
	//AKA 12pm, 10am, 1pm: hour followed by am or pm
	if (time === 0) {
		time = '12am';
	} else if (time < 12) {
		time += 'am';
	} else if (time == 12) {
		time = '12pm';
	} else {
		time -= 12;
		time += 'pm';
	}

	return {
		day: day,
		time: time
	};
}

module.exports = router;
<|endoftext|>