diff --git a/Contributing.md b/Contributing.md index 38fa0880ad..97671ca415 100644 --- a/Contributing.md +++ b/Contributing.md @@ -276,3 +276,7 @@ example that you just want to run the Spacebars test suite. Just simple do `./me ./packages/spacebars-tests` and it will just run the test files from that one package. You can examine the `package.js` file for the `onTest` block, it outlines all the test files that should be run. + +### Running Meteor Tool tests + +While TinyTest and the `test-packages` command can be used to test internal Meteor packages, they cannot be used to test the Meteor Tool itself. The Meteor Tool is a node app that uses a home-grown "self test" system. For details on how to run Meteor Tool "self tests", please refer to the [Testing section of the Meteor Tool README](https://github.com/meteor/meteor/blob/master/tools/README.md#testing). diff --git a/History.md b/History.md index b3a36ad74a..d73befad20 100644 --- a/History.md +++ b/History.md @@ -22,7 +22,16 @@ * Added support for frame-ancestors CSP option in browser-policy. [#7970](https://github.com/meteor/meteor/pull/7970) -* You can now use autoprefixer with stylus files added via packages [#7727](https://github.com/meteor/meteor/pull/7727) +* You can now use autoprefixer with stylus files added via packages. + [#7727](https://github.com/meteor/meteor/pull/7727) + +* The `"main"` field of `package.json` modules will no longer be + overwritten with the value of the optional `"browser"` field, now that + the `install` npm package can make sense of the `"browser"` field at + runtime. If you experience module resolution failures on the client + after updating Meteor, make sure you've updated the `modules-runtime` + Meteor package to at least version 0.7.8. + [#8213](https://github.com/meteor/meteor/pull/8213) ## v1.4.2.3 diff --git a/Roadmap.md b/Roadmap.md index 892fd7c6e3..94f3978295 100644 --- a/Roadmap.md +++ b/Roadmap.md @@ -1,42 +1,99 @@ -Meteor Roadmap -============== -This document describes the high level features the project has decided to prioritize in the near to medium term future. A large fraction of the MDG core engineering team's time will be dedicated to working on the features described here. -Contributors are encouraged to focus their efforts on work that aligns with the roadmap as maintainers will prioritize their time around these contributions. This however does not mean that PR's against other features and bugs will be automatically rejected. +# **Meteor Roadmap** -For the meantime, MDG won't be accepting PR's for changes to the roadmap. We hope to change this in the future as we figure out strategies to decentralize Meteor development. +**Last updated December 13, 2016** -## MongoDB updates +This document describes the high level features the Meteor project maintainers have decided to prioritize in the near- to medium-term future. A large fraction of the maintainers’ time will be dedicated to working on the features described here. As with any roadmap, this is a living document that will evolve as priorities and dependencies shift; we aim to update the roadmap with any changes or status updates on a monthly basis. -The mongo driver that currently ships with Meteor is old and doesn’t reliably work with connecting to MongoDB 3.2 databases (e.g [#6258](https://github.com/meteor/meteor/issues/6258)). We want to update to the latest driver [#5763](https://github.com/meteor/meteor/issues/5763). +Contributors are encouraged to focus their efforts on work that aligns with the roadmap as maintainers will prioritize their time spent reviewing PRs and issues around these contributions. This however does not mean that PRs against other features and bugs will automatically be rejected. -In addition, we'd like to update the dev bundle to ship with the latest stable version of MongoDB (3.2) [#5809](https://github.com/meteor/meteor/issues/5809) as MongoDB 2.6 will be officially sunsetted at the end of October, 2016. +Items can be added to this roadmap by first getting design approval for a solution to an open issue, as outlined by our [contributing guidelines](https://github.com/meteor/meteor/blob/devel/Contributing.md). Then, when a contributor has committed to solving the issue in the short to medium term, they can submit a PR to add that work to the roadmap. All other PRs to the roadmap will be rejected. -## Support for Node 4 and beyond -We want to be able to update the version of Node that ships with Meteor to 4 and eventually 6 [#5124](https://github.com/meteor/meteor/issues/5124). [#6537](https://github.com/meteor/meteor/issues/6537) lays the groundwork to overcome the main blocker for updating to Node 4, that is, needing to rebuild all existing Meteor packages that contain binary dependencies. +## Upgrade to Node 6 + +Tracking pull request: https://github.com/meteor/meteor/pull/6923 + + +## Page load performance improvements + +*Status: In progress* + +Fast initial page load times are somewhat less important for single-page reactive web apps than for other kinds of websites, but large Meteor apps with lots of packages tend to load quite a bit of JavaScript, and the cost of all that network traffic, parsing, and evaluation definitely adds up. + +Speeding up page load times will require a combination of new tools for asynchronous JavaScript delivery (code splitting), dead code elimination, deferred evaluation of JavaScript modules, and performance profiling (so that developers can identify expensive packages). + + +## Build system improvements + +*Status: In progress* + +Meteor 1.4.2 addressed a number of critical performance problems with the Meteor build system, but there are still more areas left for improvement. For example, Meteor could take better advantage of native support for new ECMAScript features in Node 4 (and eventually Node 6) on the server. + ## Full transition to npm +*Status: We encourage publishing Meteor-related packages to npm where possible. We are investigating ways to make it possible to move some parts of Meteor core onto npm without making the installation process more complex.* + The community has rallied around npm as the de-facto standard package manager for JavaScript. We believe committing fully to npm will strengthen the entire JavaScript ecosystem by removing fragmentation, will benefit existing Meteor developers by making it seamless to use any JavaScript package and increase Meteor adoption by aligning it with JavaScript best practices. 1.3 introduced `npm install` support along with ES2015 modules. In the future, we would like to transition the Meteor package ecosystem over entirely from Atmosphere to npm. We are still in the early conceptual design phase and expect to update the roadmap once we have a design in place that will underpin further development. -## Testing updates +## GraphQL Data: SQL, REST, performance -Meteor 1.3 shipped with two new testing modes and many developers are writing test suites and building test drivers as part of migrating to 1.3. We’re looking at improving the feature in upcoming releases, especially our support for continuous integration mode (see [#6755](https://github.com/meteor/meteor/issues/6755)). +*Status: In progress at [http://dev.apollodata.com/](http://dev.apollodata.com/)* -## Project Governance/Community Contribution +We're building a next generation GraphQL-focused data stack for modern applications called Apollo. We believe that this spiritual successor to the data part of the Meteor stack is impactful enough to deserve it's own fully fledged project that is compatible with other languages and frameworks. Apollo is born from the Meteor project and works perfectly with Meteor today. -Currently, it’s difficult for external developers to make meaningful contributions to Meteor as there is no clear guidance on what to work on, how best to do that work and signals around what will/won’t get merged. We plan on fixing this by creating tight documentation around how the project is developed (e.g the [Swift contribution guidelines](https://swift.org/contributing/)) and giving contributors a path towards earning increased privileges that culminate in full commit access. We’re also aiming to move more sub-projects into their own repositories that can be released on their own release schedule and more easily maintained by the community. +Apollo is our approach to giving Meteor developers SQL and other database support, the ability to choose between realtime and static data, and improved performance analysis. We are working on providing better tools and documentation for Meteor developers to integrate Apollo into their apps, and welcome contributions in this area. The next priority for Apollo and Meteor is enabling Meteor developers to choose to replace MongoDB entirely with GraphQL on top of other storage engines. -## Data (SQL, REST, Performance) +Even though Apollo could eventually be a complete replacement for Meteor’s included Mongo/DDP data stack, you should feel good about Meteor’s existing data system. We are currently open to ideas around performance and stability improvements. -We're building the next generation data stack for modern applications called [Apollo](https://github.com/apollostack/apollo). We believe the data part of the Meteor stack is impactful enough to deserve it's own fully fledged sub-project that will be compatible with other languages and frameworks. Apollo is born from the Meteor project and is naturally designed to work perfectly with Meteor. It is GraphQL based and will work with multiple data sources starting with REST. Apollo is our answer to bringing SQL and improved performance analysis to Meteor. + + +# **Recently completed** + + + +## Rebuild performance improvements + +*Status: Shipped in 1.4.2* + +Rebuild performance refers to the length of time between changing a file in development and being able to reload your app in a browser. After extensive profiling to identify performance hot-spots, and with careful caching of previously completed work, Meteor 1.4.2 takes substantially less time to rebuild most apps, especially larger apps. + + +## MongoDB updates + +*Status: Shipped in 1.4* + +The mongo driver that currently ships with Meteor is old and doesn’t reliably work with connecting to MongoDB 3.2 databases (e.g [#6258](https://github.com/meteor/meteor/issues/6258)). We want to update to the latest driver [#5763](https://github.com/meteor/meteor/issues/5763). +In addition, we'd like to update the dev bundle to ship with the latest stable version of MongoDB (3.2) [#5809](https://github.com/meteor/meteor/issues/5809) as MongoDB 2.6 will be officially sunsetted at the end of October, 2016. + + +## Support for Node 4 and beyond + +*Status: Shipped in 1.4* + +We want to be able to update the version of Node that ships with Meteor to 4 and eventually 6 [#5124](https://github.com/meteor/meteor/issues/5124). [#6537](https://github.com/meteor/meteor/issues/6537) lays the groundwork to overcome the main blocker for updating to Node 4, that is, needing to rebuild all existing Meteor packages that contain binary dependencies. ## View Layer +*Status: Blaze split into new repository and can be published independently as of 1.4.2* + Our plans around the view layer are to maintain strong integrations (along with guidance) with React, Angular and Blaze. We'll make essential fixes to Blaze but most likely won't be adding new features ourselves. We encourage you to help build the features you need at the [meteor/blaze](https://github.com/meteor/blaze) repository. + + +## Project Governance/Community Contribution + +*Status: Since this topic was added to the roadmap, we have introduced [completely new contribution guidelines](https://github.com/meteor/meteor/blob/devel/Contributing.md) that outline exactly how to contribute to Meteor in several ways, including triaging issues, improving documentation, submitting designs for new features, and submitting PRs for bug fixes and improvements. We encourage proposals about how to make the process better via new GitHub issues.* + +Currently, it’s difficult for external developers to make meaningful contributions to Meteor as there is no clear guidance on what to work on, how best to do that work and signals around what will/won’t get merged. We plan on fixing this by creating tight documentation around how the project is developed (e.g the [Swift contribution guidelines](https://swift.org/contributing/)) and giving contributors a path towards earning increased privileges that culminate in full commit access. We’re also aiming to move more sub-projects into their own repositories that can be released on their own release schedule and more easily maintained by the community. + + +## Other + +For more completed items, refer to the project history here: https://github.com/meteor/meteor/blob/devel/History.md + diff --git a/packages/appcache/README.md b/packages/appcache/README.md index e74d791bff..d0d10221ca 100644 --- a/packages/appcache/README.md +++ b/packages/appcache/README.md @@ -3,7 +3,7 @@ *** The `appcache` package, part of -[Webapp](https://www.meteor.com/webapp), stores the static parts of a +[Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp), stores the static parts of a Meteor application (the client side Javascript, HTML, CSS, and images) in the browser's [application cache](https://en.wikipedia.org/wiki/AppCache). diff --git a/packages/autoupdate/README.md b/packages/autoupdate/README.md index 26b7c0c2a4..f76824b62a 100644 --- a/packages/autoupdate/README.md +++ b/packages/autoupdate/README.md @@ -9,5 +9,5 @@ build of the app's client. When it sees that a new version is available, it uses the [reload](https://atmospherejs.com/meteor/reload) package (if included in the app) to gracefully save the app's state and reload it in place. -`autoupdate` is part of the [Webapp](https://www.meteor.com/webapp) +`autoupdate` is part of the [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp) project. diff --git a/packages/browser-policy/README.md b/packages/browser-policy/README.md index 53cb941e32..767931d2b2 100644 --- a/packages/browser-policy/README.md +++ b/packages/browser-policy/README.md @@ -3,7 +3,7 @@ *** The `browser-policy` family of packages, part of -[Webapp](https://www.meteor.com/webapp), lets you set security-related +[Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp), lets you set security-related policies that will be enforced by newer browsers. These policies help you prevent and mitigate common attacks like cross-site scripting and clickjacking. diff --git a/packages/ddp-server/livedata_server.js b/packages/ddp-server/livedata_server.js index 4a03a57ab1..e16b8f6d25 100644 --- a/packages/ddp-server/livedata_server.js +++ b/packages/ddp-server/livedata_server.js @@ -550,6 +550,11 @@ _.extend(Session.prototype, { processNext(); }; + self.server.onMessageHook.each(function (callback) { + callback(msg, self); + return true; + }); + if (_.has(self.protocol_handlers, msg.msg)) self.protocol_handlers[msg.msg].call(self, msg, unblock); else @@ -1324,6 +1329,11 @@ Server = function (options) { debugPrintExceptions: "onConnection callback" }); + // Map of callbacks to call when a new message comes in. + self.onMessageHook = new Hook({ + debugPrintExceptions: "onMessage callback" + }); + self.publish_handlers = {}; self.universal_publish_handlers = []; @@ -1407,6 +1417,18 @@ _.extend(Server.prototype, { return self.onConnectionHook.register(fn); }, + /** + * @summary Register a callback to be called when a new DDP message is received. + * @locus Server + * @param {function} callback The function to call when a new DDP message is received. + * @memberOf Meteor + * @importFromPackage meteor + */ + onMessage: function (fn) { + var self = this; + return self.onMessageHook.register(fn); + }, + _handleConnect: function (socket, msg) { var self = this; diff --git a/packages/ddp-server/livedata_server_tests.js b/packages/ddp-server/livedata_server_tests.js index 10203f319b..d24cfb0d06 100644 --- a/packages/ddp-server/livedata_server_tests.js +++ b/packages/ddp-server/livedata_server_tests.js @@ -82,7 +82,6 @@ testAsyncMulti( }] ); - Meteor.methods({ livedata_server_test_inner: function () { return this.connection.id; @@ -94,6 +93,28 @@ Meteor.methods({ }); +Tinytest.addAsync( + "livedata server - onMessage hook", + function (test, onComplete) { + + var cb = Meteor.onMessage(function (msg, session) { + test.equal(msg.method, 'livedata_server_test_inner'); + cb.stop(); + onComplete(); + }); + + makeTestConnection( + test, + function (clientConn, serverConn) { + clientConn.call('livedata_server_test_inner'); + clientConn.disconnect(); + }, + onComplete + ); + } +); + + Tinytest.addAsync( "livedata server - connection in method invocation", function (test, onComplete) { diff --git a/packages/ddp-server/server_convenience.js b/packages/ddp-server/server_convenience.js index 62384353fa..28fca40b2b 100755 --- a/packages/ddp-server/server_convenience.js +++ b/packages/ddp-server/server_convenience.js @@ -11,7 +11,7 @@ Meteor.refresh = function (notification) { // Proxy the public methods of Meteor.server so they can // be called directly on Meteor. -_.each(['publish', 'methods', 'call', 'apply', 'onConnection'], +_.each(['publish', 'methods', 'call', 'apply', 'onConnection', 'onMessage'], function (name) { Meteor[name] = _.bind(Meteor.server[name], Meteor.server); }); diff --git a/packages/ddp/DDP.md b/packages/ddp/DDP.md index ca29b4b032..d9ce63731f 100644 --- a/packages/ddp/DDP.md +++ b/packages/ddp/DDP.md @@ -240,7 +240,8 @@ error is an Object with the following fields: * `error`: string (previously a number. See appendix 3) * `reason`: optional string - * `details`: optional string + * `message`: optional string + * `errorType`: pre-defined string with a value of `Meteor.Error` Such an Error is used to represent errors raised by the method or subscription, as well as an attempt to subscribe to an unknown subscription or call an unknown diff --git a/packages/fastclick/README.md b/packages/fastclick/README.md index 5d1f8e4ffa..e5a1cf6bca 100644 --- a/packages/fastclick/README.md +++ b/packages/fastclick/README.md @@ -2,6 +2,8 @@ [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/fastclick) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/fastclick) *** +> **Warning:** As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing [bugs](https://github.com/ftlabs/fastclick/issues) into your application. Consider carefully whether you really need to use it. + FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a `click` event on mobile browsers. The aim is to make your application feel less laggy and more responsive while diff --git a/packages/force-ssl/README.md b/packages/force-ssl/README.md index ddfe0bb9ea..076fb3fe7e 100644 --- a/packages/force-ssl/README.md +++ b/packages/force-ssl/README.md @@ -2,7 +2,7 @@ [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/force-ssl) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/force-ssl) *** -This package, part of [Webapp](https://www.meteor.com/webapp), causes +This package, part of [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp), causes Meteor to redirect insecure connections (HTTP) to a secure URL (HTTPS). Use this package to ensure that communication to the server is always encrypted to protect users from active spoofing attacks. diff --git a/packages/minimongo/minimongo.js b/packages/minimongo/minimongo.js index 94db3fafdb..f79f2d4bc1 100644 --- a/packages/minimongo/minimongo.js +++ b/packages/minimongo/minimongo.js @@ -544,6 +544,24 @@ LocalCollection.prototype.insert = function (doc, callback) { var self = this; doc = EJSON.clone(doc); + // Make sure field names do not contain Mongo restricted + // characters ('.', '$', '\0'). + // https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names + if (doc) { + const invalidCharMsg = { + '.': "contain '.'", + '$': "start with '$'", + '\0': "contain null bytes", + }; + JSON.stringify(doc, (key, value) => { + let match; + if (_.isString(key) && (match = key.match(/^\$|\.|\0/))) { + throw MinimongoError(`Key ${key} must not ${invalidCharMsg[match[0]]}`); + } + return value; + }); + } + if (!_.has(doc, '_id')) { // if you really want to use ObjectIDs, set this global. // Mongo.Collection specifies its own ids and does not use this code. @@ -1110,4 +1128,3 @@ LocalCollection.prototype.resumeObservers = function () { } self._observeQueue.drain(); }; - diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 2898156114..eb66953178 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -2109,21 +2109,21 @@ Tinytest.add("minimongo - modify", function (test) { 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 @@ -2496,9 +2496,9 @@ Tinytest.add("minimongo - modify", function (test) { 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 @@ -3207,3 +3207,82 @@ Tinytest.add("minimongo - reactive skip/limit count while updating", function(te c.stop(); }); + +// Makes sure inserts cannot be performed using field names that have +// Mongo restricted characters in them ('.', '$', '\0'): +// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names +Tinytest.add("minimongo - cannot insert using invalid field names", function (test) { + const collection = new LocalCollection(); + + // Quick test to make sure non-dot field inserts are working + collection.insert({ a: 'b' }); + + // Quick test to make sure field values with dots are allowed + collection.insert({ a: 'b.c' }); + + // Verify top level dot-field inserts are prohibited + ['a.b', '.b', 'a.', 'a.b.c'].forEach((field) => { + test.throws(function () { + collection.insert({ [field]: 'c' }); + }, `Key ${field} must not contain '.'`); + }); + + // Verify nested dot-field inserts are prohibited + test.throws(function () { + collection.insert({ a: { b: { 'c.d': 'e' } } }); + }, "Key c.d must not contain '.'"); + + // Verify field names starting with $ are prohibited + test.throws(function () { + collection.insert({ '$a': 'b' }); + }, "Key $a must not start with '$'"); + + // Verify nested field names starting with $ are prohibited + test.throws(function () { + collection.insert({ a: { b: { '$c': 'd' } } }); + }, "Key $c must not start with '$'"); + + // Verify top level fields with null characters are prohibited + ['\0a', 'a\0', 'a\0b', '\u0000a', 'a\u0000', 'a\u0000b'].forEach((field) => { + test.throws(function () { + collection.insert({ [field]: 'c' }); + }, `Key ${field} must not contain null bytes`); + }); + + // Verify nested field names with null characters are prohibited + test.throws(function () { + collection.insert({ a: { b: { '\0c': 'd' } } }); + }, 'Key \0c must not contain null bytes'); +}); + +// Makes sure $set's cannot be performed using null bytes +// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names +Tinytest.add("minimongo - cannot $set with null bytes", function (test) { + const collection = new LocalCollection(); + + // Quick test to make sure non-null byte $set's are working + const id = collection.insert({ a: 'b', 'c': 'd' }); + collection.update({ _id: id }, { $set: { e: 'f' } }); + + // Verify $set's with null bytes throw an exception + test.throws(() => { + collection.update({ _id: id }, { $set: { '\0a': 'b' } }); + }, 'Key \0a must not contain null bytes'); +}); + +// Makes sure $rename's cannot be performed using null bytes +// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names +Tinytest.add("minimongo - cannot $rename with null bytes", function (test) { + const collection = new LocalCollection(); + + // Quick test to make sure non-null byte $rename's are working + let id = collection.insert({ a: 'b', c: 'd' }); + collection.update({ _id: id }, { $rename: { a: 'a1', c: 'c1' } }); + + // Verify $rename's with null bytes throw an exception + collection.remove({}); + id = collection.insert({ a: 'b', c: 'd' }); + test.throws(() => { + collection.update({ _id: id }, { $rename: { a: '\0a', c: 'c\0' } }); + }, "The 'to' field for $rename cannot contain an embedded null byte"); +}); diff --git a/packages/minimongo/modify.js b/packages/minimongo/modify.js index bb140d23e9..e5a81ba8f6 100644 --- a/packages/minimongo/modify.js +++ b/packages/minimongo/modify.js @@ -244,6 +244,11 @@ var MODIFIERS = { e.setPropertyError = true; throw e; } + if (_.isString(field) && field.indexOf('\0') > -1) { + // Null bytes are not allowed in Mongo field names + // https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names + throw MinimongoError(`Key ${field} must not contain null bytes`); + } target[field] = arg; }, $setOnInsert: function (target, field, arg) { @@ -457,6 +462,11 @@ var MODIFIERS = { throw MinimongoError("$rename source field invalid"); if (typeof arg !== "string") throw MinimongoError("$rename target must be a string"); + if (arg.indexOf('\0') > -1) { + // Null bytes are not allowed in Mongo field names + // https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names + throw MinimongoError("The 'to' field for $rename cannot contain an embedded null byte"); + } if (target === undefined) return; var v = target[field]; diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js index acdeaf194b..7c65c1da14 100644 --- a/packages/minimongo/package.js +++ b/packages/minimongo/package.js @@ -7,8 +7,17 @@ Package.onUse(function (api) { api.export('LocalCollection'); api.export('Minimongo'); api.export('MinimongoTest', { testOnly: true }); - api.use(['underscore', 'ejson', 'id-map', 'ordered-dict', 'tracker', - 'mongo-id', 'random', 'diff-sequence']); + api.use([ + 'underscore', + 'ejson', + 'id-map', + 'ordered-dict', + 'tracker', + 'mongo-id', + 'random', + 'diff-sequence', + 'ecmascript' + ]); // This package is used for geo-location queries such as $near api.use('geojson-utils'); // This package is used to get diff results on arrays and objects @@ -39,8 +48,17 @@ Package.onUse(function (api) { Package.onTest(function (api) { api.use('minimongo', ['client', 'server']); api.use('test-helpers', 'client'); - api.use(['tinytest', 'underscore', 'ejson', 'ordered-dict', - 'random', 'tracker', 'reactive-var', 'mongo-id']); + api.use([ + 'tinytest', + 'underscore', + 'ejson', + 'ordered-dict', + 'random', + 'tracker', + 'reactive-var', + 'mongo-id', + 'ecmascript' + ]); api.addFiles('minimongo_tests.js', 'client'); api.addFiles('wrap_transform_tests.js'); api.addFiles('minimongo_server_tests.js', 'server'); diff --git a/packages/modules-runtime/.npm/package/npm-shrinkwrap.json b/packages/modules-runtime/.npm/package/npm-shrinkwrap.json index ceac639e6f..6d78385bdf 100644 --- a/packages/modules-runtime/.npm/package/npm-shrinkwrap.json +++ b/packages/modules-runtime/.npm/package/npm-shrinkwrap.json @@ -1,9 +1,9 @@ { "dependencies": { "install": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/install/-/install-0.8.2.tgz", - "from": "install@0.8.2" + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/install/-/install-0.8.4.tgz", + "from": "install@0.8.4" } } } diff --git a/packages/modules-runtime/modules-runtime.js b/packages/modules-runtime/modules-runtime.js index 30403e3fbc..da38e75648 100644 --- a/packages/modules-runtime/modules-runtime.js +++ b/packages/modules-runtime/modules-runtime.js @@ -13,6 +13,10 @@ if (typeof Profile === "function" && }; } +// On the client, make package resolution prefer the "browser" field of +// package.json files to the "main" field. +options.browser = Meteor.isClient; + // This function will be called whenever a module identifier that hasn't // been installed is required. For backwards compatibility, and so that we // can require binary dependencies on the server, we implement the diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 2cf3791782..224d83dc0c 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,13 +1,13 @@ Package.describe({ name: "modules-runtime", - version: "0.7.7", + version: "0.7.8", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" }); Npm.depends({ - install: "0.8.2" + install: "0.8.4" }); Package.onUse(function(api) { diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index 77eabdc3b6..d16b6a540f 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -608,7 +608,7 @@ var isModificationMod = function (mod) { var transformResult = function (driverResult) { var meteorResult = { numberAffected: 0 }; if (driverResult) { - mongoResult = driverResult.result; + var mongoResult = driverResult.result; // On updates with upsert:true, the inserted values come as a list of // upserted values -- even with options.multi, when the upsert does insert, diff --git a/packages/non-core/blaze b/packages/non-core/blaze index dd65753c32..637dac5914 160000 --- a/packages/non-core/blaze +++ b/packages/non-core/blaze @@ -1 +1 @@ -Subproject commit dd65753c32b5535e33772ceb7ca16e998aaf6f24 +Subproject commit 637dac59146e74e2d384e8ea15b4cb7a8cb67896 diff --git a/packages/npm-mongo/.npm/package/npm-shrinkwrap.json b/packages/npm-mongo/.npm/package/npm-shrinkwrap.json index 4493b91832..99567900d0 100644 --- a/packages/npm-mongo/.npm/package/npm-shrinkwrap.json +++ b/packages/npm-mongo/.npm/package/npm-shrinkwrap.json @@ -1,9 +1,9 @@ { "dependencies": { "bson": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-0.5.6.tgz", - "from": "bson@>=0.5.6 <0.6.0" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.1.tgz", + "from": "bson@>=1.0.1 <1.1.0" }, "buffer-shims": { "version": "1.0.0", @@ -31,14 +31,14 @@ "from": "isarray@>=1.0.0 <1.1.0" }, "mongodb": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.11.tgz", - "from": "mongodb@2.2.11" + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.16.tgz", + "from": "mongodb@2.2.16" }, "mongodb-core": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.0.13.tgz", - "from": "mongodb-core@2.0.13" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.2.tgz", + "from": "mongodb-core@2.1.2" }, "process-nextick-args": { "version": "1.0.7", diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 8a21cb4846..c5bc711eaf 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -3,12 +3,12 @@ Package.describe({ summary: "Wrapper around the mongo npm package", - version: '2.2.11_2', + version: '2.2.16_1', documentation: null }); Npm.depends({ - mongodb: "2.2.11" + mongodb: "2.2.16" }); Package.onUse(function (api) { diff --git a/packages/oauth/end_of_popup_response.html b/packages/oauth/end_of_popup_response.html index 9812af83da..11cf6c5692 100644 --- a/packages/oauth/end_of_popup_response.html +++ b/packages/oauth/end_of_popup_response.html @@ -6,6 +6,6 @@

