mirror of
https://github.com/YunoHost-Apps/rocketchat_ynh.git
synced 2024-09-03 20:16:25 +02:00
1276 lines
135 KiB
JavaScript
1276 lines
135 KiB
JavaScript
(function () {
|
|
|
|
/* Imports */
|
|
var _ = Package.underscore._;
|
|
|
|
/* Package-scope variables */
|
|
var Meteor;
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/server_environment.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
Meteor = { // 1
|
|
isClient: false, // 2
|
|
isServer: true, // 3
|
|
isCordova: false // 4
|
|
}; // 5
|
|
// 6
|
|
Meteor.settings = {}; // 7
|
|
// 8
|
|
if (process.env.METEOR_SETTINGS) { // 9
|
|
try { // 10
|
|
Meteor.settings = JSON.parse(process.env.METEOR_SETTINGS); // 11
|
|
} catch (e) { // 12
|
|
throw new Error("METEOR_SETTINGS are not valid JSON: " + process.env.METEOR_SETTINGS); // 13
|
|
} // 14
|
|
} // 15
|
|
// 16
|
|
// Make sure that there is always a public attribute // 17
|
|
// to enable Meteor.settings.public on client // 18
|
|
if (! Meteor.settings.public) { // 19
|
|
Meteor.settings.public = {}; // 20
|
|
} // 21
|
|
// 22
|
|
// Push a subset of settings to the client. Note that the way this // 23
|
|
// code is written, if the app mutates `Meteor.settings.public` on the // 24
|
|
// server, it also mutates // 25
|
|
// `__meteor_runtime_config__.PUBLIC_SETTINGS`, and the modified // 26
|
|
// settings will be sent to the client. // 27
|
|
if (typeof __meteor_runtime_config__ === "object") { // 28
|
|
__meteor_runtime_config__.PUBLIC_SETTINGS = Meteor.settings.public; // 29
|
|
} // 30
|
|
// 31
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/helpers.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
if (Meteor.isServer) // 1
|
|
var Future = Npm.require('fibers/future'); // 2
|
|
// 3
|
|
if (typeof __meteor_runtime_config__ === 'object' && // 4
|
|
__meteor_runtime_config__.meteorRelease) { // 5
|
|
/** // 6
|
|
* @summary `Meteor.release` is a string containing the name of the [release](#meteorupdate) with which the project was built (for example, `"1.2.3"`). It is `undefined` if the project was built using a git checkout of Meteor.
|
|
* @locus Anywhere // 8
|
|
* @type {String} // 9
|
|
*/ // 10
|
|
Meteor.release = __meteor_runtime_config__.meteorRelease; // 11
|
|
} // 12
|
|
// 13
|
|
// XXX find a better home for these? Ideally they would be _.get, // 14
|
|
// _.ensure, _.delete.. // 15
|
|
// 16
|
|
_.extend(Meteor, { // 17
|
|
// _get(a,b,c,d) returns a[b][c][d], or else undefined if a[b] or // 18
|
|
// a[b][c] doesn't exist. // 19
|
|
// // 20
|
|
_get: function (obj /*, arguments */) { // 21
|
|
for (var i = 1; i < arguments.length; i++) { // 22
|
|
if (!(arguments[i] in obj)) // 23
|
|
return undefined; // 24
|
|
obj = obj[arguments[i]]; // 25
|
|
} // 26
|
|
return obj; // 27
|
|
}, // 28
|
|
// 29
|
|
// _ensure(a,b,c,d) ensures that a[b][c][d] exists. If it does not, // 30
|
|
// it is created and set to {}. Either way, it is returned. // 31
|
|
// // 32
|
|
_ensure: function (obj /*, arguments */) { // 33
|
|
for (var i = 1; i < arguments.length; i++) { // 34
|
|
var key = arguments[i]; // 35
|
|
if (!(key in obj)) // 36
|
|
obj[key] = {}; // 37
|
|
obj = obj[key]; // 38
|
|
} // 39
|
|
// 40
|
|
return obj; // 41
|
|
}, // 42
|
|
// 43
|
|
// _delete(a, b, c, d) deletes a[b][c][d], then a[b][c] unless it // 44
|
|
// isn't empty, then a[b] unless it isn't empty. // 45
|
|
// // 46
|
|
_delete: function (obj /*, arguments */) { // 47
|
|
var stack = [obj]; // 48
|
|
var leaf = true; // 49
|
|
for (var i = 1; i < arguments.length - 1; i++) { // 50
|
|
var key = arguments[i]; // 51
|
|
if (!(key in obj)) { // 52
|
|
leaf = false; // 53
|
|
break; // 54
|
|
} // 55
|
|
obj = obj[key]; // 56
|
|
if (typeof obj !== "object") // 57
|
|
break; // 58
|
|
stack.push(obj); // 59
|
|
} // 60
|
|
// 61
|
|
for (var i = stack.length - 1; i >= 0; i--) { // 62
|
|
var key = arguments[i+1]; // 63
|
|
// 64
|
|
if (leaf) // 65
|
|
leaf = false; // 66
|
|
else // 67
|
|
for (var other in stack[i][key]) // 68
|
|
return; // not empty -- we're done // 69
|
|
// 70
|
|
delete stack[i][key]; // 71
|
|
} // 72
|
|
}, // 73
|
|
// 74
|
|
// wrapAsync can wrap any function that takes some number of arguments that // 75
|
|
// can't be undefined, followed by some optional arguments, where the callback // 76
|
|
// is the last optional argument. // 77
|
|
// e.g. fs.readFile(pathname, [callback]), // 78
|
|
// fs.open(pathname, flags, [mode], [callback]) // 79
|
|
// For maximum effectiveness and least confusion, wrapAsync should be used on // 80
|
|
// functions where the callback is the only argument of type Function. // 81
|
|
// 82
|
|
/** // 83
|
|
* @memberOf Meteor // 84
|
|
* @summary Wrap a function that takes a callback function as its final parameter. The signature of the callback of the wrapped function should be `function(error, result){}`. On the server, the wrapped function can be used either synchronously (without passing a callback) or asynchronously (when a callback is passed). On the client, a callback is always required; errors will be logged if there is no callback. If a callback is provided, the environment captured when the original function was called will be restored in the callback.
|
|
* @locus Anywhere // 86
|
|
* @param {Function} func A function that takes a callback as its final parameter // 87
|
|
* @param {Object} [context] Optional `this` object against which the original function will be invoked // 88
|
|
*/ // 89
|
|
wrapAsync: function (fn, context) { // 90
|
|
return function (/* arguments */) { // 91
|
|
var self = context || this; // 92
|
|
var newArgs = _.toArray(arguments); // 93
|
|
var callback; // 94
|
|
// 95
|
|
for (var i = newArgs.length - 1; i >= 0; --i) { // 96
|
|
var arg = newArgs[i]; // 97
|
|
var type = typeof arg; // 98
|
|
if (type !== "undefined") { // 99
|
|
if (type === "function") { // 100
|
|
callback = arg; // 101
|
|
} // 102
|
|
break; // 103
|
|
} // 104
|
|
} // 105
|
|
// 106
|
|
if (! callback) { // 107
|
|
if (Meteor.isClient) { // 108
|
|
callback = logErr; // 109
|
|
} else { // 110
|
|
var fut = new Future(); // 111
|
|
callback = fut.resolver(); // 112
|
|
} // 113
|
|
++i; // Insert the callback just after arg. // 114
|
|
} // 115
|
|
// 116
|
|
newArgs[i] = Meteor.bindEnvironment(callback); // 117
|
|
var result = fn.apply(self, newArgs); // 118
|
|
return fut ? fut.wait() : result; // 119
|
|
}; // 120
|
|
}, // 121
|
|
// 122
|
|
// Sets child's prototype to a new object whose prototype is parent's // 123
|
|
// prototype. Used as: // 124
|
|
// Meteor._inherits(ClassB, ClassA). // 125
|
|
// _.extend(ClassB.prototype, { ... }) // 126
|
|
// Inspired by CoffeeScript's `extend` and Google Closure's `goog.inherits`. // 127
|
|
_inherits: function (Child, Parent) { // 128
|
|
// copy Parent static properties // 129
|
|
for (var key in Parent) { // 130
|
|
// make sure we only copy hasOwnProperty properties vs. prototype // 131
|
|
// properties // 132
|
|
if (_.has(Parent, key)) // 133
|
|
Child[key] = Parent[key]; // 134
|
|
} // 135
|
|
// 136
|
|
// a middle member of prototype chain: takes the prototype from the Parent // 137
|
|
var Middle = function () { // 138
|
|
this.constructor = Child; // 139
|
|
}; // 140
|
|
Middle.prototype = Parent.prototype; // 141
|
|
Child.prototype = new Middle(); // 142
|
|
Child.__super__ = Parent.prototype; // 143
|
|
return Child; // 144
|
|
} // 145
|
|
}); // 146
|
|
// 147
|
|
var warnedAboutWrapAsync = false; // 148
|
|
// 149
|
|
/** // 150
|
|
* @deprecated in 0.9.3 // 151
|
|
*/ // 152
|
|
Meteor._wrapAsync = function(fn, context) { // 153
|
|
if (! warnedAboutWrapAsync) { // 154
|
|
Meteor._debug("Meteor._wrapAsync has been renamed to Meteor.wrapAsync"); // 155
|
|
warnedAboutWrapAsync = true; // 156
|
|
} // 157
|
|
return Meteor.wrapAsync.apply(Meteor, arguments); // 158
|
|
}; // 159
|
|
// 160
|
|
function logErr(err) { // 161
|
|
if (err) { // 162
|
|
return Meteor._debug( // 163
|
|
"Exception in callback of async function", // 164
|
|
err.stack ? err.stack : err // 165
|
|
); // 166
|
|
} // 167
|
|
} // 168
|
|
// 169
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/setimmediate.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Chooses one of three setImmediate implementations: // 1
|
|
// // 2
|
|
// * Native setImmediate (IE 10, Node 0.9+) // 3
|
|
// // 4
|
|
// * postMessage (many browsers) // 5
|
|
// // 6
|
|
// * setTimeout (fallback) // 7
|
|
// // 8
|
|
// The postMessage implementation is based on // 9
|
|
// https://github.com/NobleJS/setImmediate/tree/1.0.1 // 10
|
|
// // 11
|
|
// Don't use `nextTick` for Node since it runs its callbacks before // 12
|
|
// I/O, which is stricter than we're looking for. // 13
|
|
// // 14
|
|
// Not installed as a polyfill, as our public API is `Meteor.defer`. // 15
|
|
// Since we're not trying to be a polyfill, we have some // 16
|
|
// simplifications: // 17
|
|
// // 18
|
|
// If one invocation of a setImmediate callback pauses itself by a // 19
|
|
// call to alert/prompt/showModelDialog, the NobleJS polyfill // 20
|
|
// implementation ensured that no setImmedate callback would run until // 21
|
|
// the first invocation completed. While correct per the spec, what it // 22
|
|
// would mean for us in practice is that any reactive updates relying // 23
|
|
// on Meteor.defer would be hung in the main window until the modal // 24
|
|
// dialog was dismissed. Thus we only ensure that a setImmediate // 25
|
|
// function is called in a later event loop. // 26
|
|
// // 27
|
|
// We don't need to support using a string to be eval'ed for the // 28
|
|
// callback, arguments to the function, or clearImmediate. // 29
|
|
// 30
|
|
"use strict"; // 31
|
|
// 32
|
|
var global = this; // 33
|
|
// 34
|
|
// 35
|
|
// IE 10, Node >= 9.1 // 36
|
|
// 37
|
|
function useSetImmediate() { // 38
|
|
if (! global.setImmediate) // 39
|
|
return null; // 40
|
|
else { // 41
|
|
var setImmediate = function (fn) { // 42
|
|
global.setImmediate(fn); // 43
|
|
}; // 44
|
|
setImmediate.implementation = 'setImmediate'; // 45
|
|
return setImmediate; // 46
|
|
} // 47
|
|
} // 48
|
|
// 49
|
|
// 50
|
|
// Android 2.3.6, Chrome 26, Firefox 20, IE 8-9, iOS 5.1.1 Safari // 51
|
|
// 52
|
|
function usePostMessage() { // 53
|
|
// The test against `importScripts` prevents this implementation // 54
|
|
// from being installed inside a web worker, where // 55
|
|
// `global.postMessage` means something completely different and // 56
|
|
// can't be used for this purpose. // 57
|
|
// 58
|
|
if (!global.postMessage || global.importScripts) { // 59
|
|
return null; // 60
|
|
} // 61
|
|
// 62
|
|
// Avoid synchronous post message implementations. // 63
|
|
// 64
|
|
var postMessageIsAsynchronous = true; // 65
|
|
var oldOnMessage = global.onmessage; // 66
|
|
global.onmessage = function () { // 67
|
|
postMessageIsAsynchronous = false; // 68
|
|
}; // 69
|
|
global.postMessage("", "*"); // 70
|
|
global.onmessage = oldOnMessage; // 71
|
|
// 72
|
|
if (! postMessageIsAsynchronous) // 73
|
|
return null; // 74
|
|
// 75
|
|
var funcIndex = 0; // 76
|
|
var funcs = {}; // 77
|
|
// 78
|
|
// Installs an event handler on `global` for the `message` event: see // 79
|
|
// * https://developer.mozilla.org/en/DOM/window.postMessage // 80
|
|
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages // 81
|
|
// 82
|
|
// XXX use Random.id() here? // 83
|
|
var MESSAGE_PREFIX = "Meteor._setImmediate." + Math.random() + '.'; // 84
|
|
// 85
|
|
function isStringAndStartsWith(string, putativeStart) { // 86
|
|
return (typeof string === "string" && // 87
|
|
string.substring(0, putativeStart.length) === putativeStart); // 88
|
|
} // 89
|
|
// 90
|
|
function onGlobalMessage(event) { // 91
|
|
// This will catch all incoming messages (even from other // 92
|
|
// windows!), so we need to try reasonably hard to avoid letting // 93
|
|
// anyone else trick us into firing off. We test the origin is // 94
|
|
// still this window, and that a (randomly generated) // 95
|
|
// unpredictable identifying prefix is present. // 96
|
|
if (event.source === global && // 97
|
|
isStringAndStartsWith(event.data, MESSAGE_PREFIX)) { // 98
|
|
var index = event.data.substring(MESSAGE_PREFIX.length); // 99
|
|
try { // 100
|
|
if (funcs[index]) // 101
|
|
funcs[index](); // 102
|
|
} // 103
|
|
finally { // 104
|
|
delete funcs[index]; // 105
|
|
} // 106
|
|
} // 107
|
|
} // 108
|
|
// 109
|
|
if (global.addEventListener) { // 110
|
|
global.addEventListener("message", onGlobalMessage, false); // 111
|
|
} else { // 112
|
|
global.attachEvent("onmessage", onGlobalMessage); // 113
|
|
} // 114
|
|
// 115
|
|
var setImmediate = function (fn) { // 116
|
|
// Make `global` post a message to itself with the handle and // 117
|
|
// identifying prefix, thus asynchronously invoking our // 118
|
|
// onGlobalMessage listener above. // 119
|
|
++funcIndex; // 120
|
|
funcs[funcIndex] = fn; // 121
|
|
global.postMessage(MESSAGE_PREFIX + funcIndex, "*"); // 122
|
|
}; // 123
|
|
setImmediate.implementation = 'postMessage'; // 124
|
|
return setImmediate; // 125
|
|
} // 126
|
|
// 127
|
|
// 128
|
|
function useTimeout() { // 129
|
|
var setImmediate = function (fn) { // 130
|
|
global.setTimeout(fn, 0); // 131
|
|
}; // 132
|
|
setImmediate.implementation = 'setTimeout'; // 133
|
|
return setImmediate; // 134
|
|
} // 135
|
|
// 136
|
|
// 137
|
|
Meteor._setImmediate = // 138
|
|
useSetImmediate() || // 139
|
|
usePostMessage() || // 140
|
|
useTimeout(); // 141
|
|
// 142
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/timers.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
var withoutInvocation = function (f) { // 1
|
|
if (Package.ddp) { // 2
|
|
var _CurrentInvocation = Package.ddp.DDP._CurrentInvocation; // 3
|
|
if (_CurrentInvocation.get() && _CurrentInvocation.get().isSimulation) // 4
|
|
throw new Error("Can't set timers inside simulations"); // 5
|
|
return function () { _CurrentInvocation.withValue(null, f); }; // 6
|
|
} // 7
|
|
else // 8
|
|
return f; // 9
|
|
}; // 10
|
|
// 11
|
|
var bindAndCatch = function (context, f) { // 12
|
|
return Meteor.bindEnvironment(withoutInvocation(f), context); // 13
|
|
}; // 14
|
|
// 15
|
|
_.extend(Meteor, { // 16
|
|
// Meteor.setTimeout and Meteor.setInterval callbacks scheduled // 17
|
|
// inside a server method are not part of the method invocation and // 18
|
|
// should clear out the CurrentInvocation environment variable. // 19
|
|
// 20
|
|
/** // 21
|
|
* @memberOf Meteor // 22
|
|
* @summary Call a function in the future after waiting for a specified delay. // 23
|
|
* @locus Anywhere // 24
|
|
* @param {Function} func The function to run // 25
|
|
* @param {Number} delay Number of milliseconds to wait before calling function // 26
|
|
*/ // 27
|
|
setTimeout: function (f, duration) { // 28
|
|
return setTimeout(bindAndCatch("setTimeout callback", f), duration); // 29
|
|
}, // 30
|
|
// 31
|
|
/** // 32
|
|
* @memberOf Meteor // 33
|
|
* @summary Call a function repeatedly, with a time delay between calls. // 34
|
|
* @locus Anywhere // 35
|
|
* @param {Function} func The function to run // 36
|
|
* @param {Number} delay Number of milliseconds to wait between each function call. // 37
|
|
*/ // 38
|
|
setInterval: function (f, duration) { // 39
|
|
return setInterval(bindAndCatch("setInterval callback", f), duration); // 40
|
|
}, // 41
|
|
// 42
|
|
/** // 43
|
|
* @memberOf Meteor // 44
|
|
* @summary Cancel a repeating function call scheduled by `Meteor.setInterval`. // 45
|
|
* @locus Anywhere // 46
|
|
* @param {Number} id The handle returned by `Meteor.setInterval` // 47
|
|
*/ // 48
|
|
clearInterval: function(x) { // 49
|
|
return clearInterval(x); // 50
|
|
}, // 51
|
|
// 52
|
|
/** // 53
|
|
* @memberOf Meteor // 54
|
|
* @summary Cancel a function call scheduled by `Meteor.setTimeout`. // 55
|
|
* @locus Anywhere // 56
|
|
* @param {Number} id The handle returned by `Meteor.setTimeout` // 57
|
|
*/ // 58
|
|
clearTimeout: function(x) { // 59
|
|
return clearTimeout(x); // 60
|
|
}, // 61
|
|
// 62
|
|
// XXX consider making this guarantee ordering of defer'd callbacks, like // 63
|
|
// Tracker.afterFlush or Node's nextTick (in practice). Then tests can do: // 64
|
|
// callSomethingThatDefersSomeWork(); // 65
|
|
// Meteor.defer(expect(somethingThatValidatesThatTheWorkHappened)); // 66
|
|
defer: function (f) { // 67
|
|
Meteor._setImmediate(bindAndCatch("defer callback", f)); // 68
|
|
} // 69
|
|
}); // 70
|
|
// 71
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/errors.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Makes an error subclass which properly contains a stack trace in most // 1
|
|
// environments. constructor can set fields on `this` (and should probably set // 2
|
|
// `message`, which is what gets displayed at the top of a stack trace). // 3
|
|
// // 4
|
|
Meteor.makeErrorType = function (name, constructor) { // 5
|
|
var errorClass = function (/*arguments*/) { // 6
|
|
var self = this; // 7
|
|
// 8
|
|
// Ensure we get a proper stack trace in most Javascript environments // 9
|
|
if (Error.captureStackTrace) { // 10
|
|
// V8 environments (Chrome and Node.js) // 11
|
|
Error.captureStackTrace(self, errorClass); // 12
|
|
} else { // 13
|
|
// Firefox // 14
|
|
var e = new Error; // 15
|
|
e.__proto__ = errorClass.prototype; // 16
|
|
if (e instanceof errorClass) // 17
|
|
self = e; // 18
|
|
} // 19
|
|
// Safari magically works. // 20
|
|
// 21
|
|
constructor.apply(self, arguments); // 22
|
|
// 23
|
|
self.errorType = name; // 24
|
|
// 25
|
|
return self; // 26
|
|
}; // 27
|
|
// 28
|
|
Meteor._inherits(errorClass, Error); // 29
|
|
// 30
|
|
return errorClass; // 31
|
|
}; // 32
|
|
// 33
|
|
// This should probably be in the livedata package, but we don't want // 34
|
|
// to require you to use the livedata package to get it. Eventually we // 35
|
|
// should probably rename it to DDP.Error and put it back in the // 36
|
|
// 'livedata' package (which we should rename to 'ddp' also.) // 37
|
|
// // 38
|
|
// Note: The DDP server assumes that Meteor.Error EJSON-serializes as an object // 39
|
|
// containing 'error' and optionally 'reason' and 'details'. // 40
|
|
// The DDP client manually puts these into Meteor.Error objects. (We don't use // 41
|
|
// EJSON.addType here because the type is determined by location in the // 42
|
|
// protocol, not text on the wire.) // 43
|
|
// 44
|
|
/** // 45
|
|
* @summary This class represents a symbolic error thrown by a method. // 46
|
|
* @locus Anywhere // 47
|
|
* @class // 48
|
|
* @param {String} error A string code uniquely identifying this kind of error. // 49
|
|
* This string should be used by callers of the method to determine the // 50
|
|
* appropriate action to take, instead of attempting to parse the reason // 51
|
|
* or details fields. For example: // 52
|
|
* // 53
|
|
* ``` // 54
|
|
* // on the server, pick a code unique to this error // 55
|
|
* // the reason field should be a useful debug message // 56
|
|
* throw new Meteor.Error("logged-out", // 57
|
|
* "The user must be logged in to post a comment."); // 58
|
|
* // 59
|
|
* // on the client // 60
|
|
* Meteor.call("methodName", function (error) { // 61
|
|
* // identify the error // 62
|
|
* if (error && error.error === "logged-out") { // 63
|
|
* // show a nice error message // 64
|
|
* Session.set("errorMessage", "Please log in to post a comment."); // 65
|
|
* } // 66
|
|
* }); // 67
|
|
* ``` // 68
|
|
* // 69
|
|
* For legacy reasons, some built-in Meteor functions such as `check` throw // 70
|
|
* errors with a number in this field. // 71
|
|
* // 72
|
|
* @param {String} [reason] Optional. A short human-readable summary of the // 73
|
|
* error, like 'Not Found'. // 74
|
|
* @param {String} [details] Optional. Additional information about the error, // 75
|
|
* like a textual stack trace. // 76
|
|
*/ // 77
|
|
Meteor.Error = Meteor.makeErrorType( // 78
|
|
"Meteor.Error", // 79
|
|
function (error, reason, details) { // 80
|
|
var self = this; // 81
|
|
// 82
|
|
// String code uniquely identifying this kind of error. // 83
|
|
self.error = error; // 84
|
|
// 85
|
|
// Optional: A short human-readable summary of the error. Not // 86
|
|
// intended to be shown to end users, just developers. ("Not Found", // 87
|
|
// "Internal Server Error") // 88
|
|
self.reason = reason; // 89
|
|
// 90
|
|
// Optional: Additional information about the error, say for // 91
|
|
// debugging. It might be a (textual) stack trace if the server is // 92
|
|
// willing to provide one. The corresponding thing in HTTP would be // 93
|
|
// the body of a 404 or 500 response. (The difference is that we // 94
|
|
// never expect this to be shown to end users, only developers, so // 95
|
|
// it doesn't need to be pretty.) // 96
|
|
self.details = details; // 97
|
|
// 98
|
|
// This is what gets displayed at the top of a stack trace. Current // 99
|
|
// format is "[404]" (if no reason is set) or "File not found [404]" // 100
|
|
if (self.reason) // 101
|
|
self.message = self.reason + ' [' + self.error + ']'; // 102
|
|
else // 103
|
|
self.message = '[' + self.error + ']'; // 104
|
|
}); // 105
|
|
// 106
|
|
// Meteor.Error is basically data and is sent over DDP, so you should be able to // 107
|
|
// properly EJSON-clone it. This is especially important because if a // 108
|
|
// Meteor.Error is thrown through a Future, the error, reason, and details // 109
|
|
// properties become non-enumerable so a standard Object clone won't preserve // 110
|
|
// them and they will be lost from DDP. // 111
|
|
Meteor.Error.prototype.clone = function () { // 112
|
|
var self = this; // 113
|
|
return new Meteor.Error(self.error, self.reason, self.details); // 114
|
|
}; // 115
|
|
// 116
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/fiber_helpers.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
var path = Npm.require('path'); // 1
|
|
var Fiber = Npm.require('fibers'); // 2
|
|
var Future = Npm.require(path.join('fibers', 'future')); // 3
|
|
// 4
|
|
Meteor._noYieldsAllowed = function (f) { // 5
|
|
var savedYield = Fiber.yield; // 6
|
|
Fiber.yield = function () { // 7
|
|
throw new Error("Can't call yield in a noYieldsAllowed block!"); // 8
|
|
}; // 9
|
|
try { // 10
|
|
return f(); // 11
|
|
} finally { // 12
|
|
Fiber.yield = savedYield; // 13
|
|
} // 14
|
|
}; // 15
|
|
// 16
|
|
Meteor._DoubleEndedQueue = Npm.require('meteor-deque'); // 17
|
|
// 18
|
|
// Meteor._SynchronousQueue is a queue which runs task functions serially. // 19
|
|
// Tasks are assumed to be synchronous: ie, it's assumed that they are // 20
|
|
// done when they return. // 21
|
|
// // 22
|
|
// It has two methods: // 23
|
|
// - queueTask queues a task to be run, and returns immediately. // 24
|
|
// - runTask queues a task to be run, and then yields. It returns // 25
|
|
// when the task finishes running. // 26
|
|
// // 27
|
|
// It's safe to call queueTask from within a task, but not runTask (unless // 28
|
|
// you're calling runTask from a nested Fiber). // 29
|
|
// // 30
|
|
// Somewhat inspired by async.queue, but specific to blocking tasks. // 31
|
|
// XXX break this out into an NPM module? // 32
|
|
// XXX could maybe use the npm 'schlock' module instead, which would // 33
|
|
// also support multiple concurrent "read" tasks // 34
|
|
// // 35
|
|
Meteor._SynchronousQueue = function () { // 36
|
|
var self = this; // 37
|
|
// List of tasks to run (not including a currently-running task if any). Each // 38
|
|
// is an object with field 'task' (the task function to run) and 'future' (the // 39
|
|
// Future associated with the blocking runTask call that queued it, or null if // 40
|
|
// called from queueTask). // 41
|
|
self._taskHandles = new Meteor._DoubleEndedQueue(); // 42
|
|
// This is true if self._run() is either currently executing or scheduled to // 43
|
|
// do so soon. // 44
|
|
self._runningOrRunScheduled = false; // 45
|
|
// During the execution of a task, this is set to the fiber used to execute // 46
|
|
// that task. We use this to throw an error rather than deadlocking if the // 47
|
|
// user calls runTask from within a task on the same fiber. // 48
|
|
self._currentTaskFiber = undefined; // 49
|
|
// This is true if we're currently draining. While we're draining, a further // 50
|
|
// drain is a noop, to prevent infinite loops. "drain" is a heuristic type // 51
|
|
// operation, that has a meaning like unto "what a naive person would expect // 52
|
|
// when modifying a table from an observe" // 53
|
|
self._draining = false; // 54
|
|
}; // 55
|
|
// 56
|
|
_.extend(Meteor._SynchronousQueue.prototype, { // 57
|
|
runTask: function (task) { // 58
|
|
var self = this; // 59
|
|
// 60
|
|
if (!self.safeToRunTask()) { // 61
|
|
if (Fiber.current) // 62
|
|
throw new Error("Can't runTask from another task in the same fiber"); // 63
|
|
else // 64
|
|
throw new Error("Can only call runTask in a Fiber"); // 65
|
|
} // 66
|
|
// 67
|
|
var fut = new Future; // 68
|
|
var handle = { // 69
|
|
task: Meteor.bindEnvironment(task, function (e) { // 70
|
|
Meteor._debug("Exception from task:", e && e.stack || e); // 71
|
|
throw e; // 72
|
|
}), // 73
|
|
future: fut, // 74
|
|
name: task.name // 75
|
|
}; // 76
|
|
self._taskHandles.push(handle); // 77
|
|
self._scheduleRun(); // 78
|
|
// Yield. We'll get back here after the task is run (and will throw if the // 79
|
|
// task throws). // 80
|
|
fut.wait(); // 81
|
|
}, // 82
|
|
queueTask: function (task) { // 83
|
|
var self = this; // 84
|
|
self._taskHandles.push({ // 85
|
|
task: task, // 86
|
|
name: task.name // 87
|
|
}); // 88
|
|
self._scheduleRun(); // 89
|
|
// No need to block. // 90
|
|
}, // 91
|
|
// 92
|
|
flush: function () { // 93
|
|
var self = this; // 94
|
|
self.runTask(function () {}); // 95
|
|
}, // 96
|
|
// 97
|
|
safeToRunTask: function () { // 98
|
|
var self = this; // 99
|
|
return Fiber.current && self._currentTaskFiber !== Fiber.current; // 100
|
|
}, // 101
|
|
// 102
|
|
drain: function () { // 103
|
|
var self = this; // 104
|
|
if (self._draining) // 105
|
|
return; // 106
|
|
if (!self.safeToRunTask()) // 107
|
|
return; // 108
|
|
self._draining = true; // 109
|
|
while (! self._taskHandles.isEmpty()) { // 110
|
|
self.flush(); // 111
|
|
} // 112
|
|
self._draining = false; // 113
|
|
}, // 114
|
|
// 115
|
|
_scheduleRun: function () { // 116
|
|
var self = this; // 117
|
|
// Already running or scheduled? Do nothing. // 118
|
|
if (self._runningOrRunScheduled) // 119
|
|
return; // 120
|
|
// 121
|
|
self._runningOrRunScheduled = true; // 122
|
|
setImmediate(function () { // 123
|
|
Fiber(function () { // 124
|
|
self._run(); // 125
|
|
}).run(); // 126
|
|
}); // 127
|
|
}, // 128
|
|
_run: function () { // 129
|
|
var self = this; // 130
|
|
// 131
|
|
if (!self._runningOrRunScheduled) // 132
|
|
throw new Error("expected to be _runningOrRunScheduled"); // 133
|
|
// 134
|
|
if (self._taskHandles.isEmpty()) { // 135
|
|
// Done running tasks! Don't immediately schedule another run, but // 136
|
|
// allow future tasks to do so. // 137
|
|
self._runningOrRunScheduled = false; // 138
|
|
return; // 139
|
|
} // 140
|
|
var taskHandle = self._taskHandles.shift(); // 141
|
|
// 142
|
|
// Run the task. // 143
|
|
self._currentTaskFiber = Fiber.current; // 144
|
|
var exception = undefined; // 145
|
|
try { // 146
|
|
taskHandle.task(); // 147
|
|
} catch (err) { // 148
|
|
if (taskHandle.future) { // 149
|
|
// We'll throw this exception through runTask. // 150
|
|
exception = err; // 151
|
|
} else { // 152
|
|
Meteor._debug("Exception in queued task: " + (err.stack || err)); // 153
|
|
} // 154
|
|
} // 155
|
|
self._currentTaskFiber = undefined; // 156
|
|
// 157
|
|
// Soon, run the next task, if there is any. // 158
|
|
self._runningOrRunScheduled = false; // 159
|
|
self._scheduleRun(); // 160
|
|
// 161
|
|
// If this was queued with runTask, let the runTask call return (throwing if // 162
|
|
// the task threw). // 163
|
|
if (taskHandle.future) { // 164
|
|
if (exception) // 165
|
|
taskHandle.future['throw'](exception); // 166
|
|
else // 167
|
|
taskHandle.future['return'](); // 168
|
|
} // 169
|
|
} // 170
|
|
}); // 171
|
|
// 172
|
|
// Sleep. Mostly used for debugging (eg, inserting latency into server // 173
|
|
// methods). // 174
|
|
// // 175
|
|
Meteor._sleepForMs = function (ms) { // 176
|
|
var fiber = Fiber.current; // 177
|
|
setTimeout(function() { // 178
|
|
fiber.run(); // 179
|
|
}, ms); // 180
|
|
Fiber.yield(); // 181
|
|
}; // 182
|
|
// 183
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/startup_server.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
Meteor.startup = function (callback) { // 1
|
|
if (__meteor_bootstrap__.startupHooks) { // 2
|
|
__meteor_bootstrap__.startupHooks.push(callback); // 3
|
|
} else { // 4
|
|
// We already started up. Just call it now. // 5
|
|
callback(); // 6
|
|
} // 7
|
|
}; // 8
|
|
// 9
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/debug.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
var suppress = 0; // 1
|
|
// 2
|
|
// replacement for console.log. This is a temporary API. We should // 3
|
|
// provide a real logging API soon (possibly just a polyfill for // 4
|
|
// console?) // 5
|
|
// // 6
|
|
// NOTE: this is used on the server to print the warning about // 7
|
|
// having autopublish enabled when you probably meant to turn it // 8
|
|
// off. it's not really the proper use of something called // 9
|
|
// _debug. the intent is for this message to go to the terminal and // 10
|
|
// be very visible. if you change _debug to go someplace else, etc, // 11
|
|
// please fix the autopublish code to do something reasonable. // 12
|
|
// // 13
|
|
Meteor._debug = function (/* arguments */) { // 14
|
|
if (suppress) { // 15
|
|
suppress--; // 16
|
|
return; // 17
|
|
} // 18
|
|
if (typeof console !== 'undefined' && // 19
|
|
typeof console.log !== 'undefined') { // 20
|
|
if (arguments.length == 0) { // IE Companion breaks otherwise // 21
|
|
// IE10 PP4 requires at least one argument // 22
|
|
console.log(''); // 23
|
|
} else { // 24
|
|
// IE doesn't have console.log.apply, it's not a real Object. // 25
|
|
// http://stackoverflow.com/questions/5538972/console-log-apply-not-working-in-ie9 // 26
|
|
// http://patik.com/blog/complete-cross-browser-console-log/ // 27
|
|
if (typeof console.log.apply === "function") { // 28
|
|
// Most browsers // 29
|
|
// 30
|
|
// Chrome and Safari only hyperlink URLs to source files in first argument of // 31
|
|
// console.log, so try to call it with one argument if possible. // 32
|
|
// Approach taken here: If all arguments are strings, join them on space. // 33
|
|
// See https://github.com/meteor/meteor/pull/732#issuecomment-13975991 // 34
|
|
var allArgumentsOfTypeString = true; // 35
|
|
for (var i = 0; i < arguments.length; i++) // 36
|
|
if (typeof arguments[i] !== "string") // 37
|
|
allArgumentsOfTypeString = false; // 38
|
|
// 39
|
|
if (allArgumentsOfTypeString) // 40
|
|
console.log.apply(console, [Array.prototype.join.call(arguments, " ")]); // 41
|
|
else // 42
|
|
console.log.apply(console, arguments); // 43
|
|
// 44
|
|
} else if (typeof Function.prototype.bind === "function") { // 45
|
|
// IE9 // 46
|
|
var log = Function.prototype.bind.call(console.log, console); // 47
|
|
log.apply(console, arguments); // 48
|
|
} else { // 49
|
|
// IE8 // 50
|
|
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); // 51
|
|
} // 52
|
|
} // 53
|
|
} // 54
|
|
}; // 55
|
|
// 56
|
|
// Suppress the next 'count' Meteor._debug messsages. Use this to // 57
|
|
// stop tests from spamming the console. // 58
|
|
// // 59
|
|
Meteor._suppress_log = function (count) { // 60
|
|
suppress += count; // 61
|
|
}; // 62
|
|
// 63
|
|
Meteor._suppressed_log_expected = function () { // 64
|
|
return suppress !== 0; // 65
|
|
}; // 66
|
|
// 67
|
|
// 68
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/string_utils.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Like Perl's quotemeta: quotes all regexp metacharacters. // 1
|
|
// Code taken from // 2
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions // 3
|
|
Meteor._escapeRegExp = function (string) { // 4
|
|
return String(string).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // 5
|
|
}; // 6
|
|
// 7
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/dynamics_nodejs.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Fiber-aware implementation of dynamic scoping, for use on the server // 1
|
|
// 2
|
|
var Fiber = Npm.require('fibers'); // 3
|
|
// 4
|
|
var nextSlot = 0; // 5
|
|
// 6
|
|
Meteor._nodeCodeMustBeInFiber = function () { // 7
|
|
if (!Fiber.current) { // 8
|
|
throw new Error("Meteor code must always run within a Fiber. " + // 9
|
|
"Try wrapping callbacks that you pass to non-Meteor " + // 10
|
|
"libraries with Meteor.bindEnvironment."); // 11
|
|
} // 12
|
|
}; // 13
|
|
// 14
|
|
Meteor.EnvironmentVariable = function () { // 15
|
|
this.slot = nextSlot++; // 16
|
|
}; // 17
|
|
// 18
|
|
_.extend(Meteor.EnvironmentVariable.prototype, { // 19
|
|
get: function () { // 20
|
|
Meteor._nodeCodeMustBeInFiber(); // 21
|
|
// 22
|
|
return Fiber.current._meteor_dynamics && // 23
|
|
Fiber.current._meteor_dynamics[this.slot]; // 24
|
|
}, // 25
|
|
// 26
|
|
// Most Meteor code ought to run inside a fiber, and the // 27
|
|
// _nodeCodeMustBeInFiber assertion helps you remember to include appropriate // 28
|
|
// bindEnvironment calls (which will get you the *right value* for your // 29
|
|
// environment variables, on the server). // 30
|
|
// // 31
|
|
// In some very special cases, it's more important to run Meteor code on the // 32
|
|
// server in non-Fiber contexts rather than to strongly enforce the safeguard // 33
|
|
// against forgetting to use bindEnvironment. For example, using `check` in // 34
|
|
// some top-level constructs like connect handlers without needing unnecessary // 35
|
|
// Fibers on every request is more important that possibly failing to find the // 36
|
|
// correct argumentChecker. So this function is just like get(), but it // 37
|
|
// returns null rather than throwing when called from outside a Fiber. (On the // 38
|
|
// client, it is identical to get().) // 39
|
|
getOrNullIfOutsideFiber: function () { // 40
|
|
if (!Fiber.current) // 41
|
|
return null; // 42
|
|
return this.get(); // 43
|
|
}, // 44
|
|
// 45
|
|
withValue: function (value, func) { // 46
|
|
Meteor._nodeCodeMustBeInFiber(); // 47
|
|
// 48
|
|
if (!Fiber.current._meteor_dynamics) // 49
|
|
Fiber.current._meteor_dynamics = []; // 50
|
|
var currentValues = Fiber.current._meteor_dynamics; // 51
|
|
// 52
|
|
var saved = currentValues[this.slot]; // 53
|
|
try { // 54
|
|
currentValues[this.slot] = value; // 55
|
|
var ret = func(); // 56
|
|
} finally { // 57
|
|
currentValues[this.slot] = saved; // 58
|
|
} // 59
|
|
// 60
|
|
return ret; // 61
|
|
} // 62
|
|
}); // 63
|
|
// 64
|
|
// Meteor application code is always supposed to be run inside a // 65
|
|
// fiber. bindEnvironment ensures that the function it wraps is run from // 66
|
|
// inside a fiber and ensures it sees the values of Meteor environment // 67
|
|
// variables that are set at the time bindEnvironment is called. // 68
|
|
// // 69
|
|
// If an environment-bound function is called from outside a fiber (eg, from // 70
|
|
// an asynchronous callback from a non-Meteor library such as MongoDB), it'll // 71
|
|
// kick off a new fiber to execute the function, and returns undefined as soon // 72
|
|
// as that fiber returns or yields (and func's return value is ignored). // 73
|
|
// // 74
|
|
// If it's called inside a fiber, it works normally (the // 75
|
|
// return value of the function will be passed through, and no new // 76
|
|
// fiber will be created.) // 77
|
|
// // 78
|
|
// `onException` should be a function or a string. When it is a // 79
|
|
// function, it is called as a callback when the bound function raises // 80
|
|
// an exception. If it is a string, it should be a description of the // 81
|
|
// callback, and when an exception is raised a debug message will be // 82
|
|
// printed with the description. // 83
|
|
Meteor.bindEnvironment = function (func, onException, _this) { // 84
|
|
Meteor._nodeCodeMustBeInFiber(); // 85
|
|
// 86
|
|
var boundValues = _.clone(Fiber.current._meteor_dynamics || []); // 87
|
|
// 88
|
|
if (!onException || typeof(onException) === 'string') { // 89
|
|
var description = onException || "callback of async function"; // 90
|
|
onException = function (error) { // 91
|
|
Meteor._debug( // 92
|
|
"Exception in " + description + ":", // 93
|
|
error && error.stack || error // 94
|
|
); // 95
|
|
}; // 96
|
|
} else if (typeof(onException) !== 'function') { // 97
|
|
throw new Error('onException argument must be a function, string or undefined for Meteor.bindEnvironment().');
|
|
} // 99
|
|
// 100
|
|
return function (/* arguments */) { // 101
|
|
var args = _.toArray(arguments); // 102
|
|
// 103
|
|
var runWithEnvironment = function () { // 104
|
|
var savedValues = Fiber.current._meteor_dynamics; // 105
|
|
try { // 106
|
|
// Need to clone boundValues in case two fibers invoke this // 107
|
|
// function at the same time // 108
|
|
Fiber.current._meteor_dynamics = _.clone(boundValues); // 109
|
|
var ret = func.apply(_this, args); // 110
|
|
} catch (e) { // 111
|
|
// note: callback-hook currently relies on the fact that if onException // 112
|
|
// throws and you were originally calling the wrapped callback from // 113
|
|
// within a Fiber, the wrapped call throws. // 114
|
|
onException(e); // 115
|
|
} finally { // 116
|
|
Fiber.current._meteor_dynamics = savedValues; // 117
|
|
} // 118
|
|
return ret; // 119
|
|
}; // 120
|
|
// 121
|
|
if (Fiber.current) // 122
|
|
return runWithEnvironment(); // 123
|
|
Fiber(runWithEnvironment).run(); // 124
|
|
}; // 125
|
|
}; // 126
|
|
// 127
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/url_server.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
if (process.env.ROOT_URL && // 1
|
|
typeof __meteor_runtime_config__ === "object") { // 2
|
|
__meteor_runtime_config__.ROOT_URL = process.env.ROOT_URL; // 3
|
|
if (__meteor_runtime_config__.ROOT_URL) { // 4
|
|
var parsedUrl = Npm.require('url').parse(__meteor_runtime_config__.ROOT_URL); // 5
|
|
// Sometimes users try to pass, eg, ROOT_URL=mydomain.com. // 6
|
|
if (!parsedUrl.host) { // 7
|
|
throw Error("$ROOT_URL, if specified, must be an URL"); // 8
|
|
} // 9
|
|
var pathPrefix = parsedUrl.pathname; // 10
|
|
if (pathPrefix.slice(-1) === '/') { // 11
|
|
// remove trailing slash (or turn "/" into "") // 12
|
|
pathPrefix = pathPrefix.slice(0, -1); // 13
|
|
} // 14
|
|
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = pathPrefix; // 15
|
|
} else { // 16
|
|
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = ""; // 17
|
|
} // 18
|
|
} // 19
|
|
// 20
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/url_common.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
/** // 1
|
|
* @summary Generate an absolute URL pointing to the application. The server reads from the `ROOT_URL` environment variable to determine where it is running. This is taken care of automatically for apps deployed with `meteor deploy`, but must be provided when using `meteor build`.
|
|
* @locus Anywhere // 3
|
|
* @param {String} [path] A path to append to the root URL. Do not include a leading "`/`". // 4
|
|
* @param {Object} [options] // 5
|
|
* @param {Boolean} options.secure Create an HTTPS URL. // 6
|
|
* @param {Boolean} options.replaceLocalhost Replace localhost with 127.0.0.1. Useful for services that don't recognize localhost as a domain name.
|
|
* @param {String} options.rootUrl Override the default ROOT_URL from the server environment. For example: "`http://foo.example.com`"
|
|
*/ // 9
|
|
Meteor.absoluteUrl = function (path, options) { // 10
|
|
// path is optional // 11
|
|
if (!options && typeof path === 'object') { // 12
|
|
options = path; // 13
|
|
path = undefined; // 14
|
|
} // 15
|
|
// merge options with defaults // 16
|
|
options = _.extend({}, Meteor.absoluteUrl.defaultOptions, options || {}); // 17
|
|
// 18
|
|
var url = options.rootUrl; // 19
|
|
if (!url) // 20
|
|
throw new Error("Must pass options.rootUrl or set ROOT_URL in the server environment"); // 21
|
|
// 22
|
|
if (!/^http[s]?:\/\//i.test(url)) // url starts with 'http://' or 'https://' // 23
|
|
url = 'http://' + url; // we will later fix to https if options.secure is set // 24
|
|
// 25
|
|
if (!/\/$/.test(url)) // url ends with '/' // 26
|
|
url += '/'; // 27
|
|
// 28
|
|
if (path) // 29
|
|
url += path; // 30
|
|
// 31
|
|
// turn http to https if secure option is set, and we're not talking // 32
|
|
// to localhost. // 33
|
|
if (options.secure && // 34
|
|
/^http:/.test(url) && // url starts with 'http:' // 35
|
|
!/http:\/\/localhost[:\/]/.test(url) && // doesn't match localhost // 36
|
|
!/http:\/\/127\.0\.0\.1[:\/]/.test(url)) // or 127.0.0.1 // 37
|
|
url = url.replace(/^http:/, 'https:'); // 38
|
|
// 39
|
|
if (options.replaceLocalhost) // 40
|
|
url = url.replace(/^http:\/\/localhost([:\/].*)/, 'http://127.0.0.1$1'); // 41
|
|
// 42
|
|
return url; // 43
|
|
}; // 44
|
|
// 45
|
|
// allow later packages to override default options // 46
|
|
Meteor.absoluteUrl.defaultOptions = { }; // 47
|
|
if (typeof __meteor_runtime_config__ === "object" && // 48
|
|
__meteor_runtime_config__.ROOT_URL) // 49
|
|
Meteor.absoluteUrl.defaultOptions.rootUrl = __meteor_runtime_config__.ROOT_URL; // 50
|
|
// 51
|
|
// 52
|
|
Meteor._relativeToSiteRootUrl = function (link) { // 53
|
|
if (typeof __meteor_runtime_config__ === "object" && // 54
|
|
link.substr(0, 1) === "/") // 55
|
|
link = (__meteor_runtime_config__.ROOT_URL_PATH_PREFIX || "") + link; // 56
|
|
return link; // 57
|
|
}; // 58
|
|
// 59
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function(){
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/meteor/flush-buffers-on-exit-in-windows.js //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
if (process.platform === "win32") { // 1
|
|
/* // 2
|
|
* Based on https://github.com/cowboy/node-exit // 3
|
|
* // 4
|
|
* Copyright (c) 2013 "Cowboy" Ben Alman // 5
|
|
* Licensed under the MIT license. // 6
|
|
*/ // 7
|
|
var origProcessExit = process.exit.bind(process); // 8
|
|
process.exit = function (exitCode) { // 9
|
|
var streams = [process.stdout, process.stderr]; // 10
|
|
var drainCount = 0; // 11
|
|
// Actually exit if all streams are drained. // 12
|
|
function tryToExit() { // 13
|
|
if (drainCount === streams.length) { // 14
|
|
origProcessExit(exitCode); // 15
|
|
} // 16
|
|
} // 17
|
|
streams.forEach(function(stream) { // 18
|
|
// Count drained streams now, but monitor non-drained streams. // 19
|
|
if (stream.bufferSize === 0) { // 20
|
|
drainCount++; // 21
|
|
} else { // 22
|
|
stream.write('', 'utf-8', function() { // 23
|
|
drainCount++; // 24
|
|
tryToExit(); // 25
|
|
}); // 26
|
|
} // 27
|
|
// Prevent further writing. // 28
|
|
stream.write = function() {}; // 29
|
|
}); // 30
|
|
// If all streams were already drained, exit now. // 31
|
|
tryToExit(); // 32
|
|
// In Windows, when run as a Node.js child process, a script utilizing // 33
|
|
// this library might just exit with a 0 exit code, regardless. This code, // 34
|
|
// despite the fact that it looks a bit crazy, appears to fix that. // 35
|
|
process.on('exit', function() { // 36
|
|
origProcessExit(exitCode); // 37
|
|
}); // 38
|
|
}; // 39
|
|
} // 40
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
/* Exports */
|
|
if (typeof Package === 'undefined') Package = {};
|
|
Package.meteor = {
|
|
Meteor: Meteor
|
|
};
|
|
|
|
})();
|
|
|
|
//# sourceMappingURL=meteor.js.map
|