diff --git a/.circleci/config.yml b/.circleci/config.yml
index 38c0968f0e..0a2704fe2c 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -67,7 +67,7 @@ build_machine_environment: &build_machine_environment
machine: true
environment:
# This multiplier scales the waitSecs for selftests.
- TIMEOUT_SCALE_FACTOR: 4
+ TIMEOUT_SCALE_FACTOR: 8
# These, mostly overlapping, flags ensure that CircleCI is as pretty as
# possible for a non-interactive environment. See also: --headless.
@@ -124,13 +124,13 @@ jobs:
name: Get Ready
command: |
eval $PRE_TEST_COMMANDS;
- ./meteor --help
- # shouldn't take longer than 5 minutes
- no_output_timeout: 5m
+ ./meteor --get-ready
+ # shouldn't take longer than 20 minutes
+ no_output_timeout: 20m
# Clear dev_bundle/.npm to ensure consistent test runs.
- run:
name: Clear npm cache
- command: ./meteor npm cache clear
+ command: ./meteor npm cache clear --force
# Since PhantomJS has been removed from dev_bundle/lib/node_modules
# (#6905), but self-test still needs it, install it now.
- run:
@@ -164,6 +164,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running warehouse self-tests"
command: |
@@ -197,6 +200,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (1): A-Com"
command: |
@@ -231,6 +237,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name "Running self-test (2): Con-K"
command: |
@@ -265,6 +274,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (3): L-O"
command: |
@@ -299,6 +311,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (4): P"
command: |
@@ -333,6 +348,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (5): Run"
command: |
@@ -367,10 +385,13 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (6): R-S"
command: |
- eval "$PRE_TEST_COMMANDS";
+ eval $PRE_TEST_COMMANDS;
./meteor self-test \
--exclude "${SELF_TEST_EXCLUDE}" \
--headless \
@@ -401,6 +422,9 @@ jobs:
<<: *run_env_change
- attach_workspace:
at: .
+ - run:
+ name: "Print environment"
+ command: printenv
- run:
name: "Running self-test (7): Sp-Z"
command: |
diff --git a/History.md b/History.md
index 34d91c088a..eecbea7d8c 100644
--- a/History.md
+++ b/History.md
@@ -20,6 +20,82 @@
using `for...of` loops, spread operator, `yield*`, and destructuring assignments.
[PR #8888](https://github.com/meteor/meteor/pull/8888)
+## v1.5.2, TBD
+
+* Node 4.8.4 has been patched to include
+ https://github.com/nodejs/node/pull/14829, an important PR implemented
+ by our own @abernix (:tada:), which fixes a faulty backport of garbage
+ collection-related logic in V8 that was causing occasional segmentation
+ faults during Meteor development and testing, ever since Node 4.6.2
+ (Meteor 1.4.2.3). When Node 4.8.5 is officially released with these
+ changes, we will immediately publish a small follow-up release.
+ [Issue #8648](https://github.com/meteor/meteor/issues/8648)
+
+* When Meteor writes to watched files during the build process, it no
+ longer relies on file watchers to detect the change and invalidate the
+ optimistic file system cache, which should fix a number of problems
+ related by the symptom of endless rebuilding.
+ [Issue #8988](https://github.com/meteor/meteor/issues/8988)
+ [Issue #8942](https://github.com/meteor/meteor/issues/8942)
+ [PR #9007](https://github.com/meteor/meteor/pull/9007)
+
+* The `cordova-lib` npm package has been updated to 7.0.1, along with
+ cordova-android (6.2.3) and cordova-ios (4.4.0), and various plugins.
+ [PR #8919](https://github.com/meteor/meteor/pull/8919) resolves the
+ umbrella [issue #8686](https://github.com/meteor/meteor/issues/8686), as
+ well as several Android build issues:
+ [#8408](https://github.com/meteor/meteor/issues/8408),
+ [#8424](https://github.com/meteor/meteor/issues/8424), and
+ [#8464](https://github.com/meteor/meteor/issues/8464).
+
+* The [`boilerplate-generator`](https://github.com/meteor/meteor/tree/release-1.5.2/packages/boilerplate-generator)
+ package responsible for generating initial HTML documents for Meteor
+ apps has been refactored by @stevenhao to avoid using the
+ `spacebars`-related packages, which means it is now possible to remove
+ Blaze as a dependency from the server as well as the client.
+ [PR #8820](https://github.com/meteor/meteor/pull/8820)
+
+* The `meteor-babel` package has been upgraded to version 0.23.1.
+
+* The `reify` npm package has been upgraded to version 0.12.0, which
+ includes a minor breaking
+ [change](https://github.com/benjamn/reify/commit/8defc645e556429283e0b522fd3afababf6525ea)
+ that correctly skips exports named `default` in `export * from "module"`
+ declarations. If you have any wrapper modules that re-export another
+ module's exports using `export * from "./wrapped/module"`, and the
+ wrapped module has a `default` export that you want to be included, you
+ should now explicitly re-export `default` using a second declaration:
+ ```js
+ export * from "./wrapped/module";
+ export { default } "./wrapped/module";
+ ```
+
+* The `meteor-promise` package has been upgraded to version 0.8.5,
+ and the `promise` polyfill package has been upgraded to 8.0.1.
+
+* The `semver` npm package has been upgraded to version 5.3.0.
+ [PR #8859](https://github.com/meteor/meteor/pull/8859)
+
+* The `faye-websocket` npm package has been upgraded to version 0.11.1,
+ and its dependency `websocket-driver` has been upgraded to a version
+ containing [this fix](https://github.com/faye/websocket-driver-node/issues/21),
+ thanks to [@sdarnell](https://github.com/sdarnell).
+ [meteor-feature-requests#160](https://github.com/meteor/meteor-feature-requests/issues/160)
+
+* The `uglify-js` npm package has been upgraded to version 3.0.28.
+
+* Thanks to PRs [#8960](https://github.com/meteor/meteor/pull/8960) and
+ [#9018](https://github.com/meteor/meteor/pull/9018) by @GeoffreyBooth, a
+ [`coffeescript-compiler`](https://github.com/meteor/meteor/tree/release-1.5.2/packages/non-core/coffeescript-compiler)
+ package has been extracted from the `coffeescript` package, similar to
+ how the `babel-compiler` package is separate from the `ecmascript`
+ package, so that other packages (such as
+ [`vue-coffee`](https://github.com/meteor-vue/vue-meteor/tree/master/packages/vue-coffee))
+ can make use of `coffeescript-compiler`. All `coffeescript`-related
+ packages have been moved to
+ [`packages/non-core`](https://github.com/meteor/meteor/tree/release-1.5.2/packages/non-core),
+ so that they can be published independently from Meteor releases.
+
* `meteor list --tree` can now be used to list all transitive package
dependencies (and versions) in an application. Weakly referenced dependencies
can also be listed by using the `--weak` option. For more information, run
@@ -50,12 +126,22 @@
[Issue #5121](https://github.com/meteor/meteor/issues/5121)
[PR #8917](https://github.com/meteor/meteor/pull/8917)
+* The `"env"` field is now supported in `.babelrc` files.
+ [PR #8963](https://github.com/meteor/meteor/pull/8963)
+
* Files contained by `client/compatibility/` directories or added with
`api.addFiles(files, ..., { bare: true })` are now evaluated before
importing modules with `require`, which may be a breaking change if you
depend on the interleaving of `bare` files with eager module evaluation.
[PR #8972](https://github.com/meteor/meteor/pull/8972)
+* When `meteor test-packages` runs in a browser, uncaught exceptions will
+ now be displayed above the test results, along with the usual summary of
+ test failures, in case those uncaught errors have something to do with
+ later test failures.
+ [Issue #4979](https://github.com/meteor/meteor/issues/4979)
+ [PR #9034](https://github.com/meteor/meteor/pull/9034)
+
## v1.5.1, 2017-07-12
* Node has been upgraded to version 4.8.4.
diff --git a/meteor b/meteor
index dcbbf84a68..8661fb2933 100755
--- a/meteor
+++ b/meteor
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-BUNDLE_VERSION=4.8.30
+BUNDLE_VERSION=4.8.35
# OS Check. Put here because here is where we download the precompiled
# bundles that are arch specific.
diff --git a/packages/accounts-password/password_server.js b/packages/accounts-password/password_server.js
index b088b0aafd..93af180f05 100644
--- a/packages/accounts-password/password_server.js
+++ b/packages/accounts-password/password_server.js
@@ -546,17 +546,17 @@ Meteor.methods({forgotPassword: function (options) {
Accounts.sendResetPasswordEmail(user._id, caseSensitiveEmail);
}});
-// send the user an email with a link that when opened allows the user
-// to set a new password, without the old password.
-
/**
- * @summary Send an email with a link the user can use to reset their password.
+ * @summary Generates a reset token and saves it into the database.
* @locus Server
- * @param {String} userId The id of the user to send email to.
- * @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
+ * @param {String} userId The id of the user to generate the reset token for.
+ * @param {String} email Which address of the user to generate the reset token for. This address must be in the user's `emails` list. If `null`, defaults to the first email in the list.
+ * @param {String} reason `resetPassword` or `enrollAccount`.
+ * @param {Object} [extraTokenData] Optional additional data to be added into the token record.
+ * @returns {Object} Object with {email, user, token} values.
* @importFromPackage accounts-base
*/
-Accounts.sendResetPasswordEmail = function (userId, email) {
+Accounts.generateResetToken = function (userId, email, reason, extraTokenData) {
// Make sure the user exists, and email is one of their addresses.
var user = Meteor.users.findOne(userId);
if (!user) {
@@ -574,44 +574,146 @@ Accounts.sendResetPasswordEmail = function (userId, email) {
}
var token = Random.secret();
- var when = new Date();
var tokenRecord = {
token: token,
email: email,
- when: when,
- reason: 'reset'
+ when: new Date()
};
- Meteor.users.update(userId, {$set: {
- "services.password.reset": tokenRecord
+
+ if (reason === 'resetPassword') {
+ tokenRecord.reason = 'reset';
+ } else if (reason === 'enrollAccount') {
+ tokenRecord.reason = 'enroll';
+ } else if (reason) {
+ // fallback so that this function can be used for unknown reasons as well
+ tokenRecord.reason = reason;
+ }
+
+ if (extraTokenData) {
+ _.extend(tokenRecord, extraTokenData);
+ }
+
+ Meteor.users.update({_id: user._id}, {$set: {
+ 'services.password.reset': tokenRecord
}});
+
// before passing to template, update user object with new token
Meteor._ensure(user, 'services', 'password').reset = tokenRecord;
- var resetPasswordUrl = Accounts.urls.resetPassword(token);
+ return {email, user, token};
+};
- var options = {
- to: email,
- from: Accounts.emailTemplates.resetPassword.from
- ? Accounts.emailTemplates.resetPassword.from(user)
- : Accounts.emailTemplates.from,
- subject: Accounts.emailTemplates.resetPassword.subject(user)
- };
-
- if (typeof Accounts.emailTemplates.resetPassword.text === 'function') {
- options.text =
- Accounts.emailTemplates.resetPassword.text(user, resetPasswordUrl);
+/**
+ * @summary Generates an e-mail verification token and saves it into the database.
+ * @locus Server
+ * @param {String} userId The id of the user to generate the e-mail verification token for.
+ * @param {String} email Which address of the user to generate the e-mail verification token for. This address must be in the user's `emails` list. If `null`, defaults to the first unverified email in the list.
+ * @param {Object} [extraTokenData] Optional additional data to be added into the token record.
+ * @returns {Object} Object with {email, user, token} values.
+ * @importFromPackage accounts-base
+ */
+Accounts.generateVerificationToken = function (userId, email, extraTokenData) {
+ // Make sure the user exists, and email is one of their addresses.
+ var user = Meteor.users.findOne(userId);
+ if (!user) {
+ handleError("Can't find user");
}
- if (typeof Accounts.emailTemplates.resetPassword.html === 'function') {
- options.html =
- Accounts.emailTemplates.resetPassword.html(user, resetPasswordUrl);
+ // pick the first unverified email if we weren't passed an email.
+ if (!email) {
+ var emailRecord = _.find(user.emails || [], function (e) { return !e.verified; });
+ email = (emailRecord || {}).address;
+
+ if (!email) {
+ handleError("That user has no unverified email addresses.");
+ }
+ }
+
+ // make sure we have a valid email
+ if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) {
+ handleError("No such email for user.");
+ }
+
+ var token = Random.secret();
+ var tokenRecord = {
+ token: token,
+ // TODO: This should probably be renamed to "email" to match reset token record.
+ address: email,
+ when: new Date()
+ };
+
+ if (extraTokenData) {
+ _.extend(tokenRecord, extraTokenData);
+ }
+
+ Meteor.users.update({_id: user._id}, {$push: {
+ 'services.email.verificationTokens': tokenRecord
+ }});
+
+ // before passing to template, update user object with new token
+ Meteor._ensure(user, 'services', 'email');
+ if (!user.services.email.verificationTokens) {
+ user.services.email.verificationTokens = [];
+ }
+ user.services.email.verificationTokens.push(tokenRecord);
+
+ return {email, user, token};
+};
+
+/**
+ * @summary Creates options for email sending for reset password and enroll account emails.
+ * You can use this function when customizing a reset password or enroll account email sending.
+ * @locus Server
+ * @param {Object} email Which address of the user's to send the email to.
+ * @param {Object} user The user object to generate options for.
+ * @param {String} url URL to which user is directed to confirm the email.
+ * @param {String} reason `resetPassword` or `enrollAccount`.
+ * @returns {Object} Options which can be passed to `Email.send`.
+ * @importFromPackage accounts-base
+ */
+Accounts.generateOptionsForEmail = function (email, user, url, reason) {
+ var options = {
+ to: email,
+ from: Accounts.emailTemplates[reason].from
+ ? Accounts.emailTemplates[reason].from(user)
+ : Accounts.emailTemplates.from,
+ subject: Accounts.emailTemplates[reason].subject(user)
+ };
+
+ if (typeof Accounts.emailTemplates[reason].text === 'function') {
+ options.text = Accounts.emailTemplates[reason].text(user, url);
+ }
+
+ if (typeof Accounts.emailTemplates[reason].html === 'function') {
+ options.html = Accounts.emailTemplates[reason].html(user, url);
}
if (typeof Accounts.emailTemplates.headers === 'object') {
options.headers = Accounts.emailTemplates.headers;
}
+ return options;
+};
+
+// send the user an email with a link that when opened allows the user
+// to set a new password, without the old password.
+
+/**
+ * @summary Send an email with a link the user can use to reset their password.
+ * @locus Server
+ * @param {String} userId The id of the user to send email to.
+ * @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
+ * @param {Object} [extraTokenData] Optional additional data to be added into the token record.
+ * @returns {Object} Object with {email, user, token, url, options} values.
+ * @importFromPackage accounts-base
+ */
+Accounts.sendResetPasswordEmail = function (userId, email, extraTokenData) {
+ const {email: realEmail, user, token} =
+ Accounts.generateResetToken(userId, email, 'resetPassword', extraTokenData);
+ const url = Accounts.urls.resetPassword(token);
+ const options = Accounts.generateOptionsForEmail(realEmail, user, url, 'resetPassword');
Email.send(options);
+ return {email: realEmail, user, token, url, options};
};
// send the user an email informing them that their account was created, with
@@ -627,65 +729,17 @@ Accounts.sendResetPasswordEmail = function (userId, email) {
* @locus Server
* @param {String} userId The id of the user to send email to.
* @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
+ * @param {Object} [extraTokenData] Optional additional data to be added into the token record.
+ * @returns {Object} Object with {email, user, token, url, options} values.
* @importFromPackage accounts-base
*/
-Accounts.sendEnrollmentEmail = function (userId, email) {
- // XXX refactor! This is basically identical to sendResetPasswordEmail.
-
- // Make sure the user exists, and email is in their addresses.
- var user = Meteor.users.findOne(userId);
- if (!user) {
- throw new Error("Can't find user");
- }
- // pick the first email if we weren't passed an email.
- if (!email && user.emails && user.emails[0]) {
- email = user.emails[0].address;
- }
- // make sure we have a valid email
- if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) {
- throw new Error("No such email for user.");
- }
-
- var token = Random.secret();
- var when = new Date();
- var tokenRecord = {
- token: token,
- email: email,
- when: when,
- reason: 'enroll'
- };
- Meteor.users.update(userId, {$set: {
- "services.password.reset": tokenRecord
- }});
-
- // before passing to template, update user object with new token
- Meteor._ensure(user, 'services', 'password').reset = tokenRecord;
-
- var enrollAccountUrl = Accounts.urls.enrollAccount(token);
-
- var options = {
- to: email,
- from: Accounts.emailTemplates.enrollAccount.from
- ? Accounts.emailTemplates.enrollAccount.from(user)
- : Accounts.emailTemplates.from,
- subject: Accounts.emailTemplates.enrollAccount.subject(user)
- };
-
- if (typeof Accounts.emailTemplates.enrollAccount.text === 'function') {
- options.text =
- Accounts.emailTemplates.enrollAccount.text(user, enrollAccountUrl);
- }
-
- if (typeof Accounts.emailTemplates.enrollAccount.html === 'function') {
- options.html =
- Accounts.emailTemplates.enrollAccount.html(user, enrollAccountUrl);
- }
-
- if (typeof Accounts.emailTemplates.headers === 'object') {
- options.headers = Accounts.emailTemplates.headers;
- }
-
+Accounts.sendEnrollmentEmail = function (userId, email, extraTokenData) {
+ const {email: realEmail, user, token} =
+ Accounts.generateResetToken(userId, email, 'enrollAccount', extraTokenData);
+ const url = Accounts.urls.enrollAccount(token);
+ const options = Accounts.generateOptionsForEmail(realEmail, user, url, 'enrollAccount');
Email.send(options);
+ return {email: realEmail, user, token, url, options};
};
@@ -782,71 +836,21 @@ Meteor.methods({resetPassword: function (token, newPassword) {
* @locus Server
* @param {String} userId The id of the user to send email to.
* @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first unverified email in the list.
+ * @param {Object} [extraTokenData] Optional additional data to be added into the token record.
+ * @returns {Object} Object with {email, user, token, url, options} values.
* @importFromPackage accounts-base
*/
-Accounts.sendVerificationEmail = function (userId, address) {
+Accounts.sendVerificationEmail = function (userId, email, extraTokenData) {
// XXX Also generate a link using which someone can delete this
// account if they own said address but weren't those who created
// this account.
- // Make sure the user exists, and address is one of their addresses.
- var user = Meteor.users.findOne(userId);
- if (!user)
- throw new Error("Can't find user");
- // pick the first unverified address if we weren't passed an address.
- if (!address) {
- var email = _.find(user.emails || [],
- function (e) { return !e.verified; });
- address = (email || {}).address;
-
- if (!address) {
- throw new Error("That user has no unverified email addresses.");
- }
- }
- // make sure we have a valid address
- if (!address || !_.contains(_.pluck(user.emails || [], 'address'), address))
- throw new Error("No such email address for user.");
-
-
- var tokenRecord = {
- token: Random.secret(),
- address: address,
- when: new Date()};
- Meteor.users.update(
- {_id: userId},
- {$push: {'services.email.verificationTokens': tokenRecord}});
-
- // before passing to template, update user object with new token
- Meteor._ensure(user, 'services', 'email');
- if (!user.services.email.verificationTokens) {
- user.services.email.verificationTokens = [];
- }
- user.services.email.verificationTokens.push(tokenRecord);
-
- var verifyEmailUrl = Accounts.urls.verifyEmail(tokenRecord.token);
-
- var options = {
- to: address,
- from: Accounts.emailTemplates.verifyEmail.from
- ? Accounts.emailTemplates.verifyEmail.from(user)
- : Accounts.emailTemplates.from,
- subject: Accounts.emailTemplates.verifyEmail.subject(user)
- };
-
- if (typeof Accounts.emailTemplates.verifyEmail.text === 'function') {
- options.text =
- Accounts.emailTemplates.verifyEmail.text(user, verifyEmailUrl);
- }
-
- if (typeof Accounts.emailTemplates.verifyEmail.html === 'function')
- options.html =
- Accounts.emailTemplates.verifyEmail.html(user, verifyEmailUrl);
-
- if (typeof Accounts.emailTemplates.headers === 'object') {
- options.headers = Accounts.emailTemplates.headers;
- }
-
+ const {email: realEmail, user, token} =
+ Accounts.generateVerificationToken(userId, email, extraTokenData);
+ const url = Accounts.urls.verifyEmail(token);
+ const options = Accounts.generateOptionsForEmail(realEmail, user, url, 'verifyEmail');
Email.send(options);
+ return {email: realEmail, user, token, url, options};
};
// Take token from sendVerificationEmail, mark the email as verified,
diff --git a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json
index 0aa725dbc9..d32b4b6b14 100644
--- a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json
+++ b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json
@@ -1,9 +1,9 @@
{
"dependencies": {
"acorn": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz",
- "from": "acorn@>=5.0.0 <5.1.0"
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
+ "from": "acorn@>=5.1.1 <5.2.0"
},
"ansi-regex": {
"version": "2.1.1",
@@ -280,9 +280,9 @@
"from": "babel-plugin-transform-es2015-modules-commonjs@>=6.22.0 <7.0.0"
},
"babel-plugin-transform-es2015-modules-reify": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-reify/-/babel-plugin-transform-es2015-modules-reify-0.11.2.tgz",
- "from": "babel-plugin-transform-es2015-modules-reify@>=0.11.0 <0.12.0"
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-reify/-/babel-plugin-transform-es2015-modules-reify-0.12.0.tgz",
+ "from": "babel-plugin-transform-es2015-modules-reify@>=0.12.0 <0.13.0"
},
"babel-plugin-transform-es2015-object-super": {
"version": "6.24.1",
@@ -590,9 +590,9 @@
"from": "loose-envify@>=1.0.0 <2.0.0"
},
"meteor-babel": {
- "version": "0.22.0",
- "resolved": "https://registry.npmjs.org/meteor-babel/-/meteor-babel-0.22.0.tgz",
- "from": "meteor-babel@0.22.0"
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/meteor-babel/-/meteor-babel-0.23.1.tgz",
+ "from": "meteor-babel@0.23.1"
},
"meteor-babel-helpers": {
"version": "0.0.3",
@@ -692,9 +692,9 @@
}
},
"reify": {
- "version": "0.11.24",
- "resolved": "https://registry.npmjs.org/reify/-/reify-0.11.24.tgz",
- "from": "reify@>=0.11.18 <0.12.0"
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/reify/-/reify-0.12.0.tgz",
+ "from": "reify@>=0.12.0 <0.13.0"
},
"repeating": {
"version": "2.0.1",
diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js
index c10289c199..ecc2428bb6 100644
--- a/packages/babel-compiler/babel-compiler.js
+++ b/packages/babel-compiler/babel-compiler.js
@@ -300,6 +300,16 @@ BCp._inferHelper = function (
merge(babelOptions, babelrc, "presets");
merge(babelOptions, babelrc, "plugins");
+ const babelEnv = (process.env.BABEL_ENV ||
+ process.env.NODE_ENV ||
+ "development");
+ if (babelrc && babelrc.env && babelrc.env[babelEnv]) {
+ const env = babelrc.env[babelEnv];
+ walkBabelRC(env);
+ merge(babelOptions, env, "presets");
+ merge(babelOptions, env, "plugins");
+ }
+
return !! (babelrc.presets ||
babelrc.plugins);
};
diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js
index 8b8731b79a..a48ba5a3eb 100644
--- a/packages/babel-compiler/package.js
+++ b/packages/babel-compiler/package.js
@@ -6,11 +6,11 @@ Package.describe({
// isn't possible because you can't publish a non-recommended
// release with package versions that don't have a pre-release
// identifier at the end (eg, -dev)
- version: '6.19.4'
+ version: '6.20.0'
});
Npm.depends({
- 'meteor-babel': '0.22.0'
+ 'meteor-babel': '0.23.1'
});
Package.onUse(function (api) {
diff --git a/packages/boilerplate-generator-tests/package.js b/packages/boilerplate-generator-tests/package.js
index ff30ae3ce1..b724b16212 100644
--- a/packages/boilerplate-generator-tests/package.js
+++ b/packages/boilerplate-generator-tests/package.js
@@ -1,8 +1,13 @@
-Npm.depends({'parse5': '3.0.2'});
Package.describe({
- // These tests are in a separate package so that we can Npm.depend on parse5, a html parsing library
+ // These tests are in a separate package so that we can Npm.depend on
+ // parse5, a html parsing library.
summary: "Tests for the boilerplate-generator package",
- version: '1.0.0'
+ version: '1.0.0',
+ documentation: null
+});
+
+Npm.depends({
+ parse5: '3.0.2'
});
Package.onTest(function (api) {
diff --git a/packages/boilerplate-generator/package.js b/packages/boilerplate-generator/package.js
index 23fb12dcbb..951584f37b 100644
--- a/packages/boilerplate-generator/package.js
+++ b/packages/boilerplate-generator/package.js
@@ -1,6 +1,6 @@
Package.describe({
summary: "Generates the boilerplate html from program's manifest",
- version: '1.1.2'
+ version: '1.2.0'
});
Package.onUse(api => {
diff --git a/packages/constraint-solver/constraint-solver.js b/packages/constraint-solver/constraint-solver.js
index 8e4b78be21..435c312769 100644
--- a/packages/constraint-solver/constraint-solver.js
+++ b/packages/constraint-solver/constraint-solver.js
@@ -186,6 +186,10 @@ CS.isConstraintSatisfied = function (pkg, vConstraint, version) {
var cVersion = simpleConstraint.versionString;
return (cVersion === version);
} else if (type === 'compatible-with') {
+ if (typeof simpleConstraint.test === "function") {
+ return simpleConstraint.test(version);
+ }
+
var cv = PV.parse(simpleConstraint.versionString);
var v = PV.parse(version);
diff --git a/packages/crosswalk/package.js b/packages/crosswalk/package.js
index 1dc6923f67..2e7d8b382b 100644
--- a/packages/crosswalk/package.js
+++ b/packages/crosswalk/package.js
@@ -6,5 +6,5 @@ instead of the System WebView on Android",
});
Cordova.depends({
- 'cordova-plugin-crosswalk-webview': '2.2.0'
+ 'cordova-plugin-crosswalk-webview': '2.3.0'
});
diff --git a/packages/ddp-client/.npm/package/npm-shrinkwrap.json b/packages/ddp-client/.npm/package/npm-shrinkwrap.json
index 9007897712..a44010e437 100644
--- a/packages/ddp-client/.npm/package/npm-shrinkwrap.json
+++ b/packages/ddp-client/.npm/package/npm-shrinkwrap.json
@@ -1,23 +1,14 @@
{
"dependencies": {
"faye-websocket": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.0.tgz",
- "from": "faye-websocket@0.11.0",
- "dependencies": {
- "websocket-driver": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.4.tgz",
- "from": "websocket-driver@>=0.5.1",
- "dependencies": {
- "websocket-extensions": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz",
- "from": "websocket-extensions@>=0.1.1"
- }
- }
- }
- }
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
+ "from": "faye-websocket@0.11.1"
+ },
+ "http-parser-js": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.5.tgz",
+ "from": "http-parser-js@>=0.4.0"
},
"lolex": {
"version": "1.4.0",
@@ -28,6 +19,16 @@
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/permessage-deflate/-/permessage-deflate-0.1.3.tgz",
"from": "permessage-deflate@0.1.3"
+ },
+ "websocket-driver": {
+ "version": "0.6.5",
+ "resolved": "https://github.com/faye/websocket-driver-node/tarball/1325828a9e8b5e29c7b4758995efdb84703919ad",
+ "from": "https://github.com/faye/websocket-driver-node/tarball/1325828a9e8b5e29c7b4758995efdb84703919ad"
+ },
+ "websocket-extensions": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz",
+ "from": "websocket-extensions@>=0.1.1"
}
}
}
diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js
index 59667d5992..8afeb25c69 100644
--- a/packages/ddp-client/package.js
+++ b/packages/ddp-client/package.js
@@ -1,11 +1,16 @@
Package.describe({
summary: "Meteor's latency-compensated distributed data client",
- version: '2.0.0',
+ version: '2.1.0',
documentation: null
});
Npm.depends({
- "faye-websocket": "0.11.0",
+ "faye-websocket": "0.11.1",
+ // TODO Remove this direct websocket-driver dependency when a new
+ // version gets published, though that may not happen very soon:
+ // https://github.com/faye/websocket-driver-node/issues/21
+ "websocket-driver": "https://github.com/faye/websocket-driver-node/" +
+ "tarball/1325828a9e8b5e29c7b4758995efdb84703919ad",
"lolex": "1.4.0",
"permessage-deflate": "0.1.3"
});
diff --git a/packages/ejson/package.js b/packages/ejson/package.js
index 0259ea994e..142dff4de5 100644
--- a/packages/ejson/package.js
+++ b/packages/ejson/package.js
@@ -1,6 +1,6 @@
Package.describe({
summary: 'Extended and Extensible JSON library',
- version: '1.0.14',
+ version: '1.0.14'
});
Package.onUse(function onUse(api) {
diff --git a/packages/launch-screen/package.js b/packages/launch-screen/package.js
index c027b04e60..c6c0749150 100644
--- a/packages/launch-screen/package.js
+++ b/packages/launch-screen/package.js
@@ -10,7 +10,7 @@ Package.describe({
});
Cordova.depends({
- 'cordova-plugin-splashscreen': '4.0.1'
+ 'cordova-plugin-splashscreen': '4.0.3'
});
Package.onUse(function(api) {
diff --git a/packages/logging/package.js b/packages/logging/package.js
index f92fc241ea..85e6423d1e 100644
--- a/packages/logging/package.js
+++ b/packages/logging/package.js
@@ -12,7 +12,7 @@ Npm.strip({
});
Cordova.depends({
- 'cordova-plugin-console': '1.0.5'
+ 'cordova-plugin-console': '1.0.7'
});
Package.onUse(function (api) {
diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js
index efbed2d097..13eec78560 100644
--- a/packages/meteor-tool/package.js
+++ b/packages/meteor-tool/package.js
@@ -1,6 +1,6 @@
Package.describe({
summary: "The Meteor command-line tool",
- version: '1.5.1'
+ version: "1.5.2"
});
Package.includeTool();
diff --git a/packages/minifier-js/.npm/package/npm-shrinkwrap.json b/packages/minifier-js/.npm/package/npm-shrinkwrap.json
index b92b6f3593..96cb028903 100644
--- a/packages/minifier-js/.npm/package/npm-shrinkwrap.json
+++ b/packages/minifier-js/.npm/package/npm-shrinkwrap.json
@@ -1,24 +1,19 @@
{
"dependencies": {
"commander": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
- "from": "commander@>=2.9.0 <2.10.0"
- },
- "graceful-readlink": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "from": "graceful-readlink@>=1.0.0"
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "from": "commander@>=2.11.0 <2.12.0"
},
"source-map": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"from": "source-map@>=0.5.1 <0.6.0"
},
"uglify-js": {
- "version": "3.0.18",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.0.18.tgz",
- "from": "uglify-js@3.0.18"
+ "version": "3.0.28",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.0.28.tgz",
+ "from": "uglify-js@3.0.28"
}
}
}
diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js
index 36f5e8557a..8383c30401 100644
--- a/packages/minifier-js/package.js
+++ b/packages/minifier-js/package.js
@@ -1,6 +1,6 @@
Package.describe({
summary: "JavaScript minifier",
- version: "2.1.1"
+ version: "2.1.2"
});
Npm.depends({
diff --git a/packages/minimongo/local_collection.js b/packages/minimongo/local_collection.js
index 17a2ba5216..b414dcb396 100644
--- a/packages/minimongo/local_collection.js
+++ b/packages/minimongo/local_collection.js
@@ -29,7 +29,7 @@ export default class LocalCollection {
// resultsSnapshot: snapshot of results. null if not paused.
// cursor: Cursor object for the query.
// selector, sorter, (callbacks): functions
- this.queries = {};
+ this.queries = Object.create(null);
// null if not saving originals; an IdMap from id to original document value
// if saving originals. See comments before saveOriginals().
@@ -111,11 +111,11 @@ export default class LocalCollection {
const queriesToRecompute = [];
// trigger live queries that match
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.dirty) {
- continue;
+ return;
}
const matchResult = query.matcher.documentMatches(doc);
@@ -131,7 +131,7 @@ export default class LocalCollection {
LocalCollection._insertInResults(query, doc);
}
}
- }
+ });
queriesToRecompute.forEach(qid => {
if (this.queries[qid]) {
@@ -164,11 +164,10 @@ export default class LocalCollection {
this.paused = true;
// Take a snapshot of the query results for each query.
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
-
query.resultsSnapshot = EJSON.clone(query.results);
- }
+ });
}
remove(selector, callback) {
@@ -180,7 +179,7 @@ export default class LocalCollection {
this._docs.clear();
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.ordered) {
@@ -188,7 +187,7 @@ export default class LocalCollection {
} else {
query.results.clear();
}
- }
+ });
if (callback) {
Meteor.defer(() => {
@@ -215,7 +214,7 @@ export default class LocalCollection {
const removeId = remove[i];
const removeDoc = this._docs.get(removeId);
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.dirty) {
@@ -229,7 +228,7 @@ export default class LocalCollection {
queryRemove.push({qid, doc: removeDoc});
}
}
- }
+ });
this._saveOriginal(removeId, removeDoc);
this._docs.remove(removeId);
@@ -280,7 +279,7 @@ export default class LocalCollection {
// observer methods won't actually fire when we trigger them.
this.paused = false;
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.dirty) {
@@ -302,7 +301,7 @@ export default class LocalCollection {
}
query.resultsSnapshot = null;
- }
+ });
this._observeQueue.drain();
}
@@ -360,7 +359,7 @@ export default class LocalCollection {
const docMap = new LocalCollection._IdMap;
const idsMatched = LocalCollection._idsMatchedBySelector(selector);
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if ((query.cursor.skip || query.cursor.limit) && ! this.paused) {
@@ -399,7 +398,7 @@ export default class LocalCollection {
qidToOriginalResults[qid] = query.results.map(memoizedCloneIfNeeded);
}
- }
+ });
const recomputeQids = {};
@@ -515,11 +514,11 @@ export default class LocalCollection {
_modifyAndNotify(doc, mod, recomputeQids, arrayIndices) {
const matched_before = {};
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.dirty) {
- continue;
+ return;
}
if (query.ordered) {
@@ -529,17 +528,17 @@ export default class LocalCollection {
// can just do a direct lookup.
matched_before[qid] = query.results.has(doc._id);
}
- }
+ });
const old_doc = EJSON.clone(doc);
LocalCollection._modify(doc, mod, {arrayIndices});
- for (let qid in this.queries) {
+ Object.keys(this.queries).forEach(qid => {
const query = this.queries[qid];
if (query.dirty) {
- continue;
+ return;
}
const afterMatch = query.matcher.documentMatches(doc);
@@ -568,7 +567,7 @@ export default class LocalCollection {
} else if (before && after) {
LocalCollection._updateInResults(query, doc, old_doc);
}
- }
+ });
}
// Recomputes the results of a query and runs observe callbacks for the
@@ -1081,13 +1080,13 @@ LocalCollection._isModificationMod = mod => {
let isModify = false;
let isReplace = false;
- for (const key in mod) {
+ Object.keys(mod).forEach(key => {
if (key.substr(0, 1) === '$') {
isModify = true;
} else {
isReplace = true;
}
- }
+ });
if (isModify && isReplace) {
throw new Error(
diff --git a/packages/minimongo/matcher.js b/packages/minimongo/matcher.js
index ad48271166..75929e4b09 100644
--- a/packages/minimongo/matcher.js
+++ b/packages/minimongo/matcher.js
@@ -273,10 +273,9 @@ LocalCollection._f = {
const toArray = object => {
const result = [];
- for (let key in object) {
- result.push(key);
- result.push(object[key]);
- }
+ Object.keys(object).forEach(key => {
+ result.push(key, object[key]);
+ });
return result;
};
diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js
index 30bbf4adef..97edd81586 100644
--- a/packages/minimongo/package.js
+++ b/packages/minimongo/package.js
@@ -1,5 +1,5 @@
Package.describe({
- summary: 'Meteor\'s client-side datastore: a port of MongoDB to Javascript',
+ summary: "Meteor's client-side datastore: a port of MongoDB to Javascript",
version: '1.3.0'
});
diff --git a/packages/mobile-status-bar/package.js b/packages/mobile-status-bar/package.js
index ddf88dc48d..86485b0923 100644
--- a/packages/mobile-status-bar/package.js
+++ b/packages/mobile-status-bar/package.js
@@ -4,5 +4,5 @@ Package.describe({
});
Cordova.depends({
- 'cordova-plugin-statusbar': '2.2.1'
+ 'cordova-plugin-statusbar': '2.2.3'
});
diff --git a/packages/modules/.npm/package/npm-shrinkwrap.json b/packages/modules/.npm/package/npm-shrinkwrap.json
index ed85116d23..b005c19a86 100644
--- a/packages/modules/.npm/package/npm-shrinkwrap.json
+++ b/packages/modules/.npm/package/npm-shrinkwrap.json
@@ -1,13 +1,13 @@
{
"dependencies": {
"acorn": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz",
- "from": "acorn@>=5.0.0 <5.1.0"
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
+ "from": "acorn@>=5.1.1 <5.2.0"
},
"minipass": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.0.2.tgz",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz",
"from": "minipass@>=2.0.0 <3.0.0"
},
"minizlib": {
@@ -16,9 +16,9 @@
"from": "minizlib@>=1.0.3 <2.0.0"
},
"reify": {
- "version": "0.11.24",
- "resolved": "https://registry.npmjs.org/reify/-/reify-0.11.24.tgz",
- "from": "reify@0.11.24"
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/reify/-/reify-0.12.0.tgz",
+ "from": "reify@0.12.0"
},
"semver": {
"version": "5.3.0",
diff --git a/packages/modules/package.js b/packages/modules/package.js
index 3d5e5b80e6..e7a0b80687 100644
--- a/packages/modules/package.js
+++ b/packages/modules/package.js
@@ -1,12 +1,12 @@
Package.describe({
name: "modules",
- version: "0.9.4",
+ version: "0.10.0",
summary: "CommonJS module system",
documentation: "README.md"
});
Npm.depends({
- reify: "0.11.24"
+ reify: "0.12.0"
});
Package.onUse(function(api) {
diff --git a/packages/mongo-dev-server/package.js b/packages/mongo-dev-server/package.js
index 9e858ef438..3f5d9026b3 100644
--- a/packages/mongo-dev-server/package.js
+++ b/packages/mongo-dev-server/package.js
@@ -3,7 +3,7 @@ Package.describe({
documentation: 'README.md',
name: 'mongo-dev-server',
summary: 'Start MongoDB alongside Meteor, in development mode.',
- version: '1.0.0',
+ version: '1.0.1',
});
Package.onUse(function (api) {
diff --git a/packages/mongo/collection_tests.js b/packages/mongo/collection_tests.js
index 4334a3e9b9..e6b0c3d9be 100644
--- a/packages/mongo/collection_tests.js
+++ b/packages/mongo/collection_tests.js
@@ -138,15 +138,21 @@ Tinytest.add('collection - calling native find with $reverse hint should reverse
}
);
-Tinytest.add('collection - calling native find with good hint and maxTimeMs should succeed',
- function(test) {
+Tinytest.addAsync('collection - calling native find with good hint and maxTimeMs should succeed',
+ function(test, done) {
var collectionName = 'findOptions3' + test.id;
var collection = new Mongo.Collection(collectionName);
collection.insert({a: 1});
- if (Meteor.isServer) {
- collection.rawCollection().createIndex({a: 1});
- }
- test.equal(collection.find({}, {hint: {a: 1}, maxTimeMs: 1000}).count(), 1);
+ Promise.resolve(
+ Meteor.isServer &&
+ collection.rawCollection().createIndex({ a: 1 })
+ ).then(() => {
+ test.equal(collection.find({}, {
+ hint: {a: 1},
+ maxTimeMs: 1000
+ }).count(), 1);
+ done();
+ }).catch(error => test.fail(error.message));
}
);
diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js
index faba62f641..932b98caca 100644
--- a/packages/mongo/mongo_livedata_tests.js
+++ b/packages/mongo/mongo_livedata_tests.js
@@ -2532,10 +2532,12 @@ if (Meteor.isServer) {
self.events.push({evt: "a", id: id});
Meteor._sleepForMs(200);
self.events.push({evt: "b", id: id});
+ if (! self.two) {
+ self.two = self.C.insert({});
+ }
}
});
self.one = self.C.insert({});
- self.two = self.C.insert({});
pollUntil(expect, function () {
return self.events.length === 4;
}, 10000);
diff --git a/packages/mongo/package.js b/packages/mongo/package.js
index ab0a9c17e6..22ab4f22a8 100644
--- a/packages/mongo/package.js
+++ b/packages/mongo/package.js
@@ -9,7 +9,7 @@
Package.describe({
summary: "Adaptor for using MongoDB and Minimongo over DDP",
- version: '1.1.23'
+ version: '1.2.0'
});
Npm.depends({
diff --git a/packages/non-core/blaze b/packages/non-core/blaze
index e9a03af5ed..6a82100e09 160000
--- a/packages/non-core/blaze
+++ b/packages/non-core/blaze
@@ -1 +1 @@
-Subproject commit e9a03af5edc69777058f87f521d98b6faba9910c
+Subproject commit 6a82100e09b22c27366d11805b232ceab443e386
diff --git a/packages/oauth/package.js b/packages/oauth/package.js
index f20389e65b..28b2b0dfbc 100644
--- a/packages/oauth/package.js
+++ b/packages/oauth/package.js
@@ -57,5 +57,5 @@ Package.onTest(function (api) {
});
Cordova.depends({
- 'cordova-plugin-inappbrowser': '1.6.1'
+ 'cordova-plugin-inappbrowser': '1.7.1'
});
diff --git a/packages/package-version-parser/package-version-parser.js b/packages/package-version-parser/package-version-parser.js
index c1a807260a..7d651f7edc 100644
--- a/packages/package-version-parser/package-version-parser.js
+++ b/packages/package-version-parser/package-version-parser.js
@@ -1,14 +1,9 @@
-// This file is in tools/packaging/package-version-parser.js and is symlinked to
-// packages/package-version-parser/package-version-parser.js. It's part of both
-// the tool and the package! We don't use an isopacket for it because it used
-// to be required as part of building isopackets (though that may no longer be
-// true).
-var inTool = typeof Package === 'undefined';
+var inTool = typeof Package === "undefined";
-
-var semver = inTool ?
- require ('../../dev_bundle/lib/node_modules/semver') : SemVer410;
-var __ = inTool ? require('../../dev_bundle/lib/node_modules/underscore') : _;
+// Provided by dev_bundle/server-lib/node_modules/semver.
+var semver = inTool
+ ? module.parent.require("semver")
+ : require("semver");
// Takes in a meteor version string, for example 1.2.3-rc.5_1+12345.
//
@@ -108,16 +103,14 @@ var PV = function (versionString) {
this._semverParsed = null; // populate lazily
};
+// Set module.exports for tools/packaging/package-version-parser.js and
+// module.exports.PackageVersion for api.export("PackageVersion").
+PV.PackageVersion = module.exports = PV;
+
PV.parse = function (versionString) {
return new PV(versionString);
};
-if (inTool) {
- module.exports = PV;
-} else {
- PackageVersion = PV;
-}
-
// Converts a meteor version into a large floating point number, which
// is (more or less [*]) unique to that version. Satisfies the
// following guarantee: If PV.lessThan(v1, v2) then
@@ -156,7 +149,7 @@ var prereleaseIdentifierToFraction = function (prerelease) {
if (prerelease.length === 0)
return 0;
- return __.reduce(prerelease, function (memo, part, index) {
+ return prerelease.reduce(function (memo, part, index) {
var digit;
if (typeof part === 'number') {
digit = part+1;
@@ -251,20 +244,41 @@ var parseSimpleConstraint = function (constraintString) {
throw new Error("Non-empty string required");
}
- var type, versionString;
+ var result = {};
+ var needToCheckValidity = true;
if (constraintString.charAt(0) === '=') {
- type = "exactly";
- versionString = constraintString.substr(1);
+ result.type = "exactly";
+ result.versionString = constraintString.slice(1);
+
} else {
- type = "compatible-with";
- versionString = constraintString;
+ result.type = "compatible-with";
+
+ if (constraintString.charAt(0) === "~") {
+ var semversion = PV.parse(
+ result.versionString = constraintString.slice(1)
+ ).semver;
+
+ var range = new semver.Range("~" + semversion);
+
+ result.test = function (version) {
+ return range.test(PV.parse(version).semver);
+ };
+
+ // Already checked by calling PV.parse above.
+ needToCheckValidity = false;
+
+ } else {
+ result.versionString = constraintString;
+ }
}
- // This will throw if the version string is invalid.
- PV.getValidServerVersion(versionString);
+ if (needToCheckValidity) {
+ // This will throw if the version string is invalid.
+ PV.getValidServerVersion(result.versionString);
+ }
- return { type: type, versionString: versionString };
+ return result;
};
@@ -289,7 +303,7 @@ PV.VersionConstraint = function (vConstraintString) {
} else {
// Parse out the versionString.
var parts = vConstraintString.split(/ *\|\| */);
- alternatives = __.map(parts, function (alt) {
+ alternatives = parts.map(function (alt) {
if (! alt) {
throwVersionParserError("Invalid constraint string: " +
vConstraintString);
@@ -420,7 +434,8 @@ PV.validatePackageName = function (packageName, options) {
// (There is already a package ending with a `-` and one with two consecutive `-`
// in troposphere, though they both look like typos.)
- if (packageName[0] === ":" || __.last(packageName) === ":") {
+ if (packageName.startsWith(":") ||
+ packageName.endsWith(":")) {
throwVersionParserError("Package names may not start or end with a colon: " +
JSON.stringify(packageName));
}
diff --git a/packages/package-version-parser/package.js b/packages/package-version-parser/package.js
index 601910f00f..3e8daf5f16 100644
--- a/packages/package-version-parser/package.js
+++ b/packages/package-version-parser/package.js
@@ -4,10 +4,9 @@ Package.describe({
});
Package.onUse(function (api) {
+ api.use('modules');
+ api.mainModule('package-version-parser.js');
api.export('PackageVersion');
- api.use('underscore');
- api.addFiles(['semver410.js',
- 'package-version-parser.js']);
});
Package.onTest(function (api) {
diff --git a/packages/package-version-parser/semver410.js b/packages/package-version-parser/semver410.js
deleted file mode 100644
index 11e655cd3e..0000000000
--- a/packages/package-version-parser/semver410.js
+++ /dev/null
@@ -1,1135 +0,0 @@
-//
-// Fool the module system detection code below so that it doesn't
-// do anything special.
-var exports = SemVer, module = {}, define = {};
-// Create a package-private variable. Can't use SemVer because
-// of the code that says `function SemVer(...)` below (implicitly
-// declaring a var). Can't use "semver" because that's a var in
-// package-version-parser.js.
-SemVer410 = SemVer;
-//
-
-// export the class if we are in a Node-like system.
-if (typeof module === 'object' && module.exports === exports)
- exports = module.exports = SemVer;
-
-// The debug function is excluded entirely from the minified version.
-/* nomin */ var debug;
-/* nomin */ if (typeof process === 'object' &&
- /* nomin */ process.env &&
- /* nomin */ process.env.NODE_DEBUG &&
- /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG))
- /* nomin */ debug = function() {
- /* nomin */ var args = Array.prototype.slice.call(arguments, 0);
- /* nomin */ args.unshift('SEMVER');
- /* nomin */ console.log.apply(console, args);
- /* nomin */ };
-/* nomin */ else
- /* nomin */ debug = function() {};
-
-// Note: this is the semver.org version of the spec that it implements
-// Not necessarily the package version of this code.
-exports.SEMVER_SPEC_VERSION = '2.0.0';
-
-// The actual regexps go on exports.re
-var re = exports.re = [];
-var src = exports.src = [];
-var R = 0;
-
-// The following Regular Expressions can be used for tokenizing,
-// validating, and parsing SemVer version strings.
-
-// ## Numeric Identifier
-// A single `0`, or a non-zero digit followed by zero or more digits.
-
-var NUMERICIDENTIFIER = R++;
-src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
-var NUMERICIDENTIFIERLOOSE = R++;
-src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
-
-
-// ## Non-numeric Identifier
-// Zero or more digits, followed by a letter or hyphen, and then zero or
-// more letters, digits, or hyphens.
-
-var NONNUMERICIDENTIFIER = R++;
-src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
-
-
-// ## Main Version
-// Three dot-separated numeric identifiers.
-
-var MAINVERSION = R++;
-src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
- '(' + src[NUMERICIDENTIFIER] + ')\\.' +
- '(' + src[NUMERICIDENTIFIER] + ')';
-
-var MAINVERSIONLOOSE = R++;
-src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
- '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
- '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
-
-// ## Pre-release Version Identifier
-// A numeric identifier, or a non-numeric identifier.
-
-var PRERELEASEIDENTIFIER = R++;
-src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
- '|' + src[NONNUMERICIDENTIFIER] + ')';
-
-var PRERELEASEIDENTIFIERLOOSE = R++;
-src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
- '|' + src[NONNUMERICIDENTIFIER] + ')';
-
-
-// ## Pre-release Version
-// Hyphen, followed by one or more dot-separated pre-release version
-// identifiers.
-
-var PRERELEASE = R++;
-src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
- '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
-
-var PRERELEASELOOSE = R++;
-src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
- '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
-
-// ## Build Metadata Identifier
-// Any combination of digits, letters, or hyphens.
-
-var BUILDIDENTIFIER = R++;
-src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
-
-// ## Build Metadata
-// Plus sign, followed by one or more period-separated build metadata
-// identifiers.
-
-var BUILD = R++;
-src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
- '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
-
-
-// ## Full Version String
-// A main version, followed optionally by a pre-release version and
-// build metadata.
-
-// Note that the only major, minor, patch, and pre-release sections of
-// the version string are capturing groups. The build metadata is not a
-// capturing group, because it should not ever be used in version
-// comparison.
-
-var FULL = R++;
-var FULLPLAIN = 'v?' + src[MAINVERSION] +
- src[PRERELEASE] + '?' +
- src[BUILD] + '?';
-
-src[FULL] = '^' + FULLPLAIN + '$';
-
-// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
-// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
-// common in the npm registry.
-var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
- src[PRERELEASELOOSE] + '?' +
- src[BUILD] + '?';
-
-var LOOSE = R++;
-src[LOOSE] = '^' + LOOSEPLAIN + '$';
-
-var GTLT = R++;
-src[GTLT] = '((?:<|>)?=?)';
-
-// Something like "2.*" or "1.2.x".
-// Note that "x.x" is a valid xRange identifer, meaning "any version"
-// Only the first item is strictly required.
-var XRANGEIDENTIFIERLOOSE = R++;
-src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
-var XRANGEIDENTIFIER = R++;
-src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
-
-var XRANGEPLAIN = R++;
-src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
- '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
- '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
- '(?:' + src[PRERELEASE] + ')?' +
- src[BUILD] + '?' +
- ')?)?';
-
-var XRANGEPLAINLOOSE = R++;
-src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
- '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
- '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
- '(?:' + src[PRERELEASELOOSE] + ')?' +
- src[BUILD] + '?' +
- ')?)?';
-
-var XRANGE = R++;
-src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
-var XRANGELOOSE = R++;
-src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
-
-// Tilde ranges.
-// Meaning is "reasonably at or greater than"
-var LONETILDE = R++;
-src[LONETILDE] = '(?:~>?)';
-
-var TILDETRIM = R++;
-src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
-re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
-var tildeTrimReplace = '$1~';
-
-var TILDE = R++;
-src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
-var TILDELOOSE = R++;
-src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
-
-// Caret ranges.
-// Meaning is "at least and backwards compatible with"
-var LONECARET = R++;
-src[LONECARET] = '(?:\\^)';
-
-var CARETTRIM = R++;
-src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
-re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
-var caretTrimReplace = '$1^';
-
-var CARET = R++;
-src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
-var CARETLOOSE = R++;
-src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
-
-// A simple gt/lt/eq thing, or just "" to indicate "any version"
-var COMPARATORLOOSE = R++;
-src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
-var COMPARATOR = R++;
-src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
-
-
-// An expression to strip any whitespace between the gtlt and the thing
-// it modifies, so that `> 1.2.3` ==> `>1.2.3`
-var COMPARATORTRIM = R++;
-src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
- '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
-
-// this one has to use the /g flag
-re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
-var comparatorTrimReplace = '$1$2$3';
-
-
-// Something like `1.2.3 - 1.2.4`
-// Note that these all use the loose form, because they'll be
-// checked against either the strict or loose comparator form
-// later.
-var HYPHENRANGE = R++;
-src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
- '\\s+-\\s+' +
- '(' + src[XRANGEPLAIN] + ')' +
- '\\s*$';
-
-var HYPHENRANGELOOSE = R++;
-src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
- '\\s+-\\s+' +
- '(' + src[XRANGEPLAINLOOSE] + ')' +
- '\\s*$';
-
-// Star ranges basically just allow anything at all.
-var STAR = R++;
-src[STAR] = '(<|>)?=?\\s*\\*';
-
-// Compile to actual regexp objects.
-// All are flag-free, unless they were created above with a flag.
-for (var i = 0; i < R; i++) {
- debug(i, src[i]);
- if (!re[i])
- re[i] = new RegExp(src[i]);
-}
-
-exports.parse = parse;
-function parse(version, loose) {
- var r = loose ? re[LOOSE] : re[FULL];
- return (r.test(version)) ? new SemVer(version, loose) : null;
-}
-
-exports.valid = valid;
-function valid(version, loose) {
- var v = parse(version, loose);
- return v ? v.version : null;
-}
-
-
-exports.clean = clean;
-function clean(version, loose) {
- var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
- return s ? s.version : null;
-}
-
-exports.SemVer = SemVer;
-
-function SemVer(version, loose) {
- if (version instanceof SemVer) {
- if (version.loose === loose)
- return version;
- else
- version = version.version;
- } else if (typeof version !== 'string') {
- throw new TypeError('Invalid Version: ' + version);
- }
-
- if (!(this instanceof SemVer))
- return new SemVer(version, loose);
-
- debug('SemVer', version, loose);
- this.loose = loose;
- var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
-
- if (!m)
- throw new TypeError('Invalid Version: ' + version);
-
- this.raw = version;
-
- // these are actually numbers
- this.major = +m[1];
- this.minor = +m[2];
- this.patch = +m[3];
-
- // numberify any prerelease numeric ids
- if (!m[4])
- this.prerelease = [];
- else
- this.prerelease = m[4].split('.').map(function(id) {
- return (/^[0-9]+$/.test(id)) ? +id : id;
- });
-
- this.build = m[5] ? m[5].split('.') : [];
- this.format();
-}
-
-SemVer.prototype.format = function() {
- this.version = this.major + '.' + this.minor + '.' + this.patch;
- if (this.prerelease.length)
- this.version += '-' + this.prerelease.join('.');
- return this.version;
-};
-
-SemVer.prototype.inspect = function() {
- return '';
-};
-
-SemVer.prototype.toString = function() {
- return this.version;
-};
-
-SemVer.prototype.compare = function(other) {
- debug('SemVer.compare', this.version, this.loose, other);
- if (!(other instanceof SemVer))
- other = new SemVer(other, this.loose);
-
- return this.compareMain(other) || this.comparePre(other);
-};
-
-SemVer.prototype.compareMain = function(other) {
- if (!(other instanceof SemVer))
- other = new SemVer(other, this.loose);
-
- return compareIdentifiers(this.major, other.major) ||
- compareIdentifiers(this.minor, other.minor) ||
- compareIdentifiers(this.patch, other.patch);
-};
-
-SemVer.prototype.comparePre = function(other) {
- if (!(other instanceof SemVer))
- other = new SemVer(other, this.loose);
-
- // NOT having a prerelease is > having one
- if (this.prerelease.length && !other.prerelease.length)
- return -1;
- else if (!this.prerelease.length && other.prerelease.length)
- return 1;
- else if (!this.prerelease.length && !other.prerelease.length)
- return 0;
-
- var i = 0;
- do {
- var a = this.prerelease[i];
- var b = other.prerelease[i];
- debug('prerelease compare', i, a, b);
- if (a === undefined && b === undefined)
- return 0;
- else if (b === undefined)
- return 1;
- else if (a === undefined)
- return -1;
- else if (a === b)
- continue;
- else
- return compareIdentifiers(a, b);
- } while (++i);
-};
-
-// preminor will bump the version up to the next minor release, and immediately
-// down to pre-release. premajor and prepatch work the same way.
-SemVer.prototype.inc = function(release, identifier) {
- switch (release) {
- case 'premajor':
- this.prerelease.length = 0;
- this.patch = 0;
- this.minor = 0;
- this.major++;
- this.inc('pre', identifier);
- break;
- case 'preminor':
- this.prerelease.length = 0;
- this.patch = 0;
- this.minor++;
- this.inc('pre', identifier);
- break;
- case 'prepatch':
- // If this is already a prerelease, it will bump to the next version
- // drop any prereleases that might already exist, since they are not
- // relevant at this point.
- this.prerelease.length = 0;
- this.inc('patch', identifier);
- this.inc('pre', identifier);
- break;
- // If the input is a non-prerelease version, this acts the same as
- // prepatch.
- case 'prerelease':
- if (this.prerelease.length === 0)
- this.inc('patch', identifier);
- this.inc('pre', identifier);
- break;
-
- case 'major':
- // If this is a pre-major version, bump up to the same major version.
- // Otherwise increment major.
- // 1.0.0-5 bumps to 1.0.0
- // 1.1.0 bumps to 2.0.0
- if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0)
- this.major++;
- this.minor = 0;
- this.patch = 0;
- this.prerelease = [];
- break;
- case 'minor':
- // If this is a pre-minor version, bump up to the same minor version.
- // Otherwise increment minor.
- // 1.2.0-5 bumps to 1.2.0
- // 1.2.1 bumps to 1.3.0
- if (this.patch !== 0 || this.prerelease.length === 0)
- this.minor++;
- this.patch = 0;
- this.prerelease = [];
- break;
- case 'patch':
- // If this is not a pre-release version, it will increment the patch.
- // If it is a pre-release it will bump up to the same patch version.
- // 1.2.0-5 patches to 1.2.0
- // 1.2.0 patches to 1.2.1
- if (this.prerelease.length === 0)
- this.patch++;
- this.prerelease = [];
- break;
- // This probably shouldn't be used publicly.
- // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
- case 'pre':
- if (this.prerelease.length === 0)
- this.prerelease = [0];
- else {
- var i = this.prerelease.length;
- while (--i >= 0) {
- if (typeof this.prerelease[i] === 'number') {
- this.prerelease[i]++;
- i = -2;
- }
- }
- if (i === -1) // didn't increment anything
- this.prerelease.push(0);
- }
- if (identifier) {
- // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
- // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
- if (this.prerelease[0] === identifier) {
- if (isNaN(this.prerelease[1]))
- this.prerelease = [identifier, 0];
- } else
- this.prerelease = [identifier, 0];
- }
- break;
-
- default:
- throw new Error('invalid increment argument: ' + release);
- }
- this.format();
- return this;
-};
-
-exports.inc = inc;
-function inc(version, release, loose, identifier) {
- if (typeof(loose) === 'string') {
- identifier = loose;
- loose = undefined;
- }
-
- try {
- return new SemVer(version, loose).inc(release, identifier).version;
- } catch (er) {
- return null;
- }
-}
-
-exports.compareIdentifiers = compareIdentifiers;
-
-var numeric = /^[0-9]+$/;
-function compareIdentifiers(a, b) {
- var anum = numeric.test(a);
- var bnum = numeric.test(b);
-
- if (anum && bnum) {
- a = +a;
- b = +b;
- }
-
- return (anum && !bnum) ? -1 :
- (bnum && !anum) ? 1 :
- a < b ? -1 :
- a > b ? 1 :
- 0;
-}
-
-exports.rcompareIdentifiers = rcompareIdentifiers;
-function rcompareIdentifiers(a, b) {
- return compareIdentifiers(b, a);
-}
-
-exports.compare = compare;
-function compare(a, b, loose) {
- return new SemVer(a, loose).compare(b);
-}
-
-exports.compareLoose = compareLoose;
-function compareLoose(a, b) {
- return compare(a, b, true);
-}
-
-exports.rcompare = rcompare;
-function rcompare(a, b, loose) {
- return compare(b, a, loose);
-}
-
-exports.sort = sort;
-function sort(list, loose) {
- return list.sort(function(a, b) {
- return exports.compare(a, b, loose);
- });
-}
-
-exports.rsort = rsort;
-function rsort(list, loose) {
- return list.sort(function(a, b) {
- return exports.rcompare(a, b, loose);
- });
-}
-
-exports.gt = gt;
-function gt(a, b, loose) {
- return compare(a, b, loose) > 0;
-}
-
-exports.lt = lt;
-function lt(a, b, loose) {
- return compare(a, b, loose) < 0;
-}
-
-exports.eq = eq;
-function eq(a, b, loose) {
- return compare(a, b, loose) === 0;
-}
-
-exports.neq = neq;
-function neq(a, b, loose) {
- return compare(a, b, loose) !== 0;
-}
-
-exports.gte = gte;
-function gte(a, b, loose) {
- return compare(a, b, loose) >= 0;
-}
-
-exports.lte = lte;
-function lte(a, b, loose) {
- return compare(a, b, loose) <= 0;
-}
-
-exports.cmp = cmp;
-function cmp(a, op, b, loose) {
- var ret;
- switch (op) {
- case '===':
- if (typeof a === 'object') a = a.version;
- if (typeof b === 'object') b = b.version;
- ret = a === b;
- break;
- case '!==':
- if (typeof a === 'object') a = a.version;
- if (typeof b === 'object') b = b.version;
- ret = a !== b;
- break;
- case '': case '=': case '==': ret = eq(a, b, loose); break;
- case '!=': ret = neq(a, b, loose); break;
- case '>': ret = gt(a, b, loose); break;
- case '>=': ret = gte(a, b, loose); break;
- case '<': ret = lt(a, b, loose); break;
- case '<=': ret = lte(a, b, loose); break;
- default: throw new TypeError('Invalid operator: ' + op);
- }
- return ret;
-}
-
-exports.Comparator = Comparator;
-function Comparator(comp, loose) {
- if (comp instanceof Comparator) {
- if (comp.loose === loose)
- return comp;
- else
- comp = comp.value;
- }
-
- if (!(this instanceof Comparator))
- return new Comparator(comp, loose);
-
- debug('comparator', comp, loose);
- this.loose = loose;
- this.parse(comp);
-
- if (this.semver === ANY)
- this.value = '';
- else
- this.value = this.operator + this.semver.version;
-
- debug('comp', this);
-}
-
-var ANY = {};
-Comparator.prototype.parse = function(comp) {
- var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
- var m = comp.match(r);
-
- if (!m)
- throw new TypeError('Invalid comparator: ' + comp);
-
- this.operator = m[1];
- if (this.operator === '=')
- this.operator = '';
-
- // if it literally is just '>' or '' then allow anything.
- if (!m[2])
- this.semver = ANY;
- else
- this.semver = new SemVer(m[2], this.loose);
-};
-
-Comparator.prototype.inspect = function() {
- return '';
-};
-
-Comparator.prototype.toString = function() {
- return this.value;
-};
-
-Comparator.prototype.test = function(version) {
- debug('Comparator.test', version, this.loose);
-
- if (this.semver === ANY)
- return true;
-
- if (typeof version === 'string')
- version = new SemVer(version, this.loose);
-
- return cmp(version, this.operator, this.semver, this.loose);
-};
-
-
-exports.Range = Range;
-function Range(range, loose) {
- if ((range instanceof Range) && range.loose === loose)
- return range;
-
- if (!(this instanceof Range))
- return new Range(range, loose);
-
- this.loose = loose;
-
- // First, split based on boolean or ||
- this.raw = range;
- this.set = range.split(/\s*\|\|\s*/).map(function(range) {
- return this.parseRange(range.trim());
- }, this).filter(function(c) {
- // throw out any that are not relevant for whatever reason
- return c.length;
- });
-
- if (!this.set.length) {
- throw new TypeError('Invalid SemVer Range: ' + range);
- }
-
- this.format();
-}
-
-Range.prototype.inspect = function() {
- return '';
-};
-
-Range.prototype.format = function() {
- this.range = this.set.map(function(comps) {
- return comps.join(' ').trim();
- }).join('||').trim();
- return this.range;
-};
-
-Range.prototype.toString = function() {
- return this.range;
-};
-
-Range.prototype.parseRange = function(range) {
- var loose = this.loose;
- range = range.trim();
- debug('range', range, loose);
- // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
- var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
- range = range.replace(hr, hyphenReplace);
- debug('hyphen replace', range);
- // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
- range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
- debug('comparator trim', range, re[COMPARATORTRIM]);
-
- // `~ 1.2.3` => `~1.2.3`
- range = range.replace(re[TILDETRIM], tildeTrimReplace);
-
- // `^ 1.2.3` => `^1.2.3`
- range = range.replace(re[CARETTRIM], caretTrimReplace);
-
- // normalize spaces
- range = range.split(/\s+/).join(' ');
-
- // At this point, the range is completely trimmed and
- // ready to be split into comparators.
-
- var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
- var set = range.split(' ').map(function(comp) {
- return parseComparator(comp, loose);
- }).join(' ').split(/\s+/);
- if (this.loose) {
- // in loose mode, throw out any that are not valid comparators
- set = set.filter(function(comp) {
- return !!comp.match(compRe);
- });
- }
- set = set.map(function(comp) {
- return new Comparator(comp, loose);
- });
-
- return set;
-};
-
-// Mostly just for testing and legacy API reasons
-exports.toComparators = toComparators;
-function toComparators(range, loose) {
- return new Range(range, loose).set.map(function(comp) {
- return comp.map(function(c) {
- return c.value;
- }).join(' ').trim().split(' ');
- });
-}
-
-// comprised of xranges, tildes, stars, and gtlt's at this point.
-// already replaced the hyphen ranges
-// turn into a set of JUST comparators.
-function parseComparator(comp, loose) {
- debug('comp', comp);
- comp = replaceCarets(comp, loose);
- debug('caret', comp);
- comp = replaceTildes(comp, loose);
- debug('tildes', comp);
- comp = replaceXRanges(comp, loose);
- debug('xrange', comp);
- comp = replaceStars(comp, loose);
- debug('stars', comp);
- return comp;
-}
-
-function isX(id) {
- return !id || id.toLowerCase() === 'x' || id === '*';
-}
-
-// ~, ~> --> * (any, kinda silly)
-// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
-// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
-// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
-// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
-// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
-function replaceTildes(comp, loose) {
- return comp.trim().split(/\s+/).map(function(comp) {
- return replaceTilde(comp, loose);
- }).join(' ');
-}
-
-function replaceTilde(comp, loose) {
- var r = loose ? re[TILDELOOSE] : re[TILDE];
- return comp.replace(r, function(_, M, m, p, pr) {
- debug('tilde', comp, _, M, m, p, pr);
- var ret;
-
- if (isX(M))
- ret = '';
- else if (isX(m))
- ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
- else if (isX(p))
- // ~1.2 == >=1.2.0- <1.3.0-
- ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
- else if (pr) {
- debug('replaceTilde pr', pr);
- if (pr.charAt(0) !== '-')
- pr = '-' + pr;
- ret = '>=' + M + '.' + m + '.' + p + pr +
- ' <' + M + '.' + (+m + 1) + '.0';
- } else
- // ~1.2.3 == >=1.2.3 <1.3.0
- ret = '>=' + M + '.' + m + '.' + p +
- ' <' + M + '.' + (+m + 1) + '.0';
-
- debug('tilde return', ret);
- return ret;
- });
-}
-
-// ^ --> * (any, kinda silly)
-// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
-// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
-// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
-// ^1.2.3 --> >=1.2.3 <2.0.0
-// ^1.2.0 --> >=1.2.0 <2.0.0
-function replaceCarets(comp, loose) {
- return comp.trim().split(/\s+/).map(function(comp) {
- return replaceCaret(comp, loose);
- }).join(' ');
-}
-
-function replaceCaret(comp, loose) {
- debug('caret', comp, loose);
- var r = loose ? re[CARETLOOSE] : re[CARET];
- return comp.replace(r, function(_, M, m, p, pr) {
- debug('caret', comp, _, M, m, p, pr);
- var ret;
-
- if (isX(M))
- ret = '';
- else if (isX(m))
- ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
- else if (isX(p)) {
- if (M === '0')
- ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
- else
- ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0';
- } else if (pr) {
- debug('replaceCaret pr', pr);
- if (pr.charAt(0) !== '-')
- pr = '-' + pr;
- if (M === '0') {
- if (m === '0')
- ret = '>=' + M + '.' + m + '.' + p + pr +
- ' <' + M + '.' + m + '.' + (+p + 1);
- else
- ret = '>=' + M + '.' + m + '.' + p + pr +
- ' <' + M + '.' + (+m + 1) + '.0';
- } else
- ret = '>=' + M + '.' + m + '.' + p + pr +
- ' <' + (+M + 1) + '.0.0';
- } else {
- debug('no pr');
- if (M === '0') {
- if (m === '0')
- ret = '>=' + M + '.' + m + '.' + p +
- ' <' + M + '.' + m + '.' + (+p + 1);
- else
- ret = '>=' + M + '.' + m + '.' + p +
- ' <' + M + '.' + (+m + 1) + '.0';
- } else
- ret = '>=' + M + '.' + m + '.' + p +
- ' <' + (+M + 1) + '.0.0';
- }
-
- debug('caret return', ret);
- return ret;
- });
-}
-
-function replaceXRanges(comp, loose) {
- debug('replaceXRanges', comp, loose);
- return comp.split(/\s+/).map(function(comp) {
- return replaceXRange(comp, loose);
- }).join(' ');
-}
-
-function replaceXRange(comp, loose) {
- comp = comp.trim();
- var r = loose ? re[XRANGELOOSE] : re[XRANGE];
- return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
- debug('xRange', comp, ret, gtlt, M, m, p, pr);
- var xM = isX(M);
- var xm = xM || isX(m);
- var xp = xm || isX(p);
- var anyX = xp;
-
- if (gtlt === '=' && anyX)
- gtlt = '';
-
- if (xM) {
- if (gtlt === '>' || gtlt === '<') {
- // nothing is allowed
- ret = '<0.0.0';
- } else {
- // nothing is forbidden
- ret = '*';
- }
- } else if (gtlt && anyX) {
- // replace X with 0
- if (xm)
- m = 0;
- if (xp)
- p = 0;
-
- if (gtlt === '>') {
- // >1 => >=2.0.0
- // >1.2 => >=1.3.0
- // >1.2.3 => >= 1.2.4
- gtlt = '>=';
- if (xm) {
- M = +M + 1;
- m = 0;
- p = 0;
- } else if (xp) {
- m = +m + 1;
- p = 0;
- }
- } else if (gtlt === '<=') {
- // <=0.7.x is actually <0.8.0, since any 0.7.x should
- // pass. Similarly, <=7.x is actually <8.0.0, etc.
- gtlt = '<'
- if (xm)
- M = +M + 1
- else
- m = +m + 1
- }
-
- ret = gtlt + M + '.' + m + '.' + p;
- } else if (xm) {
- ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
- } else if (xp) {
- ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
- }
-
- debug('xRange return', ret);
-
- return ret;
- });
-}
-
-// Because * is AND-ed with everything else in the comparator,
-// and '' means "any version", just remove the *s entirely.
-function replaceStars(comp, loose) {
- debug('replaceStars', comp, loose);
- // Looseness is ignored here. star is always as loose as it gets!
- return comp.trim().replace(re[STAR], '');
-}
-
-// This function is passed to string.replace(re[HYPHENRANGE])
-// M, m, patch, prerelease, build
-// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
-// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
-// 1.2 - 3.4 => >=1.2.0 <3.5.0
-function hyphenReplace($0,
- from, fM, fm, fp, fpr, fb,
- to, tM, tm, tp, tpr, tb) {
-
- if (isX(fM))
- from = '';
- else if (isX(fm))
- from = '>=' + fM + '.0.0';
- else if (isX(fp))
- from = '>=' + fM + '.' + fm + '.0';
- else
- from = '>=' + from;
-
- if (isX(tM))
- to = '';
- else if (isX(tm))
- to = '<' + (+tM + 1) + '.0.0';
- else if (isX(tp))
- to = '<' + tM + '.' + (+tm + 1) + '.0';
- else if (tpr)
- to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;
- else
- to = '<=' + to;
-
- return (from + ' ' + to).trim();
-}
-
-
-// if ANY of the sets match ALL of its comparators, then pass
-Range.prototype.test = function(version) {
- if (!version)
- return false;
-
- if (typeof version === 'string')
- version = new SemVer(version, this.loose);
-
- for (var i = 0; i < this.set.length; i++) {
- if (testSet(this.set[i], version))
- return true;
- }
- return false;
-};
-
-function testSet(set, version) {
- for (var i = 0; i < set.length; i++) {
- if (!set[i].test(version))
- return false;
- }
-
- if (version.prerelease.length) {
- // Find the set of versions that are allowed to have prereleases
- // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
- // That should allow `1.2.3-pr.2` to pass.
- // However, `1.2.4-alpha.notready` should NOT be allowed,
- // even though it's within the range set by the comparators.
- for (var i = 0; i < set.length; i++) {
- debug(set[i].semver);
- if (set[i].semver === ANY)
- return true;
-
- if (set[i].semver.prerelease.length > 0) {
- var allowed = set[i].semver;
- if (allowed.major === version.major &&
- allowed.minor === version.minor &&
- allowed.patch === version.patch)
- return true;
- }
- }
-
- // Version has a -pre, but it's not one of the ones we like.
- return false;
- }
-
- return true;
-}
-
-exports.satisfies = satisfies;
-function satisfies(version, range, loose) {
- try {
- range = new Range(range, loose);
- } catch (er) {
- return false;
- }
- return range.test(version);
-}
-
-exports.maxSatisfying = maxSatisfying;
-function maxSatisfying(versions, range, loose) {
- return versions.filter(function(version) {
- return satisfies(version, range, loose);
- }).sort(function(a, b) {
- return rcompare(a, b, loose);
- })[0] || null;
-}
-
-exports.validRange = validRange;
-function validRange(range, loose) {
- try {
- // Return '*' instead of '' so that truthiness works.
- // This will throw if it's invalid anyway
- return new Range(range, loose).range || '*';
- } catch (er) {
- return null;
- }
-}
-
-// Determine if version is less than all the versions possible in the range
-exports.ltr = ltr;
-function ltr(version, range, loose) {
- return outside(version, range, '<', loose);
-}
-
-// Determine if version is greater than all the versions possible in the range.
-exports.gtr = gtr;
-function gtr(version, range, loose) {
- return outside(version, range, '>', loose);
-}
-
-exports.outside = outside;
-function outside(version, range, hilo, loose) {
- version = new SemVer(version, loose);
- range = new Range(range, loose);
-
- var gtfn, ltefn, ltfn, comp, ecomp;
- switch (hilo) {
- case '>':
- gtfn = gt;
- ltefn = lte;
- ltfn = lt;
- comp = '>';
- ecomp = '>=';
- break;
- case '<':
- gtfn = lt;
- ltefn = gte;
- ltfn = gt;
- comp = '<';
- ecomp = '<=';
- break;
- default:
- throw new TypeError('Must provide a hilo val of "<" or ">"');
- }
-
- // If it satisifes the range it is not outside
- if (satisfies(version, range, loose)) {
- return false;
- }
-
- // From now on, variable terms are as if we're in "gtr" mode.
- // but note that everything is flipped for the "ltr" function.
-
- for (var i = 0; i < range.set.length; ++i) {
- var comparators = range.set[i];
-
- var high = null;
- var low = null;
-
- comparators.forEach(function(comparator) {
- high = high || comparator;
- low = low || comparator;
- if (gtfn(comparator.semver, high.semver, loose)) {
- high = comparator;
- } else if (ltfn(comparator.semver, low.semver, loose)) {
- low = comparator;
- }
- });
-
- // If the edge version comparator has a operator then our version
- // isn't outside it
- if (high.operator === comp || high.operator === ecomp) {
- return false;
- }
-
- // If the lowest version comparator has an operator and our version
- // is less than it then it isn't higher than the range
- if ((!low.operator || low.operator === comp) &&
- ltefn(version, low.semver)) {
- return false;
- } else if (low.operator === ecomp && ltfn(version, low.semver)) {
- return false;
- }
- }
- return true;
-}
-
-// Use the define() function if we're in AMD land
-if (typeof define === 'function' && define.amd)
- define(exports);
diff --git a/packages/promise/.npm/package/npm-shrinkwrap.json b/packages/promise/.npm/package/npm-shrinkwrap.json
index 7aa333514c..c70bd597c3 100644
--- a/packages/promise/.npm/package/npm-shrinkwrap.json
+++ b/packages/promise/.npm/package/npm-shrinkwrap.json
@@ -1,19 +1,19 @@
{
"dependencies": {
"asap": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"from": "asap@>=2.0.3 <2.1.0"
},
"meteor-promise": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/meteor-promise/-/meteor-promise-0.8.4.tgz",
- "from": "meteor-promise@0.8.4"
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/meteor-promise/-/meteor-promise-0.8.5.tgz",
+ "from": "meteor-promise@0.8.5"
},
"promise": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
- "from": "promise@7.1.1"
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.1.tgz",
+ "from": "promise@8.0.1"
}
}
}
diff --git a/packages/promise/package.js b/packages/promise/package.js
index fb2d6f8782..95a8e66a04 100644
--- a/packages/promise/package.js
+++ b/packages/promise/package.js
@@ -1,14 +1,14 @@
Package.describe({
name: "promise",
- version: "0.8.9",
+ version: "0.9.0",
summary: "ECMAScript 2015 Promise polyfill with Fiber support",
git: "https://github.com/meteor/promise",
documentation: "README.md"
});
Npm.depends({
- "meteor-promise": "0.8.4",
- "promise": "7.1.1"
+ "meteor-promise": "0.8.5",
+ "promise": "8.0.1"
});
Package.onUse(function(api) {
diff --git a/packages/webapp/package.js b/packages/webapp/package.js
index 74c55b8445..b14e991576 100644
--- a/packages/webapp/package.js
+++ b/packages/webapp/package.js
@@ -1,6 +1,6 @@
Package.describe({
summary: "Serves a Meteor app over HTTP",
- version: '1.3.17'
+ version: '1.3.18'
});
Npm.depends({connect: "2.30.2",
@@ -14,9 +14,9 @@ Npm.strip({
});
Cordova.depends({
- 'cordova-plugin-whitelist': '1.3.1',
- 'cordova-plugin-wkwebview-engine': '1.1.1',
- 'cordova-plugin-meteor-webapp': '1.4.1'
+ 'cordova-plugin-whitelist': '1.3.2',
+ 'cordova-plugin-wkwebview-engine': '1.1.3',
+ 'cordova-plugin-meteor-webapp': '1.4.2'
});
Package.onUse(function (api) {
diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json
index 759d506048..4539bff2a8 100644
--- a/scripts/admin/meteor-release-experimental.json
+++ b/scripts/admin/meteor-release-experimental.json
@@ -1,6 +1,6 @@
{
"track": "METEOR",
- "version": "1.5.1-rc.5",
+ "version": "1.5.2-rc.2",
"recommended": false,
"official": false,
"description": "Meteor"
diff --git a/scripts/admin/meteor-release-official.json b/scripts/admin/meteor-release-official.json
index bcd1814321..60a23af4c3 100644
--- a/scripts/admin/meteor-release-official.json
+++ b/scripts/admin/meteor-release-official.json
@@ -1,6 +1,6 @@
{
"track": "METEOR",
- "version": "1.5.1",
+ "version": "1.5.2",
"recommended": false,
"official": true,
"description": "The Official Meteor Distribution"
diff --git a/scripts/build-dev-bundle-common.sh b/scripts/build-dev-bundle-common.sh
index de6be8bece..f3463243fa 100644
--- a/scripts/build-dev-bundle-common.sh
+++ b/scripts/build-dev-bundle-common.sh
@@ -9,6 +9,9 @@ MONGO_VERSION=3.2.15
NODE_VERSION=4.8.4
NPM_VERSION=4.6.1
+# If we built Node from source on Jenkins, this is the build number.
+NODE_BUILD_NUMBER=35
+
if [ "$UNAME" == "Linux" ] ; then
if [ "$ARCH" != "i686" -a "$ARCH" != "x86_64" ] ; then
echo "Unsupported architecture: $ARCH"
diff --git a/scripts/build-node-for-dev-bundle.sh b/scripts/build-node-for-dev-bundle.sh
new file mode 100755
index 0000000000..27c2ec0c34
--- /dev/null
+++ b/scripts/build-node-for-dev-bundle.sh
@@ -0,0 +1,87 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+source "$(dirname $0)/build-dev-bundle-common.sh"
+echo CHECKOUT DIR IS "$CHECKOUT_DIR"
+echo BUILDING NODE "v$NODE_VERSION" IN "$DIR"
+
+cd "$DIR"
+
+if [ ! -z ${NODE_FROM_SRC+x} ] || [ ! -z ${NODE_COMMIT_HASH+x} ]
+then
+ if [ ! -z ${NODE_COMMIT_HASH+x} ]
+ then
+ NODE_FROM_SRC=${NODE_FROM_SRC:=true}
+ echo "Building Node source from Git hash ${NODE_COMMIT_HASH}...";
+ NODE_URL="https://github.com/meteor/node/archive/${NODE_COMMIT_HASH}.tar.gz"
+ else
+ echo "Building Node source from ${NODE_VERSION} src tarball...";
+ NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}.tar.gz"
+ fi
+else
+ NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TGZ}"
+fi
+
+# Update these values after building the dev-bundle-node Jenkins project.
+# Also make sure to update NODE_VERSION in generate-dev-bundle.ps1.
+function downloadNode {
+ echo "Downloading Node from ${NODE_URL}"
+ curl -sL "${NODE_URL}" | tar zx --strip-components 1
+}
+
+if [ ! -z ${NODE_FROM_SRC+x} ]
+then
+ mkdir node-build && cd node-build
+ downloadNode
+
+ # Build with International Components for Unicode (ICU) Support...
+ # Node 4.x used 56.x. Node 8.x uses 59.x. I believe the only
+ # reliable location to find the correct version of ICU for a Node.js
+ # release is to check `process.config.icu_ver_major` from an
+ # official, compiled Node.js release.
+ # https://github.com/nodejs/node/wiki/Intl#configure-node-with-specific-icu-source
+ echo "Downloading International Components for Unicode (ICU)..."
+ curl -sL http://download.icu-project.org/files/icu4c/56.1/icu4c-56_1-src.tgz | \
+ tar zx -C deps/
+
+ node_configure_flags=(\
+ '--prefix=/' \
+ '--with-intl=small-icu' \
+ '--release-urlbase=https://nodejs.org/download/release/' \
+ )
+
+ if [ "${NODE_FROM_SRC:-}" = "debug" ]
+ then
+ node_configure_flags+=('--debug')
+ fi
+
+ ./configure "${node_configure_flags[@]}"
+ make -j4
+ # PORTABLE=1 is a node hack to make npm look relative to itself instead
+ # of hard coding the PREFIX.
+ # DESTDIR installs to the requested location, without using PREFIX.
+ # See tools/install.py in the Node source for more information.
+ make install PORTABLE=1 DESTDIR="${DIR}"
+ cd "$DIR"
+else
+ downloadNode
+fi
+
+cd "$DIR"
+stripBinary bin/node
+
+# export path so we use our new node for later builds
+PATH="$DIR/bin:$PATH"
+which node
+which npm
+npm version
+
+echo BUNDLING
+
+cd "$DIR"
+rm -rf node-build
+tar czvf "${CHECKOUT_DIR}/node_${PLATFORM}_v${NODE_VERSION}.tar.gz" .
+
+echo DONE
diff --git a/scripts/dev-bundle-server-package.js b/scripts/dev-bundle-server-package.js
index 27a2a7d9db..521ac91382 100644
--- a/scripts/dev-bundle-server-package.js
+++ b/scripts/dev-bundle-server-package.js
@@ -9,25 +9,23 @@ var packageJson = {
// Version is not important but is needed to prevent warnings.
version: "0.0.0",
dependencies: {
- "meteor-promise": "0.8.4",
+ "meteor-promise": "0.8.5",
fibers: "1.0.15",
- promise: "7.1.1",
+ promise: "8.0.1",
// Not yet upgrading Underscore from 1.5.2 to 1.7.0 (which should be done
// in the package too) because we should consider using lodash instead
// (and there are backwards-incompatible changes either way).
underscore: "1.5.2",
"source-map-support": "https://github.com/meteor/node-source-map-support/tarball/1912478769d76e5df4c365e147f25896aee6375e",
- semver: "4.1.0"
+ semver: "5.3.0"
},
// These are only used in dev mode (by shell.js) so end-users can avoid
// needing to install them if they use `npm install --production`.
devDependencies: {
- // 2.4.0 (more or less, the package.json change isn't committed) plus our PR
- // https://github.com/williamwicks/node-eachline/pull/4
- eachline: "https://github.com/meteor/node-eachline/tarball/ff89722ff94e6b6a08652bf5f44c8fffea8a21da",
+ split2: "2.1.1",
+ multipipe: "1.0.2",
chalk: "0.5.1"
}
};
-
process.stdout.write(JSON.stringify(packageJson, null, 2) + '\n');
diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js
index 859a5fa26d..022f9d1f67 100644
--- a/scripts/dev-bundle-tool-package.js
+++ b/scripts/dev-bundle-tool-package.js
@@ -14,11 +14,11 @@ var packageJson = {
npm: "4.6.1",
"node-gyp": "3.6.0",
"node-pre-gyp": "0.6.34",
- "meteor-babel": "0.22.0",
- reify: "0.11.24",
- "meteor-promise": "0.8.4",
+ "meteor-babel": "0.23.1",
+ "meteor-promise": "0.8.5",
+ reify: "0.12.0",
+ promise: "8.0.1",
fibers: "1.0.15",
- promise: "7.1.1",
// So that Babel 6 can emit require("babel-runtime/helpers/...") calls.
"babel-runtime": "6.9.2",
// For various ES2015 polyfills, such as Map and Set.
@@ -28,7 +28,7 @@ var packageJson = {
// (and there are backwards-incompatible changes either way).
underscore: "1.5.2",
"source-map-support": "https://github.com/meteor/node-source-map-support/tarball/1912478769d76e5df4c365e147f25896aee6375e",
- semver: "4.1.0",
+ semver: "5.3.0",
request: "2.47.0",
fstream: "https://github.com/meteor/fstream/tarball/cf4ea6c175355cec7bee38311e170d08c4078a5d",
tar: "2.2.1",
@@ -49,13 +49,12 @@ var packageJson = {
// workaround from the tool.
"commonmark": "0.15.0",
escope: "3.2.0",
- // 2.4.0 (more or less, the package.json change isn't committed) plus our PR
- // https://github.com/williamwicks/node-eachline/pull/4
- eachline: "https://github.com/meteor/node-eachline/tarball/ff89722ff94e6b6a08652bf5f44c8fffea8a21da",
+ split2: "2.1.1",
+ multipipe: "1.0.2",
pathwatcher: "6.7.1",
optimism: "0.3.3",
'lru-cache': '4.0.1',
- 'cordova-lib': "6.4.0",
+ 'cordova-lib': "7.0.1",
longjohn: '0.2.12'
}
};
diff --git a/scripts/generate-dev-bundle.sh b/scripts/generate-dev-bundle.sh
index 2ef74cf726..e7b84becb4 100755
--- a/scripts/generate-dev-bundle.sh
+++ b/scripts/generate-dev-bundle.sh
@@ -16,13 +16,33 @@ echo BUILDING DEV BUNDLE "$BUNDLE_VERSION" IN "$DIR"
cd "$DIR"
-S3_HOST="s3.amazonaws.com/com.meteor.jenkins"
+extractNodeFromTarGz() {
+ LOCAL_TGZ="${CHECKOUT_DIR}/node_${PLATFORM}_v${NODE_VERSION}.tar.gz"
+ if [ -f "$LOCAL_TGZ" ]
+ then
+ echo "Skipping download and installing Node from $LOCAL_TGZ" >&2
+ tar zxf "$LOCAL_TGZ"
+ return 0
+ fi
+ return 1
+}
-# Update these values after building the dev-bundle-node Jenkins project.
-# Also make sure to update NODE_VERSION in generate-dev-bundle.ps1.
-NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TGZ}"
-echo "Downloading Node from ${NODE_URL}"
-curl "${NODE_URL}" | tar zx --strip-components 1
+downloadNodeFromS3() {
+ S3_HOST="s3.amazonaws.com/com.meteor.jenkins"
+ S3_TGZ="node_${UNAME}_${ARCH}_v${NODE_VERSION}.tar.gz"
+ NODE_URL="https://${S3_HOST}/dev-bundle-node-${NODE_BUILD_NUMBER}/${S3_TGZ}"
+ echo "Downloading Node from ${NODE_URL}" >&2
+ curl "${NODE_URL}" | tar zx
+}
+
+downloadOfficialNode() {
+ NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TGZ}"
+ echo "Downloading Node from ${NODE_URL}" >&2
+ curl "${NODE_URL}" | tar zx --strip-components 1
+}
+
+# Try each strategy in the following order:
+extractNodeFromTarGz || downloadNodeFromS3 || downloadOfficialNode
# Download Mongo from mongodb.com
MONGO_NAME="mongodb-${OS}-${ARCH}-${MONGO_VERSION}"
@@ -48,6 +68,15 @@ which node
which npm
npm version
+# Make node-gyp use Node headers and libraries from $DIR/include/node.
+export HOME="$DIR"
+export USERPROFILE="$DIR"
+export npm_config_nodedir="$DIR"
+
+INCLUDE_PATH="${DIR}/include/node"
+echo "Contents of ${INCLUDE_PATH}:"
+ls -al "$INCLUDE_PATH"
+
# When adding new node modules (or any software) to the dev bundle,
# remember to update LICENSE.txt! Also note that we include all the
# packages that these depend on, so watch out for new dependencies when
@@ -95,15 +124,6 @@ cp -R node_modules/* "${DIR}/lib/node_modules/"
# commands like node-gyp and node-pre-gyp.
cp -R node_modules/.bin "${DIR}/lib/node_modules/"
-# Make node-gyp install Node headers and libraries in $DIR/.node-gyp/.
-# https://github.com/nodejs/node-gyp/blob/4ee31329e0/lib/node-gyp.js#L52
-export HOME="$DIR"
-export USERPROFILE="$DIR"
-node "${DIR}/lib/node_modules/node-gyp/bin/node-gyp.js" install
-INCLUDE_PATH="${DIR}/.node-gyp/${NODE_VERSION}/include/node"
-echo "Contents of ${INCLUDE_PATH}:"
-ls -al "$INCLUDE_PATH"
-
cd "${DIR}/lib"
# Clean up some bulky stuff.
diff --git a/tools/cli/commands.js b/tools/cli/commands.js
index 4d76c2b420..f01fc03f3a 100644
--- a/tools/cli/commands.js
+++ b/tools/cli/commands.js
@@ -1551,8 +1551,31 @@ function doTestCommand(options) {
// cleaned up on process exit. Using a temporary app dir means that we can
// run multiple "test-packages" commands in parallel without them stomping
// on each other.
- var testRunnerAppDir =
- options['test-app-path'] || files.mkdtemp('meteor-test-run');
+ let testRunnerAppDir;
+ const testAppPath = options['test-app-path'];
+ if (testAppPath) {
+ try {
+ if (files.mkdir_p(testAppPath, 0o700)) {
+ testRunnerAppDir = testAppPath;
+ } else {
+ Console.error(
+ 'The specified --test-app-path directory could not be used, as ' +
+ `"${testAppPath}" already exists and it is not a directory.`
+ );
+ return 1;
+ }
+ } catch (error) {
+ Console.error(
+ 'Unable to create the specified --test-app-path directory of ' +
+ `"${testAppPath}".`
+ );
+ throw error;
+ }
+ }
+
+ if (!testRunnerAppDir) {
+ testRunnerAppDir = files.mkdtemp('meteor-test-run');
+ }
// Download packages for our architecture, and for the deploy server's
// architecture if we're deploying.
@@ -1583,7 +1606,19 @@ function doTestCommand(options) {
projectContextOptions.projectDir = testRunnerAppDir;
projectContextOptions.projectDirForLocalPackages = options.appDir;
- require("./default-npm-deps.js").install(testRunnerAppDir);
+ try {
+ require("./default-npm-deps.js").install(testRunnerAppDir);
+ } catch (error) {
+ if (error.code === 'EACCES' && options['test-app-path']) {
+ Console.error(
+ 'The specified --test-app-path directory of ' +
+ `"${testRunnerAppDir}" exists, but the current user does not have ` +
+ `read/write permission in it.`
+ );
+ }
+ throw error;
+ }
+
if (buildmessage.jobHasMessages()) {
return;
}
diff --git a/tools/cli/dev-bundle-bin-helpers.js b/tools/cli/dev-bundle-bin-helpers.js
index 5a5bef6c3d..d0b36db9f4 100644
--- a/tools/cli/dev-bundle-bin-helpers.js
+++ b/tools/cli/dev-bundle-bin-helpers.js
@@ -100,8 +100,8 @@ exports.getEnv = function (options) {
}
// This allows node-gyp to find Node headers and libraries in
- // dev_bundle/.node-gyp.
- env.USERPROFILE = devBundleDir;
+ // dev_bundle/include/node.
+ env.NPM_CONFIG_NODEDIR = devBundleDir;
var PATH = env.PATH || env.Path;
if (PATH) {
diff --git a/tools/cordova/builder.js b/tools/cordova/builder.js
index 0f26ee2031..4296b0858c 100644
--- a/tools/cordova/builder.js
+++ b/tools/cordova/builder.js
@@ -25,6 +25,15 @@ const iconsIosSizes = {
'ios_spotlight': '40x40',
'ios_spotlight_2x': '80x80',
'ios_spotlight_3x': '120x120',
+ 'ios_notification': '20x20',
+ 'ios_notification_2x': '40x40',
+ 'ios_notification_3x': '60x60',
+ 'iphone_legacy': '57x57',
+ 'iphone_legacy_2x': '114x114',
+ 'ipad_spotlight_legacy': '50x50',
+ 'ipad_spotlight_legacy_2x': '100x100',
+ 'ipad_app_legacy': '72x72',
+ 'ipad_app_legacy_2x': '144x144',
};
const iconsAndroidSizes = {
@@ -537,6 +546,15 @@ Valid platforms are: ios, android.`);
* - `ios_spotlight` (40x40)
* - `ios_spotlight_2x` (80x80)
* - `ios_spotlight_3x` (120x120)
+ * - 'ios_notification': '20x20',
+ * - 'ios_notification_2x': '40x40',
+ * - 'ios_notification_3x': '60x60',
+ * - 'iphone_legacy': '57x57',
+ * - 'iphone_legacy_2x': '114x114',
+ * - 'ipad_spotlight_legacy': '50x50',
+ * - 'ipad_spotlight_legacy_2x': '100x100',
+ * - 'ipad_app_legacy': '72x72',
+ * - 'ipad_app_legacy_2x': '144x144',
* - `android_mdpi` (48x48)
* - `android_hdpi` (72x72)
* - `android_xhdpi` (96x96)
diff --git a/tools/cordova/index.js b/tools/cordova/index.js
index 09837dc13f..4d5281196e 100644
--- a/tools/cordova/index.js
+++ b/tools/cordova/index.js
@@ -11,8 +11,8 @@ export const CORDOVA_ARCH = "web.cordova";
export const CORDOVA_PLATFORMS = ['ios', 'android'];
export const CORDOVA_PLATFORM_VERSIONS = {
- 'android': '6.1.1',
- 'ios': '4.3.0'
+ 'android': '6.2.3',
+ 'ios': '4.4.0'
};
const PLATFORM_TO_DISPLAY_NAME_MAP = {
diff --git a/tools/cordova/project.js b/tools/cordova/project.js
index b9f125d1ac..cecd8853ee 100644
--- a/tools/cordova/project.js
+++ b/tools/cordova/project.js
@@ -51,29 +51,29 @@ const pinnedPlatformVersions = CORDOVA_PLATFORM_VERSIONS;
// Versions are taken from cordova-lib's package.json and should be updated
// when we update to a newer version of cordova-lib.
const pinnedPluginVersions = {
- "cordova-plugin-battery-status": "1.2.2",
- "cordova-plugin-camera": "2.3.1",
- "cordova-plugin-console": "1.0.5",
- "cordova-plugin-contacts": "2.2.1",
- "cordova-plugin-device": "1.1.4",
- "cordova-plugin-device-motion": "1.2.3",
- "cordova-plugin-device-orientation": "1.0.5",
- "cordova-plugin-dialogs": "1.3.1",
- "cordova-plugin-file": "4.3.1",
- "cordova-plugin-file-transfer": "1.6.1",
- "cordova-plugin-geolocation": "2.4.1",
- "cordova-plugin-globalization": "1.0.5",
- "cordova-plugin-inappbrowser": "1.6.1",
+ "cordova-plugin-battery-status": "1.2.4",
+ "cordova-plugin-camera": "2.4.1",
+ "cordova-plugin-console": "1.0.7",
+ "cordova-plugin-contacts": "2.3.1",
+ "cordova-plugin-device": "1.1.6",
+ "cordova-plugin-device-motion": "1.2.5",
+ "cordova-plugin-device-orientation": "1.0.7",
+ "cordova-plugin-dialogs": "1.3.3",
+ "cordova-plugin-file": "4.3.3",
+ "cordova-plugin-file-transfer": "1.6.3",
+ "cordova-plugin-geolocation": "2.4.3",
+ "cordova-plugin-globalization": "1.0.7",
+ "cordova-plugin-inappbrowser": "1.7.1",
"cordova-plugin-legacy-whitelist": "1.1.2",
- "cordova-plugin-media": "2.4.1",
- "cordova-plugin-media-capture": "1.4.1",
- "cordova-plugin-network-information": "1.3.1",
- "cordova-plugin-splashscreen": "4.0.1",
- "cordova-plugin-statusbar": "2.2.1",
- "cordova-plugin-test-framework": "1.1.4",
- "cordova-plugin-vibration": "2.1.3",
- "cordova-plugin-whitelist": "1.3.1",
- "cordova-plugin-wkwebview-engine": "1.1.1"
+ "cordova-plugin-media": "3.0.1",
+ "cordova-plugin-media-capture": "1.4.3",
+ "cordova-plugin-network-information": "1.3.3",
+ "cordova-plugin-splashscreen": "4.0.3",
+ "cordova-plugin-statusbar": "2.2.3",
+ "cordova-plugin-test-framework": "1.1.5",
+ "cordova-plugin-vibration": "2.1.5",
+ "cordova-plugin-whitelist": "1.3.2",
+ "cordova-plugin-wkwebview-engine": "1.1.3"
}
export class CordovaProject {
diff --git a/tools/cordova/run-targets.js b/tools/cordova/run-targets.js
index d04a1efff2..80bb118f0e 100644
--- a/tools/cordova/run-targets.js
+++ b/tools/cordova/run-targets.js
@@ -1,7 +1,6 @@
import _ from 'underscore';
import chalk from 'chalk';
import child_process from 'child_process';
-import eachline from 'eachline';
import { load as loadIsopacket } from '../tool-env/isopackets.js';
import runLog from '../runners/run-log.js';
@@ -134,6 +133,8 @@ export class AndroidRunTarget extends CordovaRunTarget {
}
async tailLogs(cordovaProject, target) {
+ const { transform } = require("../utils/eachline.js");
+
cordovaProject.runCommands(`tailing logs for ${this.displayName}`, async () => {
await this.checkPlatformRequirementsAndSetEnv(cordovaProject);
@@ -146,7 +147,7 @@ export class AndroidRunTarget extends CordovaRunTarget {
const { Log } =
loadIsopacket('cordova-support')['logging'];
- const logStream = eachline((line) => {
+ const logStream = transform(line => {
const logEntry = logFromAndroidLogcatLine(Log, line);
if (logEntry) {
return `${logEntry}\n`;
diff --git a/tools/fs/safe-watcher.js b/tools/fs/safe-watcher.js
index 3793a43034..9c2eedbd39 100644
--- a/tools/fs/safe-watcher.js
+++ b/tools/fs/safe-watcher.js
@@ -266,7 +266,9 @@ function watchLibraryWatch(absPath, callback) {
let suggestedRaisingWatchLimit = false;
-function maybeSuggestRaisingWatchLimit(error) {
+// This function is async so that archinfo.host() (which may call
+// utils.execFileSync) will run in a Fiber.
+async function maybeSuggestRaisingWatchLimit(error) {
var constants = require('constants');
var archinfo = require('../utils/archinfo.js');
if (! suggestedRaisingWatchLimit &&
diff --git a/tools/fs/watch.js b/tools/fs/watch.js
index 0a930c545e..ab0d2dc143 100644
--- a/tools/fs/watch.js
+++ b/tools/fs/watch.js
@@ -562,14 +562,6 @@ export class Watcher {
});
}
- // XXX Erk! This is wrong! A null entry in a WatchSet means "is not a file",
- // not "does not exist"; if you look at readAndWatchFileWithHash, "a directory
- // where a file was expected" leads to the entry being null. Right now this
- // leads to infinite watcher refresh loops if something that needs to be a
- // directory ends up as a file. This all needs to be changed so that null
- // means "not a file" again. A simple way to reproduce is to run
- // $ meteor --settings /tmp
- // See #3854.
_mustNotExist(absPath) {
var wsFiles = this.watchSet.files;
if (_.has(wsFiles, absPath)) {
@@ -723,18 +715,39 @@ export function readAndWatchDirectory(watchSet, options) {
// *rely* on the hash being returned; merely that if the hash is
// present, it is the correct hash of the contents.
export function readAndWatchFileWithHash(watchSet, absPath) {
- var contents = readFile(absPath);
- var hash = null;
+ const result = {
+ contents: null,
+ hash: null,
+ };
+
+ try {
+ result.contents = files.readFile(absPath);
+ } catch (e) {
+ if (e && e.code === "EISDIR") {
+ // Avoid adding directories to the watchSet as files.
+ return result;
+ }
+
+ if (e && e.code === "ENOENT") {
+ // Continue, leaving result.{contents,hash} both null.
+ } else {
+ // Throw all other errors.
+ throw e;
+ }
+ }
+
+ if (result.contents !== null) {
+ result.hash = sha1(result.contents);
+ }
// Allow null watchSet, if we want to use readFile-style error handling in a
// context where we might not always have a WatchSet (eg, reading
// settings.json where we watch for "meteor run" but not for "meteor deploy").
if (watchSet) {
- hash = contents === null ? null : sha1(contents);
- watchSet.addFile(absPath, hash);
+ watchSet.addFile(absPath, result.hash);
}
- return { contents, hash };
+ return result;
}
export function readAndWatchFile(watchSet, absPath) {
diff --git a/tools/isobuild/bundler.js b/tools/isobuild/bundler.js
index cd66820910..f2dd2d6d07 100644
--- a/tools/isobuild/bundler.js
+++ b/tools/isobuild/bundler.js
@@ -2540,7 +2540,7 @@ function addSourceMappingURL(data, url) {
// If data is a Buffer, convert it to a string.
.toString("utf8")
// Remove any existing source map comments.
- .replace(/\n\/\/# sourceMappingURL=[^\n]+/g, "");
+ .replace(/\n\/\/# sourceMappingURL=[^\n]+/g, '\n');
// Append the new source map comment to the end of the code.
return dataString + "\n//# sourceMappingURL=" + url + "\n";
}
diff --git a/tools/project-context.js b/tools/project-context.js
index 971041f68e..e2071e80d1 100644
--- a/tools/project-context.js
+++ b/tools/project-context.js
@@ -748,8 +748,9 @@ _.extend(ProjectContext.prototype, {
var constraint = utils.parsePackageConstraint(
// Note that this used to be an exact name@=version constraint,
// before #7084 eliminated these constraints completely. They
- // were reinstated in Meteor 1.4.3 as name@version constraints.
- packageName + "@" + version);
+ // were reinstated in Meteor 1.4.3 as name@version constraints,
+ // and further refined to name@~version constraints in 1.5.2.
+ packageName + "@~" + version);
// Add a constraint but no dependency (we don't automatically use
// all local packages!):
depsAndConstraints.constraints.push(constraint);
diff --git a/tools/runners/run-app.js b/tools/runners/run-app.js
index 26be252981..e3c91d40e6 100644
--- a/tools/runners/run-app.js
+++ b/tools/runners/run-app.js
@@ -14,6 +14,7 @@ var release = require('../packaging/release.js');
import * as cordova from '../cordova';
import { CordovaBuilder } from '../cordova/builder.js';
import { closeAllWatchers } from "../fs/safe-watcher.js";
+import { eachline } from "../utils/eachline.js";
// Parse out s as if it were a bash command line.
var bashParse = function (s) {
@@ -86,13 +87,7 @@ _.extend(AppProcess.prototype, {
// Start the app!
self.proc = self._spawn();
- // Send stdout and stderr to the runLog
- var realEachline = require('eachline');
- function eachline(stream, encoding, callback) {
- realEachline(stream, encoding, (...args) => void(callback(...args)));
- }
-
- eachline(self.proc.stdout, 'utf8', async function (line) {
+ eachline(self.proc.stdout, function (line) {
if (line.match(/^LISTENING\s*$/)) {
// This is the child process telling us that it's ready to receive
// connections. (It does this because we told it to with
@@ -104,7 +99,7 @@ _.extend(AppProcess.prototype, {
}
});
- eachline(self.proc.stderr, 'utf8', async function (line) {
+ eachline(self.proc.stderr, function (line) {
if (self.debugPort &&
line.indexOf("Debugger listening on") >= 0) {
Console.enableProgressDisplay(false);
diff --git a/tools/shell-client.js b/tools/shell-client.js
index f1543dbd68..5b5d795cee 100644
--- a/tools/shell-client.js
+++ b/tools/shell-client.js
@@ -2,7 +2,6 @@ var assert = require("assert");
var fs = require("fs");
var path = require("path");
var net = require("net");
-var eachline = require("eachline");
var chalk = require("chalk");
var EOL = require("os").EOL;
@@ -181,7 +180,7 @@ Cp.setUpSocket = function setUpSocket(sock, key) {
sock.pipe(process.stdout);
- eachline(sock, "utf8", function(line) {
+ require("./utils/eachline.js").eachline(sock, function (line) {
self.exitOnClose = line.indexOf(EXITING_MESSAGE) >= 0;
});
diff --git a/tools/tests/apps/modules/imports/.babelrc b/tools/tests/apps/modules/imports/.babelrc
new file mode 100644
index 0000000000..f5e2cf5851
--- /dev/null
+++ b/tools/tests/apps/modules/imports/.babelrc
@@ -0,0 +1,7 @@
+{
+ "env": {
+ "development": {
+ "plugins": ["transform-do-expressions"]
+ }
+ }
+}
diff --git a/tools/tests/apps/modules/imports/babel-env.js b/tools/tests/apps/modules/imports/babel-env.js
new file mode 100644
index 0000000000..834320ebb4
--- /dev/null
+++ b/tools/tests/apps/modules/imports/babel-env.js
@@ -0,0 +1,8 @@
+export function check(y) {
+ // If the transform-do-expressions plugin is loaded correctly, there
+ // will be no errors during the compilation of this file. Without the
+ // plugin, the error will be: "SyntaxError: Unexpected token do".
+ return do {
+ y + y;
+ };
+}
diff --git a/tools/tests/apps/modules/package.json b/tools/tests/apps/modules/package.json
index fd63fa15cb..ed4a40d751 100644
--- a/tools/tests/apps/modules/package.json
+++ b/tools/tests/apps/modules/package.json
@@ -13,7 +13,8 @@
"mssql": "^3.1.1",
"regenerator-runtime": "^0.9.5",
"stripe": "^4.4.0",
- "winston": "^2.3.1"
+ "winston": "^2.3.1",
+ "babel-plugin-transform-do-expressions": "^6.22.0"
},
"scripts": {
"test": "METEOR_PROFILE=100 ../../../../meteor test --full-app --driver-package dispatch:mocha-phantomjs",
diff --git a/tools/tests/apps/modules/tests.js b/tools/tests/apps/modules/tests.js
index 0e19116b20..ae1c6abed0 100644
--- a/tools/tests/apps/modules/tests.js
+++ b/tools/tests/apps/modules/tests.js
@@ -446,6 +446,13 @@ describe("ecmascript miscellany", () => {
[2, 1, 4, 3]
);
});
+
+ it('.babelrc "env" should be respected', () => {
+ assert.strictEqual(
+ require("./imports/babel-env.js").check(2),
+ 4
+ );
+ });
});
Meteor.isClient &&
diff --git a/tools/tests/apps/package-tests/packages/tilde-constraints/README.md b/tools/tests/apps/package-tests/packages/tilde-constraints/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tools/tests/apps/package-tests/packages/tilde-constraints/package.js b/tools/tests/apps/package-tests/packages/tilde-constraints/package.js
new file mode 100644
index 0000000000..7215c5d3e3
--- /dev/null
+++ b/tools/tests/apps/package-tests/packages/tilde-constraints/package.js
@@ -0,0 +1,11 @@
+Package.describe({
+ name: "tilde-constraints",
+ version: "0.4.2",
+ summary: "Package for testing @~ version constraints",
+ documentation: "README.md"
+});
+
+Package.onUse(function(api) {
+ api.use("ecmascript");
+ api.mainModule("tilde-constraints.js");
+});
diff --git a/tools/tests/apps/package-tests/packages/tilde-constraints/tilde-constraints.js b/tools/tests/apps/package-tests/packages/tilde-constraints/tilde-constraints.js
new file mode 100644
index 0000000000..2a8dc005b2
--- /dev/null
+++ b/tools/tests/apps/package-tests/packages/tilde-constraints/tilde-constraints.js
@@ -0,0 +1 @@
+console.log(module.id);
diff --git a/tools/tests/apps/package-tests/packages/tilde-dependent/README.md b/tools/tests/apps/package-tests/packages/tilde-dependent/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tools/tests/apps/package-tests/packages/tilde-dependent/package.js b/tools/tests/apps/package-tests/packages/tilde-dependent/package.js
new file mode 100644
index 0000000000..2c0a869d87
--- /dev/null
+++ b/tools/tests/apps/package-tests/packages/tilde-dependent/package.js
@@ -0,0 +1,12 @@
+Package.describe({
+ name: "tilde-dependent",
+ version: "0.1.0",
+ summary: "Package for testing inter-package @~ constraints",
+ documentation: "README.md"
+});
+
+Package.onUse(function(api) {
+ api.use("ecmascript");
+ api.use("tilde-constraints");
+ api.mainModule("tilde-dependent.js");
+});
diff --git a/tools/tests/apps/package-tests/packages/tilde-dependent/tilde-dependent.js b/tools/tests/apps/package-tests/packages/tilde-dependent/tilde-dependent.js
new file mode 100644
index 0000000000..2a8dc005b2
--- /dev/null
+++ b/tools/tests/apps/package-tests/packages/tilde-dependent/tilde-dependent.js
@@ -0,0 +1 @@
+console.log(module.id);
diff --git a/tools/tests/command-line.js b/tools/tests/command-line.js
index 3c9336e9a4..5163a0a67a 100644
--- a/tools/tests/command-line.js
+++ b/tools/tests/command-line.js
@@ -562,3 +562,75 @@ selftest.define("old cli tests (converted)", function () {
run.expectExit(0);
files.unlink(files.pathJoin(s.cwd, 'settings.js'));
});
+
+// Added to address https://github.com/meteor/meteor/issues/8897.
+selftest.define(
+ 'meteor test-packages --test-app-path directory',
+ function () {
+ var s = new Sandbox();
+ var run;
+
+ // If test-app-path doesn't exist, it should be created.
+ var testAppPath = '/tmp/meteor_test_app_path';
+ files.rm_recursive(testAppPath);
+ selftest.expectFalse(files.exists(testAppPath));
+ s.createApp('test-app-path-app', 'package-tests', {
+ dontPrepareApp: true
+ });
+ s.cd('test-app-path-app/packages/say-something', function () {
+ run = s.run(
+ 'test-packages',
+ '--once',
+ { 'test-app-path': testAppPath },
+ './'
+ );
+ run.match('Started');
+ selftest.expectTrue(files.exists(testAppPath));
+ run.stop();
+ files.rm_recursive(testAppPath);
+ });
+
+ // If test-app-path already exists, make sure that directory is used.
+ var testAppPath = '/tmp/meteor_test_app_path';
+ files.rm_recursive(testAppPath);
+ files.mkdir_p(testAppPath);
+ selftest.expectTrue(files.exists(testAppPath));
+ selftest.expectFalse(files.exists(testAppPath + '/.meteor'));
+ s.createApp('test-app-path-app', 'package-tests', {
+ dontPrepareApp: true
+ });
+ s.cd('test-app-path-app/packages/say-something', function () {
+ run = s.run(
+ 'test-packages',
+ '--once',
+ { 'test-app-path': testAppPath },
+ './'
+ );
+ run.match('Started');
+ selftest.expectTrue(files.exists(testAppPath + '/.meteor'));
+ run.stop();
+ files.rm_recursive(testAppPath);
+ });
+
+ // If test-app-path already exists but is a file instead of a directory,
+ // show a console error message explaining this, and exit.
+ var testAppPath = '/tmp/meteor_test_app_path';
+ files.rm_recursive(testAppPath);
+ files.writeFile(testAppPath, '<3 meteor');
+ selftest.expectTrue(files.exists(testAppPath));
+ s.createApp('test-app-path-app', 'package-tests', {
+ dontPrepareApp: true
+ });
+ s.cd('test-app-path-app/packages/say-something', function () {
+ run = s.run(
+ 'test-packages',
+ '--once',
+ { 'test-app-path': testAppPath },
+ './'
+ );
+ run.matchErr('is not a directory');
+ run.expectExit(1);
+ files.rm_recursive(testAppPath);
+ });
+ }
+);
diff --git a/tools/tests/modules.js b/tools/tests/modules.js
index 5fa92593d2..5e1acbed8d 100644
--- a/tools/tests/modules.js
+++ b/tools/tests/modules.js
@@ -17,6 +17,10 @@ function startRun(sandbox) {
selftest.define("modules - test app", function () {
const s = new Sandbox();
+
+ // Make sure we use the right "env" section of .babelrc.
+ s.set("NODE_ENV", "development");
+
s.createApp("modules-test-app", "modules");
s.cd("modules-test-app", function () {
const run = s.run(
diff --git a/tools/tests/package-tests.js b/tools/tests/package-tests.js
index 856b3c393a..ccf486ff9c 100644
--- a/tools/tests/package-tests.js
+++ b/tools/tests/package-tests.js
@@ -953,3 +953,149 @@ selftest.define("show readme excerpt", function () {
run.matchErr("Documentation not found");
run.expectExit(1);
});
+
+selftest.define("tilde version constraints", [], function () {
+ var s = new Sandbox();
+
+ s.set("METEOR_WATCH_PRIORITIZE_CHANGED", "false");
+
+ s.createApp("tilde-app", "package-tests");
+ s.cd("tilde-app");
+
+ var run = s.run();
+
+ run.match("tilde-app");
+ run.match("proxy");
+ run.waitSecs(10);
+ run.match("MongoDB");
+ run.waitSecs(10);
+ run.match("your app");
+ run.waitSecs(10);
+ run.match("running at");
+ run.waitSecs(60);
+
+ var packages = s.read(".meteor/packages")
+ .replace(/\n*$/m, "\n");
+
+ function setTopLevelConstraint(constraint) {
+ s.write(
+ ".meteor/packages",
+ packages + "tilde-constraints" + (
+ constraint ? "@" + constraint : ""
+ ) + "\n"
+ );
+ }
+
+ setTopLevelConstraint("");
+ run.match(/tilde-constraints.*added, version 0\.4\.2/);
+ run.match("tilde-constraints.js");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("0.4.0");
+ run.match("tilde-constraints.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("~0.4.0");
+ run.match("tilde-constraints.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("0.4.3");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("~0.4.3");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("0.3.0");
+ run.match("tilde-constraints.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("~0.3.0");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("0.5.0");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setTopLevelConstraint("~0.5.0");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ s.write(
+ ".meteor/packages",
+ packages
+ );
+ run.match(/tilde-constraints.*removed/);
+ run.waitSecs(10);
+
+ s.write(
+ ".meteor/packages",
+ packages + "tilde-dependent\n"
+ );
+ run.match(/tilde-constraints.*added, version 0\.4\.2/);
+ run.match(/tilde-dependent.*added, version 0\.1\.0/);
+ run.match("tilde-constraints.js");
+ run.match("tilde-dependent.js");
+ run.waitSecs(10);
+
+ var depPackageJsPath = "packages/tilde-dependent/package.js"
+ var depPackageJs = s.read(depPackageJsPath);
+
+ function setDepConstraint(constraint) {
+ s.write(
+ depPackageJsPath,
+ depPackageJs.replace(
+ /tilde-constraints[^"]*/g, // Syntax highlighting hack: "
+ "tilde-constraints" + (
+ constraint ? "@" + constraint : ""
+ )
+ )
+ );
+ }
+
+ setDepConstraint("0.4.0");
+ run.match("tilde-constraints.js");
+ run.match("tilde-dependent.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ setDepConstraint("~0.4.0");
+ run.match("tilde-constraints.js");
+ run.match("tilde-dependent.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ setDepConstraint("0.3.0");
+ run.match("tilde-constraints.js");
+ run.match("tilde-dependent.js");
+ run.match("server restarted");
+ run.waitSecs(10);
+
+ // TODO The rest of these tests should cause version conflicts, but it
+ // seems like version constraints between local packages are ignored,
+ // which is a larger (preexisting) problem we should investigate.
+ /*
+ setDepConstraint("=0.4.0");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setDepConstraint("~0.3.0");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setDepConstraint("0.4.3");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+
+ setDepConstraint("~0.4.3");
+ run.match("error: No version of tilde-constraints satisfies all constraints");
+ run.waitSecs(10);
+ */
+
+ run.stop();
+});
diff --git a/tools/tests/run.js b/tools/tests/run.js
index 5a3386ebd0..06e2a35620 100644
--- a/tools/tests/run.js
+++ b/tools/tests/run.js
@@ -6,6 +6,7 @@ var Future = require('fibers/future');
var _ = require('underscore');
var files = require('../fs/files.js');
var catalog = require('../packaging/catalog/catalog.js');
+var os = require('os');
var DEFAULT_RELEASE_TRACK = catalog.DEFAULT_TRACK;
@@ -81,7 +82,7 @@ selftest.define("run", function () {
run.match("restarted");
// Crash just once, then restart successfully
- s.write("crash.js", `
+ s.write("crash_then_restart.js", `
var fs = Npm.require('fs');
var path = Npm.require('path');
var crashmark = path.join(process.env.METEOR_TEST_TMP, 'crashed');
@@ -96,7 +97,7 @@ try {
run.waitSecs(5);
run.match("restarted");
run.stop();
- s.unlink("crash.js");
+ s.unlink("crash_then_restart.js");
run = s.run('--settings', 's.json');
run.waitSecs(5);
@@ -110,6 +111,14 @@ try {
run.match('App running at');
run.stop();
+ // Make sure a directory passed to --settings does not cause an infinite
+ // re-build loop (issue #3854).
+ run = s.run('--settings', os.tmpdir());
+ run.match(`${os.tmpdir()}: file not found (settings file)`);
+ run.match('Waiting for file change');
+ run.forbid('Modified -- restarting');
+ run.stop();
+
// How about a bundle failure right at startup
s.write("junk.css", "/*");
run = s.run();
diff --git a/tools/tests/standard-minification.js b/tools/tests/standard-minification.js
index 78e373731f..eb04330ed1 100644
--- a/tools/tests/standard-minification.js
+++ b/tools/tests/standard-minification.js
@@ -29,8 +29,8 @@ selftest.define('standard-minifiers - CSS splitting', function (options) {
color: blue
`);
- run.waitSecs(60);
run.match('Client modified -- refreshing');
+ run.waitSecs(90);
run.match('the number of stylesheets: <2>');
run.match('the color of the tested 4097th property: ');
diff --git a/tools/utils/eachline.js b/tools/utils/eachline.js
new file mode 100644
index 0000000000..dff1cd36a8
--- /dev/null
+++ b/tools/utils/eachline.js
@@ -0,0 +1,31 @@
+import split from "split2";
+import pipe from "multipipe";
+import { Transform } from "stream";
+
+export function eachline(stream, callback) {
+ stream.pipe(transform(callback));
+}
+
+export function transform(callback) {
+ const splitStream = split(/\r?\n/, null, {
+ trailing: false
+ });
+
+ const transform = new Transform();
+
+ transform._transform = async function (chunk, encoding, done) {
+ let line = chunk.toString("utf8");
+ try {
+ line = await callback(line);
+ } catch (error) {
+ done(error);
+ return;
+ }
+ done(null, line);
+ };
+
+ return pipe(
+ splitStream,
+ transform,
+ );
+}
diff --git a/tools/utils/utils.js b/tools/utils/utils.js
index e3b209997a..009d7c86df 100644
--- a/tools/utils/utils.js
+++ b/tools/utils/utils.js
@@ -523,7 +523,7 @@ exports.isValidVersion = function (version, {forCordova}) {
exports.execFileSync = function (file, args, opts) {
var child_process = require('child_process');
- var eachline = require('eachline');
+ var { eachline } = require('./eachline.js');
opts = opts || {};
if (! _.has(opts, 'maxBuffer')) {
@@ -533,13 +533,13 @@ exports.execFileSync = function (file, args, opts) {
if (opts && opts.pipeOutput) {
var p = child_process.spawn(file, args, opts);
- eachline(p.stdout, fiberHelpers.bindEnvironment(function (line) {
+ eachline(p.stdout, function (line) {
process.stdout.write(line + '\n');
- }));
+ });
- eachline(p.stderr, fiberHelpers.bindEnvironment(function (line) {
+ eachline(p.stderr, function (line) {
process.stderr.write(line + '\n');
- }));
+ });
return {
success: ! new Promise(function (resolve) {
@@ -564,18 +564,18 @@ exports.execFileSync = function (file, args, opts) {
exports.execFileAsync = function (file, args, opts) {
opts = opts || {};
var child_process = require('child_process');
- var eachline = require('eachline');
+ var { eachline } = require('./eachline.js');
var p = child_process.spawn(file, args, opts);
var mapper = opts.lineMapper || _.identity;
- var logOutput = fiberHelpers.bindEnvironment(function (line) {
+ function logOutput(line) {
if (opts.verbose) {
line = mapper(line);
if (line) {
console.log(line);
}
}
- });
+ }
eachline(p.stdout, logOutput);
eachline(p.stderr, logOutput);