aboutsummaryrefslogtreecommitdiffstats
path: root/signaling-server/node_modules/socket.io/node_modules/socket.io-client/bin/builder.js
blob: 7383c75a05b480e96149a17f7877b6e101dcfe56 (plain)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs')
  , socket = require('../lib/io')
  , uglify = require('uglify-js')
  , activeXObfuscator = require('active-x-obfuscator');

/**
 * License headers.
 *
 * @api private
 */

var template = '/*! Socket.IO.%ext% build:' + socket.version + ', %type%. Copyright(c) 2011 LearnBoost <dev@learnboost.com> MIT Licensed */\n'
  , development = template.replace('%type%', 'development').replace('%ext%', 'js')
  , production = template.replace('%type%', 'production').replace('%ext%', 'min.js');

/**
 * If statements, these allows you to create serveride & client side compatible
 * code using specially designed `if` statements that remove serverside
 * designed code from the source files
 *
 * @api private
 */

var starttagIF = '// if node'
  , endtagIF = '// end node';

/**
 * The modules that are required to create a base build of Socket.IO.
 *
 * @const
 * @type {Array}
 * @api private
 */

var base = [
    'io.js'
  , 'util.js'
  , 'events.js'
  , 'json.js'
  , 'parser.js'
  , 'transport.js'
  , 'socket.js'
  , 'namespace.js'
  ];

/**
 * The available transports for Socket.IO. These are mapped as:
 * 
 *   - `key` the name of the transport
 *   - `value` the dependencies for the transport
 *
 * @const
 * @type {Object}
 * @api public
 */

var baseTransports = {
    'websocket': ['transports/websocket.js']
  , 'flashsocket': [
        'transports/websocket.js'
      , 'transports/flashsocket.js'
      , 'vendor/web-socket-js/swfobject.js'
      , 'vendor/web-socket-js/web_socket.js'
    ] 
  , 'htmlfile': ['transports/xhr.js', 'transports/htmlfile.js']
  /* FIXME: re-enable me once we have multi-part support
  , 'xhr-multipart': ['transports/xhr.js', 'transports/xhr-multipart.js'] */
  , 'xhr-polling': ['transports/xhr.js', 'transports/xhr-polling.js']
  , 'jsonp-polling': [
        'transports/xhr.js'
      , 'transports/xhr-polling.js'
      , 'transports/jsonp-polling.js'
    ]
};

/**
 * Wrappers for client-side usage.
 * This enables usage in top-level browser window, client-side CommonJS systems and AMD loaders.
 * If doing a node build for server-side client, this wrapper is NOT included.
 * @api private
 */
var wrapperPre = "\nvar io = ('undefined' === typeof module ? {} : module.exports);\n(function() {\n";

var wrapperPost = "\nif (typeof define === \"function\" && define.amd) {" +
                  "\n  define([], function () { return io; });" +
                  "\n}\n})();";


/**
 * Builds a custom Socket.IO distribution based on the transports that you
 * need. You can configure the build to create development build or production
 * build (minified).
 *
 * @param {Array} transports The transports that needs to be bundled.
 * @param {Object} [options] Options to configure the building process.
 * @param {Function} callback Last argument should always be the callback
 * @callback {String|Boolean} err An optional argument, if it exists than an error
 *    occurred during the build process.
 * @callback {String} result The result of the build process.
 * @api public
 */

