Blame view

node_modules/loopback-connector-remote/lib/remote-connector.js 3.37 KB
f7563de62   Palak Handa   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  // Copyright IBM Corp. 2014,2016. All Rights Reserved.
  // Node module: loopback-connector-remote
  // This file is licensed under the MIT License.
  // License text available at https://opensource.org/licenses/MIT
  
  /**
   * Dependencies.
   */
  
  var assert = require('assert');
  var remoting = require('strong-remoting');
  var utils = require('loopback-datasource-juggler/lib/utils');
  var jutil = require('loopback-datasource-juggler/lib/jutil');
  var RelationMixin = require('./relations');
  var InclusionMixin = require('loopback-datasource-juggler/lib/include');
  
  /**
   * Export the RemoteConnector class.
   */
  
  module.exports = RemoteConnector;
  
  /**
   * Create an instance of the connector with the given `settings`.
   */
  
  function RemoteConnector(settings) {
    assert(typeof settings ===
      'object',
      'cannot initiaze RemoteConnector without a settings object');
    this.client = settings.client;
    this.adapter = settings.adapter || 'rest';
    this.protocol = settings.protocol || 'http';
    this.root = settings.root || '';
    this.host = settings.host || 'localhost';
    this.port = settings.port || 3000;
    this.remotes = remoting.create();
    this.name = 'remote-connector';
  
    if (settings.url) {
      this.url = settings.url;
    } else {
      this.url = this.protocol + '://' + this.host + ':' + this.port + this.root;
    }
  
    // handle mixins in the define() method
    var DAO = this.DataAccessObject = function() {
    };
  
  }
  
  RemoteConnector.prototype.connect = function() {
    this.remotes.connect(this.url, this.adapter);
  };
  
  RemoteConnector.initialize = function(dataSource, callback) {
    var connector = dataSource.connector =
      new RemoteConnector(dataSource.settings);
    connector.connect();
    process.nextTick(callback);
  };
  
  RemoteConnector.prototype.define = function(definition) {
    var Model = definition.model;
    var remotes = this.remotes;
  
    assert(Model.sharedClass,
        'cannot attach ' +
        Model.modelName +
        ' to a remote connector without a Model.sharedClass');
  
    jutil.mixin(Model, RelationMixin);
    jutil.mixin(Model, InclusionMixin);
    remotes.addClass(Model.sharedClass);
    this.resolve(Model);
  };
  
  RemoteConnector.prototype.resolve = function(Model) {
    var remotes = this.remotes;
  
    Model.sharedClass.methods().forEach(function(remoteMethod) {
      if (remoteMethod.name !== 'Change' && remoteMethod.name !== 'Checkpoint') {
        createProxyMethod(Model, remotes, remoteMethod);
      }
    });
  
    // setup a remoting type converter for this model
    remotes.defineType(Model.modelName, function(val) {
      return val ? new Model(val) : val;
    });
  };
  
  function createProxyMethod(Model, remotes, remoteMethod) {
    var scope = remoteMethod.isStatic ? Model : Model.prototype;
    var original = scope[remoteMethod.name];
  
    function remoteMethodProxy() {
      var args = Array.prototype.slice.call(arguments);
      var lastArgIsFunc = typeof args[args.length - 1] === 'function';
      var callback;
      if (lastArgIsFunc) {
        callback = args.pop();
      } else {
        callback = utils.createPromiseCallback();
      }
  
      if (remoteMethod.isStatic) {
        remotes.invoke(remoteMethod.stringName, args, callback);
      } else {
        var ctorArgs = [this.id];
        remotes.invoke(remoteMethod.stringName, ctorArgs, args, callback);
      }
  
      return callback.promise;
    }
  
    scope[remoteMethod.name] = remoteMethodProxy;
    remoteMethod.aliases.forEach(function(alias) {
      scope[alias] = remoteMethodProxy;
    });
  }
  
  function noop() {
  }