<commit_before>// Generated by CoffeeScript 1.9.3
(function() {
  var API, Mapping, SchemaManager;

  SchemaManager = require("./schema_manager");

  module.exports = API = (function() {
    function API(arg) {
      var definition, mapping, mappings, name, ref1;
      this.service_url = arg.service_url, mappings = arg.mappings, this.resources = arg.resources, this.schemas = arg.schemas;
      if (!(mappings && this.resources && this.schemas)) {
        throw new Error("API specification must provide mappings, resources, and schemas");
      }
      this.mappings = {};
      for (name in mappings) {
        mapping = mappings[name];
        this.mappings[name] = new Mapping(this, mapping);
      }
      ref1 = this.resources;
      for (name in ref1) {
        definition = ref1[name];
        definition.name = name;
      }
      this.schema_manager = (function(func, args, ctor) {
        ctor.prototype = func.prototype;
        var child = new ctor, result = func.apply(child, args);
        return Object(result) === result ? result : child;
      })(SchemaManager, this.schemas, function(){});
    }

    API.prototype.decorate = function(context, schema, data) {
      var constructor, mapping, name, ref1;
      if ((name = (ref1 = schema.id) != null ? ref1.split("#")[1] : void 0) != null) {
        if ((mapping = this.mappings[name]) != null) {
          constructor = mapping.constructor;
          data = new constructor(context, data);
        }
      }
      return this._decorate(context, schema, data) || data;
    };

    API.prototype._decorate = function(context, schema, data) {
      var addprop, i, item, j, key, len, ref, ref1, ref2, result, results, value;
      if ((schema == null) || (data == null)) {
        return;
      }
      if (ref = schema.$ref) {
        if ((schema = this.schema_manager.find(ref)) != null) {
          return this.decorate(context, schema, data);
        } else {
          console.error("Can't find ref:", ref);
          return data;
        }
      } else {
        if (schema.type === "array") {
          if (schema.items != null) {
            results = [];
            for (i = j = 0, len = data.length; j < len; i = ++j) {
              item = data[i];
              if ((result = this.decorate(context, schema.items, item)) != null) {
                results.push(data[i] = result);
              } else {
                results.push(void 0);
              }
            }
            return results;
          }
        } else {
          switch (schema.type) {
            case "string":
            case "number":
            case "integer":
            case "boolean":
              return null;
            default:
              ref1 = schema.properties;
              for (key in ref1) {
                value = ref1[key];
                if ((result = this.decorate(context, value, data[key])) != null) {
                  data[key] = result;
                }
              }
              if (addprop = schema.additionalProperties) {
                for (key in data) {
                  value = data[key];
                  if (!((ref2 = schema.properties) != null ? ref2[key] : void 0)) {
                    data[key] = this.decorate(context, addprop, value);
                  }
                }
              }
              return data;
          }
        }
      }
    };

    return API;

  })();

  API.Mapping = Mapping = (function() {
    function Mapping(api, arg) {
      var resource;
      this.name = arg.name, this.resource = arg.resource, this.url = arg.url, this.template = arg.template, this.path = arg.path, this.query = arg.query;
      this.service_url = api.service_url;
      if (this.resource == null) {
        this.resource = this.name;
      }
      if (!((this.url != null) || (this.path != null) || (this.template != null))) {
        throw new Error("Mapping is missing any form of URL specification");
      }
      if ((resource = api.resources[this.resource]) == null) {
        throw new Error("Mapping specifies a resource that is not defined");
      }
      this.resource = resource;
    }

    Mapping.prototype.generate_url = function(params) {
      var j, k, key, keys, len, len1, out, part, parts, path, query, query_string, schema, string, template, url;
      if (params == null) {
        params = {};
      }
      url = this.service_url;
      path = "";
      if (params.constructor === String) {
        url = params;
      } else if (params.url) {
        url = params.url;
      } else if (this.url != null) {
        url = this.url;
      } else if ((template = this.template) != null) {
        parts = template.split("/");
        out = [];
        for (j = 0, len = parts.length; j < len; j++) {
          part = parts[j];
          if (part.indexOf(":") === 0) {
            key = part.slice(1);
            if ((string = params[key]) != null) {
              out.push(string);
            } else {
              throw new Error("Missing key: '" + key + "' in params: " + (JSON.stringify(params)));
            }
          } else {
            out.push(part);
          }
        }
        url = url + out.join("/");
      } else if (this.path != null) {
        path = this.path;
      } else {
        throw new Error("Unusable URL mapping.  Must have url, path, or template field.\nMapping: " + (JSON.stringify(this, null, 2)));
      }
      query_string = "";
      if ((query = this.query) != null) {
        parts = [];
        keys = Object.keys(query).sort();
        for (k = 0, len1 = keys.length; k < len1; k++) {
          key = keys[k];
          schema = query[key];
          if ((string = params[key]) != null) {
            parts.push((encodeURIComponent(key)) + "=" + (encodeURIComponent(string)));
          }
        }
        if (parts.length > 0) {
          query_string = "?" + (parts.join('&'));
        } else {
          query_string = "";
        }
      }
      return encodeURI(url + path) + query_string;
    };

    return Mapping;

  })();

}).call(this);
<commit_msg>recompiling to js<commit_after>// Generated by CoffeeScript 1.9.3
(function() {
  var API, Mapping, SchemaManager;

  SchemaManager = require("./schema_manager");

  module.exports = API = (function() {
    function API(arg) {
      var definition, mapping, mappings, name, ref1;
      this.service_url = arg.service_url, mappings = arg.mappings, this.resources = arg.resources, this.schemas = arg.schemas;
      if (!(mappings && this.resources && this.schemas)) {
        throw new Error("API specification must provide mappings, resources, and schemas");
      }
      this.mappings = {};
      for (name in mappings) {
        mapping = mappings[name];
        this.mappings[name] = new Mapping(this, mapping);
      }
      ref1 = this.resources;
      for (name in ref1) {
        definition = ref1[name];
        definition.name = name;
      }
      this.schema_manager = (function(func, args, ctor) {
        ctor.prototype = func.prototype;
        var child = new ctor, result = func.apply(child, args);
        return Object(result) === result ? result : child;
      })(SchemaManager, this.schemas, function(){});
    }

    API.prototype.decorate = function(context, schema, data) {
      var _data, constructor, mapping, name, ref1;
      if ((name = (ref1 = schema.id) != null ? ref1.split("#")[1] : void 0) != null) {
        if ((mapping = this.mappings[name]) != null) {
          constructor = mapping.constructor;
          _data = data;
          if (mapping.query != null) {
            data = function(params) {
              if (_data.url != null) {
                params.url = _data.url;
              }
              return new constructor(context, {
                url: mapping.generate_url(params)
              });
            };
          } else {
            data = new constructor(context, _data);
          }
        }
      }
      return this._decorate(context, schema, data) || data;
    };

    API.prototype._decorate = function(context, schema, data) {
      var addprop, i, item, j, key, len, ref, ref1, ref2, result, results, value;
      if ((schema == null) || (data == null)) {
        return;
      }
      if (ref = schema.$ref) {
        if ((schema = this.schema_manager.find(ref)) != null) {
          return this.decorate(context, schema, data);
        } else {
          console.error("Can't find ref:", ref);
          return data;
        }
      } else {
        if (schema.type === "array") {
          if (schema.items != null) {
            results = [];
            for (i = j = 0, len = data.length; j < len; i = ++j) {
              item = data[i];
              if ((result = this.decorate(context, schema.items, item)) != null) {
                results.push(data[i] = result);
              } else {
                results.push(void 0);
              }
            }
            return results;
          }
        } else {
          switch (schema.type) {
            case "string":
            case "number":
            case "integer":
            case "boolean":
              return null;
            default:
              ref1 = schema.properties;
              for (key in ref1) {
                value = ref1[key];
                if ((result = this.decorate(context, value, data[key])) != null) {
                  data[key] = result;
                }
              }
              if (addprop = schema.additionalProperties) {
                for (key in data) {
                  value = data[key];
                  if (!((ref2 = schema.properties) != null ? ref2[key] : void 0)) {
                    data[key] = this.decorate(context, addprop, value);
                  }
                }
              }
              return data;
          }
        }
      }
    };

    return API;

  })();

  API.Mapping = Mapping = (function() {
    function Mapping(api, arg) {
      var resource;
      this.name = arg.name, this.resource = arg.resource, this.url = arg.url, this.template = arg.template, this.path = arg.path, this.query = arg.query;
      this.service_url = api.service_url;
      if (this.resource == null) {
        this.resource = this.name;
      }
      if (!((this.url != null) || (this.path != null) || (this.template != null))) {
        throw new Error("Mapping is missing any form of URL specification");
      }
      if ((resource = api.resources[this.resource]) == null) {
        throw new Error("Mapping specifies a resource that is not defined");
      }
      this.resource = resource;
    }

    Mapping.prototype.generate_url = function(params) {
      var j, k, key, keys, len, len1, out, part, parts, path, query, query_string, schema, string, template, url;
      if (params == null) {
        params = {};
      }
      url = this.service_url;
      path = "";
      if (params.constructor === String) {
        url = params;
      } else if (params.url) {
        url = params.url;
      } else if (this.url != null) {
        url = this.url;
      } else if ((template = this.template) != null) {
        parts = template.split("/");
        out = [];
        for (j = 0, len = parts.length; j < len; j++) {
          part = parts[j];
          if (part.indexOf(":") === 0) {
            key = part.slice(1);
            if ((string = params[key]) != null) {
              out.push(string);
            } else {
              throw new Error("Missing key: '" + key + "' in params: " + (JSON.stringify(params)));
            }
          } else {
            out.push(part);
          }
        }
        url = url + out.join("/");
      } else if (this.path != null) {
        path = this.path;
      } else {
        throw new Error("Unusable URL mapping.  Must have url, path, or template field.\nMapping: " + (JSON.stringify(this, null, 2)));
      }
      query_string = "";
      if ((query = this.query) != null) {
        parts = [];
        keys = Object.keys(query).sort();
        for (k = 0, len1 = keys.length; k < len1; k++) {
          key = keys[k];
          schema = query[key];
          if ((string = params[key]) != null) {
            parts.push((encodeURIComponent(key)) + "=" + (encodeURIComponent(string)));
          }
        }
        if (parts.length > 0) {
          query_string = "?" + (parts.join('&'));
        } else {
          query_string = "";
        }
      }
      return encodeURI(url + path) + query_string;
    };

    return Mapping;

  })();

}).call(this);
<|endoftext|>


