Merge branch 'devel' into enable-browserstack-tests

This commit is contained in:
filipenevola
2020-09-11 17:15:56 -04:00
104 changed files with 1203 additions and 358 deletions

View File

@@ -1,3 +1,53 @@
## vNEXT, unreleased
### Breaking changes
N/A
### Migration steps
N/A
### Changes
* `--apollo` skeleton was missing client cache setup [PR #11146](https://github.com/meteor/meteor/pull/11146)
## v1.11, 2020-08-18
### Breaking changes
* `email` package dependencies have been update and package version has been bumped to 2.0.0
There is a potential breaking change as the underlying package started to use `dns.resolve()`
instead of `dns.lookup()` which might be breaking on some environments.
See [nodemailer changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) for more information.
### Migration steps
N/A
### Changes
* `meteor create --apollo` is now available thanks to [@StorytellerCZ](https://github.com/StorytellerCZ). PR [#11119](https://github.com/meteor/meteor/pull/11119)
* `meteor create --vue` is now available thanks to [@chris-visser](https://github.com/chris-visser). PR [#11086](https://github.com/meteor/meteor/pull/11086)
* `--cache-build` option is now available on `meteor deploy` command and you can use it safely all the time if you are using a Git repository to run your deploy. This is helpful if your upload is failing then you can retry just the upload and also if you deploy the same bundle to multiple environments. [Read more](https://galaxy-guide.meteor.com/deploy-guide.html#cache-build).
* Multiple optimizations in build performance, many of them for Windows thanks to [@zodern](https://github.com/zodern). PRs [#10838](https://github.com/meteor/meteor/pull/10838), [#11114](https://github.com/meteor/meteor/pull/11114), [#11115](https://github.com/meteor/meteor/pull/11115), [#11102](https://github.com/meteor/meteor/pull/11102), [#10839](https://github.com/meteor/meteor/pull/10839)
* Fixes error when removing cordova plugin that depends on cli variables. PR [#10976](https://github.com/meteor/meteor/pull/11052)
* `email` package now exposes `hookSend` that runs before emails are send.
* Node.js has been updated to version
[12.18.3](https://nodejs.org/en/blog/release/v12.18.3/)
* Updated npm to version 6.14.5
* `mongodb` driver npm dependency has been updated to 3.6.0
* The version of MongoDB used by Meteor in development has been updated
from 4.2.5 to 4.2.8
## v1.10.2, 2020-04-21

View File

@@ -1,6 +1,6 @@
# Meteor Roadmap
**Up to date as of May 21, 2020**
**Up to date as of Aug 21, 2020**
This document describes the high-level features and actions for the Meteor project in the near- to medium-term future. This roadmap was built based on community feedback and to improve areas where Meteor is already strong. The description of many items include sentences and ideas from Meteor community members.
@@ -15,9 +15,9 @@ Ideally, every item in this roadmap should have at least two leaders, leaders ar
## Core
### Tree Shaking
- Leaders: [Filipe Névola](https://github.com/filipenevola) / [Renan Castro](https://github.com/renanccastro)
- Leaders: [Renan Castro](https://github.com/renanccastro) / [Filipe Névola](https://github.com/filipenevola)
- Status: In Progress
- PRs: -
- PRs: [#11107](https://github.com/meteor/meteor/pull/11107)
Implement tree shaking / dead code elimination, which involves pruning the dependency tree while scanning imports in the `ImportScanner`. We believe it should be possible to treat values like `Meteor.isProduction` and `Meteor.isServer` as constants during this process, and eliminate those branches if their conditions are false (as in https://github.com/meteor/meteor/pull/10056).
@@ -29,25 +29,9 @@ Implement tree shaking / dead code elimination, which involves pruning the depen
A proper service worker build target. Regular Web Workers can be built from a function.toString() but service-workers require an actual server route.
### Ultra-thin Meteor
- Leaders: [Ruither Borba](https://github.com/delki8)
- Leaders: [Ruither Borba](https://github.com/delki8) / [Christian Klaussner](https://github.com/klaussner)
- Status: In Progress
- PRs:
Autoupdate package without ddp [#11034](https://github.com/meteor/meteor/pull/11034)
[Meteor 1.7](https://github.com/meteor/meteor/blob/devel/History.md#v17-2018-05-28) introduced the `meteor create --minimal` command, which generates a new application without any unnecessary Meteor packages, like `mongo` and `ddp`.
When minified and gzip-compressed, the JS bundle for this app weighs in at less than 20kB, which is much smaller than the default `meteor create` application. Nevertheless, there is still room for improvement, using techniques like bundle visualization (`meteor npm run visualize`) and converting static `import`s to dynamic `import()`s.
Additionally, minimal Meteor applications do not include the `autoupdate` package by default, because it is not strictly necessary for building an application, and its dependencies (`ddp` in particular, but no longer `mongo` or `minimongo`, thanks to [PR #10238](https://github.com/meteor/meteor/pull/10238)) contribute an additional 30kB to the JS bundle. The drawback of not using `autoupdate` is that instantaneous client refreshes are disabled, which can slow down development, so it would be great to find a way of making `autoupdate` less expensive, or enable it only in development.
In other words, we want minimal Meteor apps to be not only as tiny as possible, but also just as developer-friendly as a normal Meteor application.
Related issues:
* [MFR #31](https://github.com/meteor/meteor-feature-requests/issues/31)
* [MFR #354](https://github.com/meteor/meteor-feature-requests/issues/354)
* [Issue #9960](https://github.com/meteor/meteor/issues/9960)
* [PR #8853](https://github.com/meteor/meteor/pull/8853)
* [PR #10238](https://github.com/meteor/meteor/pull/10238)
- PRs: https://github.com/meteor/meteor/pull/11034 https://github.com/meteor/meteor/pull/11106
### Page load performance improvements
- Leaders: [Seba Kerckhof](https://github.com/sebakerckhof)
@@ -63,19 +47,13 @@ Make sure we are not delivering any dependency that is not used ([Issue #10701](
Explore ideas to improve rebuild time such as split main client bundle into several bundles, split the server bundle into several bundles, store less file content in memory, option to disabling the legacy build (at least in dev mode), etc
### Performance improvements on Windows
- Leaders: [zodern](https://github.com/zodern)
- Status: In Progress
- PRs: https://github.com/meteor/meteor/pull/10838
Explore ideas to improve performance on Windows such as build in place.
### Hot Module Replacement
- Leaders: [zodern](https://github.com/zodern)
- Status: In Progress
- PRs: -
- PRs: https://github.com/meteor/meteor/pull/11117
Explore ideas to implement HMR in Meteor.
HMR in Meteor, we already have a work in progress here, you can provide feedback already, check the PR.
### Transition as much as possible to NPM
- Leaders: <you?>
@@ -116,11 +94,6 @@ Provide a nice and friendly introduction for people that are learning Meteor.
Angular tutorial should reflect latest best practices for using Meteor and Angular together.
### Update React Tutorial
- Leaders: [Leonardo Venturini](https://github.com/leonardoventurini)
- Status: In Progress
- PRs: https://github.com/meteor/simple-todos-react/tree/tortilla-master
React tutorial should reflect latest best practices for using Meteor and React together.
### PWA documentation
@@ -147,23 +120,6 @@ Relevant issues:
Provide samples on how to run tests in Meteor these samples should include unit tests and also cypress tests.
## First-class citizen Technologies
Consider Vue.js, Svelte, React Native, and Apollo as first-class citizen, for
each technology we would like to have:
- skeleton (meteor create)
- tutorial
- documentation (how to use)
- examples
as we already have for Blaze, React and Angular.
### Vue.js
- Leaders: [Brian Mulhall](https://github.com/BrianMulhall)
- Status: In Progress
- PRs: https://github.com/meteor/simple-todos-vue
Tutorial is ready. We want a create command (--vue) yet and more docs.
### Svelte
- Leaders: [Brian Mulhall](https://github.com/BrianMulhall)
- Status: In Progress
@@ -171,18 +127,6 @@ Tutorial is ready. We want a create command (--vue) yet and more docs.
Tutorial is ready. We want a create command (--svelte) yet and more docs.
### React Native
- Leaders: [Nathaniel Dsouza](https://github.com/TheRealNate)
- Status: In Progress
- PRs: https://github.com/meteor/guide/pull/1041 https://github.com/meteor/guide/pull/1039 https://github.com/meteor/guide/pull/1035
We have some docs already maybe we could have an example in the examples folder.
### Apollo
- Leaders: <you?>
- Status: -
- PRs: -
### Third-party tools with their own build steps
- Leaders: <you?>
@@ -196,6 +140,39 @@ Relevant discussions:
- https://github.com/storybookjs/storybook/issues/5975
## Recently completed
### Vue.js
- Leaders: [Brian Mulhall](https://github.com/BrianMulhall)
- Status: shipped in August 2020
- PRs: https://github.com/meteor/simple-todos-vue
Tutorial is ready and create command meteor create --vue
### Apollo
- Leaders: [Jan Dvorak](https://github.com/StorytellerCZ)
- Status: shipped in August 2020
- PRs: https://github.com/meteor/meteor/pull/11119
Apollo skeleton, meteor create --apollo
### Performance improvements on Windows
- Leaders: [zodern](https://github.com/zodern)
- Status: shipped in August 2020
- PRs: https://github.com/meteor/meteor/pull/10838 https://github.com/meteor/meteor/pull/11114 https://github.com/meteor/meteor/pull/11115 https://github.com/meteor/meteor/pull/11102
Explore ideas to improve performance on Windows such as build in place.
### Update React Tutorial
- Leaders: [Leonardo Venturini](https://github.com/leonardoventurini) / [Brian Mulhall](https://github.com/BrianMulhall)
- Status: shipped in July 2020
- PRs: https://github.com/meteor/simple-todos-react
### React Native
- Leaders: [Nathaniel Dsouza](https://github.com/TheRealNate)
- Status: shipped in June 2020
- PRs: https://github.com/meteor/guide/pull/1041 https://github.com/meteor/guide/pull/1039 https://github.com/meteor/guide/pull/1035
Guide is ready ([check here](https://guide.meteor.com/react-native.html)).
### Update Blaze Tutorial
- Leaders: [Jan Küster](https://github.com/jankapunkt), [Harry Adel](https://github.com/harryadelb), [Brian Mulhall](https://github.com/BrianMulhall)
- Status: shipped in April 2020

2
meteor
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
BUNDLE_VERSION=12.16.1.8
BUNDLE_VERSION=12.18.3.2
# OS Check. Put here because here is where we download the precompiled
# bundles that are arch specific.

View File

@@ -71,9 +71,9 @@ export class AccountsServer extends AccountsCommon {
resetPassword: token => Meteor.absoluteUrl(`#/reset-password/${token}`),
verifyEmail: token => Meteor.absoluteUrl(`#/verify-email/${token}`),
enrollAccount: token => Meteor.absoluteUrl(`#/enroll-account/${token}`),
}
};
this.addDefaultRateLimit()
this.addDefaultRateLimit();
}
///
@@ -117,6 +117,19 @@ export class AccountsServer extends AccountsCommon {
this._validateNewUserHooks.push(func);
}
/**
* @summary Validate login from external service
* @locus Server
* @param {Function} func Called whenever login/user creation from external service is attempted. Login or user creation based on this login can be aborted by passing a falsy value or throwing an exception.
*/
beforeExternalLogin(func) {
if (this._beforeExternalLoginHook) {
throw new Error("Can only call beforeExternalLogin once");
}
this._beforeExternalLoginHook = func;
}
///
/// CREATE USER HOOKS
///
@@ -1211,6 +1224,11 @@ export class AccountsServer extends AccountsCommon {
let user = this.users.findOne(selector, {fields: this._options.defaultFieldSelector});
// Before continuing, run user hook to see if we should continue
if (this._beforeExternalLoginHook && !this._beforeExternalLoginHook(serviceName, serviceData, user)) {
throw new Meteor.Error(403, "Login forbidden");
}
// When creating a new user we pass through all options. When updating an
// existing user, by default we only process/pass through the serviceData
// (eg, so that we keep an unexpired access token and don't cache old email

View File

@@ -623,3 +623,44 @@ Tinytest.add(
Accounts._options = accountsOptions;
}
);
Tinytest.add(
'accounts - verify beforeExternalLogin hook can stop user login',
test => {
// Verify user data is saved properly when not using the
// beforeExternalLogin hook.
let facebookId = Random.id();
const uid1 = Accounts.updateOrCreateUserFromExternalService(
'facebook',
{ id: facebookId },
{ profile: { foo: 1 } },
).userId;
const ignoreFieldName = "bigArray";
const c = Meteor.users.update(uid1, {$set: {[ignoreFieldName]: [1]}});
let users =
Meteor.users.find({ 'services.facebook.id': facebookId }).fetch();
test.length(users, 1);
test.equal(users[0].profile.foo, 1);
test.isNotUndefined(users[0][ignoreFieldName], 'ignoreField - before limit fields');
// Verify that when beforeExternalLogin returns false
// that an error throws and user is not saved
Accounts.beforeExternalLogin((serviceName, serviceData, user) => {
// Check that we get the correct data
test.equal(serviceName, 'facebook');
test.equal(serviceData, { id: facebookId });
test.equal(user._id, uid1);
return false
});
test.throws(() => Accounts.updateOrCreateUserFromExternalService(
'facebook',
{ id: facebookId },
{ profile: { foo: 1 } },
));
// Cleanup
Meteor.users.remove(uid1);
Accounts._beforeExternalLoginHook = null;
}
);

View File

@@ -1,6 +1,6 @@
Package.describe({
summary: "A user account system",
version: "1.6.0",
version: "1.7.0",
});
Package.onUse(api => {

View File

@@ -20,7 +20,7 @@ Accounts.emailTemplates.headers = {
'My-Custom-Header' : 'Cool'
};
EmailTest.hookSend(options => {
Email.hookSend(options => {
const { to } = options;
if (!to || !to.toUpperCase().includes('INTERCEPT')) {
return true; // go ahead and send

View File

@@ -5,7 +5,7 @@ Package.describe({
// 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
// during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
// through -beta.5 and -rc.0 have already been published.
version: "1.6.1"
version: "1.6.2"
});
Package.onUse(api => {

View File

@@ -20,7 +20,7 @@ const reportError = (error, callback) => {
/**
* @summary Log the user in with a password.
* @locus Client
* @param {Object | String} user
* @param {Object | String} selector
* Either a string interpreted as a username or an email; or an object with a
* single key: `email`, `username` or `id`. Username or email match in a case
* insensitive manner.

View File

@@ -1,6 +1,6 @@
Package.describe({
summary: "Generates the boilerplate html from program's manifest",
version: '1.7.0'
version: '1.7.1'
});
Npm.depends({

View File

@@ -29,7 +29,7 @@ export const headTemplate = ({
' <meta name="format-detection" content="telephone=no">',
' <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, viewport-fit=cover">',
' <meta name="msapplication-tap-highlight" content="no">',
' <meta http-equiv="Content-Security-Policy" content="default-src * gap: data: blob: \'unsafe-inline\' \'unsafe-eval\' ws: wss:;">',
' <meta http-equiv="Content-Security-Policy" content="default-src * android-webview-video-poster: gap: data: blob: \'unsafe-inline\' \'unsafe-eval\' ws: wss:;">',
(headSections.length === 1)
? [cssBundle, headSections[0]].join('\n')

View File

@@ -2,9 +2,9 @@
"lockfileVersion": 1,
"dependencies": {
"lolex": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.1.tgz",
"integrity": "sha512-mQuW55GhduF3ppo+ZRUTz1PRjEh1hS5BbqU7d8D0ez2OKxHDod7StPPeAVKisZR5aLkHZjdGWSL42LSONUJsZw=="
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz",
"integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng=="
}
}
}

View File

@@ -1,6 +1,6 @@
Package.describe({
name: 'ddp-rate-limiter',
version: '1.0.7',
version: '1.0.9',
// Brief, one-line summary of the package.
summary: 'The DDPRateLimiter allows users to add rate limits to DDP' +
' methods and subscriptions.',

View File

@@ -2,9 +2,9 @@
"lockfileVersion": 1,
"dependencies": {
"core-js": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz",
"integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw=="
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
}
}
}

View File

@@ -1,13 +1,13 @@
Package.describe({
name: "ecmascript-runtime-client",
version: "0.10.0",
version: "0.11.0",
summary: "Polyfills for new ECMAScript 2015 APIs like Map and Set",
git: "https://github.com/meteor/meteor/tree/devel/packages/ecmascript-runtime-client",
documentation: "README.md"
});
Npm.depends({
"core-js": "3.2.1"
"core-js": "3.6.5"
});
Package.onUse(function(api) {

View File

@@ -2,9 +2,9 @@
"lockfileVersion": 1,
"dependencies": {
"core-js": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz",
"integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw=="
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
}
}
}

View File

@@ -1,13 +1,13 @@
Package.describe({
name: "ecmascript-runtime-server",
version: "0.9.0",
version: "0.10.0",
summary: "Polyfills for new ECMAScript 2015 APIs like Map and Set",
git: "https://github.com/meteor/meteor/tree/devel/packages/ecmascript-runtime-client",
documentation: "README.md"
});
Npm.depends({
"core-js": "3.2.1"
"core-js": "3.6.5"
});
Package.onUse(function(api) {

View File

@@ -1,15 +1,15 @@
{
"lockfileVersion": 1,
"dependencies": {
"node4mailer": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/node4mailer/-/node4mailer-4.0.3.tgz",
"integrity": "sha1-jwx6ZzdSehKFMBhaFMLoeZiaiRA="
"nodemailer": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.6.tgz",
"integrity": "sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA=="
},
"stream-buffers": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-0.2.5.tgz",
"integrity": "sha1-+TBTnTzwjXSKNArWE5+Vss60jwU="
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
"integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ=="
}
}
}

View File

@@ -1,6 +1,6 @@
var Future = Npm.require('fibers/future');
var urlModule = Npm.require('url');
var nodemailer = Npm.require('node4mailer');
var nodemailer = Npm.require('nodemailer');
Email = {};
EmailTest = {};
@@ -8,12 +8,12 @@ EmailTest = {};
EmailInternals = {
NpmModules: {
mailcomposer: {
version: Npm.require('node4mailer/package.json').version,
module: Npm.require('node4mailer/lib/mail-composer')
version: Npm.require('nodemailer/package.json').version,
module: Npm.require('nodemailer/lib/mail-composer')
},
nodemailer: {
version: Npm.require('node4mailer/package.json').version,
module: Npm.require('node4mailer')
version: Npm.require('nodemailer/package.json').version,
module: Npm.require('nodemailer')
}
}
};
@@ -98,15 +98,17 @@ var smtpSend = function (transport, mail) {
transport._syncSendMail(mail);
};
var sendHooks = [];
/**
* Mock out email sending (eg, during a test.) This is private for now.
* @summary Hook that runs before email is sent.
* @locus Server
*
* f receives the arguments to Email.send and should return true to go
* @param f {function} receives the arguments to Email.send and should return true to go
* ahead and send the email (or at least, try subsequent hooks), or
* false to skip sending.
*/
var sendHooks = [];
EmailTest.hookSend = function (f) {
Email.hookSend = function (f) {
sendHooks.push(f);
};
@@ -118,9 +120,9 @@ EmailTest.hookSend = function (f) {
* If the `MAIL_URL` environment variable is set, actually sends the email.
* Otherwise, prints the contents of the email to standard out.
*
* Note that this package is based on **mailcomposer 4**, so make sure to refer to
* [the documentation](https://github.com/nodemailer/mailcomposer/blob/v4.0.1/README.md)
* for that version when using the `attachments` or `mailComposer` options.
* Note that this package is based on **nodemailer**, so make sure to refer to
* [the documentation](http://nodemailer.com/)
* when using the `attachments` or `mailComposer` options.
*
* @locus Server
* @param {Object} options
@@ -136,7 +138,7 @@ EmailTest.hookSend = function (f) {
* @param {String} [options.icalEvent] iCalendar event attachment
* @param {Object} [options.headers] Dictionary of custom headers - e.g. `{ "header name": "header value" }`. To set an object under a header name, use `JSON.stringify` - e.g. `{ "header name": JSON.stringify({ tracking: { level: 'full' } }) }`.
* @param {Object[]} [options.attachments] Array of attachment objects, as
* described in the [mailcomposer documentation](https://github.com/nodemailer/mailcomposer/blob/v4.0.1/README.md#attachments).
* described in the [nodemailer documentation](https://nodemailer.com/message/attachments/).
* @param {MailComposer} [options.mailComposer] A [MailComposer](https://nodemailer.com/extras/mailcomposer/#e-mail-message-fields)
* object representing the message to be sent. Overrides all other options.
* You can create a `MailComposer` object via

View File

@@ -1,11 +1,11 @@
Package.describe({
summary: "Send email messages",
version: "1.2.3"
version: "2.0.0"
});
Npm.depends({
node4mailer: "4.0.3",
"stream-buffers": "0.2.5"
nodemailer: "6.4.6",
"stream-buffers": "3.0.2"
});
Package.onUse(function (api) {

View File

@@ -1,6 +1,6 @@
Package.describe({
summary: "The Meteor command-line tool",
version: '1.10.2'
version: '1.11.0'
});
Package.includeTool();

View File

@@ -1 +1,2 @@
.build*
.npm

View File

@@ -27,9 +27,9 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"browserslist": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
"integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg=="
"version": "4.14.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz",
"integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw=="
},
"caller-callsite": {
"version": "2.0.0",
@@ -52,9 +52,9 @@
"integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="
},
"caniuse-lite": {
"version": "1.0.30001066",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001066.tgz",
"integrity": "sha512-Gfj/WAastBtfxLws0RCh2sDbTK/8rJuSeZMecrSkNGYxPcv7EzblmDGfWQCFEQcSqYE2BRgQiJh8HOD07N5hIw=="
"version": "1.0.30001125",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001125.tgz",
"integrity": "sha512-9f+r7BW8Qli917mU3j0fUaTweT3f3vnX/Lcs+1C73V+RADmFme+Ih0Br8vONQi3X0lseOe6ZHfsZLCA8MSjxUA=="
},
"chalk": {
"version": "2.4.2",
@@ -124,9 +124,9 @@
"integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg=="
},
"css-what": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz",
"integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw=="
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz",
"integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg=="
},
"cssesc": {
"version": "3.0.0",
@@ -208,19 +208,19 @@
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg=="
},
"dot-prop": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
"integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A=="
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
"integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="
},
"electron-to-chromium": {
"version": "1.3.453",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.453.tgz",
"integrity": "sha512-IQbCfjJR0NDDn/+vojTlq7fPSREcALtF8M1n01gw7nQghCtfFYrJ2dfhsp8APr8bANoFC8vRTFVXMOGpT0eetw=="
"version": "1.3.564",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.564.tgz",
"integrity": "sha512-fNaYN3EtKQWLQsrKXui8mzcryJXuA0LbCLoizeX6oayG2emBaS5MauKjCPAvc29NEY4FpLHIUWiP+Y0Bfrs5dg=="
},
"entities": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.2.tgz",
"integrity": "sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
},
"error-ex": {
"version": "1.3.2",
@@ -228,15 +228,20 @@
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="
},
"es-abstract": {
"version": "1.17.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
"integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg=="
"version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
"integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw=="
},
"es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA=="
},
"escalade": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz",
"integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ=="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -247,11 +252,6 @@
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c="
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@@ -313,9 +313,9 @@
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz",
"integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg=="
},
"is-color-stop": {
"version": "1.1.0",
@@ -338,9 +338,9 @@
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg=="
},
"is-resolvable": {
"version": "1.1.0",
@@ -367,11 +367,6 @@
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
},
"locate-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -398,9 +393,9 @@
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ=="
},
"node-releases": {
"version": "1.1.57",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.57.tgz",
"integrity": "sha512-ZQmnWS7adi61A9JsllJ2gdj2PauElcjnOwTp2O011iGzoakTxUsDGSe+6vD7wXbKdqhSFymC0OSx35aAMhrSdw=="
"version": "1.1.61",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.61.tgz",
"integrity": "sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g=="
},
"normalize-url": {
"version": "3.3.0",
@@ -413,9 +408,9 @@
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg=="
},
"object-inspect": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
"integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
},
"object-keys": {
"version": "1.1.1",
@@ -437,45 +432,20 @@
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
"integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA=="
},
"p-limit": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
"integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="
},
"p-locate": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM="
},
"p-try": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
},
"parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA="
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
},
"pkg-up": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
"integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8="
},
"postcss": {
"version": "7.0.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.31.tgz",
"integrity": "sha512-a937VDHE1ftkjk+8/7nj/mrjtmkn69xxzJgRETXdAUU+IgOYPQNJF17haGWbeDxSyk++HA14UA98FurvPyBJOA=="
"version": "7.0.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
"integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw=="
},
"postcss-calc": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz",
"integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ=="
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.4.tgz",
"integrity": "sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw=="
},
"postcss-colormin": {
"version": "4.0.3",
@@ -807,16 +777,6 @@
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g=="
},
"string.prototype.trimleft": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
"integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw=="
},
"string.prototype.trimright": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
"integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg=="
},
"string.prototype.trimstart": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",

View File

@@ -1,10 +1,10 @@
Package.describe({
summary: 'CSS minifier',
version: '1.5.2'
version: '1.5.3'
});
Npm.depends({
postcss: '7.0.31',
postcss: '7.0.32',
cssnano: '4.1.10'
});

View File

@@ -2,14 +2,14 @@
"lockfileVersion": 1,
"dependencies": {
"bl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
"integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA=="
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
"integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g=="
},
"bson": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
"integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q=="
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
"integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
},
"core-util-is": {
"version": "1.0.2",
@@ -37,9 +37,9 @@
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
},
"mongodb": {
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.5.tgz",
"integrity": "sha512-GCjDxR3UOltDq00Zcpzql6dQo1sVry60OXJY3TDmFc2SWFY6c8Gn1Ardidc5jDirvJrx2GC3knGOImKphbSL3A=="
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
"integrity": "sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA=="
},
"process-nextick-args": {
"version": "2.0.1",

View File

@@ -3,12 +3,12 @@
Package.describe({
summary: "Wrapper around the mongo npm package",
version: "3.7.1",
version: "3.8.1",
documentation: null
});
Npm.depends({
mongodb: "3.5.5"
mongodb: "3.6.2"
});
Package.onUse(function (api) {

View File

@@ -1,6 +1,6 @@
Package.describe({
name: 'standard-minifier-css',
version: '1.6.0',
version: '1.6.1',
summary: 'Standard css minifier used with Meteor apps by default.',
documentation: 'README.md'
});
@@ -21,5 +21,6 @@ Package.registerBuildPlugin({
});
Package.onUse(function(api) {
api.use('minifier-css@1.5.3');
api.use('isobuild:minifier-plugin@1.0.0');
});

View File

@@ -1,6 +1,6 @@
{
"track": "METEOR",
"version": "1.10.2-rc.0",
"version": "1.11-rc.0",
"recommended": false,
"official": false,
"description": "Meteor"

View File

@@ -1,6 +1,6 @@
{
"track": "METEOR",
"version": "1.10.2",
"version": "1.11",
"recommended": false,
"official": true,
"description": "The Official Meteor Distribution"

View File

@@ -5,10 +5,10 @@ set -u
UNAME=$(uname)
ARCH=$(uname -m)
NODE_VERSION=12.16.1
MONGO_VERSION_64BIT=4.2.5
NODE_VERSION=12.18.3
MONGO_VERSION_64BIT=4.2.8
MONGO_VERSION_32BIT=3.2.22
NPM_VERSION=6.14.0
NPM_VERSION=6.14.6
# If we built Node from source on Jenkins, this is the build number.
NODE_BUILD_NUMBER=

View File

@@ -10,7 +10,7 @@ var packageJson = {
dependencies: {
// Explicit dependency because we are replacing it with a bundled version
// and we want to make sure there are no dependencies on a higher version
npm: "6.14.0",
npm: "6.14.6",
pacote: "https://github.com/meteor/pacote/tarball/a81b0324686e85d22c7688c47629d4009000e8b8",
"node-gyp": "6.0.1",
"node-pre-gyp": "0.14.0",

View File

@@ -66,7 +66,7 @@ case $OS in
linux)
[ $ARCH = "i686" ] &&
MONGO_BASE_URL="https://fastdl.mongodb.org/linux" ||
MONGO_BASE_URL="https://github.com/meteor/mongodb-builder/releases/download/${MONGO_VERSION}"
MONGO_BASE_URL="https://github.com/meteor/mongodb-builder/releases/download/v${MONGO_VERSION}"
;;
esac

View File

@@ -517,7 +517,9 @@ main.registerCommand({
minimal: { type: Boolean },
full: { type: Boolean },
react: { type: Boolean },
vue: { type: Boolean },
typescript: { type: Boolean },
apollo: { type: Boolean },
},
catalogRefresh: new catalog.Refresh.Never()
}, function (options) {
@@ -770,8 +772,12 @@ main.registerCommand({
skelName += "-full";
} else if (options.react) {
skelName += "-react";
} else if (options.vue) {
skelName += "-vue";
} else if (options.typescript) {
skelName += "-typescript";
} else if (options.apollo) {
skelName += "-apollo";
}
files.cp_r(files.pathJoin(__dirnameConverted, '..', 'static-assets', skelName), appPath, {
@@ -886,8 +892,9 @@ main.registerCommand({
! options.minimal &&
! options.full &&
! options.react &&
! options.vue &&
! options.typescript) {
// Notify people about --bare, --minimal, --full, --react, and --typescript.
// Notify people about --bare, --minimal, --full, --react, --vue, --apollo and --typescript.
Console.info([
"",
"To start with a different app template, try one of the following:",
@@ -898,6 +905,8 @@ main.registerCommand({
cmd("meteor create --minimal # to create an app with as few Meteor packages as possible");
cmd("meteor create --full # to create a more complete scaffolded app");
cmd("meteor create --react # to create a basic React-based app");
cmd("meteor create --vue # to create a basic Vue-based app");
cmd("meteor create --apollo # to create a basic Apollo + React app");
cmd("meteor create --typescript # to create an app using TypeScript and React");
}
@@ -1259,7 +1268,6 @@ main.registerCommand({
projectContext.prepareProjectForBuild();
});
const bundlePath = projectContext.getProjectLocalDirectory('build');
const bundler = require('../isobuild/bundler.js');
const bundle = bundler.bundle({
projectContext: projectContext,
@@ -1428,6 +1436,7 @@ main.registerCommand({
'allow-incompatible-update': { type: Boolean },
'deploy-polling-timeout': { type: Number },
'no-wait': { type: Boolean },
'cache-build': { type: Boolean },
},
allowUnrecognizedOptions: true,
requiresApp: function (options) {
@@ -1501,6 +1510,7 @@ function deployCommand(options, { rawOptions }) {
deployPollingTimeoutMs = options['deploy-polling-timeout'];
}
const isCacheBuildEnabled = !!options['cache-build'];
const waitForDeploy = !options['no-wait'];
var deployResult = deploy.bundleAndDeploy({
@@ -1511,6 +1521,7 @@ function deployCommand(options, { rawOptions }) {
rawOptions,
deployPollingTimeoutMs,
waitForDeploy,
isCacheBuildEnabled,
});
if (deployResult === 0) {

View File

@@ -518,6 +518,8 @@ Options:
minified code; defaults to 15 minutes.
--no-wait Exits when Meteor has uploaded the app's code instead of
waiting for the deploy to conclude.
--cache-build Reuses the build already created if the git commit hash is the
same
>>> authorized
View or change authorized users and organizations for a site.
@@ -809,7 +811,7 @@ Usage: meteor list-sites
List the sites that you have deployed with 'meteor deploy', and sites
for which other users have authorized you with the 'meteor authorized'
command. To see sites in a region other than us-east-1, set the DEPLOY_HOSTNAME
environment variable. For example,
environment variable. For example,
`DEPLOY_HOSTNAME=eu-west-1.galaxy-deploy.meteor.com meteor list-sites`

View File

@@ -74,6 +74,34 @@ const pinnedPluginVersions = {
"cordova-plugin-wkwebview-engine": "1.1.3"
}
/**
* To fix Cordova error: Variable(s) missing we convert the cli_variables
* when removing plugins we want to convert for each plugin, for instance,
* cordova-plugin-facebook4:
* commandOptions {
* ...
* cli_variables: {
* 'cordova-plugin-googleplus': {
* REVERSED_CLIENT_ID: 'com.googleusercontent.apps.11111111-xxkodsuusaiusixuaix'
* },
* 'cordova-plugin-facebook4': { APP_ID: '1111111111111111', APP_NAME: 'appname' }
* }
* }
* into this
* commandOptions {
* ...
* cli_variables: { APP_ID: '1111111111111111', APP_NAME: 'appname' }
* }
*
* @param plugin
* @param commandOptions
*/
const getCommandOptionsForPlugin = (plugin, commandOptions = {}) => {
const cli_variables = commandOptions && commandOptions.cli_variables
&& commandOptions.cli_variables[plugin] || {};
return {...commandOptions, cli_variables};
}
export class CordovaProject {
constructor(projectContext, options = {}) {
@@ -521,7 +549,7 @@ from Cordova project`, async () => {
buildmessage.assertInJob();
if (utils.isUrlWithSha(version)) {
return convertToGitUrl(version);
return `${id}@${convertToGitUrl(version)}`;
} else if (utils.isUrlWithFileScheme(version)) {
// Strip file:// and resolve the path relative to the cordova-build
// directory
@@ -560,18 +588,28 @@ from Cordova project`, async () => {
{ cli_variables: config, link: utils.isUrlWithFileScheme(version) });
this.runCommands(`adding plugin ${target} \
to Cordova project`, cordova_lib.plugin.bind(undefined, 'add', [target], commandOptions));
to Cordova project`, cordova_lib.plugin.bind(undefined, 'add', [target],
commandOptions));
}
}
// plugins is an array of plugin IDs.
removePlugins(plugins) {
removePlugins(plugins, config = {}) {
if (_.isEmpty(plugins)) {
return;
}
this.runCommands(`removing plugins ${plugins} \
from Cordova project`, cordova_lib.plugin.bind(undefined, 'rm', plugins, this.defaultOptions));
const commandOptions = _.extend(this.defaultOptions,
{ cli_variables: config });
plugins.forEach(plugin => {
const commandOptionsPlugin = getCommandOptionsForPlugin(plugin,
commandOptions);
this.runCommands(`removing plugin ${plugin} \
from Cordova project`, cordova_lib.plugin.bind(undefined, 'rm --force', [plugin],
commandOptionsPlugin));
});
}
// Ensures that the Cordova plugins are synchronized with the app-level
@@ -699,7 +737,7 @@ perform cordova plugins reinstall`);
Object.keys(installedPluginVersions));
}
this.removePlugins(pluginsToRemove);
this.removePlugins(pluginsToRemove, pluginsConfiguration);
let pluginVersionsToInstall;
@@ -735,7 +773,7 @@ perform cordova plugins reinstall`);
// cordova-plugin-whitelist@1.3.2 => { 'cordova-plugin-whitelist': '1.3.2' }
// com.cordova.plugin@file://.cordova-plugins/plugin => { 'com.cordova.plugin': 'file://.cordova-plugins/plugin' }
// @scope/plugin@1.0.0 => { 'com.cordova.plugin': 'scope/plugin' }
const installed = this.listInstalledPluginVersions(true);
const installed = this.listInstalledPluginVersions();
const installedPluginsNames = Object.keys(installed);
const installedPluginsVersions = Object.values(installed);
const missingPlugins = {};

View File

@@ -5,7 +5,7 @@
///
import assert from "assert";
import fs, { PathLike, Stats } from "fs";
import fs, { PathLike, Stats, Dirent } from "fs";
import path from "path";
import os from "os";
import { spawn, execFile } from "child_process";
@@ -727,9 +727,18 @@ export function freeTempDir(dir: string) {
});
}
// Change the status of a dir
export function changeTempDirStatus(dir: string, status: boolean) {
if (! tempDirs[dir]) {
throw Error("not a tracked temp dir: " + dir);
}
tempDirs[dir] = status;
}
if (! process.env.METEOR_SAVE_TMPDIRS) {
cleanup.onExit(function () {
Object.keys(tempDirs).forEach(dir => {
Object.entries(tempDirs).filter(([_, isTmp]) => !!isTmp).map(([dir]) => dir).forEach(dir => {
delete tempDirs[dir];
try {
rm_recursive(dir);
@@ -1538,13 +1547,13 @@ export function readBufferWithLengthAndOffset(
if (length > 0) {
const fd = open(filename, "r");
try {
var count = read(fd, data, 0, length, offset);
const count = read(fd, data, { position: 0, length, offset });
if (count !== length) {
throw new Error("couldn't read entire resource");
}
} finally {
close(fd);
}
if (count !== length) {
throw new Error("couldn't read entire resource");
}
}
return data;
}
@@ -1748,6 +1757,14 @@ wrapFsFunc<[string], string[]>("readdir", fs.readdirSync, [0], {
},
});
export const readdirWithTypes = wrapFsFunc<[string], Dirent[]>("readdirWithTypes", (dir) => {
return fs.readdirSync(dir, {
withFileTypes: true
});
}, [0], {
cached: true
});
export const appendFile = wrapDestructiveFsFunc("appendFile", fs.appendFileSync);
export const chmod = wrapDestructiveFsFunc("chmod", fs.chmodSync);
export const close = wrapFsFunc("close", fs.closeSync, []);

View File

@@ -35,6 +35,14 @@ var NO_WATCHER_POLLING_INTERVAL =
// file watchers, but it's to our advantage if they survive restarts.
const WATCHER_CLEANUP_DELAY_MS = 30000;
// Pathwatcher complains (using console.error, ugh) if you try to watch
// two files with the same stat.ino number but different paths on linux, so we have
// to deduplicate files by ino.
const DEDUPLICATE_BY_INO = process.platform !== "win32";
const entriesByIno = new Map;
export type SafeWatcher = {
close: () => void;
}
@@ -49,11 +57,6 @@ interface Entry extends SafeWatcher {
const entries: Record<string, Entry | null> = Object.create(null);
// Pathwatcher complains (using console.error, ugh) if you try to watch
// two files with the same stat.ino number but different paths, so we have
// to deduplicate files by ino.
const entriesByIno = new Map;
// Set of paths for which a change event has been fired, watched with
// watchLibrary.watch if available. This could be an LRU cache, but in
// practice it should never grow large enough for that to matter.
@@ -86,10 +89,19 @@ function acquireWatcher(absPath: string, callback: EntryCallback) {
}
function startNewWatcher(absPath: string): Entry {
const stat = statOrNull(absPath);
if (stat && stat.ino > 0 && entriesByIno.has(stat.ino)) {
const entry = entriesByIno.get(stat.ino);
if (entries[absPath] === entry) {
let stat: Stats | null = null;
if (DEDUPLICATE_BY_INO) {
stat = statOrNull(absPath);
if (stat && stat.ino > 0 && entriesByIno.has(stat.ino)) {
const entry = entriesByIno.get(stat.ino);
if (entries[absPath] === entry) {
return entry;
}
}
} else {
let entry = entries[absPath];
if (entry) {
return entry;
}
}

View File

@@ -1,4 +1,4 @@
import { Stats, FSWatcher } from "fs";
import { Stats, FSWatcher, Dirent } from "fs";
import * as files from "./files";
import * as safeWatcher from "./safe-watcher";
import { createHash } from "crypto";
@@ -339,7 +339,7 @@ export const sha512 = Profile("sha512", function (...args: (string | Buffer)[])
function readAndStatDirectory(absPath: string) {
// Read the directory.
try {
var contents = files.readdir(absPath);
var contents = files.readdirWithTypes(absPath);
} catch (e) {
// If the path is not a directory, return null; let other errors through.
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) {
@@ -351,9 +351,14 @@ function readAndStatDirectory(absPath: string) {
// Add slashes to the end of directories.
const contentsWithSlashes: string[] = [];
contents.forEach(entry => {
// We do stat instead of lstat here, so that we treat symlinks to
// directories just like directories themselves.
const stat = optimisticStatOrNull(files.pathJoin(absPath, entry));
let stat: Dirent | Stats | null = entry;
let name = entry.name;
if (entry.isSymbolicLink()) {
// We do stat instead of lstat here, so that we treat symlinks to
// directories just like directories themselves.
stat = optimisticStatOrNull(files.pathJoin(absPath, entry.name));
}
if (! stat) {
// Disappeared after the readdir (or a dangling symlink)?
// Eh, pretend it was never there in the first place.
@@ -361,10 +366,10 @@ function readAndStatDirectory(absPath: string) {
}
if (stat.isDirectory()) {
entry += '/';
name += '/';
}
contentsWithSlashes.push(entry);
contentsWithSlashes.push(name);
});
return contentsWithSlashes;

View File

@@ -1,7 +1,7 @@
import assert from "assert";
import {WatchSet, readAndWatchFile, sha1} from '../fs/watch';
import files, {
symlinkWithOverwrite,
symlinkWithOverwrite, realpath,
} from '../fs/files';
import NpmDiscards from './npm-discards.js';
import {Profile} from '../tool-env/profile';
@@ -540,7 +540,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
// as well as node_modules/meteor and the parent directories of any
// scoped npm packages.
this._ensureAllNonPackageDirectories(
files.realpath(options.from),
realpath(options.from),
options.to
);
}
@@ -637,7 +637,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
});
}
const rootDir = files.realpath(from);
const rootDir = realpath(from);
const walk = (absFrom, relTo) => {
if (symlink && ! (relTo in this.usedAsFile)) {
@@ -661,7 +661,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
return;
}
// Returns files.realpath(thisAbsFrom), iff it is external to
// Returns files.realpath(thisAbsFrom), if it is external to
// rootDir, using caching because this function might be called
// more than once.
let cachedExternalPath;
@@ -671,7 +671,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
}
try {
var real = files.realpath(thisAbsFrom);
var real = realpath(thisAbsFrom);
} catch (e) {
if (e.code !== "ENOENT" &&
e.code !== "ELOOP") {

View File

@@ -173,6 +173,7 @@ import { loadIsopackage } from '../tool-env/isopackets.js';
import { CORDOVA_PLATFORM_VERSIONS } from '../cordova';
import { gzipSync } from "zlib";
import { PackageRegistry } from "../../packages/meteor/define-package.js";
import { optimisticLStatOrNull } from '../fs/optimistic';
const SOURCE_URL_PREFIX = "meteor://\u{1f4bb}app";
@@ -486,12 +487,11 @@ export class NodeModulesDirectory {
return true;
}
const real = files.realpathOrNull(path);
if (typeof real === "string" &&
real !== path) {
const fileStatus = optimisticLStatOrNull(path);
if (fileStatus && fileStatus.isSymbolicLink()) {
// If node_modules/.bin/command is a symlink, determine the
// answer by calling isWithinProdPackage(real).
return isWithinProdPackage(real);
return isWithinProdPackage(files.realpathOrNull(path));
}
// If node_modules/.bin/command is not a symlink, then it's hard
@@ -2844,20 +2844,18 @@ var writeTargetToPath = Profile(
previousBuilder = null,
buildMode,
minifyMode,
forceInPlaceBuild
}) {
var builder = new Builder({
outputPath: files.pathJoin(outputPath, 'programs', name),
previousBuilder,
// We do not force an in-place build for individual targets like
// .meteor/local/build/programs/web.browser.legacy, because they
// tend to be written atomically, and it's important on Windows to
// avoid overwriting files that might be open currently in the build
// or server process.
// Server builds do use an in-place build since the server is always stopped
// during the build.
// If client in-place builds were safer on Windows, they
// would be much quicker than from-scratch rebuilds.
forceInPlaceBuild: name === 'server',
// We do not force an in-place build for individual targets
// like .meteor/local/build/programs/web.browser.legacy, because they tend
// to be written atomically, and it's important on Windows to avoid
// overwriting files that might be open currently in the server
// process. There are some exceptions when we know the server process
// is not using the files, such as during a full build when it is stopped.
forceInPlaceBuild
});
var targetBuild = target.write(builder, {
@@ -2910,6 +2908,7 @@ var writeSiteArchive = Profile("bundler writeSiteArchive", function (
buildMode,
minifyMode,
sourceRoot,
forceInPlaceBuild,
}) {
const builders = {};
@@ -3004,7 +3003,8 @@ Find out more about Meteor at meteor.com.
releaseName,
previousBuilder: previousBuilders[name] || null,
buildMode,
minifyMode
minifyMode,
forceInPlaceBuild
});
builders[name] = targetBuilder;
@@ -3083,6 +3083,10 @@ Find out more about Meteor at meteor.com.
* - hasCachedBundle: true if we already have a cached bundle stored in
* /build. When true, we only build the new client targets in the bundle.
*
* - forceInPlaceBuild On Windows, in place builds are disabled by default
* since they are only safe when the output files from the previous build
* are not being used. This can be set to true when it is safe.
*
* Returns an object with keys:
* - errors: A buildmessage.MessageSet, or falsy if bundling succeeded.
* - serverWatchSet: Information about server files and paths that were
@@ -3117,6 +3121,7 @@ function bundle({
previousBuilders = Object.create(null),
hasCachedBundle,
allowDelayedClientBuilds = false,
forceInPlaceBuild,
}) {
buildOptions = buildOptions || {};
@@ -3271,6 +3276,7 @@ function bundle({
builtBy,
releaseName,
minifyMode,
forceInPlaceBuild,
};
function writeClientTarget(target) {

View File

@@ -1714,7 +1714,7 @@ export class PackageSourceBatch {
if (cacheFilename) {
let diskCached = null;
try {
diskCached = optimisticReadJsonOrNull(cacheFilename);
diskCached = files.readJSONOrNull(cacheFilename);
} catch (e) {
// Ignore JSON parse errors; pretend there was no cache.
if (!(e instanceof SyntaxError)) {

View File

@@ -25,6 +25,7 @@ import {
convertToPosixPath,
realpathOrNull,
writeFileAtomically,
readFile,
} from "../fs/files";
const { SourceNode, SourceMapConsumer } = require("source-map");
@@ -74,9 +75,18 @@ const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function (
source,
_hash,
bundleArch,
cacheFilePath,
) {
if (cacheFilePath) {
try {
return readFile(cacheFilePath, "utf8");
} catch (e) {
if (e.code !== "ENOENT") throw e;
}
}
const isLegacy = isLegacyArch(bundleArch);
return reifyCompile(stripHashBang(source), {
let result = reifyCompile(stripHashBang(source), {
parse: reifyBabelParse,
generateLetDeclarations: !isLegacy,
avoidModernSyntax: isLegacy,
@@ -84,6 +94,14 @@ const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function (
dynamicImport: true,
ast: false,
}).code;
if (cacheFilePath) {
Promise.resolve().then(
() => writeFileAtomically(cacheFilePath, result),
);
}
return result;
}, {
makeCacheKey(_source, hash, bundleArch) {
return JSON.stringify([hash, bundleArch]);
@@ -132,29 +150,16 @@ class DefaultHandlers {
}
}
if (this.cacheDir) {
const cacheFileName = this.getCacheFileName(file)!;
try {
return optimisticReadFile(cacheFileName, "utf8");
} catch (e) {
if (e.code !== "ENOENT") throw e;
const code = reifyCompileWithCache(
file.dataString,
file.hash,
this.bundleArch,
);
Promise.resolve().then(
() => writeFileAtomically(cacheFileName, code),
);
return code;
}
} else {
return reifyCompileWithCache(
file.dataString,
file.hash,
this.bundleArch,
);
}
const cacheFileName = this.cacheDir ?
this.getCacheFileName(file) :
null;
return reifyCompileWithCache(
file.dataString,
file.hash,
this.bundleArch,
cacheFileName
)
}
// Files with an .mjs extension are just JavaScript plus module syntax.

View File

@@ -79,6 +79,9 @@ var loadOrderSort = function (sourceProcessorSet, arch) {
});
return function (a, b) {
const aBasename = files.pathBasename(a);
const bBasename = files.pathBasename(b);
// XXX MODERATELY SIZED HACK --
// push template files ahead of everything else. this is
// important because the user wants to be able to say
@@ -87,15 +90,15 @@ var loadOrderSort = function (sourceProcessorSet, arch) {
// before the corresponding .html file.
//
// maybe all of the templates should go in one file?
var isTemplate_a = isTemplate(files.pathBasename(a));
var isTemplate_b = isTemplate(files.pathBasename(b));
var isTemplate_a = isTemplate(aBasename);
var isTemplate_b = isTemplate(bBasename);
if (isTemplate_a !== isTemplate_b) {
return (isTemplate_a ? -1 : 1);
}
// main.* loaded last
var ismain_a = (files.pathBasename(a).indexOf('main.') === 0);
var ismain_b = (files.pathBasename(b).indexOf('main.') === 0);
var ismain_a = (aBasename.indexOf('main.') === 0);
var ismain_b = (bBasename.indexOf('main.') === 0);
if (ismain_a !== ismain_b) {
return (ismain_a ? 1 : -1);
}
@@ -213,14 +216,44 @@ var getExcerptFromReadme = function (text) {
class SymlinkLoopChecker {
constructor(sourceRoot) {
this.sourceRoot = sourceRoot;
this._realSourceRoot = files.realpath(sourceRoot);
this._seenPaths = {};
this._cache = new Map();
}
// Avoids running realpath unless necessary
// since it is relatively slow on windows
_realpath = Profile('_realpath', function (relDir) {
const absPath = files.pathJoin(this._realSourceRoot, relDir);
if (files.lstat(absPath).isSymbolicLink()) {
const result = files.realpath(absPath);
this._cache.set(relDir, result);
return result;
}
let result;
const parentDir = files.pathDirname(relDir);
const parentEntry = this._cache.get(parentDir);
if (parentDir === '.') {
result = absPath;
} else if (parentEntry) {
result = files.pathJoin(parentEntry, files.pathBasename(relDir));
} else {
// The parent dir was never checked, which prevents us from
// skipping realpath
result = files.realpath(absPath);
}
this._cache.set(relDir, result);
return result;
})
check(relDir, quietly = true) {
const absPath = files.pathJoin(this.sourceRoot, relDir);
try {
var realPath = files.realpath(absPath);
var realPath = this._realpath(relDir);
} catch (e) {
if (!e || e.code !== 'ELOOP') {
throw e;
@@ -834,10 +867,21 @@ _.extend(PackageSource.prototype, {
}),
_readAndWatchDirectory(relDir, watchSet, {include, exclude, names}) {
return watch.readAndWatchDirectory(watchSet, {
const options = {
absPath: files.pathJoin(this.sourceRoot, relDir),
include, exclude, names
}).map(name => files.pathJoin(relDir, name));
};
const contents = watch.readDirectory(options);
if (watchSet) {
watchSet.addDirectory({
contents,
...options
});
}
return contents.map(name => files.pathJoin(relDir, name));
},
// Initialize a package from an application directory (has .meteor/packages).
@@ -1099,7 +1143,7 @@ _.extend(PackageSource.prototype, {
// complete list of source files for directories within node_modules.
_findSourcesCache: Object.create(null),
_findSources: Profile("PackageSource#_findSources", function ({
_findSources: Profile(({ sourceArch }) => `PackageSource#_findSources for ${sourceArch.arch}`, function ({
sourceProcessorSet,
watchSet,
isApp,
@@ -1216,9 +1260,10 @@ _.extend(PackageSource.prototype, {
const baseCacheKey = JSON.stringify({
isApp,
arch,
sourceRoot: self.sourceRoot,
excludes: anyLevelExcludes,
names: sourceReadOptions.names,
include: sourceReadOptions.include
}, (key, value) => {
if (_.isRegExp(value)) {
return [value.source, value.flags];
@@ -1260,13 +1305,13 @@ _.extend(PackageSource.prototype, {
return array;
}
function find(dir, depth, inNodeModules) {
function find(dir, depth, { inNodeModules = false, cache = false } = {}) {
// Remove trailing slash.
dir = dir.replace(/\/$/, "");
// If we're in a node_modules directory, cache the results of the
// find function for the duration of the process.
let cacheKey = inNodeModules && makeCacheKey(dir);
let cacheKey = inNodeModules && cache && makeCacheKey(dir);
if (cacheKey &&
cacheKey in self._findSourcesCache) {
return self._findSourcesCache[cacheKey];
@@ -1305,13 +1350,16 @@ _.extend(PackageSource.prototype, {
}
const sources = _.difference(
self._readAndWatchDirectory(dir, watchSet, readOptions),
self._readAndWatchDirectory(dir, inNodeModules ? null : watchSet, readOptions),
depth > 0 ? [] : controlFiles
);
const subdirectories = self._readAndWatchDirectory(dir, watchSet, {
include: [/\/$/],
exclude: depth > 0
const subdirectories = self._readAndWatchDirectory(
dir,
inNodeModules ? null : watchSet,
{
include: [/\/$/],
exclude: depth > 0
? anyLevelExcludes
: topLevelExcludes
});
@@ -1342,7 +1390,7 @@ _.extend(PackageSource.prototype, {
}
} else {
sources.push(...find(subdir, depth + 1, inNodeModules));
sources.push(...find(subdir, depth + 1, { inNodeModules, cache: !inNodeModules }));
}
});
@@ -1353,7 +1401,7 @@ _.extend(PackageSource.prototype, {
// subdirectories, continue searching this node_modules directory,
// so that any non-.js(on) files it contains can be imported by
// the app (#6037).
sources.push(...find(nodeModulesDir, depth + 1, true));
sources.push(...find(nodeModulesDir, depth + 1, { inNodeModules: true, cache: !inNodeModules}));
}
delete dotMeteorIgnoreFiles[dir];

View File

@@ -9,6 +9,9 @@ import {
createTarGzStream,
getSettings,
mkdtemp,
changeTempDirStatus,
exists,
findGitCommitHash,
} from '../fs/files';
import { request } from '../utils/http-helpers.js';
import buildmessage from '../utils/buildmessage.js';
@@ -469,6 +472,8 @@ async function pollForDeploy(pollingState, versionId, site) {
// - buildOptions: the 'buildOptions' argument to the bundler
// - rawOptions: any unknown options that were passed to the command line tool
// - waitForDeploy: whether to poll Galaxy after upload for deploy status
// - isCacheBuildEnabled: Reuses the build already created if the git commit
// hash is the same
// - deployPollingTimeoutMs: user overridden timeout for polling Galaxy
// for deploy status
export async function bundleAndDeploy(options) {
@@ -517,10 +522,49 @@ export async function bundleAndDeploy(options) {
return 1;
}
var buildDir = mkdtemp('build_tar');
var bundlePath = pathJoin(buildDir, 'bundle');
const projectDir = options.projectContext.getProjectLocalDirectory('');
const gitCommitHash = process.env.METEOR_GIT_COMMIT_HASH || findGitCommitHash(projectDir);
Console.info('Preparing to deploy your app...');
const buildCache = options.projectContext.getBuildCache();
let isCacheBuildValid = options.isCacheBuildEnabled;
if (options.isCacheBuildEnabled) {
if (!buildCache ||
!exists(buildCache.buildDir) ||
!exists(buildCache.bundlePath) ||
!buildCache.gitCommitHash ||
!gitCommitHash ||
buildCache.gitCommitHash !== gitCommitHash) {
Console.warn(`We don't have a valid build cache so a new build will be performed.`);
isCacheBuildValid = false;
}
}
function getBuildDirAndBundlePath() {
if (isCacheBuildValid) {
return buildCache;
}
const buildDir = mkdtemp('build_tar');
if (options.isCacheBuildEnabled) {
changeTempDirStatus(buildDir, false);
Console.info(`The --cache-build was used so the build folder (${buildDir}) will not be deleted on exit...`);
}
const bundlePath = pathJoin(buildDir, 'bundle');
return { buildDir, bundlePath };
}
const {buildDir, bundlePath} = getBuildDirAndBundlePath();
if (options.isCacheBuildEnabled) {
Console.info('Saving build in cache (--cache-build)...');
options.projectContext.saveBuildCache({
buildDir,
bundlePath,
gitCommitHash
});
}
Console.info('Preparing to build your app...');
var settings = null;
var messages = buildmessage.capture({
@@ -533,16 +577,21 @@ export async function bundleAndDeploy(options) {
});
if (! messages.hasMessages()) {
var bundler = require('../isobuild/bundler.js');
var bundleResult = bundler.bundle({
projectContext: options.projectContext,
outputPath: bundlePath,
buildOptions: options.buildOptions,
});
if(isCacheBuildValid) {
Console.info('Skipping build (--cache-build)...');
} else {
const bundler = require('../isobuild/bundler.js');
if (bundleResult.errors) {
messages = bundleResult.errors;
const bundleResult = bundler.bundle({
projectContext: options.projectContext,
outputPath: bundlePath,
buildOptions: options.buildOptions,
});
if (bundleResult.errors) {
messages = bundleResult.errors;
}
}
}
@@ -560,6 +609,7 @@ export async function bundleAndDeploy(options) {
});
}
Console.info('Preparing to upload your app...');
const result = buildmessage.enterJob({
title: "uploading"
}, Profile("upload bundle", function () {
@@ -593,6 +643,7 @@ export async function bundleAndDeploy(options) {
// build / deploy succeed. We indicate that Meteor should poll for version
// status by including a newVersionId in the payload.
if (options.waitForDeploy && result.payload.newVersionId) {
Console.info('Waiting for deployment updates from Galaxy...');
return await pollForDeploymentSuccess(
result.payload.newVersionId,
options.deployPollingTimeoutMs,

View File

@@ -625,6 +625,27 @@ _.extend(ProjectContext.prototype, {
);
},
getBuildCache() {
try {
return JSON.parse(files.readFile(files.pathJoin(
this.projectLocalDir,
"build-cache.json"
)));
} catch (e) {
return null;
}
},
saveBuildCache(buildCache) {
files.writeFileAtomically(
files.pathJoin(
this.projectLocalDir,
"build-cache.json"
),
JSON.stringify(buildCache) + "\n"
);
},
// When running test-packages for an app with local packages, this
// method will return the original app dir, as opposed to the temporary
// testRunnerAppDir created for the tests.

View File

@@ -579,6 +579,10 @@ _.extend(AppRunner.prototype, {
// Permit delayed bundling of client architectures if the
// console is interactive.
allowDelayedClientBuilds: ! Console.isHeadless(),
// None of the targets are used during full rebuilds
// so we can safely build in place on Windows
forceInPlaceBuild: !cachedServerWatchSet
});
});

View File

@@ -938,6 +938,10 @@ _.extend(MRp, {
"Looks like you are out of free disk space under .meteor/local.";
} else if (explanation) {
message += "\n" + explanation.longText;
} else if (process.platform === 'win32') {
message += "\n\n" +
"Check how to troubleshoot here " +
"https://docs.meteor.com/windows.html#cant-start-mongo-server";
}
if (explanation && explanation.symbol === 'EXIT_NET_ERROR') {

View File

@@ -0,0 +1 @@
node_modules/

View File

@@ -0,0 +1 @@
local

View File

@@ -0,0 +1,21 @@
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base # Packages every Meteor app needs to have
mobile-experience # Packages for a great mobile UX
mongo # The database Meteor supports right now
reactive-var # Reactive variable for tracker
standard-minifier-css # CSS minifier run for production mode
standard-minifier-js # JS minifier run for production mode
es5-shim # ECMAScript 5 compatibility for older browsers
ecmascript # Enable ECMAScript2015+ syntax in app code
typescript # Enable TypeScript syntax in .ts and .tsx modules
shell-server # Server-side component of the `meteor shell` command
static-html # Define static page content in .html files
apollo # Basic Apollo integration for Meteor apps
swydo:graphql # Import .graphql files

View File

@@ -0,0 +1,2 @@
server
browser

View File

@@ -0,0 +1,4 @@
body {
padding: 10px;
font-family: sans-serif;
}

View File

@@ -0,0 +1,7 @@
<head>
<title>Apollo Skeleton</title>
</head>
<body>
<div id="react-target"></div>
</body>

View File

@@ -0,0 +1,8 @@
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { App } from '/imports/ui/App';
Meteor.startup(() => {
render(<App/>, document.getElementById('react-target'));
});

View File

@@ -0,0 +1,3 @@
import { Mongo } from 'meteor/mongo';
export const LinksCollection = new Mongo.Collection('links');

View File

@@ -0,0 +1,10 @@
type Link {
_id: ID!
title: String
url: String
}
type Query {
getLink (id: ID!): Link
getLinks: [Link]
}

View File

@@ -0,0 +1,27 @@
import React from 'react';
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client';
import { Hello } from './Hello.jsx';
import { Info } from './Info.jsx';
const client = new ApolloClient({
uri: '/graphql',
cache: new InMemoryCache(),
/* Uncomment this for accounts use
request: operation =>
operation.setContext(() => ({
headers: {
authorization: Accounts._storedLoginToken()
}
}))
*/
});
export const App = () => (
<ApolloProvider client={client}>
<div>
<h1>Welcome to Meteor! </h1>
<Hello/>
<Info/>
</div>
</ApolloProvider>
);

View File

@@ -0,0 +1,16 @@
import React, { useState } from 'react';
export const Hello = () => {
const [counter, setCounter] = useState(0);
const increment = () => {
setCounter(counter + 1);
};
return (
<div>
<button onClick={increment}>Click Me</button>
<p>You've pressed the button {counter} times.</p>
</div>
);
};

View File

@@ -0,0 +1,31 @@
import React from 'react';
import { useQuery } from '@apollo/client';
import { gql } from 'apollo-boost';
const GET_LINKS = gql`
{
links: getLinks {
_id
title
url
}
}
`;
export const Info = () => {
const { loading, error, data } = useQuery(GET_LINKS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error </p>;
return (
<div>
<h2>Learn Meteor!</h2>
<ul>{data?.links?.map(
link => <li key={link._id}>
<a href={link.url} target="_blank">{link.title}</a>
</li>
)}</ul>
</div>
);
};

View File

@@ -0,0 +1,27 @@
{
"name": "~name~",
"private": true,
"scripts": {
"start": "meteor run",
"test": "meteor test --once --driver-package meteortesting:mocha",
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@apollo/client": "^3.1.1",
"@babel/runtime": "^7.10.5",
"apollo-boost": "^0.4.9",
"apollo-server-express": "^2.16.1",
"graphql": "^15.3.0",
"meteor-node-stubs": "^1.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"meteor": {
"mainModule": {
"client": "client/main.jsx",
"server": "server/main.js"
},
"testModule": "tests/main.js"
}
}

View File

@@ -0,0 +1,31 @@
import { ApolloServer } from 'apollo-server-express';
import { WebApp } from 'meteor/webapp';
import { getUser } from 'meteor/apollo';
import { LinksCollection } from '/imports/api/links';
import typeDefs from '/imports/apollo/schema.graphql';
const resolvers = {
Query: {
getLink: (obj, { id }) => LinksCollection.findOne(id),
getLinks: () => LinksCollection.find().fetch()
}
};
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => ({
user: await getUser(req.headers.authorization)
})
});
server.applyMiddleware({
app: WebApp.connectHandlers,
path: '/graphql'
});
WebApp.connectHandlers.use('/graphql', (req, res) => {
if (req.method === 'GET') {
res.end();
}
});

View File

@@ -0,0 +1,32 @@
import { Meteor } from 'meteor/meteor';
import { LinksCollection } from '/imports/api/links';
import './apollo'
function insertLink({ title, url }) {
LinksCollection.insert({title, url, createdAt: new Date()});
}
Meteor.startup(() => {
// If the Links collection is empty, add some data.
if (LinksCollection.find().count() === 0) {
insertLink({
title: 'Do the Tutorial',
url: 'https://www.meteor.com/tutorials/react/creating-an-app'
});
insertLink({
title: 'Follow the Guide',
url: 'http://guide.meteor.com'
});
insertLink({
title: 'Read the Docs',
url: 'https://docs.meteor.com'
});
insertLink({
title: 'Discussions',
url: 'https://forums.meteor.com'
});
}
});

View File

@@ -0,0 +1,20 @@
import assert from "assert";
describe("~name~", function () {
it("package.json has correct name", async function () {
const { name } = await import("../package.json");
assert.strictEqual(name, "~name~");
});
if (Meteor.isClient) {
it("client is not server", function () {
assert.strictEqual(Meteor.isServer, false);
});
}
if (Meteor.isServer) {
it("server is not client", function () {
assert.strictEqual(Meteor.isClient, false);
});
}
});

View File

@@ -5,7 +5,7 @@
"start": "meteor run"
},
"dependencies": {
"@babel/runtime": "^7.8.3",
"meteor-node-stubs": "^1.0.0"
"@babel/runtime": "^7.10.5",
"meteor-node-stubs": "^1.0.1"
}
}

View File

@@ -6,11 +6,11 @@
"test": "meteor test --once --driver-package meteortesting:mocha"
},
"dependencies": {
"@babel/runtime": "^7.8.3",
"jquery": "^3.4.1",
"meteor-node-stubs": "^1.0.0"
"@babel/runtime": "^7.10.5",
"jquery": "^3.5.1",
"meteor-node-stubs": "^1.0.1"
},
"devDependencies": {
"chai": "^4.1.2"
"chai": "^4.2.0"
}
}

View File

@@ -8,8 +8,8 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "^7.8.3",
"meteor-node-stubs": "^1.0.0"
"@babel/runtime": "^7.10.5",
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

View File

@@ -8,10 +8,10 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "^7.8.4",
"meteor-node-stubs": "^1.0.0",
"react": "^16.13.0",
"react-dom": "^16.13.0"
"@babel/runtime": "^7.10.5",
"meteor-node-stubs": "^1.0.1",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"meteor": {
"mainModule": {

View File

@@ -8,17 +8,17 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "^7.8.4",
"meteor-node-stubs": "^1.0.0",
"react": "^16.13.0",
"react-dom": "^16.13.0"
"@babel/runtime": "^7.10.5",
"meteor-node-stubs": "^1.0.1",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"@types/meteor": "^1.4.40",
"@types/mocha": "^5.2.7",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
"typescript": "^3.8.2"
"@types/meteor": "^1.4.48",
"@types/mocha": "^8.0.0",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"typescript": "^3.9.7"
},
"meteor": {
"mainModule": {

View File

@@ -0,0 +1 @@
node_modules/

View File

@@ -0,0 +1 @@
local

View File

@@ -0,0 +1,24 @@
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base # Packages every Meteor app needs to have
mobile-experience # Packages for a great mobile UX
mongo # The database Meteor supports right now
reactive-var # Reactive variable for tracker
standard-minifier-css # CSS minifier run for production mode
standard-minifier-js # JS minifier run for production mode
es5-shim # ECMAScript 5 compatibility for older browsers
ecmascript # Enable ECMAScript2015+ syntax in app code
typescript # Enable TypeScript syntax in .ts and .tsx modules
shell-server # Server-side component of the `meteor shell` command
tracker # Dependency tracker to allow reactive callbacks
static-html # Define static page content in .html files
akryum:vue-component # Vue-CLI template to publish components
meteortesting:mocha # A package for writing and running your meteor app and package tests with mocha
johanbrook:publication-collector # Test a Meteor publication by collecting its output

View File

@@ -0,0 +1,2 @@
server
browser

View File

@@ -0,0 +1,23 @@
{
"name": "skel",
"private": true,
"scripts": {
"start": "meteor run",
"test": "meteor test --once --driver-package meteortesting:mocha",
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "^7.10.5",
"meteor-node-stubs": "^1.0.1",
"vue": "^2.6.11",
"vue-meteor-tracker": "^2.0.0-beta.5"
},
"meteor": {
"mainModule": {
"client": "src/client.js",
"server": "src/server.js"
},
"testModule": "tests/main.js"
}
}

View File

@@ -0,0 +1,26 @@
<template>
<div>
<h1>Welcome to Meteor!</h1>
<hello/>
<info/>
</div>
</template>
<script>
import Hello from './components/Hello.vue'
import Info from './components/Info.vue'
export default {
components: {
Hello,
Info,
},
}
</script>
<style>
body {
font-family: sans-serif;
padding: 10px;
}
</style>

View File

@@ -0,0 +1,12 @@
import Vue from 'vue'
import './plugins'
import App from './App.vue'
Meteor.startup(() => {
new Vue({
el: '#app',
...App,
})
})

View File

@@ -0,0 +1,3 @@
import { Mongo } from 'meteor/mongo';
export default new Mongo.Collection('links');

View File

@@ -0,0 +1,24 @@
// Tests for the behavior of the links collection
//
// https://guide.meteor.com/testing.html
import { Meteor } from 'meteor/meteor';
import { assert } from 'chai';
import Links from './links.js';
if (Meteor.isServer) {
describe('links collection', function () {
it('insert correctly', function () {
const linkId = Links.insert({
title: 'meteor homepage',
url: 'https://www.meteor.com',
});
const added = Links.find({ _id: linkId });
const collectionName = added._getCollectionName();
const count = added.count();
assert.equal(collectionName, 'links');
assert.equal(count, 1);
});
});
}

View File

@@ -0,0 +1,27 @@
<template>
<div>
<button @click="increment">Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
}
},
methods: {
increment() {
this.counter += 1
}
},
}
</script>
<style scoped>
p {
font-family: serif;
}
</style>

View File

@@ -0,0 +1,55 @@
<template>
<div>
<h2>Learn Meteor!</h2>
<ul>
<li>
<form class="info-link-add">
<input type="text" v-model="title" name="title" placeholder="Title" required>
<input type="url" v-model="url" name="url" placeholder="Url" required>
<input type="submit" name="submit" @click="submit($event)" value="Add new link">
</form>
</li>
<li v-for="link in links"><a :href="link.url" target="_blank">{{link.title}}</a></li>
</ul>
</div>
</template>
<script>
import Links from '../collections/Links'
export default {
data() {
return {
title: "",
url: "",
}
},
meteor: {
$subscribe: {
'links': [],
},
links () {
return Links.find({})
},
},
methods: {
submit(event) {
event.preventDefault()
Meteor.call('createLink', this.title, this.url, (error) => {
if (error) {
alert(error.error)
} else {
this.title = ''
this.url = ''
}
})
}
},
}
</script>
<style scoped>
ul {
font-family: monospace;
}
</style>

View File

@@ -0,0 +1,32 @@
import { Meteor } from 'meteor/meteor';
import Links from './collections/Links.js';
Meteor.startup(() => {
// if the Links collection is empty
if (Links.find().count() === 0) {
const data = [
{
title: 'Do the Tutorial',
url: 'https://www.meteor.com/try',
createdAt: new Date(),
},
{
title: 'Follow the Guide',
url: 'http://guide.meteor.com',
createdAt: new Date(),
},
{
title: 'Read the Docs',
url: 'https://docs.meteor.com',
createdAt: new Date(),
},
{
title: 'Discussions',
url: 'https://forums.meteor.com',
createdAt: new Date(),
},
];
data.forEach(link => Links.insert(link));
}
});

View File

@@ -0,0 +1,7 @@
<head>
<title>~name~</title>
</head>
<body>
<div id="app"></div>
</body>

View File

@@ -0,0 +1,16 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import Links from '../collections/Links.js';
Meteor.methods({
'createLink'(title, url) {
check(url, String);
check(title, String);
return Links.insert({
url,
title,
createdAt: new Date(),
});
},
});

View File

@@ -0,0 +1,20 @@
import { Meteor } from 'meteor/meteor';
import { assert } from 'chai';
import Links from '../collections/Links.js';
import './methods.js';
if (Meteor.isServer) {
describe('method: createLink', function () {
beforeEach(function () {
Links.remove({});
});
it('can add a new link', function () {
const addLink = Meteor.server.method_handlers['createLink'];
addLink.apply({}, ['meteor.com', 'https://www.meteor.com']);
assert.equal(Links.find().count(), 1);
});
});
}

View File

@@ -0,0 +1 @@
import './createLink'

View File

@@ -0,0 +1,4 @@
import Vue from 'vue'
import VueMeteorTracker from 'vue-meteor-tracker'
Vue.use(VueMeteorTracker)

View File

@@ -0,0 +1 @@
import './links'

View File

@@ -0,0 +1,6 @@
import { Meteor } from 'meteor/meteor';
import Links from '../collections/Links.js';
Meteor.publish('links', function () {
return Links.find();
});

View File

@@ -0,0 +1,22 @@
import { assert } from 'chai'
import { PublicationCollector } from 'meteor/johanbrook:publication-collector'
import Links from '../collections/Links.js'
import './publications.js'
describe('Publish links', function () {
beforeEach(function () {
Links.remove({})
Links.insert({
title: 'meteor homepage',
url: 'https://www.meteor.com'
})
})
it('sends all links', function (done) {
const collector = new PublicationCollector()
collector.collect('links', (collections) => {
assert.equal(collections.links.length, 1)
done()
})
})
})

View File

@@ -0,0 +1,3 @@
import './fixtures'
import './methods'
import './publications'

View File

@@ -0,0 +1,20 @@
import assert from "assert";
describe("skel", function () {
it("package.json has correct name", async function () {
const { name } = await import("../package.json");
assert.strictEqual(name, "skel");
});
if (Meteor.isClient) {
it("client is not server", function () {
assert.strictEqual(Meteor.isServer, false);
});
}
if (Meteor.isServer) {
it("server is not client", function () {
assert.strictEqual(Meteor.isClient, false);
});
}
});

View File

@@ -8,9 +8,9 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "^7.8.3",
"jquery": "^3.4.1",
"meteor-node-stubs": "^1.0.0"
"@babel/runtime": "^7.10.4",
"jquery": "^3.5.1",
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

View File

@@ -6,7 +6,7 @@
},
"dependencies": {
"@babel/runtime": "^7.5.0",
"meteor-node-stubs": "^1.0.0",
"meteor-node-stubs": "^1.0.1",
"puppeteer": "^1.6.2"
},
"meteor": {

View File

@@ -3,7 +3,7 @@
"private": true,
"dependencies": {
"@babel/runtime": "^7.5.0",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.7.4",
"jquery": "^3.4.1",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": "code.js"

View File

@@ -8,6 +8,6 @@
},
"dependencies": {
"@babel/runtime": "^7.5.0",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
}
}

View File

@@ -10,7 +10,7 @@
"acorn": "^7.1.1",
"arson": "^0.2.6",
"jquery": "^3.4.1",
"meteor-node-stubs": "^1.0.0",
"meteor-node-stubs": "^1.0.1",
"moment": "^2.24.0",
"optimism": "^0.11.5",
"private": "^0.1.8",

View File

@@ -7,7 +7,7 @@
},
"dependencies": {
"@babel/runtime": "^7.5.0",
"meteor-node-stubs": "^1.0.0",
"meteor-node-stubs": "^1.0.1",
"puppeteer": "^1.6.2"
},
"meteor": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.5.0",
"config": "file:../config-package",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.5.0",
"external-package": "file:../external-package",
"meteor-node-stubs": "^1.0.0"
"meteor-node-stubs": "^1.0.1"
},
"meteor": {
"mainModule": {

Some files were not shown because too many files have changed in this diff Show More