var builder = module.exports = function () {
  var transports, options, callback, error = null
    , args = Array.prototype.slice.call(arguments, 0)
    , settings = {
        minify: true
      , node: false
      , custom: []
      };

  // Fancy pancy argument support this makes any pattern possible mainly
  // because we require only one of each type
  args.forEach(function (arg) {
    var type = Object.prototype.toString.call(arg)
        .replace(/\[object\s(\w+)\]/gi , '$1' ).toLowerCase();

    switch (type) {
      case 'array':
        return transports = arg;
      case 'object':
        return options = arg;
      case 'function':
        return callback = arg;
    }
  });

  // Add defaults
  options = options || {};
  transports = transports || Object.keys(baseTransports);

  // Merge the data
  for(var option in options) {
    settings[option] = options[option];
  }

  // Start creating a dependencies chain with all the required files for the
  // custom Socket.IO bundle.
  var files = [];
  base.forEach(function (file) {
    files.push(__dirname + '/../lib/' + file);
  });

  transports.forEach(function (transport) {
    var dependencies = baseTransports[transport];
    if (!dependencies) {
      error = 'Unsupported transport `' + transport + '` supplied as argument.';
      return;
    }

    // Add the files to the files list, but only if they are not added before
    dependencies.forEach(function (file) {
      var path = __dirname + '/../lib/' + file;
      if (!~files.indexOf(path)) files.push(path);
    })
  });

  // check to see if the files tree compilation generated any errors.
  if (error) return callback(error);

  var results = {};
  files.forEach(function (file) {
    fs.readFile(file, function (err, content) {
      if (err) error = err;
      results[file] = content;

      // check if we are done yet, or not.. Just by checking the size of the result
      // object.
      if (Object.keys(results).length !== files.length) return;

      // we are done, did we error?
      if (error) return callback(error);

      // start with the license header
      var code = development
        , ignore = 0;

      // pre-wrapper for non-server-side builds
      if (!settings.node) code += wrapperPre;

      // concatenate the file contents in order
      files.forEach(function (file) {
        code += results[file];
      });

      // check if we need to add custom code
      if (settings.custom.length) {
        settings.custom.forEach(function (content) {
          code += content;
        });
      }

      // post-wrapper for non-server-side builds
      if (!settings.node) {
          code += wrapperPost;
      }

      code = activeXObfuscator(code);

      // Search for conditional code blocks that need to be removed as they
      // where designed for a server side env. but only if we don't want to
      // make this build node compatible.
      if (!settings.node) {
        code = code.split('\n').filter(function (line) {
          // check if there are tags in here
          var start = line.indexOf(starttagIF) >= 0
            , end = line.indexOf(endtagIF) >= 0
            , ret = ignore;

          // ignore the current line
          if (start) {
            ignore++;
            ret = ignore;
          }

          // stop ignoring the next line
          if (end) {
            ignore--;
          }

          return ret == 0;
        }).join('\n');
      }

      // check if we need to process it any further
      if (settings.minify) {
        var ast = uglify.parser.parse(code);
        ast = uglify.uglify.ast_mangle(ast);
        ast = uglify.uglify.ast_squeeze(ast);

        code = production + uglify.uglify.gen_code(ast, { ascii_only: true });
      }

      callback(error, code);
    })
  })
};

/**
 * Builder version is also the current client version
 * this way we don't have to do another include for the
 * clients version number and we can just include the builder.
 *
 * @type {String}
 * @api public
 */
 
builder.version = socket.version;

/**
 * A list of all build in transport types.
 *
 * @type {Object}
 * @api public
 */
 
builder.transports = baseTransports;

/**
 * Command line support, this allows us to generate builds without having
 * to load it as module.
 */
 
if (!module.parent){
  // the first 2 are `node` and the path to this file, we don't need them
  var args = process.argv.slice(2);

  // build a development build
  builder(args.length ? args : false, { minify:false }, function (err, content) {
    if (err) return console.error(err);

    fs.write(
        fs.openSync(__dirname + '/../dist/socket.io.js', 'w')
      , content
      , 0
      , 'utf8'
    );
    console.log('Successfully generated the development build: socket.io.js');
  });

  // and build a production build
  builder(args.length ? args : false, function (err, content) {
    if (err) return console.error(err);
 
    fs.write(
        fs.openSync(__dirname + '/../dist/socket.io.min.js', 'w')
      , content
      , 0
      , 'utf8'
    );
    console.log('Successfully generated the production build: socket.io.min.js');
  });
}