<commit_before>/*
 * Copyright (c) 2015 Limerun Project Contributors
 * Portions Copyright (c) 2015 Internet of Protocols Assocation (IOPA)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Module dependencies.
 */
var util = require('util');
var Stream = require('stream');
var EventEmitter = require('events').EventEmitter;
var Writable = Stream.Writable;
var Readable = Stream.Readable;

var constants = require('../util/constants.js');
var Shallow = require('../util/shallow.js');

var iopaConnect = require('./iopaConnect.js');

var guidFactory = require('../util/guid.js');
var iopaContextFactory = require('./iopaContextFactory.js');

/**
 * Run Once Self Initiating Function
 *
 * @method init
 * @returns (void)
 * @private
 */
(function  init() {
 var _context = iopaContextFactory.createContext();   // use for adding properties
 _helpers_refreshPrototype(_context, "iopa.", IopaIopa.prototype);
 _helpers_refreshPrototype(_context, "server.", IopaServer.prototype);

 var context_prototype = Object.getPrototypeOf(_context);

 _helpers_cloneBodyPrototypeAlias(context_prototype, EventEmitter.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Stream.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Readable.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Writable.prototype, "iopa.Body");

 context_prototype.writeHead = function(){this["iopa.WriteHead"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.getHeader = function(){this["iopa.GetHeader"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.removeHeader = function(){this["iopa.RemoveHeader"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.setHeader = function(){this["iopa.SetHeader"].apply(this, Array.prototype.slice.call(arguments));};

 iopaContextFactory.free(_context);
 _context = null;
 }).call(this);

// PUBLIC EXPORTS
/**
 * Expands IOPA context object with various helper methods;  called for every request context passing through IOPA
 *
 * @method private_refreshPrototype
 * @this appBuilder (object)  a representative IOPA context with all desired properties
 * @param context (dictionary)  the IOPA properties dictionary
 * @param addReqRes (function)  function to add req res methods
 * @returns (void)
 * @private
 */
exports.expandContext = function expandContext(context, addReqRes) {
    var isIopaNative = true;

    if (context.reqres)
        isIopaNative = false;

    context.iopa = new IopaIopa(context);
    context.server = new IopaServer(context);
    context["iopa.Id"] = guidFactory.guid();
    context["server.Capabilities"] = Shallow.copy(this.properties["server.Capabilities"], context["server.Capabilities"]);
    context["server.Logger"] = this.properties["server.Logger"];
    context.log = context["server.Logger"];

   if (!context["server.AppId"])
    {
        context.log.log("IOPA app running " + this.properties["server.AppId"]);

        var context_prototype = Object.getPrototypeOf(context);

        // add default aliases to IopaContext if needed;  not currently in default IOPA spec
        // _helpers_refreshPrototypeIopaContext(context);

        Object.defineProperty(context_prototype, "server.AppId", {value : this.properties["server.AppId"],
                              writable : false, enumerable : true, configurable : false});

        context_prototype.toString = function()
        {
            return util.inspect(this).replace(/\n/g,"\r");
        }

        if (isIopaNative)
            initIopaNativeContextPrototype(context_prototype);
    }

   if (isIopaNative)
        iopaConnect.addReqRes(context);
};

/**
 * Representss an IOPA iopa Object
 *
 * @class IopaIopa
 * @constructor
 */
function IopaIopa(iopa){ this.context = iopa;  };

/**
 * Represents an IOPA server Object
 *
 * @class IopaServer
 * @constructor
 */
function IopaServer(iopa){ this.context = iopa;  };

/**
 * Run Once Self Initiating Function to create prototype methods on IopaIopa, IopaResponse, IopaServer etc.
 *
 * @method init
 * @returns (void)
 * @private
 */
(function initPrototypes(){
 Object.defineProperty(IopaIopa.prototype, "host", {   get: function () {
                       return this.context["iopa.GetHeader"]("host");
                       }});

 Object.defineProperty(IopaIopa.prototype, "originalUrl", {   get: function () {
                       var ctx = this.context;
                       var uri =
                       ctx["iopa.Scheme"] +
                       "://" +
                       ctx.host +
                       ctx["iopa.PathBase"] +
                       ctx["iopa.Path"];

                       if (ctx["iopa.QueryString"] != "")
                       uri += "?" + ctx["iopa.QueryString"];

                       return uri;
                       }});

 IopaIopa.prototype.writeHead= function(){this.context["iopa.WriteHead"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.getHeader= function(){this.context["iopa.GetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.removeHeader = function(){this.context["iopa.RemoveHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.setHeader = function(){this.context["iopa.SetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.getHeader = function(){this.context["iopa.GetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};

 }).call(this);

function initIopaNativeContextPrototype(contextPrototype){

    contextPrototype["iopa.WriteHead"] = function iopa_WriteHead(statusCode, headers)
    {
        this["iopa.StatusCode"] = statusCode;

        var keys = Object.keys(headers);
        for (var i = 0; i < keys.length; i++) {
            var k = keys[i];
            if (k)
            {
                this["Iopa.setResponseHeader"].call(this, k, headers[k]);
            }
        }
    };

    contextPrototype["iopa.SetHeader"] = function iopa_SetHeader(key, val)
    {
        private_setIgnoreCase(this["iopa.Headers"], key, val);
    }

    contextPrototype["iopa.GetHeader"] = function iopa_GetHeader(key)
    {
        return private_getIgnoreCase(this["iopa.Headers"], key);
    }

    contextPrototype["iopa.RemoveHeader"] = function iopa_RemoveHeader(key, value)
    {
          return private_deleteIgnoreCase(this["iopa.Headers"], key);
    }

}

/**
 * Adds or updates a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @param val (string) the new property value
 * @private
 */
function private_setIgnoreCase(obj, key, val)
{
     key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            obj[p] = val;
            return;
        }
    }
    obj[key] = val;

}

/**
 * Returns a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @param val (string) the new property value
 * @private
 */
function private_getIgnoreCase(obj, key)
{
    key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            return obj[p];
        }
    }
    return null;
}

/**
 * Returns a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @return (bool) true if successful, false if not
 * @private
 */
function private_deleteIgnoreCase(obj, key)
{
    key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            delete obj[p];
            return true;
        }
    }
    return false;
}

exports.shrinkContext = function(context) {
    if (context.iopa){
        delete context.iopa.context ;
        delete context.server.context ;
        delete context.req.context;
        delete context.res.context;

        delete context.iopa ;
        delete context.server ;
        delete context.req;
        delete context.res;
    }
}

// PRIVATE HELPERS

/**
 * Adds alias property accessors to IOPA context object for given IOPA category
 *     (e.g., request.pathBase for fn({"iopa.RequestPathBase": ""}, "iopa.Request", context.request.prototype))
 *
 * @method _helpers_refreshPrototype
 * @param propertyList (object)  a representative IOPA context with all desired properties set (to null, default or value)
 * @param iopaPrefix (string)  the IOPA  prefix to search for (e.g., "iopa.Request")
 * @param iopaObjectPrototype (object)  the javascript object on which to add the prototypes (e.g., context.request)
 * @returns (void)
 * @private
 */
function _helpers_refreshPrototype(propertyList, iopaPrefix, iopaObjectPrototype)
{
    Object.keys(propertyList).forEach(function (_property)
                                      {
                                     var suffix = private_getSuffix(iopaPrefix, _property);

                                      if (suffix)
                                      {
                                      if (suffix.length >1)
                                      suffix = suffix.substring(0,1).toLowerCase() + suffix.substring(1)
                                      else
                                      suffix = suffix.toLowerCase();

                                      Object.defineProperty(iopaObjectPrototype, suffix, {

                                                            get: function () {
                                                            return this[_property];
                                                            },

                                                            set: function (val) {
                                                            this[_property] = val;
                                                            }

                                                            })
                                      }
                                      });
}

/**
 * Add alias properties to IOPA Context object  (e.g., context.Server from "Server.*")
 * NOT CURRENTLY USED
 *
 * @method _helpers_refreshPrototypeIopaContext
 * @param context (object) the IOPA Context object on which to add the alias properties
 * @returns (void)
 * @private
 */
function _helpers_refreshPrototypeIopaContext (context)
{
    var proto = Object.getPrototypeOf(context);

    Object.keys(context).forEach(function (_property)
                                    {

                                    var n = _property.indexOf(".");
                                    if (n>-1)
                                    {

                                    var short = _property.substring(0,n) + _property.substring(n+1);

                                    Object.defineProperty(proto, short, {
                                                          get: function () {
                                                          return this[_property];
                                                          },

                                                          set: function (val) {
                                                          this[_property] = val;
                                                          }

                                                          });
                                    }

                                    });

}

/**
 * Create alias access methods on context.response for context body elemeent for given stream/readable/writable prototype
 *
 * Note: the alias will be a collection of both functions (which simply shell out to target function) and valuetypes (which
 * have a getter and setter defined which each shell out to the target property)
 *
 * @method _helpers_cloneBodyPrototypeAlias
 *
 * @param targetObjectPrototype (__proto__)  the prototype object for the context.response object on which the alias properties are set
 * @param sourceObjectprototype (__proto__)  the prototpye object for the generic stream/writable on which to enumerate all properties
 * @param iopaContextKey (string) e.g., "iopa.Body"
 * @returns (void)
 * @private
 */
function _helpers_cloneBodyPrototypeAlias(targetObjectPrototype, sourceObjectprototype, iopaContextKey)
{
    Object.getOwnPropertyNames(sourceObjectprototype).forEach(function (_property)
                                                              {
                                                              if (typeof( sourceObjectprototype[_property]) === 'function')
                                                              {
                                                              targetObjectPrototype[_property] = function(){
                                                              var body = this[iopaContextKey];
                                                              return body[_property].apply(body, Array.prototype.slice.call(arguments));
                                                              };
                                                              }
                                                              else
                                                              {
                                                              Object.defineProperty(targetObjectPrototype, _property, {

                                                                                get: function () {
                                                                                return this[iopaContextKey][_property];
                                                                                },

                                                                                set: function (val) {
                                                                                this[iopaContextKey][_property] = val;
                                                                                }

                                                                                });
                                                              }
                                                              });

}

/**
 * Extract name from IOPA Property
 *
 * @method private_getSuffix
 * @param prefix (string)  the prefix to search for (e.g., "iopa.")
 * @param data (string)  the Owin Property (e.g., "iopa.Body")
 * @returns (string)  the suffix if found (e.g., "iopa.Body"), null if no match
 * @private
 */

function private_getSuffix(prefix, data) {
    if (data.lastIndexOf(prefix, 0) === 0)
        return data.substring(prefix.length);
    else
        return null;
}
<commit_msg>remove console log<commit_after>/*
 * Copyright (c) 2015 Limerun Project Contributors
 * Portions Copyright (c) 2015 Internet of Protocols Assocation (IOPA)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Module dependencies.
 */
var util = require('util');
var Stream = require('stream');
var EventEmitter = require('events').EventEmitter;
var Writable = Stream.Writable;
var Readable = Stream.Readable;

var constants = require('../util/constants.js');
var Shallow = require('../util/shallow.js');

var iopaConnect = require('./iopaConnect.js');

var guidFactory = require('../util/guid.js');
var iopaContextFactory = require('./iopaContextFactory.js');

/**
 * Run Once Self Initiating Function
 *
 * @method init
 * @returns (void)
 * @private
 */
(function  init() {
 var _context = iopaContextFactory.createContext();   // use for adding properties
 _helpers_refreshPrototype(_context, "iopa.", IopaIopa.prototype);
 _helpers_refreshPrototype(_context, "server.", IopaServer.prototype);

 var context_prototype = Object.getPrototypeOf(_context);

 _helpers_cloneBodyPrototypeAlias(context_prototype, EventEmitter.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Stream.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Readable.prototype, "iopa.Body");
 _helpers_cloneBodyPrototypeAlias(context_prototype, Writable.prototype, "iopa.Body");

 context_prototype.writeHead = function(){this["iopa.WriteHead"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.getHeader = function(){this["iopa.GetHeader"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.removeHeader = function(){this["iopa.RemoveHeader"].apply(this, Array.prototype.slice.call(arguments));};
 context_prototype.setHeader = function(){this["iopa.SetHeader"].apply(this, Array.prototype.slice.call(arguments));};

 iopaContextFactory.free(_context);
 _context = null;
 }).call(this);

// PUBLIC EXPORTS
/**
 * Expands IOPA context object with various helper methods;  called for every request context passing through IOPA
 *
 * @method private_refreshPrototype
 * @this appBuilder (object)  a representative IOPA context with all desired properties
 * @param context (dictionary)  the IOPA properties dictionary
 * @param addReqRes (function)  function to add req res methods
 * @returns (void)
 * @private
 */
exports.expandContext = function expandContext(context, addReqRes) {
    var isIopaNative = true;

    if (context.reqres)
        isIopaNative = false;

    context.iopa = new IopaIopa(context);
    context.server = new IopaServer(context);
    context["iopa.Id"] = guidFactory.guid();
    context["server.Capabilities"] = Shallow.copy(this.properties["server.Capabilities"], context["server.Capabilities"]);
    context["server.Logger"] = this.properties["server.Logger"];
    context.log = context["server.Logger"];

   if (!context["server.AppId"])
    {

        var context_prototype = Object.getPrototypeOf(context);

        // add default aliases to IopaContext if needed;  not currently in default IOPA spec
        // _helpers_refreshPrototypeIopaContext(context);

        Object.defineProperty(context_prototype, "server.AppId", {value : this.properties["server.AppId"],
                              writable : false, enumerable : true, configurable : false});

        context_prototype.toString = function()
        {
            return util.inspect(this).replace(/\n/g,"\r");
        }

        if (isIopaNative)
            initIopaNativeContextPrototype(context_prototype);
    }

   if (isIopaNative)
        iopaConnect.addReqRes(context);
};

/**
 * Representss an IOPA iopa Object
 *
 * @class IopaIopa
 * @constructor
 */
function IopaIopa(iopa){ this.context = iopa;  };

/**
 * Represents an IOPA server Object
 *
 * @class IopaServer
 * @constructor
 */
function IopaServer(iopa){ this.context = iopa;  };

/**
 * Run Once Self Initiating Function to create prototype methods on IopaIopa, IopaResponse, IopaServer etc.
 *
 * @method init
 * @returns (void)
 * @private
 */
(function initPrototypes(){
 Object.defineProperty(IopaIopa.prototype, "host", {   get: function () {
                       return this.context["iopa.GetHeader"]("host");
                       }});

 Object.defineProperty(IopaIopa.prototype, "originalUrl", {   get: function () {
                       var ctx = this.context;
                       var uri =
                       ctx["iopa.Scheme"] +
                       "://" +
                       ctx.host +
                       ctx["iopa.PathBase"] +
                       ctx["iopa.Path"];

                       if (ctx["iopa.QueryString"] != "")
                       uri += "?" + ctx["iopa.QueryString"];

                       return uri;
                       }});

 IopaIopa.prototype.writeHead= function(){this.context["iopa.WriteHead"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.getHeader= function(){this.context["iopa.GetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.removeHeader = function(){this.context["iopa.RemoveHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.setHeader = function(){this.context["iopa.SetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};
 IopaIopa.prototype.getHeader = function(){this.context["iopa.GetHeader"].apply(this.context, Array.prototype.slice.call(arguments));};

 }).call(this);

function initIopaNativeContextPrototype(contextPrototype){

    contextPrototype["iopa.WriteHead"] = function iopa_WriteHead(statusCode, headers)
    {
        this["iopa.StatusCode"] = statusCode;

        var keys = Object.keys(headers);
        for (var i = 0; i < keys.length; i++) {
            var k = keys[i];
            if (k)
            {
                this["Iopa.setResponseHeader"].call(this, k, headers[k]);
            }
        }
    };

    contextPrototype["iopa.SetHeader"] = function iopa_SetHeader(key, val)
    {
        private_setIgnoreCase(this["iopa.Headers"], key, val);
    }

    contextPrototype["iopa.GetHeader"] = function iopa_GetHeader(key)
    {
        return private_getIgnoreCase(this["iopa.Headers"], key);
    }

    contextPrototype["iopa.RemoveHeader"] = function iopa_RemoveHeader(key, value)
    {
          return private_deleteIgnoreCase(this["iopa.Headers"], key);
    }

}

/**
 * Adds or updates a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @param val (string) the new property value
 * @private
 */
function private_setIgnoreCase(obj, key, val)
{
     key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            obj[p] = val;
            return;
        }
    }
    obj[key] = val;

}

/**
 * Returns a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @param val (string) the new property value
 * @private
 */
function private_getIgnoreCase(obj, key)
{
    key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            return obj[p];
        }
    }
    return null;
}

/**
 * Returns a javascript object, case insensitive for key property
 *
 * @method private_setIgnoreCase
 * @param obj (object)  the object to search
 * @param key (string) the new or existing property name
 * @return (bool) true if successful, false if not
 * @private
 */
function private_deleteIgnoreCase(obj, key)
{
    key = key.toLowerCase();
    for(var p in obj){
        if(obj.hasOwnProperty(p) && key == p.toLowerCase()){
            delete obj[p];
            return true;
        }
    }
    return false;
}

exports.shrinkContext = function(context) {
    if (context.iopa){
        delete context.iopa.context ;
        delete context.server.context ;
        delete context.req.context;
        delete context.res.context;

        delete context.iopa ;
        delete context.server ;
        delete context.req;
        delete context.res;
    }
}

// PRIVATE HELPERS

/**
 * Adds alias property accessors to IOPA context object for given IOPA category
 *     (e.g., request.pathBase for fn({"iopa.RequestPathBase": ""}, "iopa.Request", context.request.prototype))
 *
 * @method _helpers_refreshPrototype
 * @param propertyList (object)  a representative IOPA context with all desired properties set (to null, default or value)
 * @param iopaPrefix (string)  the IOPA  prefix to search for (e.g., "iopa.Request")
 * @param iopaObjectPrototype (object)  the javascript object on which to add the prototypes (e.g., context.request)
 * @returns (void)
 * @private
 */
function _helpers_refreshPrototype(propertyList, iopaPrefix, iopaObjectPrototype)
{
    Object.keys(propertyList).forEach(function (_property)
                                      {
                                     var suffix = private_getSuffix(iopaPrefix, _property);

                                      if (suffix)
                                      {
                                      if (suffix.length >1)
                                      suffix = suffix.substring(0,1).toLowerCase() + suffix.substring(1)
                                      else
                                      suffix = suffix.toLowerCase();

                                      Object.defineProperty(iopaObjectPrototype, suffix, {

                                                            get: function () {
                                                            return this[_property];
                                                            },

                                                            set: function (val) {
                                                            this[_property] = val;
                                                            }

                                                            })
                                      }
                                      });
}

/**
 * Add alias properties to IOPA Context object  (e.g., context.Server from "Server.*")
 * NOT CURRENTLY USED
 *
 * @method _helpers_refreshPrototypeIopaContext
 * @param context (object) the IOPA Context object on which to add the alias properties
 * @returns (void)
 * @private
 */
function _helpers_refreshPrototypeIopaContext (context)
{
    var proto = Object.getPrototypeOf(context);

    Object.keys(context).forEach(function (_property)
                                    {

                                    var n = _property.indexOf(".");
                                    if (n>-1)
                                    {

                                    var short = _property.substring(0,n) + _property.substring(n+1);

                                    Object.defineProperty(proto, short, {
                                                          get: function () {
                                                          return this[_property];
                                                          },

                                                          set: function (val) {
                                                          this[_property] = val;
                                                          }

                                                          });
                                    }

                                    });

}

/**
 * Create alias access methods on context.response for context body elemeent for given stream/readable/writable prototype
 *
 * Note: the alias will be a collection of both functions (which simply shell out to target function) and valuetypes (which
 * have a getter and setter defined which each shell out to the target property)
 *
 * @method _helpers_cloneBodyPrototypeAlias
 *
 * @param targetObjectPrototype (__proto__)  the prototype object for the context.response object on which the alias properties are set
 * @param sourceObjectprototype (__proto__)  the prototpye object for the generic stream/writable on which to enumerate all properties
 * @param iopaContextKey (string) e.g., "iopa.Body"
 * @returns (void)
 * @private
 */
function _helpers_cloneBodyPrototypeAlias(targetObjectPrototype, sourceObjectprototype, iopaContextKey)
{
    Object.getOwnPropertyNames(sourceObjectprototype).forEach(function (_property)
                                                              {
                                                              if (typeof( sourceObjectprototype[_property]) === 'function')
                                                              {
                                                              targetObjectPrototype[_property] = function(){
                                                              var body = this[iopaContextKey];
                                                              return body[_property].apply(body, Array.prototype.slice.call(arguments));
                                                              };
                                                              }
                                                              else
                                                              {
                                                              Object.defineProperty(targetObjectPrototype, _property, {

                                                                                get: function () {
                                                                                return this[iopaContextKey][_property];
                                                                                },

                                                                                set: function (val) {
                                                                                this[iopaContextKey][_property] = val;
                                                                                }

                                                                                });
                                                              }
                                                              });

}

/**
 * Extract name from IOPA Property
 *
 * @method private_getSuffix
 * @param prefix (string)  the prefix to search for (e.g., "iopa.")
 * @param data (string)  the Owin Property (e.g., "iopa.Body")
 * @returns (string)  the suffix if found (e.g., "iopa.Body"), null if no match
 * @private
 */

function private_getSuffix(prefix, data) {
    if (data.lastIndexOf(prefix, 0) === 0)
        return data.substring(prefix.length);
    else
        return null;
}
<|endoftext|>


<commit_before>/*!
{
  "name": "Input attributes",
  "property": "input",
  "tags": ["forms"],
  "authors": ["Mike Taylor"],
  "notes": [{
    "name": "WHATWG spec",
    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary"
  }]
}
!*/
/* DOC
Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results:

```javascript
Modernizr.input.autocomplete
Modernizr.input.autofocus
Modernizr.input.list
Modernizr.input.max
Modernizr.input.min
Modernizr.input.multiple
Modernizr.input.pattern
Modernizr.input.placeholder
Modernizr.input.required
Modernizr.input.step
```
*/
define(['Modernizr', 'createElement', 'attrs', 'inputattrs', 'inputElem'], function( Modernizr, createElement, attrs, inputattrs, inputElem ) {
  // Run through HTML5's new input attributes to see if the UA understands any.
  // Mike Taylr has created a comprehensive resource for testing these attributes
  //   when applied to all input types:
  //   miketaylr.com/code/input-type-attr.html

  // Only input placeholder is tested while textarea's placeholder is not.
  // Currently Safari 4 and Opera 11 have support only for the input placeholder
  // Both tests are available in feature-detects/forms-placeholder.js
  Modernizr['input'] = (function( props ) {
    for ( var i = 0, len = props.length; i < len; i++ ) {
      attrs[ props[i] ] = !!(props[i] in inputElem);
    }
    if (attrs.list){
      // safari false positive's on datalist: webk.it/74252
      // see also github.com/Modernizr/Modernizr/issues/146
      attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
    }
    return attrs;
  })(inputattrs);
});
<commit_msg>add knownBug for blackberry and input.multiple<commit_after>/*!
{
  "name": "Input attributes",
  "property": "input",
  "tags": ["forms"],
  "authors": ["Mike Taylor"],
  "notes": [{
    "name": "WHATWG spec",
    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary"
  }],
  "knownBugs": ["Some blackberry devices report false positive for input.multiple"]
}
!*/
/* DOC
Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results:

```javascript
Modernizr.input.autocomplete
Modernizr.input.autofocus
Modernizr.input.list
Modernizr.input.max
Modernizr.input.min
Modernizr.input.multiple
Modernizr.input.pattern
Modernizr.input.placeholder
Modernizr.input.required
Modernizr.input.step
```
*/
define(['Modernizr', 'createElement', 'attrs', 'inputattrs', 'inputElem'], function( Modernizr, createElement, attrs, inputattrs, inputElem ) {
  // Run through HTML5's new input attributes to see if the UA understands any.
  // Mike Taylr has created a comprehensive resource for testing these attributes
  //   when applied to all input types:
  //   miketaylr.com/code/input-type-attr.html

  // Only input placeholder is tested while textarea's placeholder is not.
  // Currently Safari 4 and Opera 11 have support only for the input placeholder
  // Both tests are available in feature-detects/forms-placeholder.js
  Modernizr['input'] = (function( props ) {
    for ( var i = 0, len = props.length; i < len; i++ ) {
      attrs[ props[i] ] = !!(props[i] in inputElem);
    }
    if (attrs.list){
      // safari false positive's on datalist: webk.it/74252
      // see also github.com/Modernizr/Modernizr/issues/146
      attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
    }
    return attrs;
  })(inputattrs);
});
<|endoftext|>


<commit_before>/*     / \____  _    _  ____   ______  / \ ____  __    _ _____
 *    /  /    \/ \  / \/    \ /  /\__\/  //    \/  \  / /  _  \   Javaslang
 *  _/  /  /\  \  \/  /  /\  \\__\\  \  //  /\  \ /\\/  \__/  /   Copyright 2014-now Daniel Dietrich
 * /___/\_/  \_/\____/\_/  \_/\__\/__/___\_/  \_//  \__/_____/    Licensed under the Apache License, Version 2.0
 */

/*
 * Expands a given Array using a function `f` and optional
 * `delimiter`, `prefix` and `suffix`.
 *
 * Examples:
 *
 * // 1, 2, 3
 * range(1, 3).gen(function(j) j)(", ")
 *
 * // >1<>0<>-1<
 * range(1, -1).gen(function(j) ">${j}<")()
 *
 * // {1, 0, -1}
 * // {2, 1, 0, -1, -2}
 * // {3, 2, 1, 0, -1, -2, -3}
 * range(1, 3).gen(function(i)
 *     range(i, -i).gen(function(j) j)(", ", "{", "}")
 * )("\n")
 *
 */
Array.prototype.gen = function(f) {
    var array = this
    return function(delimiter, prefix, suffix) {
        var result = (prefix === undefined ? "" : prefix)
        var last = array.length - 1;
        for (var index = 0; index <= last; index++) {
            var elem = array[index]
            result = result + f(elem) + (index == last || delimiter === undefined ? "" : delimiter)
        }
        return result + (suffix === undefined ? "" : suffix)
    }
}

/*
 * Results in `code`, if `condition` is true, otherwise returns the empty string.
 *
 * Examples:
 *
 * var s = "Hi"
 *
 * // = even length
 * (s.length % 2 == 0).gen("even length")
 *
 * // = Hi!
 * s.isDefined().gen(s + "!)
 *
 * // (empty string)
 * s.isEmpty().gen(s + "!")
 */
Boolean.prototype.gen = function(code) { return this.valueOf() ? code : "" }
String.prototype.isDefined = function() { return this.length > 0 }
String.prototype.isEmpty = function() { return this.length == 0 }

/*
 * Range (inclusive), returns an array containing [from, ..., to]
 *
 * Examples:
 *
 *
 */
var range = function(from, to) {
    array = []
    if (from <= to) {
        index = to-from+1
        while (index--) array[index] = to--
    } else {
        index = from-to+1
        while (index--) array[index] = to++
    }
    return array
}
<commit_msg>java(script)doc<commit_after>/*     / \____  _    _  ____   ______  / \ ____  __    _ _____
 *    /  /    \/ \  / \/    \ /  /\__\/  //    \/  \  / /  _  \   Javaslang
 *  _/  /  /\  \  \/  /  /\  \\__\\  \  //  /\  \ /\\/  \__/  /   Copyright 2014-now Daniel Dietrich
 * /___/\_/  \_/\____/\_/  \_/\__\/__/___\_/  \_//  \__/_____/    Licensed under the Apache License, Version 2.0
 */

/*
 * Expands a given Array using a function `f` and optional
 * `delimiter`, `prefix` and `suffix`.
 *
 * Examples:
 *
 * // 1, 2, 3
 * range(1, 3).gen(function(j) j)(", ")
 *
 * // (1)(0)(-1)
 * range(1, -1).gen(function(j) "(${j})")()
 *
 * // {1, 0, -1}
 * // {2, 1, 0, -1, -2}
 * // {3, 2, 1, 0, -1, -2, -3}
 * range(1, 3).gen(function(i)
 *     range(i, -i).gen(function(j) j)(", ", "{", "}")
 * )("\n")
 *
 */
Array.prototype.gen = function(f) {
    var array = this
    return function(delimiter, prefix, suffix) {
        var result = (prefix === undefined ? "" : prefix)
        var last = array.length - 1;
        for (var index = 0; index <= last; index++) {
            var elem = array[index]
            result = result + f(elem) + (index == last || delimiter === undefined ? "" : delimiter)
        }
        return result + (suffix === undefined ? "" : suffix)
    }
}

/*
 * Results in `code`, if `condition` is true, otherwise returns the empty string.
 *
 * Examples:
 *
 * var s = "Hi"
 *
 * // = even length
 * (s.length % 2 == 0).gen("even length")
 *
 * // = Hi!
 * s.isDefined().gen(s + "!)
 *
 * // (empty string)
 * s.isEmpty().gen(s + "!")
 *
 */
Boolean.prototype.gen = function(code) { return this.valueOf() ? code : "" }
String.prototype.isDefined = function() { return this.length > 0 }
String.prototype.isEmpty = function() { return this.length == 0 }

/*
 * Range (inclusive), returns an array containing [from, ..., to]
 *
 * Examples:
 *
 * // = [1, 2, 3]
 * range(1, 3)
 *
 * // = [1, 0, -1]
 * range(1, -1)
 *
 */
var range = function(from, to) {
    array = []
    if (from <= to) {
        index = to-from+1
        while (index--) array[index] = to--
    } else {
        index = from-to+1
        while (index--) array[index] = to++
    }
    return array
}
<|endoftext|>


<commit_before>/**
    Framework for building object relational database apps
    Copyright (C) 2019  John Rogelstad

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/*jslint node, this*/
(function (exports) {
    "use strict";

    const {CRUD} = require("./crud");
    const {Feathers} = require("./feathers");
    const f = require("../../common/core");
    const XLSX = require("xlsx");
    const fs = require("fs");
    const crud = new CRUD();
    const feathers = new Feathers();

    exports.Exporter = function () {
        // ..........................................................
        // PUBLIC
        //

        let that = {};

        function tidy(obj) {
            delete obj.objectType;
            delete obj.isDeleted;
            delete obj.lock;

            Object.keys(obj).forEach(function (key) {
                if (Array.isArray(obj[key])) {
                    obj[key].forEach(function (row) {
                        delete row.id;
                        tidy(row);
                    });
                }
            });
        }

        function doExport(
            client,
            feather,
            properties,
            filter,
            dir,
            format,
            writeFile
        ) {
            return new Promise(function (resolve, reject) {
                let id = f.createId();
                let filename = dir + id + format;
                let payload = {
                    client: client,
                    name: feather,
                    filter: filter,
                    properties: properties
                };

                if (properties && properties.indexOf("objectType") === -1) {
                    properties.push("objectType");
                }

                function callback(resp) {
                    writeFile(filename, resp, format).then(
                        () => resolve(filename)
                    );
                }

                crud.doSelect(
                    payload,
                    false,
                    true
                ).then(callback).catch(reject);
            });
        }

        function writeWorkbook(filename, data, format) {
            return new Promise(function (resolve) {
                let wb = XLSX.utils.book_new();
                let sheets = {};
                let keys;
                let key;
                let ws;

                function toSheets(d, rename) {
                    let type;
                    let tmp;
                    let c = 0;

                    function doRename(data, key) {
                        if (
                            key === "objectType" ||
                            key === "isDeleted" ||
                            key === "lock"
                        ) {
                            tmp[key] = data[key];
                        } else {
                            tmp[key.toName()] = data[key];
                        }
                    }

                    if (d.length) {
                        d.forEach(function (row) {
                            let pkey = row.objectType.toName() + " Id";
                            let pval = row.id;

                            Object.keys(row).forEach(function (key) {
                                let n;

                                if (
                                    Array.isArray(row[key]) &&
                                    row[key].length &&
                                    row[key][0].objectType
                                ) {
                                    // Add parent key in
                                    n = 0;
                                    row[key].forEach(function (r) {
                                        tmp = {};
                                        tmp[pkey] = pval;
                                        Object.keys(r).forEach(
                                            doRename.bind(null, r)
                                        );
                                        row[key][n] = tmp;
                                        n += 1;
                                    });
                                    toSheets(row[key], false);
                                    delete row[key];
                                } else if (
                                    row[key] !== null &&
                                    typeof row[key] === "object" &&
                                    row[key].id
                                ) {
                                    row[key] = row[key].id;
                                }
                            });

                            if (rename !== false) {
                                tmp = {};
                                Object.keys(row).forEach(
                                    doRename.bind(null, row)
                                );
                                d[c] = tmp;
                                c += 1;
                            }
                        });

                        type = d[0].objectType;
                        if (!sheets[type]) {
                            sheets[type] = d;
                        } else {
                            sheets[type] = sheets[type].concat(d);
                        }
                    }
                }

                toSheets(data);

                // Add worksheets in reverse order
                keys = Object.keys(sheets);
                while (keys.length) {
                    key = keys.pop();
                    sheets[key].forEach(tidy);
                    ws = XLSX.utils.json_to_sheet(sheets[key]);
                    XLSX.utils.book_append_sheet(wb, ws, key);
                }

                XLSX.writeFile(wb, filename, {bookType: format});
                resolve();
            });
        }

        /**
          Export as json.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.json = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                function writeFile(filename, data) {
                    return new Promise(function (resolve) {
                        data.forEach(tidy);

                        fs.appendFile(
                            filename,
                            JSON.stringify(data, null, 4),
                            function (err) {
                                if (err) {
                                    reject(err);
                                    return;
                                }

                                resolve();
                            }
                        );
                    });
                }

                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "json",
                    writeFile
                ).then(resolve).catch(reject);
            });
        };

        /**
          Export as Open Document spreadsheet.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.ods = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "ods",
                    writeWorkbook
                ).then(resolve).catch(reject);
            });
        };

        /**
          Export as Excel spreadsheet.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.xlsx = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "xlsx",
                    writeWorkbook
                ).then(resolve).catch(reject);
            });
        };

        return that;
    };

    exports.Importer = function () {
        // ..........................................................
        // PUBLIC
        //

        let that = {};

        /**
          Import JSON file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.json = function (datasource, client, feather, filename) {
            return new Promise(function (resolve, reject) {
                let requests = [];
                let log = [];

                function error(err) {
                    log.push({
                        feather: this.name,
                        id: this.id,
                        error: err
                    });
                }

                function callback(err, data) {
                    if (err) {
                        console.error(err);
                        return reject(err);
                    }

                    try {
                        data = JSON.parse(data);

                        data.forEach(function (item) {
                            let payload = {
                                method: "POST",
                                client: client,
                                name: feather,
                                id: item.id,
                                data: item
                            };

                            requests.push(
                                datasource.request(payload).catch(
                                    error.bind(payload)
                                )
                            );
                        });
                    } catch (e) {
                        reject(e);
                        return;
                    }

                    Promise.all(requests).then(
                        resolve.bind(null, log)
                    ).catch(reject);
                }

                fs.readFile(filename, "utf8", callback);
            });
        };

        /**
          Import Excel file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.xlsx = function (datasource, client, feather, filename) {
            return new Promise(function (resolve, reject) {
                let requests = [];
                let log = [];
                let wb = XLSX.readFile(filename);
                let sheets = {};
                let localFeathers = {};

                wb.SheetNames.forEach(function (name) {
                    sheets[name] = XLSX.utils.sheet_to_json(
                        wb.Sheets[name]
                    );
                });

                function error(err) {
                    log.push({
                        feather: this.name,
                        id: this.id,
                        error: err
                    });
                }

                function getFeather(name) {
                    return new Promise(function (resolve, reject) {
                        function getChildFeathers(resp) {
                            let frequests = [];
                            let props = resp.properties;

                            try {
                                localFeathers[name] = resp;

                                // Recursively get feathers for all children
                                Object.keys(props).forEach(function (key) {
                                    let type = props[key].type;

                                    if (
                                        typeof type === "object" &&
                                        type.parentOf
                                    ) {
                                        frequests.push(
                                            getFeather(
                                                type.relation
                                            )
                                        );
                                    }
                                });
                            } catch (e) {
                                reject(e);
                                return;
                            }

                            Promise.all(
                                frequests
                            ).then(resolve).catch(reject);
                        }

                        feathers.getFeather({
                            client,
                            data: {
                                name: name
                            }
                        }).then(getChildFeathers).catch(reject);
                    });
                }

                function buildRow(feather, row) {
                    let ret = {};
                    let props = localFeathers[feather].properties;
                    let ary;
                    let id = row.Id;

                    if (!id) {
                        throw new Error(
                            "Id is required for \"" + feather + "\""
                        );
                    }

                    try {
                        Object.keys(props).forEach(function (key) {
                            let value = row[key.toName()];
                            let pkey = feather.toName() + " Id";
                            let rel;

                            if (typeof props[key].type === "object") {
                                if (props[key].type.isParent) {
                                    rel = props[key].type.relation;
                                    ary = sheets[rel].filter(
                                        (r) => r[pkey] === id
                                    );
                                    ret[key] = ary.forEach(
                                        buildRow.bind(null, localFeathers[rel])
                                    );
                                } else if (value) {
                                    ret[key] = {id: value};
                                }
                            } else if (value !== undefined) {
                                ret[key] = value;
                            }
                        });
                    } catch (e) {
                        reject(e);
                        return;
                    }

                    return ret;
                }

                function doRequest(row) {
                    let payload = {
                        client: client,
                        method: "POST",
                        name: feather,
                        id: row.Id,
                        data: buildRow(feather, row)
                    };

                    requests.push(
                        datasource.request(payload).catch(
                            error.bind(payload)
                        )
                    );
                }

                function callback() {
                    sheets[feather].forEach(doRequest);

                    Promise.all(requests).then(
                        resolve.bind(null, log)
                    ).catch(reject);
                }

                getFeather(feather).then(callback).catch(reject);
            });
        };

        /**
          Import Open Document Spreadsheet file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.ods = that.xlsx;

        return that;
    };

}(exports));

<commit_msg>Export money<commit_after>/**
    Framework for building object relational database apps
    Copyright (C) 2019  John Rogelstad

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/*jslint node, this*/
(function (exports) {
    "use strict";

    const {CRUD} = require("./crud");
    const {Feathers} = require("./feathers");
    const f = require("../../common/core");
    const XLSX = require("xlsx");
    const fs = require("fs");
    const crud = new CRUD();
    const feathers = new Feathers();

    exports.Exporter = function () {
        // ..........................................................
        // PUBLIC
        //

        let that = {};

        function tidy(obj) {
            delete obj.objectType;
            delete obj.isDeleted;
            delete obj.lock;

            Object.keys(obj).forEach(function (key) {
                if (Array.isArray(obj[key])) {
                    obj[key].forEach(function (row) {
                        delete row.id;
                        tidy(row);
                    });
                }
            });
        }

        function doExport(
            client,
            feather,
            properties,
            filter,
            dir,
            format,
            writeFile
        ) {
            return new Promise(function (resolve, reject) {
                let id = f.createId();
                let filename = dir + id + format;
                let payload = {
                    client: client,
                    name: feather,
                    filter: filter,
                    properties: properties
                };

                if (properties && properties.indexOf("objectType") === -1) {
                    properties.push("objectType");
                }

                function callback(resp) {
                    writeFile(filename, resp, format).then(
                        () => resolve(filename)
                    );
                }

                crud.doSelect(
                    payload,
                    false,
                    true
                ).then(callback).catch(reject);
            });
        }

        function writeWorkbook(filename, data, format) {
            return new Promise(function (resolve) {
                let wb = XLSX.utils.book_new();
                let sheets = {};
                let keys;
                let key;
                let ws;

                function toSheets(d, rename) {
                    let type;
                    let tmp;
                    let c = 0;

                    function doRename(data, key) {
                        if (
                            key === "objectType" ||
                            key === "isDeleted" ||
                            key === "lock"
                        ) {
                            tmp[key] = data[key];
                        } else {
                            tmp[key.toName()] = data[key];
                        }
                    }

                    if (d.length) {
                        d.forEach(function (row) {
                            let pkey = row.objectType.toName() + " Id";
                            let pval = row.id;

                            Object.keys(row).forEach(function (key) {
                                let n;

                                if (
                                    Array.isArray(row[key]) &&
                                    row[key].length &&
                                    row[key][0].objectType
                                ) {
                                    // Add parent key in
                                    n = 0;
                                    row[key].forEach(function (r) {
                                        tmp = {};
                                        tmp[pkey] = pval;
                                        Object.keys(r).forEach(
                                            doRename.bind(null, r)
                                        );
                                        row[key][n] = tmp;
                                        n += 1;
                                    });
                                    toSheets(row[key], false);
                                    delete row[key];
                                } else if (
                                    row[key] !== null &&
                                    typeof row[key] === "object"
                                ) {
                                    if (row[key].id) {
                                        row[key] = row[key].id;
                                    } else if (row[key].currency) {
                                        if (row[key].effective) {
                                            row[key] = (
                                                row[key].amount + " " +
                                                row[key].currency + " " +
                                                row[key].effective + " " +
                                                row[key].baseAmount
                                            );
                                        } else {
                                            row[key] = (
                                                row[key].amount + " " +
                                                row[key].currency
                                            );
                                        }

                                        if (row[key].effective) {
                                            row[key] += (
                                                " " + row[key].effective +
                                                " " + row[key].baseAmount
                                            );
                                        }
                                    }
                                }
                            });

                            if (rename !== false) {
                                tmp = {};
                                Object.keys(row).forEach(
                                    doRename.bind(null, row)
                                );
                                d[c] = tmp;
                                c += 1;
                            }
                        });

                        type = d[0].objectType;
                        if (!sheets[type]) {
                            sheets[type] = d;
                        } else {
                            sheets[type] = sheets[type].concat(d);
                        }
                    }
                }

                toSheets(data);

                // Add worksheets in reverse order
                keys = Object.keys(sheets);
                while (keys.length) {
                    key = keys.pop();
                    sheets[key].forEach(tidy);
                    ws = XLSX.utils.json_to_sheet(sheets[key]);
                    XLSX.utils.book_append_sheet(wb, ws, key);
                }

                XLSX.writeFile(wb, filename, {bookType: format});
                resolve();
            });
        }

        /**
          Export as json.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.json = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                function writeFile(filename, data) {
                    return new Promise(function (resolve) {
                        data.forEach(tidy);

                        fs.appendFile(
                            filename,
                            JSON.stringify(data, null, 4),
                            function (err) {
                                if (err) {
                                    reject(err);
                                    return;
                                }

                                resolve();
                            }
                        );
                    });
                }

                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "json",
                    writeFile
                ).then(resolve).catch(reject);
            });
        };

        /**
          Export as Open Document spreadsheet.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.ods = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "ods",
                    writeWorkbook
                ).then(resolve).catch(reject);
            });
        };

        /**
          Export as Excel spreadsheet.

          @param {Object} Database client
          @param {String} Feather name
          @param {Array} Properties
          @param {Object} Filter
          @param {String} Target file directory
          @return {String} Filename
        */
        that.xlsx = function (client, feather, properties, filter, dir) {
            return new Promise(function (resolve, reject) {
                doExport(
                    client,
                    feather,
                    properties,
                    filter,
                    dir,
                    "xlsx",
                    writeWorkbook
                ).then(resolve).catch(reject);
            });
        };

        return that;
    };

    exports.Importer = function () {
        // ..........................................................
        // PUBLIC
        //

        let that = {};

        /**
          Import JSON file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.json = function (datasource, client, feather, filename) {
            return new Promise(function (resolve, reject) {
                let requests = [];
                let log = [];

                function error(err) {
                    log.push({
                        feather: this.name,
                        id: this.id,
                        error: err
                    });
                }

                function callback(err, data) {
                    if (err) {
                        console.error(err);
                        return reject(err);
                    }

                    try {
                        data = JSON.parse(data);

                        data.forEach(function (item) {
                            let payload = {
                                method: "POST",
                                client: client,
                                name: feather,
                                id: item.id,
                                data: item
                            };

                            requests.push(
                                datasource.request(payload).catch(
                                    error.bind(payload)
                                )
                            );
                        });
                    } catch (e) {
                        reject(e);
                        return;
                    }

                    Promise.all(requests).then(
                        resolve.bind(null, log)
                    ).catch(reject);
                }

                fs.readFile(filename, "utf8", callback);
            });
        };

        /**
          Import Excel file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.xlsx = function (datasource, client, feather, filename) {
            return new Promise(function (resolve, reject) {
                let requests = [];
                let log = [];
                let wb = XLSX.readFile(filename);
                let sheets = {};
                let localFeathers = {};

                wb.SheetNames.forEach(function (name) {
                    sheets[name] = XLSX.utils.sheet_to_json(
                        wb.Sheets[name]
                    );
                });

                function error(err) {
                    log.push({
                        feather: this.name,
                        id: this.id,
                        error: err
                    });
                }

                function getFeather(name) {
                    return new Promise(function (resolve, reject) {
                        function getChildFeathers(resp) {
                            let frequests = [];
                            let props = resp.properties;

                            try {
                                localFeathers[name] = resp;

                                // Recursively get feathers for all children
                                Object.keys(props).forEach(function (key) {
                                    let type = props[key].type;

                                    if (
                                        typeof type === "object" &&
                                        type.parentOf
                                    ) {
                                        frequests.push(
                                            getFeather(
                                                type.relation
                                            )
                                        );
                                    }
                                });
                            } catch (e) {
                                reject(e);
                                return;
                            }

                            Promise.all(
                                frequests
                            ).then(resolve).catch(reject);
                        }

                        feathers.getFeather({
                            client,
                            data: {
                                name: name
                            }
                        }).then(getChildFeathers).catch(reject);
                    });
                }

                function buildRow(feather, row) {
                    let ret = {};
                    let props = localFeathers[feather].properties;
                    let ary;
                    let id = row.Id;

                    if (!id) {
                        throw new Error(
                            "Id is required for \"" + feather + "\""
                        );
                    }

                    try {
                        Object.keys(props).forEach(function (key) {
                            let value = row[key.toName()];
                            let pkey = feather.toName() + " Id";
                            let rel;

                            if (typeof props[key].type === "object") {
                                if (props[key].type.isParent) {
                                    rel = props[key].type.relation;
                                    ary = sheets[rel].filter(
                                        (r) => r[pkey] === id
                                    );
                                    ret[key] = ary.forEach(
                                        buildRow.bind(null, localFeathers[rel])
                                    );
                                } else if (value) {
                                    ret[key] = {id: value};
                                }
                            } else if (value !== undefined) {
                                ret[key] = value;
                            }
                        });
                    } catch (e) {
                        reject(e);
                        return;
                    }

                    return ret;
                }

                function doRequest(row) {
                    let payload = {
                        client: client,
                        method: "POST",
                        name: feather,
                        id: row.Id,
                        data: buildRow(feather, row)
                    };

                    requests.push(
                        datasource.request(payload).catch(
                            error.bind(payload)
                        )
                    );
                }

                function callback() {
                    sheets[feather].forEach(doRequest);

                    Promise.all(requests).then(
                        resolve.bind(null, log)
                    ).catch(reject);
                }

                getFeather(feather).then(callback).catch(reject);
            });
        };

        /**
          Import Open Document Spreadsheet file.

          @param {Object} Datasource
          @param {Object} Database client
          @param {String} Feather name
          @param {String} Source file
          @return {Array} Error log
        */
        that.ods = that.xlsx;

        return that;
    };

}(exports));

<|endoftext|>


<commit_before>// 2013, Muaz Khan - https://github.com/muaz-khan
// MIT License     - https://www.webrtc-experiment.com/licence/
// Documentation   - https://github.com/muaz-khan/WebRTC-Experiment/blob/master/socketio-over-nodejs

var app = require('express')(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

var port = process.env.PORT || 5000;
server.listen(port);

// ----------------------------------socket.io

var channels = {};

io.sockets.on('connection', function (socket) {
    var initiatorChannel = '';
    if (!io.isConnected)
        io.isConnected = true;

    socket.on('new-channel', function (data) {
        channels[data.channel] = data.channel;
        onNewNamespace(data.channel, data.sender);
    });

    socket.on('presence', function (channel) {
        var isChannelPresent = !! channels[channel];
        socket.emit('presence', isChannelPresent);
        if (!isChannelPresent)
            initiatorChannel = channel;
    });

    socket.on('disconnect', function (channel) {
        if (initiatorChannel)
            channels[initiatorChannel] = null;
    });
});

function onNewNamespace(channel, sender) {
    io.of('/' + channel).on('connection', function (socket) {
        if (io.isConnected) {
            io.isConnected = false;
            socket.emit('connect', true);
        }

        socket.on('message', function (data) {
            if (data.sender == sender)
                socket.broadcast.emit('message', data.data);
        });
    });
}

// ----------------------------------extras

app.get('/', function (req, res) {
    res.sendfile(__dirname + '/static/video-conferencing/index.html');
});

app.get('/conference.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference.js');
});

app.get('/conference-ui.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference-ui.js');
});

app.get('/chat', function (req, res) {
    res.sendfile(__dirname + '/static/text-chat.html');
});

app.get('/RTCMultiConnection', function (req, res) {
    res.sendfile(__dirname + '/static/RTCMultiConnection/index.html');
});

app.get('/socketio.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/socket.io.js');
});
<commit_msg>Calling demo<commit_after>var app = require('express')(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

var port = process.env.PORT || 5000;
server.listen(port);
console.log("Connected on port " + port);
// ----------------------------------socket.io

var channels = {};

io.sockets.on('connection', function (socket) {
    var initiatorChannel = '';
    if (!io.isConnected)
        io.isConnected = true;

    socket.on('new-channel', function (data) {
        channels[data.channel] = data.channel;
        onNewNamespace(data.channel, data.sender);
    });

    socket.on('presence', function (channel) {
        var isChannelPresent = !! channels[channel];
        socket.emit('presence', isChannelPresent);
        if (!isChannelPresent)
            initiatorChannel = channel;
    });

    socket.on('disconnect', function (channel) {
        if (initiatorChannel)
            channels[initiatorChannel] = null;
    });
});

function onNewNamespace(channel, sender) {
    io.of('/' + channel).on('connection', function (socket) {
        if (io.isConnected) {
            io.isConnected = false;
            socket.emit('connect', true);
        }

        socket.on('message', function (data) {
            if (data.sender == sender)
                socket.broadcast.emit('message', data.data);
        });
    });
}

// ----------------------------------extras

app.get('/', function (req, res) {
    res.sendfile(__dirname + '/static/call/index.html');
});

app.get('/admin', function (req, res) {
    res.sendfile(__dirname + '/static/call/admin.html');
});

app.get('/conference.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference.js');
});

app.get('/conference-ui.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference-ui.js');
});

app.get('/chat', function (req, res) {
    res.sendfile(__dirname + '/static/text-chat.html');
});

app.get('/RTCMultiConnection', function (req, res) {
    res.sendfile(__dirname + '/static/RTCMultiConnection/index.html');
});

app.get('/socketio.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/socket.io.js');
});

app.get('/call.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/RTCall.js');
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

class Interpolate extends Component {

  constructor(props, context) {
    super(props, context);
    this.i18n = context.i18n;
    this.t = context.t;
  }

  render() {
    const parent = this.props.parent || 'span';
    const REGEXP = this.props.regexp || this.i18n.services.interpolator.regexp;

    // Set to true if you want to use raw HTML in translation values
    // See https://github.com/i18next/react-i18next/issues/189
    const useDangerouslySetInnerHTML = this.props.useDangerouslySetInnerHTML || false;
    const dangerouslySetInnerHTMLPartElement = this.props.dangerouslySetInnerHTMLPartElement || 'span';

    let tOpts = {...{}, ...this.props.options, ...{interpolation: { prefix: '#$?', suffix: '?$#'}}}
    let format = this.t(this.props.i18nKey, tOpts);

    if (!format || typeof format !== 'string') return React.createElement('noscript', null);

    let children = [];

    format.split(REGEXP).reduce((memo, match, index) => {
      var child;

      if (index % 2 === 0) {
        if (match.length === 0)  return memo;
        if (useDangerouslySetInnerHTML) {
          child = React.createElement(dangerouslySetInnerHTMLPartElement, {dangerouslySetInnerHTML: {__html: match}});
        } else {
          child = match;
        }
      } else {
        child = this.props[match];
        if (!this.props[match]) this.i18n.services.logger.warn('interpolator: missed to pass in variable ' + match + ' for interpolating ' + format);
      }

      memo.push(child);
      return memo;
    }, children);

    return React.createElement.apply(this, [parent, null].concat(children));
  }
}

Interpolate.contextTypes = {
  i18n: PropTypes.object.isRequired,
  t: PropTypes.func.isRequired
};

export default Interpolate;
<commit_msg>Support classnames on parents of interpolated components<commit_after>import React, { Component, PropTypes } from 'react';

class Interpolate extends Component {

  constructor(props, context) {
    super(props, context);
    this.i18n = context.i18n;
    this.t = context.t;
  }

  render() {
    const parent = this.props.parent || 'span';
    const REGEXP = this.props.regexp || this.i18n.services.interpolator.regexp;

    // Set to true if you want to use raw HTML in translation values
    // See https://github.com/i18next/react-i18next/issues/189
    const useDangerouslySetInnerHTML = this.props.useDangerouslySetInnerHTML || false;
    const dangerouslySetInnerHTMLPartElement = this.props.dangerouslySetInnerHTMLPartElement || 'span';

    let tOpts = {...{}, ...this.props.options, ...{interpolation: { prefix: '#$?', suffix: '?$#'}}}
    let format = this.t(this.props.i18nKey, tOpts);
    let className = this.props.className;

    if (!format || typeof format !== 'string') return React.createElement('noscript', null);

    let children = [];

    format.split(REGEXP).reduce((memo, match, index) => {
      var child;

      if (index % 2 === 0) {
        if (match.length === 0)  return memo;
        if (useDangerouslySetInnerHTML) {
          child = React.createElement(dangerouslySetInnerHTMLPartElement, {dangerouslySetInnerHTML: {__html: match}});
        } else {
          child = match;
        }
      } else {
        child = this.props[match];
        if (!this.props[match]) this.i18n.services.logger.warn('interpolator: missed to pass in variable ' + match + ' for interpolating ' + format);
      }

      memo.push(child);
      return memo;
    }, children);

    return React.createElement.apply(this, [parent, { className }].concat(children));
  }
}

Interpolate.contextTypes = {
  i18n: PropTypes.object.isRequired,
  t: PropTypes.func.isRequired
};

export default Interpolate;
<|endoftext|>