<commit_before>;(function(exports) {
  var library = {
    first: function(x) {
      return x[0];
    },
    rest: function(x) {
      return x.slice(1);
    },
    print: function(x) {
      console.log(x);
      return x;
    }
  };

  var Ctx = function(scope, parent) {
    this.scope = scope;
    this.parent = parent;
    this.get = function(name) {
      var item = this.scope[name];
      if (item !== undefined) {
        return item;
      } else if (this.parent !== undefined) {
        return this.parent.get(name);
      }
    };
  };

  var lambda = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        var lambdaScope = input[1].reduce(function(acc, x, i) {
          acc[x.value] = args[i];
          return acc;
        }, {});
        return interpret(input[2], new Ctx(lambdaScope, ctx));
      }
    };
  };

  var fn = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        return ctx.get(input.value).apply(undefined, args);
      }
    };
  };

  var interpret = function(input, ctx) {
    if (ctx === undefined) {
      return interpret(input, new Ctx(library));
    } else if (Object.prototype.toString.call(input) === '[object Array]') {
      if (input[0].value === "lambda") {
        return lambda(input, ctx);
      } else {
        var list = input.map(function(x) { return interpret(x, ctx); });
        if (list[0].type === "function") {
          return list[0].value(list.slice(1));
        } else {
          return list;
        }
      }
    } else if (input.type === "identifier") {
      if (typeof ctx.get(input.value) === "function") { // fn
        return fn(input, ctx);
      } else { // var lookup
        return ctx.get(input.value);
      }
    } else { // literal
      return input.value;
    }
  };

  var atDepth = function(output, depth) {
    if (depth === 0) {
      return output;
    } else {
      return atDepth(output[output.length - 1], depth - 1);
    }
  };

  var type = function(input) {
    if (!isNaN(parseFloat(input))) {
      return { type:'literal', value: parseFloat(input) };
    } else if (input[0] === '"' && input.slice(-1) === '"') {
      return { type:'literal', value: input.slice(1, -1) };
    } else {
      return { type:'identifier', value: input };
    }
  };

  var parenthesize = function(input) {
    var output = [];
    var depth = 0;
    while (input.length > 0) {
      var token = input.shift();
      if (token === "(") {
        atDepth(output, depth++).push([]);
      } else if (token === ")") {
        depth--;
      } else {
        atDepth(output, depth).push(type(token));
      }
    }

    return output.pop();
  };

  var tokenize = function(input) {
    return input.split('"').map(function(x, i) {
                   return i % 2 === 0 ? x : x.replace(/ /g, "spaceholder");
                 }).join('"')
                .replace(/\(/g, ' ( ')
                .replace(/\)/g, ' ) ')
                .trim()
                .split(/ +/)
                .map(function(x) {
                  return x.replace(/spaceholder/g, " ");
                });
  };

  var parse = function(input) {
    return parenthesize(tokenize(input));
  };

  exports.tinyLisp = {};
  exports.tinyLisp.parse = parse;
  exports.tinyLisp.interpret = interpret;
})(typeof exports === 'undefined' ? this : exports);
<commit_msg>Make Ctx.get() use identifier rather than name for item being got.<commit_after>;(function(exports) {
  var library = {
    first: function(x) {
      return x[0];
    },
    rest: function(x) {
      return x.slice(1);
    },
    print: function(x) {
      console.log(x);
      return x;
    }
  };

  var Ctx = function(scope, parent) {
    this.scope = scope;
    this.parent = parent;
    this.get = function(identifier) {
      var item = this.scope[identifier];
      if (item !== undefined) {
        return item;
      } else if (this.parent !== undefined) {
        return this.parent.get(identifier);
      }
    };
  };

  var lambda = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        var lambdaScope = input[1].reduce(function(acc, x, i) {
          acc[x.value] = args[i];
          return acc;
        }, {});
        return interpret(input[2], new Ctx(lambdaScope, ctx));
      }
    };
  };

  var fn = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        return ctx.get(input.value).apply(undefined, args);
      }
    };
  };

  var interpret = function(input, ctx) {
    if (ctx === undefined) {
      return interpret(input, new Ctx(library));
    } else if (Object.prototype.toString.call(input) === '[object Array]') {
      if (input[0].value === "lambda") {
        return lambda(input, ctx);
      } else {
        var list = input.map(function(x) { return interpret(x, ctx); });
        if (list[0].type === "function") {
          return list[0].value(list.slice(1));
        } else {
          return list;
        }
      }
    } else if (input.type === "identifier") {
      if (typeof ctx.get(input.value) === "function") { // fn
        return fn(input, ctx);
      } else { // var lookup
        return ctx.get(input.value);
      }
    } else { // literal
      return input.value;
    }
  };

  var atDepth = function(output, depth) {
    if (depth === 0) {
      return output;
    } else {
      return atDepth(output[output.length - 1], depth - 1);
    }
  };

  var type = function(input) {
    if (!isNaN(parseFloat(input))) {
      return { type:'literal', value: parseFloat(input) };
    } else if (input[0] === '"' && input.slice(-1) === '"') {
      return { type:'literal', value: input.slice(1, -1) };
    } else {
      return { type:'identifier', value: input };
    }
  };

  var parenthesize = function(input) {
    var output = [];
    var depth = 0;
    while (input.length > 0) {
      var token = input.shift();
      if (token === "(") {
        atDepth(output, depth++).push([]);
      } else if (token === ")") {
        depth--;
      } else {
        atDepth(output, depth).push(type(token));
      }
    }

    return output.pop();
  };

  var tokenize = function(input) {
    return input.split('"').map(function(x, i) {
                   return i % 2 === 0 ? x : x.replace(/ /g, "spaceholder");
                 }).join('"')
                .replace(/\(/g, ' ( ')
                .replace(/\)/g, ' ) ')
                .trim()
                .split(/ +/)
                .map(function(x) {
                  return x.replace(/spaceholder/g, " ");
                });
  };

  var parse = function(input) {
    return parenthesize(tokenize(input));
  };

  exports.tinyLisp = {};
  exports.tinyLisp.parse = parse;
  exports.tinyLisp.interpret = interpret;
})(typeof exports === 'undefined' ? this : exports);
<|endoftext|>


<commit_before>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var async = require('async');