- + diff --git a/packages/oauth/end_of_redirect_response.html b/packages/oauth/end_of_redirect_response.html index af0e9885e5..bf53b766a5 100644 --- a/packages/oauth/end_of_redirect_response.html +++ b/packages/oauth/end_of_redirect_response.html @@ -1,6 +1,6 @@ - + diff --git a/packages/oauth/oauth_server.js b/packages/oauth/oauth_server.js index f5cc5d592e..cca82cb2bd 100644 --- a/packages/oauth/oauth_server.js +++ b/packages/oauth/oauth_server.js @@ -342,7 +342,10 @@ var renderEndOfLoginResponse = function (options) { throw new Error('invalid loginStyle: ' + options.loginStyle); } - var result = template.replace(/##CONFIG##/, JSON.stringify(config)); + var result = template.replace(/##CONFIG##/, JSON.stringify(config)) + .replace( + /##ROOT_URL_PATH_PREFIX##/, __meteor_runtime_config__.ROOT_URL_PATH_PREFIX + ); return "\n" + result; }; diff --git a/packages/oauth/oauth_tests.js b/packages/oauth/oauth_tests.js index dcca94ea18..bbca33dfeb 100644 --- a/packages/oauth/oauth_tests.js +++ b/packages/oauth/oauth_tests.js @@ -59,3 +59,96 @@ Tinytest.add( test.equal(OAuth._retrievePendingCredential(key, secret), cred); } ); + +Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports unspecified ROOT_URL_PATH_PREFIX", + function (test) { + var res = { + writeHead: function () {}, + end: function (content) { + test.matches( + content, + /\/packages\/oauth\/end_of_popup_response\.js/ + ); + } + }; + var details = { + credentials: {}, + loginStyle: 'popup' + }; + OAuth._endOfLoginResponse(res, details); + } +); + +Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports ROOT_URL_PATH_PREFIX", + function (test) { + var rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX; + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX = '/test-root-url-prefix'; + var res = { + writeHead: function () {}, + end: function (content) { + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX = rootUrlPathPrefix; + test.matches( + content, + /\/test-root-url-prefix\/packages\/oauth\/end_of_popup_response\.js/ + ); + } + }; + var details = { + credentials: {}, + loginStyle: 'popup' + }; + OAuth._endOfLoginResponse(res, details); + } +); + +Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports unspecified ROOT_URL_PATH_PREFIX", + function (test) { + var res = { + writeHead: function () {}, + end: function (content) { + test.matches( + content, + /\/packages\/oauth\/end_of_redirect_response\.js/ + ); + } + }; + var details = { + credentials: {}, + loginStyle: 'redirect', + query: { + state: new Buffer(JSON.stringify({ + redirectUrl: __meteor_runtime_config__.ROOT_URL + }), 'binary').toString('base64') + } + }; + OAuth._endOfLoginResponse(res, details); + } +); + + +Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports ROOT_URL_PATH_PREFIX", + function (test) { + var rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX; + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX = '/test-root-url-prefix'; + var res = { + writeHead: function () {}, + end: function (content) { + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX = rootUrlPathPrefix; + test.matches( + content, + /\/test-root-url-prefix\/packages\/oauth\/end_of_redirect_response\.js/ + ); + } + }; + var details = { + credentials: {}, + loginStyle: 'redirect', + query: { + state: new Buffer(JSON.stringify({ + redirectUrl: __meteor_runtime_config__.ROOT_URL + }), 'binary').toString('base64') + } + }; + OAuth._endOfLoginResponse(res, details); + } +); diff --git a/packages/observe-sequence/observe_sequence.js b/packages/observe-sequence/observe_sequence.js index 1a823ab019..68ec026591 100644 --- a/packages/observe-sequence/observe_sequence.js +++ b/packages/observe-sequence/observe_sequence.js @@ -94,7 +94,7 @@ ObserveSequence = { if (!seq) { seqArray = seqChangedToEmpty(lastSeqArray, callbacks); - } else if (seq instanceof Array) { + } else if (_.isArray(seq)) { seqArray = seqChangedToArray(lastSeqArray, seq, callbacks); } else if (isStoreCursor(seq)) { var result /* [seqArray, activeObserveHandle] */ = @@ -126,7 +126,7 @@ ObserveSequence = { fetch: function (seq) { if (!seq) { return []; - } else if (seq instanceof Array) { + } else if (_.isArray(seq)) { return seq; } else if (isStoreCursor(seq)) { return seq.fetch(); diff --git a/packages/reload/README.md b/packages/reload/README.md index ca025fbae0..0eb283305f 100644 --- a/packages/reload/README.md +++ b/packages/reload/README.md @@ -13,4 +13,4 @@ with `reload`. They can make the migration process wait until they are ready and include whatever state they may possess in the serialization and deserialization process. -`reload` is part of the [Webapp](https://www.meteor.com/webapp) project. +`reload` is part of the [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp) project. diff --git a/packages/routepolicy/README.md b/packages/routepolicy/README.md index c825fda7f8..7ccbb8e288 100644 --- a/packages/routepolicy/README.md +++ b/packages/routepolicy/README.md @@ -2,7 +2,7 @@ [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/routepolicy) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/routepolicy) *** -RoutePolicy, part of [Webapp](https://www.meteor.com/webapp), is a +RoutePolicy, part of [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp), is a low-level API for declaring the offline access semantics that apply to portions of the app's URL space. This is information is necessary when generating HTML5 Appcache manifests. diff --git a/packages/shell-server/shell-server.js b/packages/shell-server/shell-server.js index eff77e0468..419fdaa4c7 100644 --- a/packages/shell-server/shell-server.js +++ b/packages/shell-server/shell-server.js @@ -3,7 +3,6 @@ var path = require("path"); var stream = require("stream"); var fs = require("fs"); var net = require("net"); -var tty = require("tty"); var vm = require("vm"); var _ = require("underscore"); var INFO_FILE_MODE = parseInt("600", 8); // Only the owner can read or write. @@ -119,6 +118,12 @@ class Server { } delete options.key; + // Set the columns to what is being requested by the client. + if (options.columns && socket) { + socket.columns = options.columns; + } + delete options.columns; + if (options.evaluateAndExit) { evalCommand.call( Object.create(null), // Dummy repl object without ._RecoverableError. @@ -166,13 +171,6 @@ class Server { startREPL(options) { var self = this; - if (! options.output.columns) { - // The REPL's tab completion logic assumes process.stdout is a TTY, - // and while that isn't technically true here, we can get tab - // completion to behave correctly if we fake the .columns property. - options.output.columns = getTerminalWidth(); - } - // Make sure this function doesn't try to write anything to the output // stream after it has been closed. options.output.on("close", function() { @@ -384,19 +382,6 @@ function getHistoryFile(shellDir) { return path.join(shellDir, "history"); } -function getTerminalWidth() { - try { - // Inspired by https://github.com/TooTallNate/ttys/blob/master/index.js - var fd = fs.openSync("/dev/tty", "r"); - assert.ok(tty.isatty(fd)); - var ws = new tty.WriteStream(fd); - ws.end(); - return ws.columns; - } catch (fancyApproachWasTooFancy) { - return 80; - } -} - // Shell commands need to be executed in a Fiber in case they call into // code that yields. Using a Promise is an even better idea, since it runs // its callbacks in Fibers drawn from a pool, so the Fibers are recycled. diff --git a/packages/spiderable/README.md b/packages/spiderable/README.md index 9f9b65c32d..22978f7c5a 100644 --- a/packages/spiderable/README.md +++ b/packages/spiderable/README.md @@ -2,7 +2,7 @@ [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/spiderable) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/spiderable) *** -`spiderable` is part of [Webapp](https://www.meteor.com/webapp). It's one possible way to allow web search engines to index a Meteor application. It uses the [AJAX Crawling specification](https://developers.google.com/webmasters/ajax-crawling/) published by Google to serve HTML to compatible spiders (Google, Bing, Yandex, and more). +`spiderable` is part of [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp). It's one possible way to allow web search engines to index a Meteor application. It uses the [AJAX Crawling specification](https://developers.google.com/webmasters/ajax-crawling/) published by Google to serve HTML to compatible spiders (Google, Bing, Yandex, and more). When a spider requests an HTML snapshot of a page the Meteor server runs the client half of the application inside [phantomjs](http://phantomjs.org/), a headless browser, and returns the full HTML generated by the client code. diff --git a/packages/twitter/twitter_configure.html b/packages/twitter/twitter_configure.html index 0a98c7b3fb..eed56c1959 100644 --- a/packages/twitter/twitter_configure.html +++ b/packages/twitter/twitter_configure.html @@ -4,7 +4,7 @@

  1. - Visit https://dev.twitter.com/apps/new + Visit https://apps.twitter.com/app/new
  2. Set Website to: {{siteUrl}} diff --git a/packages/ui/.gitignore b/packages/ui/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/ui/README.md b/packages/ui/README.md deleted file mode 100644 index 33120c7c56..0000000000 --- a/packages/ui/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ui -[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/ui) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/ui) -*** - -This is an internal Meteor package. \ No newline at end of file diff --git a/packages/ui/package.js b/packages/ui/package.js deleted file mode 100644 index 680a4a272b..0000000000 --- a/packages/ui/package.js +++ /dev/null @@ -1,16 +0,0 @@ -Package.describe({ - summary: "Deprecated: Use the 'blaze' package", - version: '1.0.11' -}); - -Package.onUse(function (api) { - api.use('blaze'); - api.imply('blaze'); - - // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0. - // - // (in particular, packages that have a weak dependency on this - // package, since then exported symbols live on the - // `Package.ui` object) - api.export(['Blaze', 'UI', 'Handlebars']); -}); diff --git a/packages/webapp/README.md b/packages/webapp/README.md index f0af8c30a1..3a2810ccb3 100644 --- a/packages/webapp/README.md +++ b/packages/webapp/README.md @@ -7,7 +7,7 @@ Meteor project into a web application. It is a "value added HTTP server" that includes not just a web server, but also advanced app serving functionality like over-the-air mobile app updates and HTML5 Appcache support. For more information, see the [Webapp project -page](https://www.meteor.com/webapp). +page](https://github.com/meteor/meteor/tree/master/packages/webapp). ## Direct access to connect mongodb API diff --git a/tools/cli/commands-packages.js b/tools/cli/commands-packages.js index baf35ca5a4..a075ffacea 100644 --- a/tools/cli/commands-packages.js +++ b/tools/cli/commands-packages.js @@ -2617,7 +2617,7 @@ main.registerCommand({ try { Console.rawInfo( "Changing homepage on " - + name + " to " + url + "..."); + + name + " to " + url + "...\n"); packageClient.callPackageServer(conn, '_changePackageHomepage', name, url); Console.info(" done"); @@ -2670,7 +2670,7 @@ main.registerCommand({ _.each(versions, function (version) { Console.rawInfo( "Setting " + name + "@" + version + " as " + - status + " migrated ... "); + status + " migrated ...\n"); packageClient.callPackageServer( conn, '_changeVersionMigrationStatus', diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 3632698a2e..82ff99149e 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -1016,12 +1016,22 @@ ${cordova.displayNameForPlatform(platform)}` }, () => { 'platforms', platform); const platformOutputPath = files.pathJoin(outputPath, platform); + // Prepare the project once again to ensure that it is up to date + // with current build options. For example, --server=example.com + // is utilized in the Cordova builder to write boilerplate HTML and + // various config.xml settings (e.g. access policies) + if (platform === 'ios') { + cordovaProject.prepareForPlatform(platform, buildOptions); + } else if (platform === 'android') { + cordovaProject.buildForPlatform(platform, buildOptions); + } + + // Once prepared, copy the bundle to the final location. files.cp_r(buildPath, files.pathJoin(platformOutputPath, 'project')); + // Make some platform-specific adjustments to the resulting build. if (platform === 'ios') { - cordovaProject.prepareForPlatform(platform, buildOptions); - files.writeFile( files.pathJoin(platformOutputPath, 'README'), `This is an auto-generated XCode project for your iOS application. @@ -1030,8 +1040,6 @@ Instructions for publishing your iOS app to App Store can be found at: https://github.com/meteor/meteor/wiki/How-to-submit-your-iOS-app-to-App-Store `, "utf8"); } else if (platform === 'android') { - cordovaProject.buildForPlatform(platform, buildOptions); - const apkPath = files.pathJoin(buildPath, 'build/outputs/apk', options.debug ? 'android-debug.apk' : 'android-release-unsigned.apk') diff --git a/tools/isobuild/import-scanner.js b/tools/isobuild/import-scanner.js index 23c8127930..f95fa14556 100644 --- a/tools/isobuild/import-scanner.js +++ b/tools/isobuild/import-scanner.js @@ -505,6 +505,16 @@ export default class ImportScanner { let depFile = this._getFile(absImportedPath); if (depFile) { + // If the module was imported implicitly before, update to the + // explicit version now. + if (depFile.imported === "implicit") { + const file = this._readModule(absImportedPath); + if (file) { + Object.assign(depFile, file); + depFile.imported = true; + } + } + // Avoid scanning files that we've scanned before, but mark them // as imported so we know to include them in the bundle if they // are lazy. Eager files and files that we have imported before do @@ -827,7 +837,13 @@ export default class ImportScanner { servePath: relPkgJsonPath, hash: sha1(data), lazy: true, - imported: true, + // Since _addPkgJsonToOutput is only ever called for package.json + // files that are involved in resolving package directories, and + // pkg is only a subset of the information in the actual + // package.json module, we mark it as being imported implicitly, + // so that the subset can be overridden by the actual module if + // this package.json file is imported explicitly elsewhere. + imported: "implicit", }; this._addFile(pkgJsonPath, pkgFile); diff --git a/tools/isobuild/resolver.js b/tools/isobuild/resolver.js index ac00eb2ce0..70e5f7703c 100644 --- a/tools/isobuild/resolver.js +++ b/tools/isobuild/resolver.js @@ -285,26 +285,30 @@ export default class Resolver { return null; } - let main = pkg.main; + // Output a JS module that exports just the "name", "version", "main", + // and "browser" properties (if defined) from the package.json file. + const pkgSubset = {}; - if (archMatches(this.targetArch, "web") && - isString(pkg.browser)) { - main = pkg.browser; + if (has(pkg, "name")) { + pkgSubset.name = pkg.name; } - // Output a JS module that exports just the "name", "version", and - // "main" properties defined in the package.json file. - const pkgSubset = { - name: pkg.name, - }; - if (has(pkg, "version")) { pkgSubset.version = pkg.version; } - if (isString(main)) { - pkgSubset.main = main; + let main = pkg.main; + if (has(pkg, "main")) { + pkgSubset.main = pkg.main; + } + if (archMatches(this.targetArch, "web") && + isString(pkg.browser)) { + main = pkg.browser; + pkgSubset.browser = pkg.browser; + } + + if (isString(main)) { // The "main" field of package.json does not have to begin with ./ // to be considered relative, so first we try simply appending it to // the directory path before falling back to a full resolve, which diff --git a/tools/runners/run-mongo.js b/tools/runners/run-mongo.js index a8a2dab23f..e3cf6b3a53 100644 --- a/tools/runners/run-mongo.js +++ b/tools/runners/run-mongo.js @@ -591,8 +591,12 @@ var launchMongo = function (options) { // Connect to the intended primary and start a replset. var db = new mongoNpmModule.Db( 'meteor', - new mongoNpmModule.Server('127.0.0.1', options.port, {poolSize: 1}), + new mongoNpmModule.Server('127.0.0.1', options.port, { + poolSize: 1, + socketOptions: {connectTimeoutMS: 30000}, + }), {safe: true}); + yieldingMethod(db, 'open'); if (stopped) { return; diff --git a/tools/shell-client.js b/tools/shell-client.js index 4f6bc936ee..f1543dbd68 100644 --- a/tools/shell-client.js +++ b/tools/shell-client.js @@ -137,6 +137,7 @@ Cp.setUpSocket = function setUpSocket(sock, key) { // Sending a JSON-stringified options object (even just an empty // object) over the socket is required to start the REPL session. sock.write(JSON.stringify({ + columns: process.stdout.columns, terminal: ! process.env.EMACS, key: key }) + "\n"); diff --git a/tools/static-assets/skel-bare/.meteor/packages b/tools/static-assets/skel-bare/.meteor/packages index 1615051104..7c56527178 100644 --- a/tools/static-assets/skel-bare/.meteor/packages +++ b/tools/static-assets/skel-bare/.meteor/packages @@ -17,6 +17,3 @@ standard-minifier-js # JS minifier run for production mode es5-shim # ECMAScript 5 compatibility for older browsers. ecmascript # Enable ECMAScript2015+ syntax in app code shell-server # Server-side component of the `meteor shell` command - -autopublish # Publish all data to the clients (for prototyping) -insecure # Allow all DB writes from clients (for prototyping) diff --git a/tools/static-assets/skel-bare/package.json b/tools/static-assets/skel-bare/package.json index 509ac7e54f..0700d68455 100644 --- a/tools/static-assets/skel-bare/package.json +++ b/tools/static-assets/skel-bare/package.json @@ -5,6 +5,7 @@ "start": "meteor run" }, "dependencies": { - "meteor-node-stubs": "~0.2.0" + "babel-runtime": "^6.20.0", + "meteor-node-stubs": "~0.2.4" } } diff --git a/tools/static-assets/skel-full/package.json b/tools/static-assets/skel-full/package.json index 8c667e0354..0700d68455 100644 --- a/tools/static-assets/skel-full/package.json +++ b/tools/static-assets/skel-full/package.json @@ -5,7 +5,7 @@ "start": "meteor run" }, "dependencies": { - "babel-runtime": "^6.18.0", - "meteor-node-stubs": "~0.2.3" + "babel-runtime": "^6.20.0", + "meteor-node-stubs": "~0.2.4" } } diff --git a/tools/static-assets/skel/package.json b/tools/static-assets/skel/package.json index c56bdcbd4d..0700d68455 100644 --- a/tools/static-assets/skel/package.json +++ b/tools/static-assets/skel/package.json @@ -5,7 +5,7 @@ "start": "meteor run" }, "dependencies": { - "meteor-node-stubs": "~0.2.0", - "babel-runtime": "6.18.0" + "babel-runtime": "^6.20.0", + "meteor-node-stubs": "~0.2.4" } }