mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'devel' into release-1.3.3
This commit is contained in:
15
History.md
15
History.md
@@ -16,6 +16,11 @@
|
||||
* Allow using authType in Facebook login [PR #5694](https://github.com/meteor/meteor/pull/5694)
|
||||
|
||||
* Adds flush() method to Tracker to force recomputation [PR #4710](https://github.com/meteor/meteor/pull/4710)
|
||||
* Adds `defineMutationMethods` option (default: true) to `new Mongo.Collection` to override default behavior that sets up mutation methods (/collection/[insert|update...]) [PR #5778](https://github.com/meteor/meteor/pull/5778)
|
||||
* Allow overridding the default warehouse url by specifying `METEOR_WAREHOUSE_URLBASE` [PR #7054](https://github.com/meteor/meteor/pull/7054)
|
||||
* Allow `_id` in `$setOnInsert` in Minimongo: https://github.com/meteor/meteor/pull/7066
|
||||
* Added support for `$eq` to Minimongo: https://github.com/meteor/meteor/pull/4235
|
||||
* Insert a `Date` header into emails by default: https://github.com/meteor/meteor/pull/6916/files
|
||||
|
||||
* DDP callbacks are now batched on the client side. This means that after a DDP message arrives, the local DDP client will batch changes for a minimum of 5ms (configurable via `bufferedWritesInterval`) and a maximum of 500ms (configurable via `bufferedWritesMaxAge`) before calling any callbacks (such as cursor observe callbacks).
|
||||
|
||||
@@ -71,16 +76,14 @@
|
||||
* The `npm-bcrypt` package has been upgraded to use the latest version
|
||||
(0.8.5) of the `bcrypt` npm package.
|
||||
|
||||
* `Match.Optional` only passes if the value is `null` or the specified
|
||||
type, whereas previously it accepted `undefined`. Use `Match.Maybe` to
|
||||
allow `undefined`. #6735
|
||||
|
||||
* Compiler plugins can call `addJavaScript({ path })` multiple times with
|
||||
different paths for the same source file, and `module.id` will reflect
|
||||
this `path` instead of the source path, if they are different. #6806
|
||||
|
||||
* Fixed bugs: https://github.com/meteor/meteor/milestones/Release%201.3.2
|
||||
|
||||
* Fixed unintended change to `Match.Optional` which caused it to behave the same as the new `Match.Maybe` and incorrectly matching `null` where it previously would not have allowed it. #6735
|
||||
|
||||
## v1.3.1
|
||||
|
||||
* Long isopacket node_modules paths have been shortened, fixing upgrade
|
||||
@@ -303,6 +306,10 @@
|
||||
* Improve automatic blocking of URLs in attribute values to also
|
||||
include `vbscript:` URLs.
|
||||
|
||||
### Check
|
||||
|
||||
* Introduced new matcher `Match.Maybe(type)` which will also match (permit) `null` in addition to `undefined`. This is a suggested replacement (where appropriate) for `Match.Optional` which did not permit `null`. This prevents the need to use `Match.OneOf(null, undefined, type)`. #6220
|
||||
|
||||
### Testing
|
||||
|
||||
* Packages can now be marked as `testOnly` to only run as part of app
|
||||
|
||||
@@ -70,8 +70,9 @@ CollectionPrototype.deny = function(options) {
|
||||
addValidator(this, 'deny', options);
|
||||
};
|
||||
|
||||
CollectionPrototype._defineMutationMethods = function() {
|
||||
CollectionPrototype._defineMutationMethods = function(options) {
|
||||
const self = this;
|
||||
options = options || {};
|
||||
|
||||
// set to true once we call any allow or deny methods. If true, use
|
||||
// allow/deny semantics. If false, use insecure mode semantics.
|
||||
@@ -99,12 +100,26 @@ CollectionPrototype._defineMutationMethods = function() {
|
||||
// "Meteor:Mongo:insert/NAME"?
|
||||
self._prefix = '/' + self._name + '/';
|
||||
|
||||
// mutation methods
|
||||
if (self._connection) {
|
||||
// Mutation Methods
|
||||
// Minimongo on the server gets no stubs; instead, by default
|
||||
// it wait()s until its result is ready, yielding.
|
||||
// This matches the behavior of macromongo on the server better.
|
||||
// XXX see #MeteorServerNull
|
||||
if (self._connection && (self._connection === Meteor.server || Meteor.isClient)) {
|
||||
const m = {};
|
||||
|
||||
_.each(['insert', 'update', 'remove'], function (method) {
|
||||
m[self._prefix + method] = function (/* ... */) {
|
||||
const methodName = self._prefix + method;
|
||||
|
||||
if (options.useExisting) {
|
||||
const handlerPropName = Meteor.isClient ? '_methodHandlers' : 'method_handlers';
|
||||
// Do not try to create additional methods if this has already been called.
|
||||
// (Otherwise the .methods() call below will throw an error.)
|
||||
if (self._connection[handlerPropName] &&
|
||||
typeof self._connection[handlerPropName][methodName] === 'function') return;
|
||||
}
|
||||
|
||||
m[methodName] = function (/* ... */) {
|
||||
// All the methods do their own validation, instead of using check().
|
||||
check(arguments, [Match.Any]);
|
||||
const args = _.toArray(arguments);
|
||||
@@ -183,12 +198,8 @@ CollectionPrototype._defineMutationMethods = function() {
|
||||
}
|
||||
};
|
||||
});
|
||||
// Minimongo on the server gets no stubs; instead, by default
|
||||
// it wait()s until its result is ready, yielding.
|
||||
// This matches the behavior of macromongo on the server better.
|
||||
// XXX see #MeteorServerNull
|
||||
if (Meteor.isClient || self._connection === Meteor.server)
|
||||
self._connection.methods(m);
|
||||
|
||||
self._connection.methods(m);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -178,6 +178,10 @@ Email.send = function (options) {
|
||||
mc.addHeader(name, value);
|
||||
});
|
||||
|
||||
if (!options.headers.hasOwnProperty('Date')) {
|
||||
mc.addHeader('Date', new Date().toUTCString().replace(/GMT/, '+0000'));
|
||||
}
|
||||
|
||||
_.each(options.attachments, function(attachment){
|
||||
mc.addAttachment(attachment);
|
||||
});
|
||||
|
||||
@@ -13,7 +13,10 @@ Tinytest.add("email - dev mode smoke test", function (test) {
|
||||
cc: ["friends@example.com", "enemies@example.com"],
|
||||
subject: "This is the subject",
|
||||
text: "This is the body\nof the message\nFrom us.",
|
||||
headers: {'X-Meteor-Test': 'a custom header'}
|
||||
headers: {
|
||||
'X-Meteor-Test': 'a custom header',
|
||||
'Date': 'dummy',
|
||||
},
|
||||
});
|
||||
// XXX brittle if mailcomposer changes header order, etc
|
||||
test.equal(stream.getContentsAsString("utf8"),
|
||||
@@ -22,6 +25,7 @@ Tinytest.add("email - dev mode smoke test", function (test) {
|
||||
"environment variable.)\n" +
|
||||
"MIME-Version: 1.0\r\n" +
|
||||
"X-Meteor-Test: a custom header\r\n" +
|
||||
"Date: dummy\r\n" +
|
||||
"From: foo@example.com\r\n" +
|
||||
"To: bar@example.com\r\n" +
|
||||
"Cc: friends@example.com, enemies@example.com\r\n" +
|
||||
@@ -52,6 +56,20 @@ Tinytest.add("email - dev mode smoke test", function (test) {
|
||||
"\r\n" +
|
||||
"body\r\n" +
|
||||
"====== END MAIL #1 ======\n");
|
||||
|
||||
// Test if date header is automaticall generated, if not specified
|
||||
Email.send({
|
||||
from: "foo@example.com",
|
||||
to: "bar@example.com",
|
||||
subject: "This is the subject",
|
||||
text: "This is the body\nof the message\nFrom us.",
|
||||
headers: {
|
||||
'X-Meteor-Test': 'a custom header',
|
||||
},
|
||||
});
|
||||
|
||||
test.matches(stream.getContentsAsString("utf8"),
|
||||
/^Date: .+$/m);
|
||||
} finally {
|
||||
EmailTest.restoreOutputStream();
|
||||
}
|
||||
|
||||
@@ -527,6 +527,10 @@ Tinytest.add("minimongo - sorter and projection combination", function (test) {
|
||||
// XXX this test should be F, but since it is so hard to be precise in
|
||||
// floating point math, the current implementation falls back to T
|
||||
T({ a: { $gt: 9.999999999999999, $lt: 10 }, x: 1 }, { $set: { x: 1 } }, "very close $gt and $lt");
|
||||
T({ a: { $eq: 5 } }, { $set: { a: 5 } }, "set of $eq");
|
||||
T({ a: { $eq: 5 }, b: { $eq: 7 } }, { $set: { a: 5 } }, "set of $eq with other $eq");
|
||||
F({ a: { $eq: 5 } }, { $set: { a: 4 } }, "set below of $eq");
|
||||
F({ a: { $eq: 5 } }, { $set: { a: 6 } }, "set above of $eq");
|
||||
T({ a: { $ne: 5 } }, { $unset: { a: 1 } }, "unset of $ne");
|
||||
T({ a: { $ne: 5 } }, { $set: { a: 1 } }, "set of $ne");
|
||||
T({ a: { $ne: "some string" }, x: 1 }, { $set: { x: 1 } }, "$ne dummy");
|
||||
@@ -549,6 +553,11 @@ Tinytest.add("minimongo - sorter and projection combination", function (test) {
|
||||
|
||||
Tinytest.add("minimongo - can selector become true by modifier - $-nonscalar selectors and simple tests", function (t) {
|
||||
test = t;
|
||||
T({ a: { $eq: { x: 5 } } }, { $set: { 'a.x': 5 } }, "set of $eq");
|
||||
// XXX this test should be F, but it is not implemented yet
|
||||
T({ a: { $eq: { x: 5 } } }, { $set: { 'a.x': 4 } }, "set of $eq");
|
||||
// XXX this test should be F, but it is not implemented yet
|
||||
T({ a: { $eq: { x: 5 } } }, { $set: { 'a.y': 4 } }, "set of $eq");
|
||||
T({ a: { $ne: { x: 5 } } }, { $set: { 'a.x': 3 } }, "set of $ne");
|
||||
// XXX this test should be F, but it is not implemented yet
|
||||
T({ a: { $ne: { x: 5 } } }, { $set: { 'a.x': 5 } }, "set of $ne");
|
||||
@@ -560,4 +569,3 @@ Tinytest.add("minimongo - sorter and projection combination", function (test) {
|
||||
T({ a: { $ne: { a: 2 } } }, { $set: { a: { a: 2 } } }, "$ne object");
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -510,6 +510,23 @@ Tinytest.add("minimongo - selector_compiler", function (test) {
|
||||
});
|
||||
});
|
||||
|
||||
// $eq
|
||||
nomatch({a: {$eq: 1}}, {a: 2});
|
||||
match({a: {$eq: 2}}, {a: 2});
|
||||
nomatch({a: {$eq: [1]}}, {a: [2]});
|
||||
|
||||
match({a: {$eq: [1, 2]}}, {a: [1, 2]});
|
||||
match({a: {$eq: 1}}, {a: [1, 2]});
|
||||
match({a: {$eq: 2}}, {a: [1, 2]});
|
||||
nomatch({a: {$eq: 3}}, {a: [1, 2]});
|
||||
match({'a.b': {$eq: 1}}, {a: [{b: 1}, {b: 2}]});
|
||||
match({'a.b': {$eq: 2}}, {a: [{b: 1}, {b: 2}]});
|
||||
nomatch({'a.b': {$eq: 3}}, {a: [{b: 1}, {b: 2}]});
|
||||
|
||||
match({a: {$eq: {x: 1}}}, {a: {x: 1}});
|
||||
nomatch({a: {$eq: {x: 1}}}, {a: {x: 2}});
|
||||
nomatch({a: {$eq: {x: 1}}}, {a: {x: 1, y: 2}});
|
||||
|
||||
// $ne
|
||||
match({a: {$ne: 1}}, {a: 2});
|
||||
nomatch({a: {$ne: 2}}, {a: 2});
|
||||
@@ -2085,6 +2102,23 @@ Tinytest.add("minimongo - modify", function (test) {
|
||||
exceptionWithQuery(doc, {}, mod);
|
||||
};
|
||||
|
||||
var upsert = function (query, mod, expected) {
|
||||
var coll = new LocalCollection;
|
||||
|
||||
var result = coll.upsert(query, mod);
|
||||
|
||||
var actual = coll.findOne();
|
||||
|
||||
if (expected._id) {
|
||||
test.equal(result.insertedId, expected._id);
|
||||
}
|
||||
else {
|
||||
delete actual._id;
|
||||
}
|
||||
|
||||
test.equal(actual, expected);
|
||||
};
|
||||
|
||||
// document replacement
|
||||
modify({}, {}, {});
|
||||
modify({a: 12}, {}, {}); // tested against mongodb
|
||||
@@ -2406,6 +2440,13 @@ Tinytest.add("minimongo - modify", function (test) {
|
||||
exception({}, {$rename: {'a.b': 'a.b'}});
|
||||
modify({a: 12, b: 13}, {$rename: {a: 'b'}}, {b: 12});
|
||||
|
||||
// $setOnInsert
|
||||
modify({a: 0}, {$setOnInsert: {a: 12}}, {a: 0});
|
||||
upsert({a: 12}, {$setOnInsert: {b: 12}}, {a: 12, b: 12});
|
||||
upsert({a: 12}, {$setOnInsert: {_id: 'test'}}, {_id: 'test', a: 12});
|
||||
|
||||
exception({}, {$set: {_id: 'bad'}});
|
||||
|
||||
// $bit
|
||||
// unimplemented
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ LocalCollection._modify = function (doc, mod, options) {
|
||||
throw MinimongoError("An empty update path is not valid.");
|
||||
}
|
||||
|
||||
if (keypath === '_id') {
|
||||
if (keypath === '_id' && op !== '$setOnInsert') {
|
||||
throw MinimongoError("Mod on _id not allowed");
|
||||
}
|
||||
|
||||
|
||||
@@ -255,15 +255,13 @@ var operatorBranchedMatcher = function (valueSelector, matcher, isRoot) {
|
||||
|
||||
var operatorMatchers = [];
|
||||
_.each(valueSelector, function (operand, operator) {
|
||||
// XXX we should actually implement $eq, which is new in 2.6
|
||||
var simpleRange = _.contains(['$lt', '$lte', '$gt', '$gte'], operator) &&
|
||||
_.isNumber(operand);
|
||||
var simpleInequality = operator === '$ne' && !_.isObject(operand);
|
||||
var simpleEquality = _.contains(['$ne', '$eq'], operator) && !_.isObject(operand);
|
||||
var simpleInclusion = _.contains(['$in', '$nin'], operator) &&
|
||||
_.isArray(operand) && !_.any(operand, _.isObject);
|
||||
|
||||
if (! (operator === '$eq' || simpleRange ||
|
||||
simpleInclusion || simpleInequality)) {
|
||||
if (! (simpleRange || simpleInclusion || simpleEquality)) {
|
||||
matcher._isSimple = false;
|
||||
}
|
||||
|
||||
@@ -380,6 +378,10 @@ var invertBranchedMatcher = function (branchedMatcher) {
|
||||
// "match each branched value independently and combine with
|
||||
// convertElementMatcherToBranchedMatcher".
|
||||
var VALUE_OPERATORS = {
|
||||
$eq: function (operand) {
|
||||
return convertElementMatcherToBranchedMatcher(
|
||||
equalityElementMatcher(operand));
|
||||
},
|
||||
$not: function (operand, valueSelector, matcher) {
|
||||
return invertBranchedMatcher(compileValueSelector(operand, matcher));
|
||||
},
|
||||
|
||||
@@ -141,7 +141,9 @@ Minimongo.Matcher.prototype.matchingDocument = function () {
|
||||
// if there is a strict equality, there is a good
|
||||
// chance we can use one of those as "matching"
|
||||
// dummy value
|
||||
if (valueSelector.$in) {
|
||||
if (valueSelector.$eq) {
|
||||
return valueSelector.$eq;
|
||||
} else if (valueSelector.$in) {
|
||||
var matcher = new Minimongo.Matcher({ placeholder: valueSelector });
|
||||
|
||||
// Return anything from $in that matches the whole selector for this
|
||||
@@ -168,7 +170,7 @@ Minimongo.Matcher.prototype.matchingDocument = function () {
|
||||
fallback = true;
|
||||
|
||||
return middle;
|
||||
} else if (onlyContainsKeys(valueSelector, ['$nin',' $ne'])) {
|
||||
} else if (onlyContainsKeys(valueSelector, ['$nin', '$ne'])) {
|
||||
// Since self._isSimple makes sure $nin and $ne are not combined with
|
||||
// objects or arrays, we can confidently return an empty object as it
|
||||
// never matches any scalar.
|
||||
@@ -217,4 +219,3 @@ var startsWith = function(str, starts) {
|
||||
return str.length >= starts.length &&
|
||||
str.substring(0, starts.length) === starts;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ Mongo = {};
|
||||
|
||||
The default id generation technique is `'STRING'`.
|
||||
* @param {Function} options.transform An optional transformation function. Documents will be passed through this function before being returned from `fetch` or `findOne`, and before being passed to callbacks of `observe`, `map`, `forEach`, `allow`, and `deny`. Transforms are *not* applied for the callbacks of `observeChanges` or to cursors returned from publish functions.
|
||||
* @param {Boolean} options.defineMutationMethods Set to `false` to skip setting up the mutation methods that enable insert/update/remove from client code. Default `true`.
|
||||
*/
|
||||
Mongo.Collection = function (name, options) {
|
||||
var self = this;
|
||||
@@ -209,21 +210,41 @@ Mongo.Collection = function (name, options) {
|
||||
getDoc: function(id) {
|
||||
return self.findOne(id);
|
||||
},
|
||||
|
||||
|
||||
// To be able to get back to the collection from the store.
|
||||
_getCollection: function () {
|
||||
return self;
|
||||
}
|
||||
});
|
||||
|
||||
if (!ok)
|
||||
throw new Error("There is already a collection named '" + name + "'");
|
||||
if (!ok) {
|
||||
const message = `There is already a collection named "${name}"`;
|
||||
if (options._suppressSameNameError === true) {
|
||||
// XXX In theory we do not have to throw when `ok` is falsy. The store is already defined
|
||||
// for this collection name, but this will simply be another reference to it and everything
|
||||
// should work. However, we have historically thrown an error here, so for now we will
|
||||
// skip the error only when `_suppressSameNameError` is `true`, allowing people to opt in
|
||||
// and give this some real world testing.
|
||||
console.warn ? console.warn(message) : console.log(message);
|
||||
} else {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX don't define these until allow or deny is actually used for this
|
||||
// collection. Could be hard if the security rules are only defined on the
|
||||
// server.
|
||||
self._defineMutationMethods();
|
||||
if (options.defineMutationMethods !== false) {
|
||||
try {
|
||||
self._defineMutationMethods({ useExisting: (options._suppressSameNameError === true) });
|
||||
} catch (error) {
|
||||
// Throw a more understandable error on the server for same collection name
|
||||
if (error.message === `A method named '/${name}/insert' is already defined`)
|
||||
throw new Error(`There is already a collection named "${name}"`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// autopublish
|
||||
if (Package.autopublish && !options._preventAutopublish && self._connection
|
||||
|
||||
@@ -9,3 +9,46 @@ Tinytest.add(
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Tinytest.add('collection - call new Mongo.Collection multiple times',
|
||||
function (test) {
|
||||
var collectionName = 'multiple_times_1_' + test.id;
|
||||
new Mongo.Collection(collectionName);
|
||||
|
||||
test.throws(
|
||||
function () {
|
||||
new Mongo.Collection(collectionName);
|
||||
},
|
||||
/There is already a collection named/
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Tinytest.add('collection - call new Mongo.Collection multiple times with _suppressSameNameError=true',
|
||||
function (test) {
|
||||
var collectionName = 'multiple_times_2_' + test.id;
|
||||
new Mongo.Collection(collectionName);
|
||||
|
||||
try {
|
||||
new Mongo.Collection(collectionName, {_suppressSameNameError: true});
|
||||
test.ok();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
test.fail('Expected new Mongo.Collection not to throw an error when called twice with the same name');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Tinytest.add('collection - call new Mongo.Collection with defineMutationMethods=false',
|
||||
function (test) {
|
||||
var handlerPropName = Meteor.isClient ? '_methodHandlers' : 'method_handlers';
|
||||
|
||||
var methodCollectionName = 'hasmethods' + test.id;
|
||||
var hasmethods = new Mongo.Collection(methodCollectionName);
|
||||
test.equal(typeof hasmethods._connection[handlerPropName]['/' + methodCollectionName + '/insert'], 'function');
|
||||
|
||||
var noMethodCollectionName = 'nomethods' + test.id;
|
||||
var nomethods = new Mongo.Collection(noMethodCollectionName, {defineMutationMethods: false});
|
||||
test.equal(nomethods._connection[handlerPropName]['/' + noMethodCollectionName + '/insert'], undefined);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -16,6 +16,18 @@ Tinytest.add('ReactiveDict - setDefault', function (test) {
|
||||
dict.setDefault('D', undefined);
|
||||
test.equal(dict.all(), {A: 'blah', B: undefined,
|
||||
C: 'default', D: undefined});
|
||||
|
||||
dict = new ReactiveDict;
|
||||
dict.set('A', 'blah');
|
||||
dict.set('B', undefined);
|
||||
dict.setDefault({
|
||||
A: 'default',
|
||||
B: 'defualt',
|
||||
C: 'default',
|
||||
D: undefined
|
||||
});
|
||||
test.equal(dict.all(), {A: 'blah', B: undefined,
|
||||
C: 'default', D: undefined});
|
||||
});
|
||||
|
||||
Tinytest.add('ReactiveDict - all() works', function (test) {
|
||||
|
||||
@@ -79,8 +79,18 @@ _.extend(ReactiveDict.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
setDefault: function (key, value) {
|
||||
setDefault: function (keyOrObject, value) {
|
||||
var self = this;
|
||||
|
||||
if ((typeof keyOrObject === 'object') && (value === undefined)) {
|
||||
// Called as `dict.setDefault({...})`
|
||||
self._setDefaultObject(keyOrObject);
|
||||
return;
|
||||
}
|
||||
// the input isn't an object, so it must be a key
|
||||
// and we resume with the rest of the function
|
||||
var key = keyOrObject;
|
||||
|
||||
if (! _.has(self.keys, key)) {
|
||||
self.set(key, value);
|
||||
}
|
||||
@@ -198,6 +208,14 @@ _.extend(ReactiveDict.prototype, {
|
||||
});
|
||||
},
|
||||
|
||||
_setDefaultObject: function (object) {
|
||||
var self = this;
|
||||
|
||||
_.each(object, function (value, key){
|
||||
self.setDefault(key, value);
|
||||
});
|
||||
},
|
||||
|
||||
_ensureKey: function (key) {
|
||||
var self = this;
|
||||
if (!(key in self.keyDeps)) {
|
||||
|
||||
@@ -43,7 +43,9 @@ var files = require('../fs/files.js');
|
||||
var httpHelpers = require('../utils/http-helpers.js');
|
||||
var fiberHelpers = require('../utils/fiber-helpers.js');
|
||||
|
||||
var WAREHOUSE_URLBASE = 'https://warehouse.meteor.com';
|
||||
// Use `METEOR_WAREHOUSE_URLBASE` to override the default warehouse
|
||||
// url base.
|
||||
var WAREHOUSE_URLBASE = process.env.METEOR_WAREHOUSE_URLBASE || 'https://warehouse.meteor.com';
|
||||
|
||||
var warehouse = exports;
|
||||
_.extend(warehouse, {
|
||||
|
||||
@@ -13,6 +13,7 @@ var archinfo = require('../utils/archinfo.js');
|
||||
var config = require('../meteor-services/config.js');
|
||||
var buildmessage = require('../utils/buildmessage.js');
|
||||
var execFileSync = require('../utils/processes.js').execFileSync;
|
||||
var Builder = require('../isobuild/builder.js').default;
|
||||
|
||||
var catalog = require('../packaging/catalog/catalog.js');
|
||||
var catalogRemote = require('../packaging/catalog/catalog-remote.js');
|
||||
@@ -836,9 +837,14 @@ _.extend(Sandbox.prototype, {
|
||||
|
||||
var serverUrl = self.env.METEOR_PACKAGE_SERVER_URL;
|
||||
var packagesDirectoryName = config.getPackagesDirectoryName(serverUrl);
|
||||
files.cp_r(files.pathJoin(builtPackageTropohouseDir, 'packages'),
|
||||
files.pathJoin(self.warehouse, packagesDirectoryName),
|
||||
{ preserveSymlinks: true });
|
||||
|
||||
var builder = new Builder({outputPath: self.warehouse});
|
||||
builder.copyDirectory({
|
||||
from: files.pathJoin(builtPackageTropohouseDir, 'packages'),
|
||||
to: packagesDirectoryName,
|
||||
symlink: true
|
||||
});
|
||||
builder.complete();
|
||||
|
||||
var stubCatalog = {
|
||||
syncToken: {},
|
||||
|
||||
Reference in New Issue
Block a user