module.exports = function(options, _sr, _analyzer, _containers) {
  var ERR_NOCDEF = 'unable to find container definition';
  var ERR_NOSYSID = 'unable to find system';
  var ERR_NOREV = 'unable to find revision';

  var _sys;
  var _builder;
  var _deployer;
  var _compiler;
  var _synchrotron;
  var logger = options.logger;

  /**
   * list all of the available systems
   */
  var listSystems = function(cb) {
    logger.info('list systems');
    var systems = _sr.listSystems();
    cb(null, systems);
  };

  /**
   * get the full head system definition (latest revision)
   */
  var getHeadSystem = function(identifier, cb) {
    logger.info('get head system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getHead(systemId, cb);
  };

  /**
   * get the full deployed system definition
   */
  var getDeployedSystem = function(identifier, cb) {
    logger.info('get deployed system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getDeployedRevision(systemId, cb);
  };

  /**
   * create a new  blank system
   */
  var createSystem = function(user, name, namespace, cwd, cb) {
    logger.info('create system name: ' + name + ', namespace: ' + namespace + ', cwd: ' + cwd);
    _sr.createSystem(user, namespace, name, cwd, cb);
  };

  /**
   * put the system definition, if the system doesn't exist it will be created
   */
  var putSystem = function(user, system, cb) {
    var doc = JSON.parse(system);
    logger.info('put system: ' + system.name);

    if (!_sr.systemExists(doc.namespace, doc.name)) {
      _sr.createSystem(user, doc.namespace, doc.name, function(err, repoId) {
        if (err) { return cb(err); }
        doc.id = repoId;
        _sr.commitRevision(user, doc.id, 'no comment', doc, function(err, revisionId) {
          _sr.markDeployedRevision(user, doc.id, revisionId, cb);
        });
      });
    }
    else {
      _sr.commitRevision(user, doc.id, 'no comment', doc, cb);
    }
  };

  /**
   * clone a system from github
   */
  var cloneSystem = function(user, url, cwd, cb) {
    logger.info('clone system: ' + url + ', ' + cwd);
    _sr.cloneSystem(user, url, cwd, cb);
  };

  /**
   * link a system from local fs
   */
  var linkSystem = function(user, path, cwd, cb) {
    logger.info('link system: ' + path + ', ' + cwd);
    _sr.linkSystem(user, path, cwd, cb);
  };

  /**
   * pull/push system and sync with remote
   */
  var syncSystem = function(user, identifier, cb) {
    logger.info('sync system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.syncSystem(user, systemId, cb);
  };

  /**
   * add a remote url to the system repository
   */
  var addRemote = function(user, identifier, url, cb) {
    logger.info('add remote: ' + identifier + ', ' + url);
    var systemId = _sr.findSystem(identifier);
    _sr.addRemote(user, systemId, url, cb);
  };

  /**
   * list all of the available containers in a system
   */
  var listContainers = function(identifier, cb) {
    logger.info('list containers: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getHead(systemId, function(err, json) {
      if (err) { return cb(err); }
      cb(err, json.containerDefinitions);
    });
  };

  /**
   * add a new container to the system
   */
  var addContainer = function(user, identifier, container, cb) {
    logger.info('add container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var cont = JSON.parse(container);
    _sr.addContainer(user, systemId, cont, cb);
  };

  /**
   * update the container
   */
  var putContainer = function(user, identifier, container, cb) {
    logger.info('put container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var cont = JSON.parse(container);
    _sr.putContainer(user, systemId, cont, cb);
  };

  /**
   * delete the container
   */
  var deleteContainer = function(user, identifier, containerIdentifier, cb) {
    logger.info('delete container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.deleteContainer(user, systemId, containerIdentifier, cb);
  };

  /**
   * build a container
   */
  var buildContainer = function(user, identifier, containerIdentifier, out, cb) {
    var doBuild = function(json, containerDef, out, cb) {
      out.progress('--> initiating container build');
      _builder.build('live', json, containerDef, out, function(err, specific) {
        if (err) { out.stdout(err); logger.error(err); return cb(err); }
        out.progress('updating timeline');
        _sr.writeTimeline(user, systemId, 'build', 'built container: ' + containerDef.id);
        _sr.commitRevision(user, systemId, 'built container: ' + containerDef.id, json, function(err) {
          out.progress('comitting revision');
          return cb(err);
        });
      });
    };

    logger.info({
      identifier: identifier,
      container: containerIdentifier
    }, 'container build requested');

    var systemId = _sr.findSystem(identifier);
    var systemRoot = _sr.repoPath(systemId);

    out.initProgress(9, '--> finding container');

    if (!systemId) { out.stdout(ERR_NOSYSID); logger.error(ERR_NOSYSID); return cb(ERR_NOSYSID); }

    _sr.findContainer(systemId, containerIdentifier, function(err, containerDefId) {
      if (err) { out.stdout(err); logger.error(err); return cb(err); }
      if (!containerDefId) { out.stdout(ERR_NOCDEF); logger.error(ERR_NOCDEF); return cb(ERR_NOCDEF); }
      _sr.getHead(systemId, function(err, json) {
        if (err) { out.stderr(err); logger.error(err); return cb(err); }
        var root = _sys(options);

        root.load(json);
        var containerDef = root.containerDefByDefId(containerDefId);

        // fix needed to pass through the system root
        // and build the docker containers from the folder.
        json.repoPath = systemRoot;

        if (!containerDef.specific.repositoryUrl) {
          return doBuild(json, containerDef, out, cb);
        }

        _synchrotron.synch(json, containerDef, out, function(err) {
          if (err) { out.stdout(err); logger.error(err); return cb(err); }
          doBuild(json, containerDef, out, cb);
        });
      });
    });
  };

  /**
   * build all containers belong to a system, in series
   */
  var buildAllContainers = function(user, systemName, out, cb) {
    logger.info('building all containers for ' + systemName);
    out.stdout('--> building all containers for ' + systemName + '...');

    var systemId = _sr.findSystem(systemName);
    _sr.getHead(systemId, function(err, json) {
      if (err) { return cb(err); }

      async.eachSeries(json.containerDefinitions, function (container, next) {
        buildContainer(user, systemId, container.name, out, function(err) {
          if (err) { out.stderr(err); }
          next();
        });
      }, cb);
    });
  };

  /**
   * deploy the current or specified revision
   */
  var deployRevision = function(user, identifier, revisionIdentifier, mode, out, cb) {
    logger.info('deploy revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);

    if (!systemId) { out.stdout(ERR_NOSYSID); logger.error(ERR_NOSYSID); return cb(ERR_NOSYSID); }
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      if (err) { out.stdout(ERR_NOREV); logger.error(ERR_NOREV); return cb(ERR_NOREV); }

      if (!mode) { mode = 'live'; }
      if (!revisionId) {
        _sr.getHeadRevisionId(systemId, function(err, headId) {
          _sr.getHeadRevision(systemId, function(err, head) {
            analyzeSystem(user, identifier, out, function(err, analyzed) {
              if (err) { return cb(err); }

              var systemRoot = _sr.repoPath(systemId);
              analyzed.rootPath = systemRoot;
              head.rootPath = systemRoot;

              _deployer.deploy(user, systemId, headId, analyzed, head, _sr, mode, out, function(err, result) {
                cb(err, result);
              });
            });
          });
        });
      }
      else {
        _sr.getRevision(systemId, revisionId, function(err, target) {
          analyzeSystem(user, identifier, out, function(err, analyzed) {
            if (err) { return cb(err); }
            _deployer.deploy(user, systemId, revisionId, analyzed, target, _sr, mode, out, function(err, result) {
              cb(err, result);
            });
          });
        });
      }
    });
  };

  /**
   * preview a system deploy
   */
  var previewRevision = function(user, identifier, revisionIdentifier, out, cb) {
    logger.info('preview revision: ' + identifier + ', ' + revisionIdentifier);
    deployRevision(user, identifier, revisionIdentifier, 'preview', out, function(err) {
      cb(err, {plan: out.getPlan(), ops: out.operations()});
    });
  };

  /**
   * get the revision history for a system
   */
  var listRevisions = function(identifier, cb) {
    logger.info('list revisions: ' + identifier);
    if (!identifier) {
      return cb(new Error('no identifier'));
    }
    var systemId = _sr.findSystem(identifier);

    if (!systemId) {
      return cb(new Error('system not found'));
    }

    _sr.listRevisions(systemId, function(err, revisions) {
      cb(err, revisions);
    });
  };

  /**
   * get a specific revision
   */
  var getRevision = function(identifier, revisionIdentifier, cb) {
    logger.info('get revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      _sr.getRevision(systemId, revisionId, cb);
    });
  };

  var markRevision = function(user, identifier, revisionIdentifier, cb) {
    logger.info('mark revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      _sr.markDeployedRevisionNoCommit(user, systemId, revisionId, cb);
    });
  };

  /**
   * get timeline
   */
  // TODO: update this to read git commit log
  var timeline = function(identifier, cb) {
    var systemId = _sr.findSystem(identifier);
    _sr.getTimeline(systemId, function(err, timeline) {
      cb(err, timeline);
    });
  };

  var getDeployedOrHeadSystem = function(systemId, cb) {
    getDeployedSystem(systemId, function(err, system) {
      if (!system) {
        getHeadSystem(systemId, function(err, head) {
          cb(err, head);
        });
      }
      else {
        cb(err, system);
      }
    });
  };

  var analyzeSystem = function(user, identifier, out, cb) {
    logger.info({ system: identifier }, 'analyze system');
    var systemId = _sr.findSystem(identifier);

    getDeployedOrHeadSystem(systemId, function(err, system) {
      logger.info('running analysis against deployed system');
      _analyzer.analyze(options.modules.analysis.specific, system, function(err, result) {
        logger.info('analysis complete');
        if (err) {
          logger.error(err)
        }
        cb(err, result, system);
      });
    });
  };

  var getDeployedOrHeadRevisionId = function(systemId, cb) {
    _sr.getDeployedRevisionId(systemId, function(err, revId) {
      if (!revId) {
        _sr.getHeadRevisionId(systemId, function(err, headId) {
          cb(err, headId);
        });
      }
      else {
        cb(err, revId);
      }
    });
  };

  var checkSystem = function(user, identifier, out, cb) {
    logger.info('check system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    analyzeSystem(systemId, function(err, analyzed, system) {
      if (err) { return cb(err); }
      getDeployedOrHeadRevisionId(systemId, function(err, deployedId) {
        _deployer.deploy(user, systemId, deployedId, analyzed, system, _sr, 'preview', out, function(err/*, result*/) {
          cb(err, {plan: out.getPlan(), ops: out.operations()});
        });
      });
    });
  };

  var fixSystem = function(user, identifier, out, cb) {
    logger.info('fix system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    analyzeSystem(systemId, function(err, analyzed, system) {
      if (err) { return cb(err); }
      getDeployedOrHeadRevisionId(systemId, function(err, deployedId) {
        _deployer.deploy(user, systemId, deployedId, analyzed, system, _sr, 'live', out, function(err, result) {
          cb(err, result);
        });
      });
    });
  };

  var compileSystem = function(user, identifier, platform, out, cb) {
    logger.info('compile system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var repoPath = _sr.repoPath(systemId);

    if (!platform || platform === 'undefined') { return cb('missing required parameter: platform'); }
    getHeadSystem(systemId, function(err, head) {
      _compiler.compile(head, repoPath, platform, out, function(err, system) {
        if (err) { return cb(err); }
        _sr.commitRevision(user, system.id, 'system compile', system, function(err, revisionId) {
          if (err) { return cb(err); }
          cb(null, revisionId);
        });
      });
    });
  };

  var construct = function() {
    _sys = require('./container');
    _synchrotron = require('./synchrotron')(options);
    _builder = require('./builder')(options, _containers);
    _deployer = require('./deployer')(options, _containers);
    _compiler = require('./compiler')(logger);
  };

  construct();
  return {
    listSystems: listSystems,
    createSystem: createSystem,
    getHeadSystem: getHeadSystem,
    getDeployedSystem: getDeployedSystem,
    putSystem: putSystem,
    //deleteSystem: deleteSystem,
    cloneSystem: cloneSystem,
    linkSystem: linkSystem,
    syncSystem: syncSystem,
    addRemote: addRemote,
    fixSystem: fixSystem,
    compileSystem: compileSystem,

    listContainers: listContainers,
    buildContainer: buildContainer,
    buildAllContainers: buildAllContainers,
    addContainer: addContainer,
    putContainer: putContainer,
    deleteContainer: deleteContainer,
    deployRevision: deployRevision,
    previewRevision : previewRevision,

    listRevisions: listRevisions,
    getRevision: getRevision,
    markRevision: markRevision,

    timeline: timeline,

    analyzeSystem: analyzeSystem,
    checkSystem: checkSystem
  };
};

<commit_msg>recent change appears to have broken analyze api, now fixed<commit_after>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var async = require('async');

module.exports = function(options, _sr, _analyzer, _containers) {
  var ERR_NOCDEF = 'unable to find container definition';
  var ERR_NOSYSID = 'unable to find system';
  var ERR_NOREV = 'unable to find revision';

  var _sys;
  var _builder;
  var _deployer;
  var _compiler;
  var _synchrotron;
  var logger = options.logger;

  /**
   * list all of the available systems
   */
  var listSystems = function(cb) {
    logger.info('list systems');
    var systems = _sr.listSystems();
    cb(null, systems);
  };

  /**
   * get the full head system definition (latest revision)
   */
  var getHeadSystem = function(identifier, cb) {
    logger.info('get head system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getHead(systemId, cb);
  };

  /**
   * get the full deployed system definition
   */
  var getDeployedSystem = function(identifier, cb) {
    logger.info('get deployed system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getDeployedRevision(systemId, cb);
  };

  /**
   * create a new  blank system
   */
  var createSystem = function(user, name, namespace, cwd, cb) {
    logger.info('create system name: ' + name + ', namespace: ' + namespace + ', cwd: ' + cwd);
    _sr.createSystem(user, namespace, name, cwd, cb);
  };

  /**
   * put the system definition, if the system doesn't exist it will be created
   */
  var putSystem = function(user, system, cb) {
    var doc = JSON.parse(system);
    logger.info('put system: ' + system.name);

    if (!_sr.systemExists(doc.namespace, doc.name)) {
      _sr.createSystem(user, doc.namespace, doc.name, function(err, repoId) {
        if (err) { return cb(err); }
        doc.id = repoId;
        _sr.commitRevision(user, doc.id, 'no comment', doc, function(err, revisionId) {
          _sr.markDeployedRevision(user, doc.id, revisionId, cb);
        });
      });
    }
    else {
      _sr.commitRevision(user, doc.id, 'no comment', doc, cb);
    }
  };

  /**
   * clone a system from github
   */
  var cloneSystem = function(user, url, cwd, cb) {
    logger.info('clone system: ' + url + ', ' + cwd);
    _sr.cloneSystem(user, url, cwd, cb);
  };

  /**
   * link a system from local fs
   */
  var linkSystem = function(user, path, cwd, cb) {
    logger.info('link system: ' + path + ', ' + cwd);
    _sr.linkSystem(user, path, cwd, cb);
  };

  /**
   * pull/push system and sync with remote
   */
  var syncSystem = function(user, identifier, cb) {
    logger.info('sync system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.syncSystem(user, systemId, cb);
  };

  /**
   * add a remote url to the system repository
   */
  var addRemote = function(user, identifier, url, cb) {
    logger.info('add remote: ' + identifier + ', ' + url);
    var systemId = _sr.findSystem(identifier);
    _sr.addRemote(user, systemId, url, cb);
  };

  /**
   * list all of the available containers in a system
   */
  var listContainers = function(identifier, cb) {
    logger.info('list containers: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.getHead(systemId, function(err, json) {
      if (err) { return cb(err); }
      cb(err, json.containerDefinitions);
    });
  };

  /**
   * add a new container to the system
   */
  var addContainer = function(user, identifier, container, cb) {
    logger.info('add container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var cont = JSON.parse(container);
    _sr.addContainer(user, systemId, cont, cb);
  };

  /**
   * update the container
   */
  var putContainer = function(user, identifier, container, cb) {
    logger.info('put container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var cont = JSON.parse(container);
    _sr.putContainer(user, systemId, cont, cb);
  };

  /**
   * delete the container
   */
  var deleteContainer = function(user, identifier, containerIdentifier, cb) {
    logger.info('delete container: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    _sr.deleteContainer(user, systemId, containerIdentifier, cb);
  };

  /**
   * build a container
   */
  var buildContainer = function(user, identifier, containerIdentifier, out, cb) {
    var doBuild = function(json, containerDef, out, cb) {
      out.progress('--> initiating container build');
      _builder.build('live', json, containerDef, out, function(err, specific) {
        if (err) { out.stdout(err); logger.error(err); return cb(err); }
        out.progress('updating timeline');
        _sr.writeTimeline(user, systemId, 'build', 'built container: ' + containerDef.id);
        _sr.commitRevision(user, systemId, 'built container: ' + containerDef.id, json, function(err) {
          out.progress('comitting revision');
          return cb(err);
        });
      });
    };

    logger.info({
      identifier: identifier,
      container: containerIdentifier
    }, 'container build requested');

    var systemId = _sr.findSystem(identifier);
    var systemRoot = _sr.repoPath(systemId);

    out.initProgress(9, '--> finding container');

    if (!systemId) { out.stdout(ERR_NOSYSID); logger.error(ERR_NOSYSID); return cb(ERR_NOSYSID); }

    _sr.findContainer(systemId, containerIdentifier, function(err, containerDefId) {
      if (err) { out.stdout(err); logger.error(err); return cb(err); }
      if (!containerDefId) { out.stdout(ERR_NOCDEF); logger.error(ERR_NOCDEF); return cb(ERR_NOCDEF); }
      _sr.getHead(systemId, function(err, json) {
        if (err) { out.stderr(err); logger.error(err); return cb(err); }
        var root = _sys(options);

        root.load(json);
        var containerDef = root.containerDefByDefId(containerDefId);

        // fix needed to pass through the system root
        // and build the docker containers from the folder.
        json.repoPath = systemRoot;

        if (!containerDef.specific.repositoryUrl) {
          return doBuild(json, containerDef, out, cb);
        }

        _synchrotron.synch(json, containerDef, out, function(err) {
          if (err) { out.stdout(err); logger.error(err); return cb(err); }
          doBuild(json, containerDef, out, cb);
        });
      });
    });
  };

  /**
   * build all containers belong to a system, in series
   */
  var buildAllContainers = function(user, systemName, out, cb) {
    logger.info('building all containers for ' + systemName);
    out.stdout('--> building all containers for ' + systemName + '...');

    var systemId = _sr.findSystem(systemName);
    _sr.getHead(systemId, function(err, json) {
      if (err) { return cb(err); }

      async.eachSeries(json.containerDefinitions, function (container, next) {
        buildContainer(user, systemId, container.name, out, function(err) {
          if (err) { out.stderr(err); }
          next();
        });
      }, cb);
    });
  };

  /**
   * deploy the current or specified revision
   */
  var deployRevision = function(user, identifier, revisionIdentifier, mode, out, cb) {
    logger.info('deploy revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);

    if (!systemId) { out.stdout(ERR_NOSYSID); logger.error(ERR_NOSYSID); return cb(ERR_NOSYSID); }
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      if (err) { out.stdout(ERR_NOREV); logger.error(ERR_NOREV); return cb(ERR_NOREV); }

      if (!mode) { mode = 'live'; }
      if (!revisionId) {
        _sr.getHeadRevisionId(systemId, function(err, headId) {
          _sr.getHeadRevision(systemId, function(err, head) {
            analyzeSystem(user, identifier, out, function(err, analyzed) {
              if (err) { return cb(err); }

              var systemRoot = _sr.repoPath(systemId);
              analyzed.rootPath = systemRoot;
              head.rootPath = systemRoot;

              _deployer.deploy(user, systemId, headId, analyzed, head, _sr, mode, out, function(err, result) {
                cb(err, result);
              });
            });
          });
        });
      }
      else {
        _sr.getRevision(systemId, revisionId, function(err, target) {
          analyzeSystem(user, identifier, out, function(err, analyzed) {
            if (err) { return cb(err); }
            _deployer.deploy(user, systemId, revisionId, analyzed, target, _sr, mode, out, function(err, result) {
              cb(err, result);
            });
          });
        });
      }
    });
  };

  /**
   * preview a system deploy
   */
  var previewRevision = function(user, identifier, revisionIdentifier, out, cb) {
    logger.info('preview revision: ' + identifier + ', ' + revisionIdentifier);
    deployRevision(user, identifier, revisionIdentifier, 'preview', out, function(err) {
      cb(err, {plan: out.getPlan(), ops: out.operations()});
    });
  };

  /**
   * get the revision history for a system
   */
  var listRevisions = function(identifier, cb) {
    logger.info('list revisions: ' + identifier);
    if (!identifier) {
      return cb(new Error('no identifier'));
    }
    var systemId = _sr.findSystem(identifier);

    if (!systemId) {
      return cb(new Error('system not found'));
    }

    _sr.listRevisions(systemId, function(err, revisions) {
      cb(err, revisions);
    });
  };

  /**
   * get a specific revision
   */
  var getRevision = function(identifier, revisionIdentifier, cb) {
    logger.info('get revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      _sr.getRevision(systemId, revisionId, cb);
    });
  };

  var markRevision = function(user, identifier, revisionIdentifier, cb) {
    logger.info('mark revision: ' + identifier + ', ' + revisionIdentifier);
    var systemId = _sr.findSystem(identifier);
    _sr.findRevision(systemId, revisionIdentifier, function(err, revisionId) {
      _sr.markDeployedRevisionNoCommit(user, systemId, revisionId, cb);
    });
  };

  /**
   * get timeline
   */
  // TODO: update this to read git commit log
  var timeline = function(identifier, cb) {
    var systemId = _sr.findSystem(identifier);
    _sr.getTimeline(systemId, function(err, timeline) {
      cb(err, timeline);
    });
  };

  var getDeployedOrHeadSystem = function(systemId, cb) {
    getDeployedSystem(systemId, function(err, system) {
      if (!system) {
        getHeadSystem(systemId, function(err, head) {
          cb(err, head);
        });
      }
      else {
        cb(err, system);
      }
    });
  };

  var analyzeSystem = function(user, identifier, out, cb) {
    logger.info({ system: identifier }, 'analyze system');
    var systemId = _sr.findSystem(identifier);

    getDeployedOrHeadSystem(systemId, function(err, system) {
      logger.info('running analysis against deployed system');
      _analyzer.analyze(options.modules.analysis.specific, system, function(err, result) {
        logger.info('analysis complete');
        if (err) {
          logger.error(err);
        }
        cb(err, result, system);
      });
    });
  };

  var getDeployedOrHeadRevisionId = function(systemId, cb) {
    _sr.getDeployedRevisionId(systemId, function(err, revId) {
      if (!revId) {
        _sr.getHeadRevisionId(systemId, function(err, headId) {
          cb(err, headId);
        });
      }
      else {
        cb(err, revId);
      }
    });
  };

  var checkSystem = function(user, identifier, out, cb) {
    logger.info('check system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    analyzeSystem(user, systemId, out, function(err, analyzed, system) {
      if (err) { return cb(err); }
      getDeployedOrHeadRevisionId(systemId, function(err, deployedId) {
        _deployer.deploy(user, systemId, deployedId, analyzed, system, _sr, 'preview', out, function(err/*, result*/) {
          cb(err, {plan: out.getPlan(), ops: out.operations()});
        });
      });
    });
  };

  var fixSystem = function(user, identifier, out, cb) {
    logger.info('fix system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    analyzeSystem(systemId, function(err, analyzed, system) {
      if (err) { return cb(err); }
      getDeployedOrHeadRevisionId(systemId, function(err, deployedId) {
        _deployer.deploy(user, systemId, deployedId, analyzed, system, _sr, 'live', out, function(err, result) {
          cb(err, result);
        });
      });
    });
  };

  var compileSystem = function(user, identifier, platform, out, cb) {
    logger.info('compile system: ' + identifier);
    var systemId = _sr.findSystem(identifier);
    var repoPath = _sr.repoPath(systemId);

    if (!platform || platform === 'undefined') { return cb('missing required parameter: platform'); }
    getHeadSystem(systemId, function(err, head) {
      _compiler.compile(head, repoPath, platform, out, function(err, system) {
        if (err) { return cb(err); }
        _sr.commitRevision(user, system.id, 'system compile', system, function(err, revisionId) {
          if (err) { return cb(err); }
          cb(null, revisionId);
        });
      });
    });
  };

  var construct = function() {
    _sys = require('./container');
    _synchrotron = require('./synchrotron')(options);
    _builder = require('./builder')(options, _containers);
    _deployer = require('./deployer')(options, _containers);
    _compiler = require('./compiler')(logger);
  };

  construct();
  return {
    listSystems: listSystems,
    createSystem: createSystem,
    getHeadSystem: getHeadSystem,
    getDeployedSystem: getDeployedSystem,
    putSystem: putSystem,
    //deleteSystem: deleteSystem,
    cloneSystem: cloneSystem,
    linkSystem: linkSystem,
    syncSystem: syncSystem,
    addRemote: addRemote,
    fixSystem: fixSystem,
    compileSystem: compileSystem,

    listContainers: listContainers,
    buildContainer: buildContainer,
    buildAllContainers: buildAllContainers,
    addContainer: addContainer,
    putContainer: putContainer,
    deleteContainer: deleteContainer,
    deployRevision: deployRevision,
    previewRevision : previewRevision,

    listRevisions: listRevisions,
    getRevision: getRevision,
    markRevision: markRevision,

    timeline: timeline,

    analyzeSystem: analyzeSystem,
    checkSystem: checkSystem
  };
};

<|endoftext|>


<commit_before>'use strict';

const express = require('express');
const https = require('https');

const reposApi = express.Router();
const cache = new Map();

const commonOptions = {
    hostname: 'api.github.com',
    headers: {
        'User-Agent': 'GithubberAPI'
    }
};

/**
 * Gets a list of repositories
 */
reposApi.get('/', (req, res) => {

    let options = commonOptions;
    options.path = '/repositories';

    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            let repositories = [];
            if(typeof payload !== 'array') {
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }
            payload.forEach((repo) => {
                const {id,name} = repo;
                const r = {
                    id,
                    name
                };
                repositories.push(r);
            });

            cache.set(options.path,repositories);
            res.end(JSON.stringify(repositories));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

/**
 * Gets detail of a particular
 */
reposApi.get('/:id', (req, res) => {

    let options = commonOptions;
    options.path = '/repositories/'+req.params.id;

    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            if(!!payload.message)
                return res.end(payload.message);

            const {id, name, owner, description, pushed_at, created_at, updated_at} = payload;
            const repo = {
                id, name, description, pushed_at, created_at, updated_at,
                user: {
                    id: owner.id,
                    login: owner.login
                }
            }

            cache.set(options.path,repo);
            res.end(JSON.stringify(repo));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

/**
 * Searches into repository directory
 */
reposApi.get('/search/:query', (req, res) => {

    let options = commonOptions;
    options.path = '/search/repositories?q='+req.params.query;
    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            if(payload.total_count===0)
                return res.end('No results');

            let repositories = [];
            payload.items.forEach((repo) => {
                const {id,name,description} = repo;
                const r = {
                    id,
                    name,
                    description
                };
                repositories.push(r);
            });

            cache.set(options.path,repositories);
            res.end(JSON.stringify(repositories));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

module.exports = reposApi;<commit_msg>fixed array check<commit_after>'use strict';

const express = require('express');
const https = require('https');

const reposApi = express.Router();
const cache = new Map();

const commonOptions = {
    hostname: 'api.github.com',
    headers: {
        'User-Agent': 'GithubberAPI'
    }
};

/**
 * Gets a list of repositories
 */
reposApi.get('/', (req, res) => {

    let options = commonOptions;
    options.path = '/repositories';

    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            let repositories = [];
            if(!(payload instanceof Array)) {
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }
            payload.forEach((repo) => {
                const {id,name} = repo;
                const r = {
                    id,
                    name
                };
                repositories.push(r);
            });

            cache.set(options.path,repositories);
            res.end(JSON.stringify(repositories));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

/**
 * Gets detail of a particular
 */
reposApi.get('/:id', (req, res) => {

    let options = commonOptions;
    options.path = '/repositories/'+req.params.id;

    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            if(!!payload.message)
                return res.end(payload.message);

            const {id, name, owner, description, pushed_at, created_at, updated_at} = payload;
            const repo = {
                id, name, description, pushed_at, created_at, updated_at,
                user: {
                    id: owner.id,
                    login: owner.login
                }
            }

            cache.set(options.path,repo);
            res.end(JSON.stringify(repo));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

/**
 * Searches into repository directory
 */
reposApi.get('/search/:query', (req, res) => {

    let options = commonOptions;
    options.path = '/search/repositories?q='+req.params.query;
    https.get(options, (gitHubRes) => {

        let payload = '';

        gitHubRes.on('data', (d) => {
            payload+=d;
        });

        gitHubRes.on('end', () => {
            try {
                payload = JSON.parse(payload);
            }catch(e){
                console.log(e);
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            if(payload.total_count===0)
                return res.end('No results');

            let repositories = [];

            if(!(payload.items instanceof Array)) {
                return res.end(JSON.stringify(cache.get(options.path) || []));
            }

            payload.items.forEach((repo) => {
                const {id,name,description} = repo;
                const r = {
                    id,
                    name,
                    description
                };
                repositories.push(r);
            });

            cache.set(options.path,repositories);
            res.end(JSON.stringify(repositories));
        });

    }).on('error', (e) => {
        console.log(`Got error: ${e.message}`);
        res.end(JSON.stringify(cache.get(options.path) || []));
    });
});

module.exports = reposApi;<|endoftext|>


<commit_before>import React from 'react';
import { mount, shallow } from 'enzyme';
import Select from './select.component';
import guid from '../../../utils/helpers/guid';
import Events from '../../../utils/helpers/events';

jest.mock('../../../utils/helpers/guid');
guid.mockImplementation(() => 'guid-12345');

describe('Select', () => {
  const renderWrapper = ({ props, type = mount } = {}) => (
    type(
      <Select { ...props }>

1

2

3

      </Select>
    )
  );

  // an example of a single value
  const singleValue = {
    value: '1',
    text: 'Orange'
  };

  // an example of a multi value
  const multiValue = [{
    value: '1',
    text: 'Orange'
  }, {
    value: '2',
    text: 'Blue'
  }, {
    value: '3',
    text: 'Red'
  }];

  // utility functions to fetch various elements from the wrapper
  const listOf = wrapper => wrapper.find('SelectList');
  const textboxOf = wrapper => wrapper.find('InputDecoratorBridge');
  const pillsOf = wrapper => wrapper.find('Pill');

  // open the list for the select component and returns the wrapper
  const openList = (wrapper) => {
    wrapper.find('input').simulate('focus');
    return wrapper;
  };

  /**
   * Begin tests
   */

  it('renders only the InputDecoratorBridge when closed', () => {
    expect(renderWrapper({ type: shallow })).toMatchSnapshot();
  });

  it('renders the SelectList with any given children when in an open state', () => {
    const wrapper = renderWrapper();

    let list = listOf(wrapper);
    expect(list.exists()).toBe(false);

    list = listOf(openList(wrapper));
    expect(list.exists()).toBe(true);
    expect(list.props()).toMatchSnapshot();
  });

  it('does not apply any events if disabled or readonly', () => {
    [{ disabled: true }, { readOnly: true }].forEach((state) => {
      expect(renderWrapper({ state, type: shallow })).toMatchSnapshot();
    });
  });

  describe('when multi-value', () => {
    it(`renders the the textbox with the following:
        * formattedValue is empty
        * value contains the array of values
        * leftChildren contains the pills
        * inputIcon is disabled
        * placeholder is disabled`, () => {
      const props = { value: multiValue, placeholder: 'placeholder' };
      const textbox = textboxOf(renderWrapper({ props }));
      expect(textbox.props().formattedValue).toEqual('');
      expect(textbox.props().value).toEqual(multiValue);
      expect(textbox.props().leftChildren).toMatchSnapshot();
      expect(textbox.props().inputIcon).toEqual(undefined);
      expect(textbox.props().placeholder).toEqual(null);
    });

    it('triggers onChange with the item added when choosing an item', () => {
      const props = { value: multiValue, onChange: jest.fn() };
      const list = listOf(openList(renderWrapper({ props })));
      const newValue = { value: 'new!' };
      list.props().onSelect(newValue);
      expect(props.onChange).toHaveBeenCalledWith({
        target: { value: [...multiValue, newValue] }
      });
    });

    it('triggers onChange with the item removed when clicking delete on the pill', () => {
      const props = { value: multiValue, onChange: jest.fn() };
      const pill = pillsOf(renderWrapper({ props })).at(1);
      pill.props().onDelete();
      expect(props.onChange).toHaveBeenCalledWith({
        // we deleted the item at index 1
        target: { value: [multiValue[0], multiValue[2]] }
      });
    });

    describe('when backspace is pressed', () => {
      const setupTest = (additionalSetup) => {
        spyOn(Events, 'isBackspaceKey').and.returnValue(true);
        const props = { value: multiValue, onChange: jest.fn() };
        const wrapper = renderWrapper({ props });
        const textbox = textboxOf(openList(wrapper));
        if (additionalSetup) additionalSetup(wrapper);
        textbox.find('input').simulate('keydown');
        return { props, wrapper };
      };

      it('triggers onChange with the item removed when typing backspace in the filter', () => {
        const { props } = setupTest();
        expect(props.onChange).toHaveBeenCalledWith({
          target: { value: [multiValue[0], multiValue[1]] }
        });
      });

      it('does not trigger onChange if there is a filter in effect', () => {
        const { props } = setupTest(wrapper => wrapper.setState({ filter: 'x' }));
        expect(props.onChange).not.toHaveBeenCalled();
      });

      it('does not trigger onChange if there is no values left to delete', () => {
        const { props } = setupTest(wrapper => wrapper.setProps({ value: [] }));
        expect(props.onChange).not.toHaveBeenCalled();
      });
    });

    it('does not render onDelete action when disabled or readonly', () => {
      [{ disabled: true }, { readOnly: true }].forEach((state) => {
        const props = { value: multiValue, ...state };
        const pill = pillsOf(renderWrapper({ props })).first();
        expect(pill.props().onDelete).toEqual(null);
      });
    });
  });

  describe('when single value', () => {
    it(`renders the the textbox with the following:
        * formattedValue is the text of the object
        * value is the value of the object
        * leftChildren is empty
        * inputIcon is dropdown
        * placeholder is the value given as a prop`, () => {
      const props = { value: singleValue, placeholder: 'placeholder' };
      const textbox = textboxOf(renderWrapper({ props }));
      expect(textbox.props().formattedValue).toEqual(singleValue.text);
      expect(textbox.props().value).toEqual(singleValue.value);
      expect(textbox.props().leftChildren).toBeFalsy();
      expect(textbox.props().inputIcon).toEqual('dropdown');
      expect(textbox.props().placeholder).toEqual('placeholder');
    });

    it('triggers onChange with the new item when choosing an item', () => {
      const props = { value: singleValue, onChange: jest.fn() };
      const list = listOf(openList(renderWrapper({ props })));
      const newValue = { value: 'new!' };
      list.props().onSelect(newValue);
      expect(props.onChange).toHaveBeenCalledWith({
        target: { value: newValue }
      });
    });

    it('does not throw an error on change if no callback is provided', () => {
      const props = { value: singleValue };
      const list = listOf(openList(renderWrapper({ props })));
      expect(() => list.props().onSelect({ value: 'new!' })).not.toThrowError();
    });
  });

  describe('blur / focus events', () => {
    it('blocks blur on mouse enter of the list and unblocks on leaving the list', () => {
      const wrapper = openList(renderWrapper());
      const list = listOf(wrapper);
      expect(wrapper.instance().blurBlocked).toEqual(false);
      list.find('div').first().simulate('mouseEnter');
      expect(wrapper.instance().blurBlocked).toEqual(true);
      list.find('div').first().simulate('mouseLeave');
      expect(wrapper.instance().blurBlocked).toEqual(false);
    });

    describe('onBlur', () => {
      const setupTest = (blocked) => {
        const wrapper = openList(renderWrapper());
        wrapper.instance().blurBlocked = blocked;
        wrapper.setState({ open: true, filter: 'x' });
        expect(wrapper.state().open).toEqual(true);
        expect(wrapper.state().filter).toEqual('x');
        textboxOf(wrapper).find('input').simulate('blur');
        return wrapper;
      };

      it('resets the state on blur on the input', () => {
        const wrapper = setupTest(false);
        expect(wrapper.state().open).toEqual(false);
        expect(wrapper.state().filter).toEqual(undefined);
      });

      it('does not reset the state if blur is blocked', () => {
        const wrapper = setupTest(true);
        expect(wrapper.state().open).toEqual(true);
        expect(wrapper.state().filter).toEqual('x');
      });
    });
  });

  describe('key events', () => {
    it('unblocks blur on tab', () => {
      spyOn(Events, 'isTabKey').and.returnValue(true);
      const wrapper = renderWrapper();
      wrapper.instance().blurBlocked = true;
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(wrapper.instance().blurBlocked).toEqual(false);
    });

    it('opens the list on any key if it is closed (but not if it is already open)', () => {
      const wrapper = renderWrapper();
      expect(listOf(wrapper).exists()).toEqual(false);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(true);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(true);
    });

    it('closes the list on esc', () => {
      spyOn(Events, 'isEscKey').and.returnValue(true);
      const wrapper = openList(renderWrapper());
      expect(listOf(wrapper).exists()).toEqual(true);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(false);
    });
  });

  describe('filter', () => {
    it('updates the filter value when the textbox value is updated', () => {
      const wrapper = openList(renderWrapper());
      expect(listOf(wrapper).props().filterValue).toEqual(undefined);
      textboxOf(wrapper).find('input').simulate('change', { target: { value: 'x' } });
      expect(listOf(wrapper).props().filterValue).toEqual('x');
    });

    it('triggers custom onFilter event if one if passed', () => {
      const props = { onFilter: jest.fn() };
      const wrapper = renderWrapper({ props });
      textboxOf(wrapper).find('input').simulate('change', { target: { value: 'x' } });
      expect(props.onFilter).toHaveBeenCalledWith('x');
    });
  });
});
<commit_msg>fixed typo in select spec<commit_after>import React from 'react';
import { mount, shallow } from 'enzyme';
import Select from './select.component';
import guid from '../../../utils/helpers/guid';
import Events from '../../../utils/helpers/events';

jest.mock('../../../utils/helpers/guid');
guid.mockImplementation(() => 'guid-12345');

describe('Select', () => {
  const renderWrapper = ({ props, type = mount } = {}) => (
    type(
      <Select { ...props }>

1

2

3

      </Select>
    )
  );

  // an example of a single value
  const singleValue = {
    value: '1',
    text: 'Orange'
  };

  // an example of a multi value
  const multiValue = [{
    value: '1',
    text: 'Orange'
  }, {
    value: '2',
    text: 'Blue'
  }, {
    value: '3',
    text: 'Red'
  }];

  // utility functions to fetch various elements from the wrapper
  const listOf = wrapper => wrapper.find('SelectList');
  const textboxOf = wrapper => wrapper.find('InputDecoratorBridge');
  const pillsOf = wrapper => wrapper.find('Pill');

  // open the list for the select component and returns the wrapper
  const openList = (wrapper) => {
    wrapper.find('input').simulate('focus');
    return wrapper;
  };

  /**
   * Begin tests
   */

  it('renders only the InputDecoratorBridge when closed', () => {
    expect(renderWrapper({ type: shallow })).toMatchSnapshot();
  });

  it('renders the SelectList with any given children when in an open state', () => {
    const wrapper = renderWrapper();

    let list = listOf(wrapper);
    expect(list.exists()).toBe(false);

    list = listOf(openList(wrapper));
    expect(list.exists()).toBe(true);
    expect(list.props()).toMatchSnapshot();
  });

  it('does not apply any events if disabled or readonly', () => {
    [{ disabled: true }, { readOnly: true }].forEach((state) => {
      expect(renderWrapper({ state, type: shallow })).toMatchSnapshot();
    });
  });

  describe('when multi-value', () => {
    it(`renders the the textbox with the following:
        * formattedValue is empty
        * value contains the array of values
        * leftChildren contains the pills
        * inputIcon is disabled
        * placeholder is disabled`, () => {
      const props = { value: multiValue, placeholder: 'placeholder' };
      const textbox = textboxOf(renderWrapper({ props }));
      expect(textbox.props().formattedValue).toEqual('');
      expect(textbox.props().value).toEqual(multiValue);
      expect(textbox.props().leftChildren).toMatchSnapshot();
      expect(textbox.props().inputIcon).toEqual(undefined);
      expect(textbox.props().placeholder).toEqual(null);
    });

    it('triggers onChange with the item added when choosing an item', () => {
      const props = { value: multiValue, onChange: jest.fn() };
      const list = listOf(openList(renderWrapper({ props })));
      const newValue = { value: 'new!' };
      list.props().onSelect(newValue);
      expect(props.onChange).toHaveBeenCalledWith({
        target: { value: [...multiValue, newValue] }
      });
    });

    it('triggers onChange with the item removed when clicking delete on the pill', () => {
      const props = { value: multiValue, onChange: jest.fn() };
      const pill = pillsOf(renderWrapper({ props })).at(1);
      pill.props().onDelete();
      expect(props.onChange).toHaveBeenCalledWith({
        // we deleted the item at index 1
        target: { value: [multiValue[0], multiValue[2]] }
      });
    });

    describe('when backspace is pressed', () => {
      const setupTest = (additionalSetup) => {
        spyOn(Events, 'isBackspaceKey').and.returnValue(true);
        const props = { value: multiValue, onChange: jest.fn() };
        const wrapper = renderWrapper({ props });
        const textbox = textboxOf(openList(wrapper));
        if (additionalSetup) additionalSetup(wrapper);
        textbox.find('input').simulate('keydown');
        return { props, wrapper };
      };

      it('triggers onChange with the item removed when typing backspace in the filter', () => {
        const { props } = setupTest();
        expect(props.onChange).toHaveBeenCalledWith({
          target: { value: [multiValue[0], multiValue[1]] }
        });
      });

      it('does not trigger onChange if there is a filter in effect', () => {
        const { props } = setupTest(wrapper => wrapper.setState({ filter: 'x' }));
        expect(props.onChange).not.toHaveBeenCalled();
      });

      it('does not trigger onChange if there is no values left to delete', () => {
        const { props } = setupTest(wrapper => wrapper.setProps({ value: [] }));
        expect(props.onChange).not.toHaveBeenCalled();
      });
    });

    it('does not render onDelete action when disabled or readonly', () => {
      [{ disabled: true }, { readOnly: true }].forEach((state) => {
        const props = { value: multiValue, ...state };
        const pill = pillsOf(renderWrapper({ props })).first();
        expect(pill.props().onDelete).toEqual(null);
      });
    });
  });

  describe('when single value', () => {
    it(`renders the the textbox with the following:
        * formattedValue is the text of the object
        * value is the value of the object
        * leftChildren is empty
        * inputIcon is dropdown
        * placeholder is the value given as a prop`, () => {
      const props = { value: singleValue, placeholder: 'placeholder' };
      const textbox = textboxOf(renderWrapper({ props }));
      expect(textbox.props().formattedValue).toEqual(singleValue.text);
      expect(textbox.props().value).toEqual(singleValue.value);
      expect(textbox.props().leftChildren).toBeFalsy();
      expect(textbox.props().inputIcon).toEqual('dropdown');
      expect(textbox.props().placeholder).toEqual('placeholder');
    });

    it('triggers onChange with the new item when choosing an item', () => {
      const props = { value: singleValue, onChange: jest.fn() };
      const list = listOf(openList(renderWrapper({ props })));
      const newValue = { value: 'new!' };
      list.props().onSelect(newValue);
      expect(props.onChange).toHaveBeenCalledWith({
        target: { value: newValue }
      });
    });

    it('does not throw an error on change if no callback is provided', () => {
      const props = { value: singleValue };
      const list = listOf(openList(renderWrapper({ props })));
      expect(() => list.props().onSelect({ value: 'new!' })).not.toThrowError();
    });
  });

  describe('blur / focus events', () => {
    it('blocks blur on mouse enter of the list and unblocks on leaving the list', () => {
      const wrapper = openList(renderWrapper());
      const list = listOf(wrapper);
      expect(wrapper.instance().blurBlocked).toEqual(false);
      list.find('div').first().simulate('mouseEnter');
      expect(wrapper.instance().blurBlocked).toEqual(true);
      list.find('div').first().simulate('mouseLeave');
      expect(wrapper.instance().blurBlocked).toEqual(false);
    });

    describe('onBlur', () => {
      const setupTest = (blocked) => {
        const wrapper = openList(renderWrapper());
        wrapper.instance().blurBlocked = blocked;
        wrapper.setState({ open: true, filter: 'x' });
        expect(wrapper.state().open).toEqual(true);
        expect(wrapper.state().filter).toEqual('x');
        textboxOf(wrapper).find('input').simulate('blur');
        return wrapper;
      };

      it('resets the state on blur on the input', () => {
        const wrapper = setupTest(false);
        expect(wrapper.state().open).toEqual(false);
        expect(wrapper.state().filter).toEqual(undefined);
      });

      it('does not reset the state if blur is blocked', () => {
        const wrapper = setupTest(true);
        expect(wrapper.state().open).toEqual(true);
        expect(wrapper.state().filter).toEqual('x');
      });
    });
  });

  describe('key events', () => {
    it('unblocks blur on tab', () => {
      spyOn(Events, 'isTabKey').and.returnValue(true);
      const wrapper = renderWrapper();
      wrapper.instance().blurBlocked = true;
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(wrapper.instance().blurBlocked).toEqual(false);
    });

    it('opens the list on any key if it is closed (but not if it is already open)', () => {
      const wrapper = renderWrapper();
      expect(listOf(wrapper).exists()).toEqual(false);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(true);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(true);
    });

    it('closes the list on esc', () => {
      spyOn(Events, 'isEscKey').and.returnValue(true);
      const wrapper = openList(renderWrapper());
      expect(listOf(wrapper).exists()).toEqual(true);
      textboxOf(wrapper).find('input').simulate('keydown');
      expect(listOf(wrapper).exists()).toEqual(false);
    });
  });

  describe('filter', () => {
    it('updates the filter value when the textbox value is updated', () => {
      const wrapper = openList(renderWrapper());
      expect(listOf(wrapper).props().filterValue).toEqual(undefined);
      textboxOf(wrapper).find('input').simulate('change', { target: { value: 'x' } });
      expect(listOf(wrapper).props().filterValue).toEqual('x');
    });

    it('triggers custom onFilter event if one is passed', () => {
      const props = { onFilter: jest.fn() };
      const wrapper = renderWrapper({ props });
      textboxOf(wrapper).find('input').simulate('change', { target: { value: 'x' } });
      expect(props.onFilter).toHaveBeenCalledWith('x');
    });
  });
});
<|endoftext|>


<commit_before>const fs = require(`fs`)

exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions

  // Type definitions can be provided in SDL
  const typeDefs = `
    type AuthorJson implements Node {
      name: String!
      firstName: String!
      email: String!
      picture: File
    }

    type BlogJson implements Node {
      title: String!
      authors: [AuthorJson]
      text: String
      date: Date
      tags: [String]
      meta: Metadata
    }
  `
  createTypes(typeDefs)

  // Alternatively, you can use type builders to construct types
  createTypes([
    schema.buildObjectType({
      name: `CommentJson`,
      fields: {
        text: `String!`,
        blog: {
          type: `BlogJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `BlogJson`,
            })
          },
        },
        author: {
          type: `AuthorJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `AuthorJson`,
            })
          },
        },
      },
      interfaces: [`Node`],
    }),
  ])

  // It is of course also possible to read type definitions from a .gql file,
  // which will give you proper syntax highlighting
  const additionalTypeDefs = fs.readFileSync(`type-defs.gql`, {
    encoding: `utf-8`,
  })
  createTypes(additionalTypeDefs)
}

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      // Create a new root query field.
      allAuthorFullNames: {
        type: [`String!`],
        resolve(source, args, context, info) {
          const authors = context.nodeModel.getAllNodes({
            type: `AuthorJson`,
          })
          return authors.map(author => `${author.name}, ${author.firstName}`)
        },
      },
      // Field resolvers can use all of Gatsby's querying capabilities
      allPostsTaggedWithBaz: {
        type: [`BlogJson`],
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: { filter: { tags: { eq: `baz` } } },
            type: `BlogJson`,
            firstOnly: false,
          })
        },
      },
    },
    AuthorJson: {
      // Add a field to an existing type by providing a field config.
      // Note that added fields will not be available in the input filter
      // when no type definitions are provided wth `createTypes`.
      posts: {
        type: [`BlogJson`],
        resolve(source, args, context, info) {
          // We use an author's `email` as foreign key in `BlogJson.authors`
          const fieldValue = source.email

          const posts = context.nodeModel.getAllNodes({
            type: `BlogJson`,
          })
          return posts.filter(post =>
            (post.authors || []).some(author => author === fieldValue)
          )
        },
      },
    },
    BlogJson: {
      // Add a resolver to a field defined with `createTypes`.
      authors: {
        resolve(source, args, context, info) {
          const emails = source[info.fieldName]
          if (emails == null) return null

          const authors = context.nodeModel.getAllNodes({
            type: `AuthorJson`,
          })
          return authors.filter(author => emails.includes(author.email))
        },
      },
      comments: {
        type: `[CommentJson!]!`,
        resolve(source, args, context, info) {
          const result = context.nodeModel.getAllNodes({
            type: `CommentJson`,
          })
          return result.filter(({ blog }) => blog === source.id)
        },
      },
    },
  })
}
<commit_msg>fix(gatsby): Fix wrong resolve id for CommentJson type (#30389)<commit_after>const fs = require(`fs`)

exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions

  // Type definitions can be provided in SDL
  const typeDefs = `
    type AuthorJson implements Node {
      name: String!
      firstName: String!
      email: String!
      picture: File
    }

    type BlogJson implements Node {
      title: String!
      authors: [AuthorJson]
      text: String
      date: Date
      tags: [String]
      meta: Metadata
    }
  `
  createTypes(typeDefs)

  // Alternatively, you can use type builders to construct types
  createTypes([
    schema.buildObjectType({
      name: `CommentJson`,
      fields: {
        text: `String!`,
        blog: {
          type: `BlogJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.blog,
              type: `BlogJson`,
            })
          },
        },
        author: {
          type: `AuthorJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `AuthorJson`,
            })
          },
        },
      },
      interfaces: [`Node`],
    }),
  ])

  // It is of course also possible to read type definitions from a .gql file,
  // which will give you proper syntax highlighting
  const additionalTypeDefs = fs.readFileSync(`type-defs.gql`, {
    encoding: `utf-8`,
  })
  createTypes(additionalTypeDefs)
}

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      // Create a new root query field.
      allAuthorFullNames: {
        type: [`String!`],
        resolve(source, args, context, info) {
          const authors = context.nodeModel.getAllNodes({
            type: `AuthorJson`,
          })
          return authors.map(author => `${author.name}, ${author.firstName}`)
        },
      },
      // Field resolvers can use all of Gatsby's querying capabilities
      allPostsTaggedWithBaz: {
        type: [`BlogJson`],
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: { filter: { tags: { eq: `baz` } } },
            type: `BlogJson`,
            firstOnly: false,
          })
        },
      },
    },
    AuthorJson: {
      // Add a field to an existing type by providing a field config.
      // Note that added fields will not be available in the input filter
      // when no type definitions are provided wth `createTypes`.
      posts: {
        type: [`BlogJson`],
        resolve(source, args, context, info) {
          // We use an author's `email` as foreign key in `BlogJson.authors`
          const fieldValue = source.email

          const posts = context.nodeModel.getAllNodes({
            type: `BlogJson`,
          })
          return posts.filter(post =>
            (post.authors || []).some(author => author === fieldValue)
          )
        },
      },
    },
    BlogJson: {
      // Add a resolver to a field defined with `createTypes`.
      authors: {
        resolve(source, args, context, info) {
          const emails = source[info.fieldName]
          if (emails == null) return null

          const authors = context.nodeModel.getAllNodes({
            type: `AuthorJson`,
          })
          return authors.filter(author => emails.includes(author.email))
        },
      },
      comments: {
        type: `[CommentJson!]!`,
        resolve(source, args, context, info) {
          const result = context.nodeModel.getAllNodes({
            type: `CommentJson`,
          })
          return result.filter(({ blog }) => blog === source.id)
        },
      },
    },
  })
}
<|endoftext|>


<commit_before>var API,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

/**
 *  Module: API
 *  ===========
 *
 *  Abstraction for the basic GET/POST operations.
 **/
module.exports = API = (function() {

  /**
   *
   *  Constructor
   *  -----------
   **/
  function API(uri, opts) {
    this.uri = uri;
    this.opts = opts;

    // bindings
    this.get = __bind(this.get, this);
    this.post = __bind(this.post, this);
  };

  /**
   *
   *  Public: Abstract GET request to the API
   *  ---------------------------------------
   *
   *  url             - String
   *  params          - [Optional] Object with params to be passed
   *  callback        - Callback Function
   **/
  API.prototype.get = function(url, params, callback) {
    var self = this,
        request = require('request');

    url = self.uri.base + url;

    if ((params != null) && (typeof params === 'object')) {
      var qs = require('querystring');
      url += '?' + qs.stringify(params);
    }

    request({
      method: 'GET',
      uri: url,
      oauth: self.opts,
      json: true,
    }, function (err, response, body) {
      if (err)
        return callback(err);

      return callback(null, body);
    });
  };

  /**
   *
   *  Public: abstract POST request to the API
   *  ----------------------------------------
   *
   *  url             - String
   *  params          - [Optional] Object with params to be passed
   *  data            - [Required] Object with data
   *  callback        - Callback Function
   **/
  API.prototype.post = function(url, params, data, callback) {
    var self = this,
        request = require('request');

    url = self.uri.base + url;

    if ((params != null) && (typeof params === 'object')) {
      var qs = require('querystring');
      url += '?' + qs.stringify(params);
    }

    request({
      method: 'POST',
      uri: url,
      body: JSON.stringify(data)
    }, function (err, response, body) {
      if (err)
        return callback(err);
    });
  };

  return API;
})();
<commit_msg>api#proto.post(): removing params<commit_after>var API,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

/**
 *  Module: API
 *  ===========
 *
 *  Abstraction for the basic GET/POST operations.
 **/
module.exports = API = (function() {

  /**
   *
   *  Constructor
   *  -----------
   **/
  function API(uri, opts) {
    this.uri = uri;
    this.opts = opts;

    // bindings
    this.get = __bind(this.get, this);
    this.post = __bind(this.post, this);
  };

  /**
   *
   *  Public: Abstract GET request to the API
   *  ---------------------------------------
   *
   *  url             - String
   *  params          - [Optional] Object with params to be passed
   *  callback        - Callback Function
   **/
  API.prototype.get = function(url, params, callback) {
    var self = this,
        request = require('request');

    url = self.uri.base + url;

    if ((params != null) && (typeof params === 'object')) {
      var qs = require('querystring');
      url += '?' + qs.stringify(params);
    }

    request({
      method: 'GET',
      uri: url,
      oauth: self.opts,
      json: true,
    }, function (err, response, body) {
      if (err)
        return callback(err);

      return callback(null, body);
    });
  };

  /**
   *
   *  Public: abstract POST request to the API
   *  ----------------------------------------
   *
   *  url             - String
   *  data            - [Required] Object with data
   *  callback        - Callback Function
   **/
  API.prototype.post = function(url, data, callback) {
    var self = this,
        request = require('request'),
        body = null;

    url = self.uri.base + url;

    if (data != null)
      body = JSON.stringify(data);

    request({
      method: 'POST',
      uri: url,
      body: JSON.stringify(data)
    }, function (err, response, body) {
      if (err)
        return callback(err);
    });
  };

  return API;
})();
<|endoftext|>