mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'release-2.6.1' into feature/github-return-data
This commit is contained in:
@@ -58,6 +58,7 @@ sidebar_categories:
|
||||
Packages:
|
||||
- packages/accounts-ui
|
||||
- packages/accounts-passwordless
|
||||
- packages/accounts-2fa
|
||||
- packages/appcache
|
||||
- packages/audit-argument-checks
|
||||
- packages/autoupdate
|
||||
|
||||
@@ -1,13 +1,60 @@
|
||||
## vNEXT, UNRELEASED
|
||||
## v2.6.1, UNRELEASED
|
||||
|
||||
#### Highlights
|
||||
* TailwindCSS 3.x support
|
||||
* Typescript `4.5.4` upgrade
|
||||
* New core package: `accounts-2fa`
|
||||
* Support for 2FA in `accounts-password` and `accounts-passwordless`
|
||||
* Postcss configurations are now handled by `standard-minifier-css`
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
N/A
|
||||
|
||||
#### Migration Steps
|
||||
|
||||
Read our [Migration Guide](https://guide.meteor.com/2.6.1-migration.html) for this version.
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `standard-minifier-css@1.8.0`
|
||||
- Postcss configurations are now handled in this package
|
||||
- TailwindCSS 3.x support
|
||||
- Support postcss dependency messages. [PR](https://github.com/meteor/meteor/pull/11903)
|
||||
|
||||
* `accounts-2fa@1.0.0`
|
||||
- New package to provide 2FA support
|
||||
|
||||
* `accounts-password@2.3.0`
|
||||
- 2FA support
|
||||
|
||||
* `accounts-passwordless@2.1.0`
|
||||
- 2FA support
|
||||
|
||||
* `@meteorjs/babel@7.16.0`
|
||||
- Upgrade TypeScript to `4.5.4`
|
||||
|
||||
* `babel-compiler@7.9.0`
|
||||
- Upgrade TypeScript to `4.5.4`
|
||||
|
||||
* `ecmascript@0.16.2`
|
||||
- Upgrade TypeScript to `4.5.4`
|
||||
|
||||
* `typescript@4.5.4`
|
||||
- Upgrade TypeScript to `4.5.4` [PR](https://github.com/meteor/meteor/pull/11846)
|
||||
|
||||
* `accounts-ui-unstyled@1.6.0`
|
||||
- `Accounts.ui.config` can now be set via `Meteor.settings.public.packages.accounts-ui-unstyled`.
|
||||
|
||||
* `meteor-tool@2.6.1`
|
||||
- Have build plugins handle caching for css minifiers. [PR](https://github.com/meteor/meteor/pull/11882).
|
||||
|
||||
* `standard-minifier-css@1.8.0`
|
||||
- Cache minified stylesheets. [PR](https://github.com/meteor/meteor/pull/11882).
|
||||
|
||||
* `ejson@1.1.2`
|
||||
- Fixing error were EJSON.equals fail to compare object and array if first param is object and second is array. [PR](https://github.com/meteor/meteor/pull/11866), [Issue](https://github.com/meteor/meteor/issues/11864).
|
||||
|
||||
#### Independent Releases
|
||||
|
||||
* `mongo@1.14.3` at 2022-02-08
|
||||
@@ -17,6 +64,9 @@
|
||||
* `mongo@1.14.1` at 2022-02-04
|
||||
- Fix flatten object issue when the object is empty on oplog converter. [PR](https://github.com/meteor/meteor/pull/11885), [Issue](https://github.com/meteor/meteor/issues/11884).
|
||||
|
||||
* `email@2.2.1`
|
||||
- Modernizes the code.
|
||||
|
||||
## v2.6, 2022-02-01
|
||||
|
||||
#### Highlights
|
||||
|
||||
@@ -242,7 +242,7 @@ ServiceConfiguration.configurations.upsert(
|
||||
);
|
||||
```
|
||||
|
||||
Since Meteor 2.5 you no longer need to manually set the configuration and instead can use Meteor settings by setting your services under `Meteor.settings.packages.service-configuration.<service>`. All the properties can be set under the service and will be added to the database as is, so make sure that they are correct. For the example above, the settings would look like:
|
||||
Since Meteor 2.6.1 you no longer need to manually set the configuration and instead can use Meteor settings by setting your services under `Meteor.settings.packages.service-configuration.<service>`. All the properties can be set under the service and will be added to the database as is, so make sure that they are correct. For the example above, the settings would look like:
|
||||
```json
|
||||
{
|
||||
"packages": {
|
||||
@@ -334,3 +334,6 @@ Accounts.ui.config({
|
||||
passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL'
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
Since Meteor 2.6.1 you can configure these in your Meteor settings under `Meteor.settings.public.packages.accounts-ui-unstyled`.
|
||||
|
||||
@@ -183,3 +183,7 @@ Accounts.emailTemplates.verifyEmail = {
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
<h3 id="enabling-2fa">Enable 2FA for this package</h3>
|
||||
|
||||
You can add 2FA to your login flow by using the package [accounts-2fa](https://docs.meteor.com/packages/accounts-2fa.html). You can find an example showing how this would look like [here](https://docs.meteor.com/packages/accounts-2fa.html#working-with-accounts-password).
|
||||
|
||||
@@ -38,6 +38,16 @@ If you only use sudo because of a distribution default permission system, [check
|
||||
|
||||
In some cases you can get this error `npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules` because your Node.js installation was performed with wrong permissions. An easy way to fix this is to install Node.js using [nvm](https://github.com/nvm-sh/nvm) and forcing it to be used in your terminal. You can force it in the current session of your terminal by running `nvm use 14`.
|
||||
|
||||
<h2 id="path-management">PATH management</h2>
|
||||
|
||||
By default, the Meteor installer adds its install path (by default, `~/.meteor/`) to your PATH by updating either your `.bashrc`, `.bash_profile`, or `.zshrc` as appropriate. To disable this behavior, install Meteor by running:
|
||||
|
||||
```bash
|
||||
npm install -g meteor --ignore-meteor-setup-exec-path
|
||||
```
|
||||
|
||||
(or by setting the environment variable `npm_config_ignore_meteor_setup_exec_path=true`)
|
||||
|
||||
<h2 id="old-versions-m1">Old Versions on Apple M1</h2>
|
||||
|
||||
For Apple M1 computers, you can append Rosetta prefix as following, if you need to run older versions of Meteor (before 2.5.1):
|
||||
|
||||
241
docs/source/packages/accounts-2fa.md
Normal file
241
docs/source/packages/accounts-2fa.md
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
title: accounts-2fa
|
||||
description: Documentation of Meteor's `accounts-2fa` package.
|
||||
---
|
||||
|
||||
This package allows you to provide a way for your users to enable 2FA on their accounts, using an authenticator app such as Google Authenticator, or 1Password. When the user is logged in on your app, they will be able to generate a new QR code and read this code on the app they prefer. After that, they'll start receiving their codes. Then, they can finish enabling 2FA on your app, and every time they try to log in to your app, you can redirect them to a place where they can provide a code they received from the authenticator.
|
||||
|
||||
This package uses [node-2fa](https://www.npmjs.com/package/node-2fa) which works on top of [notp](https://github.com/guyht/notp), **that** implements TOTP ([RFC 6238](https://www.ietf.org/rfc/rfc6238.txt)) (the Authenticator standard), which is based on HOTP ([RFC 4226](https://www.ietf.org/rfc/rfc4226.txt)) to provide codes that are exactly compatible with all other Authenticator apps and services that use them.
|
||||
|
||||
> This package is meant to be used with [`accounts-password`](https://docs.meteor.com/api/passwords.html) or [`accounts-passwordless`](https://docs.meteor.com/packages/accounts-passwordless.html), so if you don't have either of those in your project, you'll need to add one of them. In the future, we want to enable the use of this package with other login methods, our oauth methods (Google, GitHub, etc...).
|
||||
|
||||
<h2 id="activating-2fa">Activating 2FA</h2>
|
||||
|
||||
The first step, in order to enable 2FA, is to generate a QR code so that the user can scan it in an authenticator app and start receiving codes.
|
||||
|
||||
{% apibox "Accounts.generate2faActivationQrCode" "module":"accounts-base" %}
|
||||
|
||||
Receives an `appName` which is the name of your app that will show up when the user scans the QR code. Also, a callback called with a QR code in SVG format on success or a single `Error` argument
|
||||
on failure.
|
||||
|
||||
On success, this function will also add an object to the logged user's services object containing the QR secret:
|
||||
|
||||
```js
|
||||
services: {
|
||||
...
|
||||
twoFactorAuthentication: {
|
||||
secret: "***"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here it's an example on how to call this function:
|
||||
|
||||
```js
|
||||
import { Buffer } from "buffer";
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
|
||||
--
|
||||
|
||||
const [qrCode, setQrCode] = useState(null);
|
||||
|
||||
--
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
Accounts.generate2faActivationQrCode("My app name", (err, svg) => {
|
||||
if (err) {console.error("...", err);return;}
|
||||
/*
|
||||
the svg can be converted to base64, then be used like:
|
||||
<img
|
||||
width="200"
|
||||
src={`data:image/svg+xml;base64,${qrCode}`}
|
||||
/>
|
||||
*/
|
||||
setQrCode(Buffer.from(svg).toString('base64'));
|
||||
})
|
||||
}}
|
||||
>
|
||||
Generate a new code
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
At this point, the 2FA won't be activated just yet. Now that the user has access to the codes generated by their authenticator app, you can call the function `Accounts.enableUser2fa`:
|
||||
|
||||
{% apibox "Accounts.enableUser2fa" "module":"accounts-base" %}
|
||||
|
||||
It should be called with a code that the users will receive from the authenticator app once they read the QR code. The callback is called with a single `Error` argument on failure. If the code provided is correct, a `type` will be added to the user's `twoFactorAuthentication` object and now 2FA is considered enabled:
|
||||
|
||||
```js
|
||||
services: {
|
||||
...
|
||||
twoFactorAuthentication: {
|
||||
type: "otp",
|
||||
secret: "***",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<h2 id="disabling-2fa">Disabling 2FA</h2>
|
||||
|
||||
To disable 2FA for a user use this method:
|
||||
|
||||
{% apibox "Accounts.disableUser2fa" "module":"accounts-base" %}
|
||||
|
||||
To call this function the user must be already logged in.
|
||||
|
||||
<h2 id="log-in-with-2fa">Log in with 2FA</h2>
|
||||
|
||||
Now that you have a way to allow your users to enable 2FA on their accounts, you can create a login flow based on that.
|
||||
|
||||
To verify whether or not a user has 2FA enabled, you can call the function `Accounts.has2faEnabled`:
|
||||
|
||||
{% apibox "Accounts.has2faEnabled" "module":"accounts-base" %}
|
||||
|
||||
As said at the beginning of this guide, this package is currently working with two other packages: `accounts-password` and `accounts-passwordless`. Below there is an explanation on how to use this package with them.
|
||||
|
||||
<h3 id="working-with-accounts-password">Working with accounts-password</h3>
|
||||
|
||||
With the function `Accounts.has2faEnabled`, you can check whether or not the user has 2FA enabled, and based on this information, you can directly call `Meteor.loginWithPassword` if the 2FA is not enabled, or redirect the user to a place where they can provide a code, in case they do have 2FA enabled.
|
||||
|
||||
A way of using it would be:
|
||||
|
||||
```js
|
||||
<button
|
||||
onClick={() => {
|
||||
Accounts.has2faEnabled(username, (err, isEnabled) => {
|
||||
if (err) {
|
||||
console.error("Error verifying if user has 2fa enabled", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEnabled) {
|
||||
// send user to a page or show a component
|
||||
// where they can provide a 2FA code
|
||||
setShouldAskCode(true);
|
||||
return;
|
||||
}
|
||||
// Normal login when they don't have 2FA enabled.
|
||||
Meteor.loginWithPassword(username, password, error => {
|
||||
if (error) {
|
||||
console.error("Error trying to log in (user without 2fa)", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}>
|
||||
Login
|
||||
</button>
|
||||
```
|
||||
|
||||
If the user has 2FA enabled, and you try to use the function `Meteor.loginWithPassword`, the login will fail, as the user should provide a code to access the app.
|
||||
|
||||
The function you will need to call now to allow the user to login is `Meteor.loginWithPasswordAnd2faCode`:
|
||||
|
||||
{% apibox "Meteor.loginWithPasswordAnd2faCode" %}
|
||||
|
||||
Now you will be able to receive a code from the user and this function will verify if the code is valid. If it is, the user will be logged in.
|
||||
|
||||
So the call of this function should look something like this:
|
||||
|
||||
```js
|
||||
<button onClick={() => {
|
||||
Meteor.loginWithPasswordAnd2faCode(username, password, code,error => {
|
||||
if (error) {
|
||||
console.error("Error trying to log in (user with 2fa)", error);
|
||||
}
|
||||
})}
|
||||
}>
|
||||
Validate and log in
|
||||
</button>
|
||||
```
|
||||
|
||||
<h3 id="working-with-accounts-passwordless">Working with accounts-passwordless</h3>
|
||||
|
||||
Following the same strategy from the previous package, you can use the function `Accounts.has2faEnabled` to verify whether or not the user has 2FA enabled. If yes, you send them their token and on next step you receive their token and their 2FA code, otherwise, you still send them their token but on the next step you don't ask them for a 2FA code.
|
||||
|
||||
Here it's an example:
|
||||
|
||||
```js
|
||||
Accounts.has2faEnabled(username, (err, isEnabled) => {
|
||||
if (err) {console.error("...", err);return;}
|
||||
|
||||
Accounts.requestLoginTokenForUser({selector: "email@example.com"}, e => {
|
||||
if (e) {console.error("...", e);return;}
|
||||
|
||||
if (isEnabled) {
|
||||
setShouldAskTokenAndCode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setShouldAskToken(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Now you can either call the standard method [`Meteor.passwordlessLoginWithToken`](https://docs.meteor.com/packages/accounts-passwordless.html#Meteor-passwordlessLoginWithToken) if they don't have 2FA enabled, or in case they do, you call the method `Meteor.passwordlessLoginWithTokenAnd2faCode` that will allow you to provide a selector, token, and 2FA code:
|
||||
|
||||
{% apibox "Meteor.passwordlessLoginWithTokenAnd2faCode" %}
|
||||
|
||||
So, using this strategy your code should look something like this:
|
||||
|
||||
```js
|
||||
<button
|
||||
onClick={() => {
|
||||
// logging in with token and code
|
||||
if (shouldAskTokenAndCode) {
|
||||
Meteor.passwordlessLoginWithTokenAnd2faCode(
|
||||
email,
|
||||
token,
|
||||
code,
|
||||
error => {
|
||||
if (error) {console.error('...', error);}
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// logging in just with token
|
||||
Meteor.passwordlessLoginWithToken(
|
||||
email,
|
||||
token,
|
||||
error => {
|
||||
if (error) {console.error('...', error);}
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
Validate and Log in
|
||||
</button>;
|
||||
```
|
||||
|
||||
<h2 id="integrating-auth-package">How to integrate an Authentication Package with accounts-2fa</h2>
|
||||
|
||||
To integrate this package with any other existing Login method, it's necessary following two steps:
|
||||
|
||||
1 - For the client, create a new method from your current login method. So for example, from the method `Meteor.loginWithPassword` we created a new one called `Meteor.loginWithPasswordAnd2faCode`, and the only difference between them is that the latest one receives one additional parameter, the 2FA code, but we call the same function on the server side.
|
||||
|
||||
2 - For the server, inside the function that will log the user in, you verify if the function `Accounts._is2faEnabledForUser` exists, and if yes, you call it providing the user you want to check if the 2FA is enabled, and if either of these statements are false, you proceed with the login flow. This function exists only when the package `accounts-2fa` is added to the project.
|
||||
|
||||
If both statements are true, now you verify if a code was provided, if not throw an error, if it was provided, verify if the code is valid by calling the function `Accounts._isTokenValid`, if not, throw an error.
|
||||
|
||||
Here it's an example:
|
||||
|
||||
```js
|
||||
if (
|
||||
Accounts._is2faEnabledForUser &&
|
||||
Accounts._is2faEnabledForUser(user)
|
||||
) {
|
||||
if (!code) {
|
||||
Accounts._handleError('2FA code must be informed.');
|
||||
}
|
||||
if (
|
||||
!Accounts._isTokenValid(user.services.twoFactorAuthentication.secret, code)
|
||||
) {
|
||||
Accounts._handleError('Invalid 2FA code.');
|
||||
}
|
||||
}
|
||||
|
||||
// continue the login flow
|
||||
```
|
||||
|
||||
@@ -25,3 +25,7 @@ sendLoginToken: {
|
||||
text: (user, url, { sequence }) => { /* text template */ }
|
||||
}
|
||||
```
|
||||
|
||||
<h3 id="enabling-2fa">Enable 2FA for this package</h3>
|
||||
|
||||
You can add 2FA to your login flow by using the package [accounts-2fa](https://docs.meteor.com/packages/accounts-2fa.html). You can find an example showing how this would look like [here](https://docs.meteor.com/packages/accounts-2fa.html#working-with-accounts-passwordless).
|
||||
|
||||
@@ -35,7 +35,7 @@ sidebar_categories:
|
||||
- index
|
||||
- code-style
|
||||
- structure
|
||||
- 2.6-migration
|
||||
- 2.6.1-migration
|
||||
Data:
|
||||
- collections
|
||||
- data-loading
|
||||
|
||||
55
guide/source/2.6.1-migration.md
Normal file
55
guide/source/2.6.1-migration.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: Migrating to Meteor 2.6.1
|
||||
description: How to migrate your application to Meteor 2.6.1.
|
||||
---
|
||||
|
||||
Meteor 2.6.1 introduce the new `accounts-2fa` package and also support to TailwindCSS 3.x incorporating `postcss` minifier code to core in the `standard-minifier-css`. For a complete breakdown of the changes, please refer to the [changelog](http://docs.meteor.com/changelog.html).
|
||||
|
||||
The above being said, there are a few items that you should do to have the latest CSS minifier in your project.
|
||||
|
||||
<h3 id="new-css-minifier">CSS Minifier with PostCSS</h3>
|
||||
|
||||
If you are using `juliancwirko:postcss` as your PostCSS CSS Minifier and you want to use the latest Minifier for PostCSS you should use the core package: `standard-minifier-css` instead. Starting from this version of Meteor (and 1.8.0 of `standard-minifier-css`) it supports the latest PostCSS features as well.
|
||||
|
||||
If you want to use TailwindCSS 3.x you must use the `standard-minifier-css` core package to insure Tailwind JIT working properly.
|
||||
|
||||
Steps to replace the package:
|
||||
- `meteor remove juliancwirko:postcss`
|
||||
- `meteor add standard-minifier-css`
|
||||
|
||||
After replacing the package with the commands above TailwindCSS 3.x should work fine with Meteor 2.6.1.
|
||||
|
||||
Please read the [Tailwind Official migration guide](https://tailwindcss.com/docs/upgrade-guide) to make sure you had applied the changes required by TailwindCSS itself.
|
||||
|
||||
> Note: In beta.1 of Meteor 2.6.1 we had added a new core package `minifier-css-postcss` but later in this discussion we decided to unify everything inside `standard-minifier-css`. So you shouldn't use `minifier-css-postcss`.
|
||||
|
||||
<h3 id="2fa">Accounts 2FA</h3>
|
||||
|
||||
`accounts-2fa` is a new package that enables two-factor authentication for `accounts-password` and `accounts-passwordless`.
|
||||
|
||||
There are no required changes to your application in any case, but if you want to provide 2FA for your users, and you are already using `accounts-password` or `accounts-passwordless` you can start using the new functions provided from 2FA package, read more in the [docs](https://docs.meteor.com/packages/accounts-2fa.html).
|
||||
|
||||
<h2 id="older-versions">Migrating from a version older than 2.6?</h2>
|
||||
|
||||
If you're migrating from a version of Meteor older than Meteor 2.6, there may be important considerations not listed in this guide (which specifically covers 2.6 to 2.6.1). Please review the older migration guides for details:
|
||||
|
||||
* [Migrating to Meteor 2.6](2.6-migration.html) (from 2.5)
|
||||
* [Migrating to Meteor 2.5](2.5-migration.html) (from 2.4)
|
||||
* [Migrating to Meteor 2.4](2.4-migration.html) (from 2.3)
|
||||
* [Migrating to Meteor 2.3](2.3-migration.html) (from 2.2)
|
||||
* [Migrating to Meteor 2.2](2.2-migration.html) (from 2.0)
|
||||
* [Migrating to Meteor 2.0](2.0-migration.html) (from 1.12)
|
||||
* [Migrating to Meteor 1.12](1.12-migration.html) (from 1.11)
|
||||
* [Migrating to Meteor 1.11](1.11-migration.html) (from 1.10.2)
|
||||
* [Migrating to Meteor 1.10.2](1.10.2-migration.html) (from 1.10)
|
||||
* [Migrating to Meteor 1.10](1.10-migration.html) (from 1.9.3)
|
||||
* [Migrating to Meteor 1.9.3](1.9.3-migration.html) (from 1.9)
|
||||
* [Migrating to Meteor 1.9](1.9-migration.html) (from 1.8.3)
|
||||
* [Migrating to Meteor 1.8.3](1.8.3-migration.html) (from 1.8.2)
|
||||
* [Migrating to Meteor 1.8.2](1.8.2-migration.html) (from 1.8)
|
||||
* [Migrating to Meteor 1.8](1.8-migration.html) (from 1.7)
|
||||
* [Migrating to Meteor 1.7](1.7-migration.html) (from 1.6)
|
||||
* [Migrating to Meteor 1.6](1.6-migration.html) (from 1.5)
|
||||
* [Migrating to Meteor 1.5](1.5-migration.html) (from 1.4)
|
||||
* [Migrating to Meteor 1.4](1.4-migration.html) (from 1.3)
|
||||
* [Migrating to Meteor 1.3](1.3-migration.html) (from 1.2)
|
||||
2
meteor
2
meteor
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUNDLE_VERSION=14.18.3.4
|
||||
BUNDLE_VERSION=14.19.0.0
|
||||
|
||||
# OS Check. Put here because here is where we download the precompiled
|
||||
# bundles that are arch specific.
|
||||
|
||||
@@ -14,8 +14,8 @@ var packageJson = {
|
||||
pacote: "https://github.com/meteor/pacote/tarball/a81b0324686e85d22c7688c47629d4009000e8b8",
|
||||
"node-gyp": "8.0.0",
|
||||
"node-pre-gyp": "0.15.0",
|
||||
typescript: "4.3.5",
|
||||
"@meteorjs/babel": "7.15.0",
|
||||
typescript: "4.5.4",
|
||||
"@meteorjs/babel": "7.16.0-beta.0",
|
||||
// Keep the versions of these packages consistent with the versions
|
||||
// found in dev-bundle-server-package.js.
|
||||
"meteor-promise": "0.9.0",
|
||||
|
||||
8
npm-packages/meteor-babel/package-lock.json
generated
8
npm-packages/meteor-babel/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@meteorjs/babel",
|
||||
"version": "7.15.0",
|
||||
"version": "7.16.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -2438,9 +2438,9 @@
|
||||
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA=="
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
||||
},
|
||||
"unbox-primitive": {
|
||||
"version": "1.0.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@meteorjs/babel",
|
||||
"author": "Meteor <dev@meteor.com>",
|
||||
"version": "7.15.0",
|
||||
"version": "7.16.0-beta.0",
|
||||
"license": "MIT",
|
||||
"description": "Babel wrapper package for use with Meteor",
|
||||
"keywords": [
|
||||
@@ -41,13 +41,13 @@
|
||||
"@babel/template": "^7.14.5",
|
||||
"@babel/traverse": "^7.15.0",
|
||||
"@babel/types": "^7.15.0",
|
||||
"@meteorjs/reify": "0.23.0",
|
||||
"babel-preset-meteor": "^7.10.0",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"convert-source-map": "^1.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"meteor-babel-helpers": "0.0.3",
|
||||
"@meteorjs/reify": "0.23.0",
|
||||
"typescript": "^4.3.5"
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-decorators": "7.14.5",
|
||||
|
||||
@@ -34,3 +34,13 @@ npm install -g meteor
|
||||
### Important note
|
||||
|
||||
This npm package is not Meteor itself, this npm package is just an installer. You should not include it as a dependency in your project. If you do your deploy is going to be broken.
|
||||
|
||||
### Path management
|
||||
|
||||
By default, the Meteor installer adds its install path (by default, `~/.meteor/`) to your PATH by updating either your `.bashrc`, `.bash_profile`, or `.zshrc` as appropriate. To disable this behavior, install Meteor by running:
|
||||
|
||||
```bash
|
||||
npm install -g meteor --ignore-meteor-setup-exec-path
|
||||
```
|
||||
|
||||
(or by setting the environment variable `npm_config_ignore_meteor_setup_exec_path=true`)
|
||||
@@ -31,6 +31,10 @@ if (isWindows() && !localAppData) {
|
||||
throw new Error('LOCALAPPDATA env var is not set.');
|
||||
}
|
||||
|
||||
const shouldSetupExecPath = () => {
|
||||
return !process.env.npm_config_ignore_meteor_setup_exec_path;
|
||||
}
|
||||
|
||||
const meteorLocalFolder = '.meteor';
|
||||
const meteorPath = path.resolve(rootPath, meteorLocalFolder);
|
||||
|
||||
@@ -45,5 +49,6 @@ module.exports = {
|
||||
isWindows,
|
||||
isMac,
|
||||
isRoot,
|
||||
isSudo
|
||||
isSudo,
|
||||
shouldSetupExecPath,
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ const {
|
||||
isSudo,
|
||||
isMac,
|
||||
METEOR_LATEST_VERSION,
|
||||
shouldSetupExecPath,
|
||||
} = require('./config.js');
|
||||
const { uninstall } = require('./uninstall');
|
||||
const {
|
||||
@@ -246,7 +247,10 @@ async function extract() {
|
||||
}
|
||||
async function setup() {
|
||||
fs.unlinkSync(startedPath);
|
||||
await setupExecPath();
|
||||
if (shouldSetupExecPath()) {
|
||||
await setupExecPath();
|
||||
}
|
||||
await fixOwnership();
|
||||
showGettingStarted();
|
||||
}
|
||||
async function setupExecPath() {
|
||||
@@ -267,8 +271,9 @@ async function setupExecPath() {
|
||||
await appendPathToFile('.bashrc');
|
||||
await appendPathToFile('.bash_profile');
|
||||
}
|
||||
|
||||
if (isSudo()) {
|
||||
}
|
||||
async function fixOwnership() {
|
||||
if (!isWindows() && isSudo()) {
|
||||
// if we identified sudo is being used, we need to change the ownership of the meteorpath folder
|
||||
child_process.execSync(`chown -R ${sudoUser} "${meteorPath}"`);
|
||||
}
|
||||
|
||||
2
packages/accounts-2fa/.gitignore
vendored
Normal file
2
packages/accounts-2fa/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.build*
|
||||
.versions
|
||||
76
packages/accounts-2fa/2fa-client.js
Normal file
76
packages/accounts-2fa/2fa-client.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
|
||||
// Used in the various functions below to handle errors consistently
|
||||
const reportError = (error, callback) => {
|
||||
if (callback) {
|
||||
callback(error);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Verify if the user has 2FA enabled
|
||||
* @locus Client
|
||||
* @param {Object|String} selector Username, email or custom selector to identify the user.
|
||||
* @param {Function} [callback] Called with a boolean on success that indicates whether the user has
|
||||
* or not 2FA enabled, or with a single `Error` argument on failure.
|
||||
*/
|
||||
Accounts.has2faEnabled = (selector, callback) => {
|
||||
Accounts.connection.call('has2faEnabled', selector, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Generates a svg QR code and save secret on user
|
||||
* @locus Client
|
||||
* @param {String} appName It's the name of your app that will show up when the user scans the QR code.
|
||||
* @param {Function} callback
|
||||
* Called with a QR code in SVG format on success, or with a single `Error` argument
|
||||
* on failure.
|
||||
*/
|
||||
Accounts.generate2faActivationQrCode = (appName, callback) => {
|
||||
if (!appName) {
|
||||
throw new Meteor.Error(
|
||||
500,
|
||||
'An app name is necessary when calling the function generate2faActivationQrCode'
|
||||
);
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
throw new Meteor.Error(
|
||||
500,
|
||||
'A callback is necessary when calling the function generate2faActivationQrCode so a QR code can be provided'
|
||||
);
|
||||
}
|
||||
|
||||
Accounts.connection.call('generate2faActivationQrCode', appName, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Enable the user 2FA
|
||||
* @locus Client
|
||||
* @param {String} code Code received from the authenticator app.
|
||||
* @param {Function} [callback] Optional callback.
|
||||
* Called with no arguments on success, or with a single `Error` argument
|
||||
* on failure.
|
||||
*/
|
||||
Accounts.enableUser2fa = (code, callback) => {
|
||||
if (!code) {
|
||||
return reportError(
|
||||
new Meteor.Error(400, 'Must provide a code to validate'),
|
||||
callback
|
||||
);
|
||||
}
|
||||
Accounts.connection.call('enableUser2fa', code, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Disable user 2FA
|
||||
* @locus Client
|
||||
* @param {Function} [callback] Optional callback.
|
||||
* Called with no arguments on success, or with a single `Error` argument
|
||||
* on failure.
|
||||
*/
|
||||
Accounts.disableUser2fa = callback => {
|
||||
Accounts.connection.call('disableUser2fa', callback);
|
||||
};
|
||||
129
packages/accounts-2fa/2fa-server.js
Normal file
129
packages/accounts-2fa/2fa-server.js
Normal file
@@ -0,0 +1,129 @@
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
import twofactor from 'node-2fa';
|
||||
import QRCode from 'qrcode-svg';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
|
||||
Accounts._is2faEnabledForUser = selector => {
|
||||
if (!Meteor.isServer) {
|
||||
throw new Meteor.Error(
|
||||
400,
|
||||
'The function _is2faEnabledForUser can only be called on the server'
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
if (!selector.includes('@')) {
|
||||
selector = { username: selector };
|
||||
} else {
|
||||
selector = { email: selector };
|
||||
}
|
||||
}
|
||||
|
||||
const user = Meteor.users.findOne(selector) || {};
|
||||
const { services: { twoFactorAuthentication } = {} } = user;
|
||||
return (
|
||||
twoFactorAuthentication &&
|
||||
twoFactorAuthentication.secret &&
|
||||
twoFactorAuthentication.type === 'otp'
|
||||
);
|
||||
};
|
||||
|
||||
Accounts._generate2faToken = secret => twofactor.generateToken(secret);
|
||||
|
||||
Accounts._isTokenValid = (secret, code) => {
|
||||
if (!Meteor.isServer) {
|
||||
throw new Meteor.Error(
|
||||
400,
|
||||
'The function _isTokenValid can only be called on the server'
|
||||
);
|
||||
}
|
||||
const { delta } = twofactor.verifyToken(secret, code, 10) || {};
|
||||
return delta != null && delta >= 0;
|
||||
};
|
||||
|
||||
Meteor.methods({
|
||||
generate2faActivationQrCode(appName) {
|
||||
const user = Meteor.user();
|
||||
|
||||
if (!user) {
|
||||
throw new Meteor.Error(
|
||||
400,
|
||||
'There must be a user logged in to generate the QR code.'
|
||||
);
|
||||
}
|
||||
|
||||
const { username } = user;
|
||||
|
||||
const { secret, uri } = twofactor.generateSecret({
|
||||
name: appName.trim(),
|
||||
account: username,
|
||||
});
|
||||
const svg = new QRCode(uri).svg();
|
||||
|
||||
Meteor.users.update(
|
||||
{ username },
|
||||
{
|
||||
$set: {
|
||||
'services.twoFactorAuthentication': {
|
||||
secret,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return svg;
|
||||
},
|
||||
enableUser2fa(code) {
|
||||
const user = Meteor.user();
|
||||
|
||||
if (!user) {
|
||||
throw new Meteor.Error(400, 'No user logged in.');
|
||||
}
|
||||
|
||||
const {
|
||||
services: { twoFactorAuthentication },
|
||||
username,
|
||||
} = user;
|
||||
|
||||
if (!twoFactorAuthentication || !twoFactorAuthentication.secret) {
|
||||
throw new Meteor.Error(
|
||||
500,
|
||||
'The user does not have a secret generated. You may have to call the function generateSvgCode first.'
|
||||
);
|
||||
}
|
||||
if (!Accounts._isTokenValid(twoFactorAuthentication.secret, code)) {
|
||||
throw new Meteor.Error(400, 'Invalid code.');
|
||||
}
|
||||
|
||||
Meteor.users.update(
|
||||
{ username },
|
||||
{
|
||||
$set: {
|
||||
'services.twoFactorAuthentication': {
|
||||
...twoFactorAuthentication,
|
||||
type: 'otp',
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
disableUser2fa() {
|
||||
const user = Meteor.user();
|
||||
|
||||
if (!user) {
|
||||
throw new Meteor.Error(400, 'No user logged in.');
|
||||
}
|
||||
|
||||
Meteor.users.update(
|
||||
{ username: user.username },
|
||||
{
|
||||
$unset: {
|
||||
'services.twoFactorAuthentication': 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
has2faEnabled(selector) {
|
||||
return Accounts._is2faEnabledForUser(selector);
|
||||
},
|
||||
});
|
||||
7
packages/accounts-2fa/README.md
Normal file
7
packages/accounts-2fa/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# accounts-2fa
|
||||
|
||||
[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/accounts-2fa)
|
||||
| [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/accounts-2fa)
|
||||
***
|
||||
|
||||
A package that provides a simple way to integrate 2FA in login services. Check the [docs](https://docs.meteor.com/packages/accounts-2fa.html) to see which packages are compatible with 2FA already.
|
||||
22
packages/accounts-2fa/package.js
Normal file
22
packages/accounts-2fa/package.js
Normal file
@@ -0,0 +1,22 @@
|
||||
Package.describe({
|
||||
version: '1.0.0-beta261.3',
|
||||
summary:
|
||||
'Package used to enable two factor authentication through OTP protocol',
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
'node-2fa': '2.0.3',
|
||||
'qrcode-svg': '1.1.0',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.use(['accounts-base'], ['client', 'server']);
|
||||
|
||||
// Export Accounts (etc) to packages using this one.
|
||||
api.imply('accounts-base', ['client', 'server']);
|
||||
|
||||
api.use('ecmascript');
|
||||
|
||||
api.addFiles(['2fa-client.js'], 'client');
|
||||
api.addFiles(['2fa-server.js'], 'server');
|
||||
});
|
||||
@@ -1,8 +1,11 @@
|
||||
import {Accounts} from "meteor/accounts-base";
|
||||
|
||||
const username = 'jsmith';
|
||||
const password = 'password';
|
||||
const excludeField = 'excludeField';
|
||||
const defaultExcludeField = 'defaultExcludeField';
|
||||
const excludeValue = 'foo';
|
||||
const secret2fa = 'shhhh';
|
||||
const profile = {
|
||||
name: username,
|
||||
[excludeField]: excludeValue,
|
||||
@@ -22,12 +25,49 @@ const logoutAndCreateUser = (test, done, nextTests) => {
|
||||
});
|
||||
};
|
||||
|
||||
const removeTestUser = (done) => {
|
||||
const createUserAndLogout = (test, done, nextTests) => {
|
||||
// Setup a new test user
|
||||
Accounts.createUser(
|
||||
{
|
||||
username,
|
||||
password,
|
||||
profile: {
|
||||
name: username,
|
||||
},
|
||||
},
|
||||
() => {
|
||||
Meteor.logout(() => {
|
||||
// Make sure we're logged out
|
||||
test.isFalse(Meteor.user());
|
||||
// Handle next tests
|
||||
nextTests(test, done);
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const removeTestUser = done => {
|
||||
Meteor.call('removeAccountsTestUser', username, () => {
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
const forceEnableUser2fa = done => {
|
||||
Meteor.call('forceEnableUser2fa', username, secret2fa, (err, token) => {
|
||||
done(token);
|
||||
});
|
||||
};
|
||||
|
||||
const getTokenFromSecret = done => {
|
||||
Meteor.call(
|
||||
'getTokenFromSecret',
|
||||
{ username },
|
||||
(err, token) => {
|
||||
done(token);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Tinytest.addAsync(
|
||||
'accounts - Meteor.loggingIn() is true right after a login call',
|
||||
(test, done) => {
|
||||
@@ -137,3 +177,84 @@ Tinytest.addAsync(
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Tinytest.addAsync(
|
||||
'accounts-2fa - Meteor.loginWithPasswordAnd2faCode() fails when token is not provided',
|
||||
(test, done) => {
|
||||
createUserAndLogout(test, done, () => {
|
||||
try {
|
||||
Meteor.loginWithPasswordAnd2faCode(username, password);
|
||||
} catch (e) {
|
||||
test.equal(
|
||||
e.reason,
|
||||
'token is required to use loginWithPasswordAnd2faCode and must be a string'
|
||||
);
|
||||
} finally {
|
||||
test.isFalse(Meteor.user());
|
||||
removeTestUser(done);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Tinytest.addAsync(
|
||||
'accounts-2fa - Meteor.loginWithPasswordAnd2faCode() fails with invalid code',
|
||||
(test, done) => {
|
||||
createUserAndLogout(test, done, () => {
|
||||
forceEnableUser2fa(() => {
|
||||
Meteor.loginWithPasswordAnd2faCode(username, password, 'ABC', e => {
|
||||
test.isFalse(Meteor.user());
|
||||
test.equal(e.reason, 'Invalid 2FA code.');
|
||||
removeTestUser(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Tinytest.addAsync(
|
||||
'accounts-2fa - Meteor.loginWithPasswordAnd2faCode() succeeds when token is correct',
|
||||
(test, done) => {
|
||||
createUserAndLogout(test, done, () => {
|
||||
forceEnableUser2fa((token) => {
|
||||
Meteor.loginWithPasswordAnd2faCode(username, password, token, e => {
|
||||
test.equal(e, undefined);
|
||||
test.isTrue(Meteor.user());
|
||||
removeTestUser(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Tinytest.addAsync(
|
||||
'accounts-2fa - Generates secret, enable 2fa, verifies if 2fa is enabled, disable 2fa, verifies if 2fa is disabled',
|
||||
(test, done) => {
|
||||
logoutAndCreateUser(test, done, () => {
|
||||
// Generates secret
|
||||
Accounts.generate2faActivationQrCode('test', (err, svg) => {
|
||||
test.isTrue(svg != null);
|
||||
getTokenFromSecret(token => {
|
||||
// enable 2fa
|
||||
Accounts.enableUser2fa(token, () => {
|
||||
// verifies if 2fa is enabled
|
||||
Accounts.has2faEnabled(username, (err, isEnabled) => {
|
||||
test.isTrue(isEnabled);
|
||||
// disable 2fa
|
||||
Accounts.disableUser2fa(() => {
|
||||
// verifies if 2fa is disabled
|
||||
Accounts.has2faEnabled(username, (err, isEnabled) => {
|
||||
test.isFalse(!!isEnabled);
|
||||
removeTestUser(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
const getTokenFromSecret = ({ username, secret: secretParam }) => {
|
||||
let secret = secretParam;
|
||||
|
||||
if (!secret) {
|
||||
const { services: { twoFactorAuthentication } = {} } =
|
||||
Meteor.users.findOne({ username }) || {};
|
||||
if (!twoFactorAuthentication) {
|
||||
throw new Meteor.Error(500, 'twoFactorAuthentication not set.');
|
||||
}
|
||||
secret = twoFactorAuthentication.secret;
|
||||
}
|
||||
const { token } = Accounts._generate2faToken(secret);
|
||||
|
||||
return token;
|
||||
};
|
||||
|
||||
Meteor.methods({
|
||||
removeAccountsTestUser(username) {
|
||||
Meteor.users.remove({ username });
|
||||
},
|
||||
forceEnableUser2fa(username, secret) {
|
||||
Meteor.users.update(
|
||||
{ username },
|
||||
{
|
||||
$set: {
|
||||
'services.twoFactorAuthentication': {
|
||||
secret,
|
||||
type: 'otp',
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
return getTokenFromSecret({ username, secret });
|
||||
},
|
||||
getTokenFromSecret,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'A user account system',
|
||||
version: '2.2.1',
|
||||
version: '2.2.2-beta261.3',
|
||||
});
|
||||
|
||||
Package.onUse(api => {
|
||||
@@ -60,6 +60,7 @@ Package.onTest(api => {
|
||||
'oauth-encryption',
|
||||
'ddp',
|
||||
'accounts-password',
|
||||
'accounts-2fa',
|
||||
]);
|
||||
|
||||
api.addFiles('accounts_tests_setup.js', 'server');
|
||||
|
||||
@@ -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: '2.2.0',
|
||||
version: '2.3.0-beta261.3',
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
|
||||
@@ -7,6 +7,31 @@ const reportError = (error, callback) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const internalLoginWithPassword = ({ selector, password, code, callback }) => {
|
||||
if (typeof selector === 'string')
|
||||
if (!selector.includes('@')) selector = { username: selector };
|
||||
else selector = { email: selector };
|
||||
|
||||
Accounts.callLoginMethod({
|
||||
methodArguments: [
|
||||
{
|
||||
user: selector,
|
||||
password: Accounts._hashPassword(password),
|
||||
code,
|
||||
},
|
||||
],
|
||||
userCallback: (error, result) => {
|
||||
if (error) {
|
||||
reportError(error, callback);
|
||||
} else {
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
});
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Attempt to log in with a password.
|
||||
//
|
||||
// @param selector {String|Object} One of the following:
|
||||
@@ -31,25 +56,7 @@ const reportError = (error, callback) => {
|
||||
* @importFromPackage meteor
|
||||
*/
|
||||
Meteor.loginWithPassword = (selector, password, callback) => {
|
||||
if (typeof selector === 'string')
|
||||
if (!selector.includes('@'))
|
||||
selector = {username: selector};
|
||||
else
|
||||
selector = {email: selector};
|
||||
|
||||
Accounts.callLoginMethod({
|
||||
methodArguments: [{
|
||||
user: selector,
|
||||
password: Accounts._hashPassword(password)
|
||||
}],
|
||||
userCallback: (error, result) => {
|
||||
if (error) {
|
||||
reportError(error, callback);
|
||||
} else {
|
||||
callback && callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
return internalLoginWithPassword({ selector, password, callback });
|
||||
};
|
||||
|
||||
Accounts._hashPassword = password => ({
|
||||
@@ -57,6 +64,33 @@ Accounts._hashPassword = password => ({
|
||||
algorithm: "sha-256"
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @summary Log the user in with a password and token.
|
||||
* @locus Client
|
||||
* @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.
|
||||
* @param {String} password The user's password.
|
||||
* @param {String} token Token provide by the user's authenticator app.
|
||||
* @param {Function} [callback] Optional callback.
|
||||
* Called with no arguments on success, or with a single `Error` argument
|
||||
* on failure.
|
||||
* @importFromPackage meteor
|
||||
*/
|
||||
|
||||
Meteor.loginWithPasswordAnd2faCode = (selector, password, code, callback) => {
|
||||
if (code == null || typeof code !== 'string' || !code) {
|
||||
throw new Meteor.Error(
|
||||
400,
|
||||
'token is required to use loginWithPasswordAnd2faCode and must be a string'
|
||||
);
|
||||
}
|
||||
return internalLoginWithPassword({ selector, password, code, callback });
|
||||
};
|
||||
|
||||
|
||||
// Attempt to log in as a new user.
|
||||
|
||||
/**
|
||||
|
||||
@@ -169,7 +169,8 @@ Accounts.registerLoginHandler("password", options => {
|
||||
|
||||
check(options, {
|
||||
user: Accounts._userQueryValidator,
|
||||
password: passwordValidator
|
||||
password: passwordValidator,
|
||||
code: Match.Optional(NonEmptyString),
|
||||
});
|
||||
|
||||
|
||||
@@ -181,6 +182,21 @@ Accounts.registerLoginHandler("password", options => {
|
||||
Accounts._handleError("User not found");
|
||||
}
|
||||
|
||||
// This method is added by the package accounts-2fa
|
||||
if (
|
||||
Accounts._is2faEnabledForUser &&
|
||||
Accounts._is2faEnabledForUser(options.user)
|
||||
) {
|
||||
if (!options.code) {
|
||||
Accounts._handleError('2FA code must be informed.');
|
||||
}
|
||||
if (
|
||||
!Accounts._isTokenValid(user.services.twoFactorAuthentication.secret, options.code)
|
||||
) {
|
||||
Accounts._handleError('Invalid 2FA code.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!user.services || !user.services.password ||
|
||||
!user.services.password.bcrypt) {
|
||||
Accounts._handleError("User has no password set");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'No-password login/sign-up support for accounts',
|
||||
version: '2.0.0',
|
||||
version: '2.1.0-beta261.3',
|
||||
});
|
||||
|
||||
Package.onUse(api => {
|
||||
|
||||
@@ -21,6 +21,31 @@ const transformSelector = selector => {
|
||||
return { username: selector };
|
||||
};
|
||||
|
||||
const internalPasswordlessLoginWithToken = ({
|
||||
selector,
|
||||
token,
|
||||
code,
|
||||
callback,
|
||||
}) => {
|
||||
Accounts.callLoginMethod({
|
||||
methodArguments: [
|
||||
{
|
||||
selector: transformSelector(selector),
|
||||
token,
|
||||
code,
|
||||
},
|
||||
],
|
||||
userCallback: error => {
|
||||
if (error) {
|
||||
reportError(error, callback);
|
||||
} else {
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Attempt to log in with a token.
|
||||
//
|
||||
// @param selector {String|Object} One of the following:
|
||||
@@ -31,6 +56,7 @@ const transformSelector = selector => {
|
||||
// @param password {String}
|
||||
// @param callback {Function(error|undefined)}
|
||||
|
||||
|
||||
/**
|
||||
* @summary Log the user in with a one time token.
|
||||
* @locus Client
|
||||
@@ -42,21 +68,22 @@ const transformSelector = selector => {
|
||||
* @importFromPackage meteor
|
||||
*/
|
||||
Meteor.passwordlessLoginWithToken = (selector, token, callback) => {
|
||||
Accounts.callLoginMethod({
|
||||
methodArguments: [
|
||||
{
|
||||
selector: transformSelector(selector),
|
||||
token,
|
||||
},
|
||||
],
|
||||
userCallback: error => {
|
||||
if (error) {
|
||||
reportError(error, callback);
|
||||
} else {
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
});
|
||||
internalPasswordlessLoginWithToken({ selector, token, callback });
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Log the user in with a one time token.
|
||||
* @locus Client
|
||||
* @param {Object|String} selector Username, email or custom selector to identify the user.
|
||||
* @param {String} token one time token generated by the server
|
||||
* @param {String} code generated by the user's authenticator app
|
||||
* @param {Function} [callback] Optional callback.
|
||||
* Called with no arguments on success, or with a single `Error` argument
|
||||
* on failure.
|
||||
* @importFromPackage meteor
|
||||
*/
|
||||
Meteor.passwordlessLoginWithTokenAnd2faCode = (selector, token, code, callback) => {
|
||||
internalPasswordlessLoginWithToken({ selector, token, code, callback });
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
import { getUserById, tokenValidator } from './server_utils';
|
||||
import {getUserById, NonEmptyString, tokenValidator} from './server_utils';
|
||||
import { Random } from 'meteor/random';
|
||||
|
||||
const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000;
|
||||
@@ -63,6 +63,7 @@ Accounts.registerLoginHandler('passwordless', options => {
|
||||
|
||||
check(options, {
|
||||
token: tokenValidator(),
|
||||
code: Match.Optional(NonEmptyString),
|
||||
selector: Accounts._userQueryValidator,
|
||||
});
|
||||
|
||||
@@ -79,6 +80,21 @@ Accounts.registerLoginHandler('passwordless', options => {
|
||||
Accounts._handleError('User has no token set');
|
||||
}
|
||||
|
||||
// This method is added by the package accounts-2fa
|
||||
if (
|
||||
Accounts._is2faEnabledForUser &&
|
||||
Accounts._is2faEnabledForUser(user)
|
||||
) {
|
||||
if (!options.code) {
|
||||
Accounts._handleError('2FA code must be informed.');
|
||||
}
|
||||
if (
|
||||
!Accounts._isTokenValid(user.services.twoFactorAuthentication.secret, options.code)
|
||||
) {
|
||||
Accounts._handleError('Invalid 2FA code.');
|
||||
}
|
||||
}
|
||||
|
||||
const result = checkToken({
|
||||
user,
|
||||
selector,
|
||||
|
||||
@@ -9,3 +9,8 @@ export const tokenValidator = () => {
|
||||
str => Match.test(str, String) && str.length <= tokenLength
|
||||
);
|
||||
};
|
||||
|
||||
export const NonEmptyString = Match.Where(x => {
|
||||
check(x, String);
|
||||
return x.length > 0;
|
||||
});
|
||||
|
||||
@@ -20,18 +20,18 @@ const VALID_OPTIONS = new Set()
|
||||
.add('passwordlessSignupFields');
|
||||
|
||||
const VALID_PASSWORD_SIGNUP_FIELDS = new Set()
|
||||
.add("USERNAME_AND_EMAIL")
|
||||
.add("USERNAME_AND_OPTIONAL_EMAIL")
|
||||
.add("USERNAME_ONLY")
|
||||
.add("EMAIL_ONLY");
|
||||
.add('USERNAME_AND_EMAIL')
|
||||
.add('USERNAME_AND_OPTIONAL_EMAIL')
|
||||
.add('USERNAME_ONLY')
|
||||
.add('EMAIL_ONLY');
|
||||
|
||||
function isValidPasswordSignupField(field) {
|
||||
return VALID_PASSWORD_SIGNUP_FIELDS.has(field);
|
||||
}
|
||||
|
||||
const VALID_PASSWORDLESS_SIGNUP_FIELDS = new Set()
|
||||
.add("USERNAME_AND_EMAIL")
|
||||
.add("EMAIL_ONLY")
|
||||
.add('USERNAME_AND_EMAIL')
|
||||
.add('EMAIL_ONLY');
|
||||
|
||||
function isValidPasswordlessSignupField(field) {
|
||||
return VALID_PASSWORDLESS_SIGNUP_FIELDS.has(field);
|
||||
@@ -62,15 +62,25 @@ Accounts.ui.config = options => {
|
||||
handleForceApprovalPrompt(options);
|
||||
};
|
||||
|
||||
Meteor.startup(function() {
|
||||
const settings = Meteor.settings.public?.packages?.['accounts-ui-unstyled'];
|
||||
|
||||
if (settings) {
|
||||
Accounts.ui.config(settings);
|
||||
}
|
||||
});
|
||||
|
||||
function handlePasswordlessSignupFields(options) {
|
||||
let { passwordlessSignupFields } = options;
|
||||
|
||||
if (passwordlessSignupFields) {
|
||||
const reportInvalid = () => {
|
||||
throw new Error(`Accounts.ui.config: Invalid option for \`passwordlessSignupFields\`: ${passwordlessSignupFields}`);
|
||||
throw new Error(
|
||||
`Accounts.ui.config: Invalid option for \`passwordlessSignupFields\`: ${passwordlessSignupFields}`
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof passwordlessSignupFields === "string") {
|
||||
if (typeof passwordlessSignupFields === 'string') {
|
||||
passwordlessSignupFields = [passwordlessSignupFields];
|
||||
} else if (!Array.isArray(passwordlessSignupFields)) {
|
||||
reportInvalid();
|
||||
@@ -78,7 +88,9 @@ function handlePasswordlessSignupFields(options) {
|
||||
|
||||
if (passwordlessSignupFields.every(isValidPasswordlessSignupField)) {
|
||||
if (Accounts.ui._options.passwordlessSignupFields) {
|
||||
throw new Error("Accounts.ui.config: Can't set `passwordlessSignupFields` more than once");
|
||||
throw new Error(
|
||||
"Accounts.ui.config: Can't set `passwordlessSignupFields` more than once"
|
||||
);
|
||||
}
|
||||
Object.assign(Accounts.ui._options, { passwordlessSignupFields });
|
||||
return;
|
||||
@@ -93,10 +105,12 @@ function handlePasswordSignupFields(options) {
|
||||
|
||||
if (passwordSignupFields) {
|
||||
const reportInvalid = () => {
|
||||
throw new Error(`Accounts.ui.config: Invalid option for \`passwordSignupFields\`: ${passwordSignupFields}`);
|
||||
throw new Error(
|
||||
`Accounts.ui.config: Invalid option for \`passwordSignupFields\`: ${passwordSignupFields}`
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof passwordSignupFields === "string") {
|
||||
if (typeof passwordSignupFields === 'string') {
|
||||
passwordSignupFields = [passwordSignupFields];
|
||||
} else if (!Array.isArray(passwordSignupFields)) {
|
||||
reportInvalid();
|
||||
@@ -104,7 +118,9 @@ function handlePasswordSignupFields(options) {
|
||||
|
||||
if (passwordSignupFields.every(isValidPasswordSignupField)) {
|
||||
if (Accounts.ui._options.passwordSignupFields) {
|
||||
throw new Error("Accounts.ui.config: Can't set `passwordSignupFields` more than once");
|
||||
throw new Error(
|
||||
"Accounts.ui.config: Can't set `passwordSignupFields` more than once"
|
||||
);
|
||||
}
|
||||
Object.assign(Accounts.ui._options, { passwordSignupFields });
|
||||
return;
|
||||
@@ -125,7 +141,7 @@ export function passwordSignupFields() {
|
||||
return [passwordSignupFields];
|
||||
}
|
||||
|
||||
return ["EMAIL_ONLY"];
|
||||
return ['EMAIL_ONLY'];
|
||||
}
|
||||
|
||||
export function passwordlessSignupFields() {
|
||||
@@ -139,21 +155,24 @@ export function passwordlessSignupFields() {
|
||||
return [passwordlessSignupFields];
|
||||
}
|
||||
|
||||
return ["EMAIL_ONLY"];
|
||||
return ['EMAIL_ONLY'];
|
||||
}
|
||||
|
||||
|
||||
function handleRequestPermissions({ requestPermissions }) {
|
||||
if (requestPermissions) {
|
||||
Object.keys(requestPermissions).forEach(service => {
|
||||
if (Accounts.ui._options.requestPermissions[service]) {
|
||||
throw new Error(`Accounts.ui.config: Can't set \`requestPermissions\` more than once for ${service}`);
|
||||
throw new Error(
|
||||
`Accounts.ui.config: Can't set \`requestPermissions\` more than once for ${service}`
|
||||
);
|
||||
}
|
||||
|
||||
const scope = requestPermissions[service];
|
||||
|
||||
if (!Array.isArray(scope)) {
|
||||
throw new Error("Accounts.ui.config: Value for `requestPermissions` must be an array");
|
||||
throw new Error(
|
||||
'Accounts.ui.config: Value for `requestPermissions` must be an array'
|
||||
);
|
||||
}
|
||||
|
||||
Accounts.ui._options.requestPermissions[service] = scope;
|
||||
@@ -165,11 +184,15 @@ function handleRequestOfflineToken({ requestOfflineToken }) {
|
||||
if (requestOfflineToken) {
|
||||
Object.keys(requestOfflineToken).forEach(service => {
|
||||
if (service !== 'google') {
|
||||
throw new Error("Accounts.ui.config: `requestOfflineToken` only supported for Google login at the moment.");
|
||||
throw new Error(
|
||||
'Accounts.ui.config: `requestOfflineToken` only supported for Google login at the moment.'
|
||||
);
|
||||
}
|
||||
|
||||
if (Accounts.ui._options.requestOfflineToken[service]) {
|
||||
throw new Error(`Accounts.ui.config: Can't set \`requestOfflineToken\` more than once for ${service}`);
|
||||
throw new Error(
|
||||
`Accounts.ui.config: Can't set \`requestOfflineToken\` more than once for ${service}`
|
||||
);
|
||||
}
|
||||
|
||||
Accounts.ui._options.requestOfflineToken[service] =
|
||||
@@ -182,11 +205,15 @@ function handleForceApprovalPrompt({ forceApprovalPrompt }) {
|
||||
if (forceApprovalPrompt) {
|
||||
Object.keys(forceApprovalPrompt).forEach(service => {
|
||||
if (service !== 'google') {
|
||||
throw new Error("Accounts.ui.config: `forceApprovalPrompt` only supported for Google login at the moment.");
|
||||
throw new Error(
|
||||
'Accounts.ui.config: `forceApprovalPrompt` only supported for Google login at the moment.'
|
||||
);
|
||||
}
|
||||
|
||||
if (Accounts.ui._options.forceApprovalPrompt[service]) {
|
||||
throw new Error(`Accounts.ui.config: Can't set \`forceApprovalPrompt\` more than once for ${service}`);
|
||||
throw new Error(
|
||||
`Accounts.ui.config: Can't set \`forceApprovalPrompt\` more than once for ${service}`
|
||||
);
|
||||
}
|
||||
|
||||
Accounts.ui._options.forceApprovalPrompt[service] =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Unstyled version of login widgets',
|
||||
version: '1.6.0',
|
||||
version: '1.7.0-beta261.3',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
523
packages/babel-compiler/.npm/package/npm-shrinkwrap.json
generated
523
packages/babel-compiler/.npm/package/npm-shrinkwrap.json
generated
@@ -1,20 +1,25 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.0.3.tgz",
|
||||
"integrity": "sha512-DmIAguV77yFP0MGVFWknCMgSLAtsLR3VlRTteR6xgMpIfYtwaZuMvjGv5YlpiqN7S/5q87DHyuIx8oa15kiyag=="
|
||||
},
|
||||
"@babel/code-frame": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
|
||||
"integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
|
||||
"integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg=="
|
||||
},
|
||||
"@babel/compat-data": {
|
||||
"version": "7.16.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz",
|
||||
"integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz",
|
||||
"integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng=="
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz",
|
||||
"integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.0.tgz",
|
||||
"integrity": "sha512-x/5Ea+RO5MvF9ize5DeVICJoVrNv0Mi2RnIABrZEKYvPEpldXwauPkgvYA17cKa6WpU3LoYvYbuEMFtSNFsarA==",
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "2.2.0",
|
||||
@@ -24,104 +29,104 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz",
|
||||
"integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz",
|
||||
"integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw=="
|
||||
},
|
||||
"@babel/helper-annotate-as-pure": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz",
|
||||
"integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
|
||||
"integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw=="
|
||||
},
|
||||
"@babel/helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz",
|
||||
"integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz",
|
||||
"integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA=="
|
||||
},
|
||||
"@babel/helper-compilation-targets": {
|
||||
"version": "7.16.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz",
|
||||
"integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz",
|
||||
"integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA=="
|
||||
},
|
||||
"@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz",
|
||||
"integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg=="
|
||||
"version": "7.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz",
|
||||
"integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ=="
|
||||
},
|
||||
"@babel/helper-create-regexp-features-plugin": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz",
|
||||
"integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz",
|
||||
"integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA=="
|
||||
},
|
||||
"@babel/helper-define-polyfill-provider": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz",
|
||||
"integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg=="
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz",
|
||||
"integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA=="
|
||||
},
|
||||
"@babel/helper-environment-visitor": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz",
|
||||
"integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz",
|
||||
"integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag=="
|
||||
},
|
||||
"@babel/helper-explode-assignable-expression": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz",
|
||||
"integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz",
|
||||
"integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ=="
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz",
|
||||
"integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz",
|
||||
"integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA=="
|
||||
},
|
||||
"@babel/helper-get-function-arity": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz",
|
||||
"integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
|
||||
"integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw=="
|
||||
},
|
||||
"@babel/helper-hoist-variables": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz",
|
||||
"integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz",
|
||||
"integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg=="
|
||||
},
|
||||
"@babel/helper-member-expression-to-functions": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz",
|
||||
"integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz",
|
||||
"integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q=="
|
||||
},
|
||||
"@babel/helper-module-imports": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz",
|
||||
"integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
|
||||
"integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg=="
|
||||
},
|
||||
"@babel/helper-module-transforms": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz",
|
||||
"integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz",
|
||||
"integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng=="
|
||||
},
|
||||
"@babel/helper-optimise-call-expression": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz",
|
||||
"integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz",
|
||||
"integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w=="
|
||||
},
|
||||
"@babel/helper-plugin-utils": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz",
|
||||
"integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
|
||||
"integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA=="
|
||||
},
|
||||
"@babel/helper-remap-async-to-generator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz",
|
||||
"integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw=="
|
||||
"version": "7.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz",
|
||||
"integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw=="
|
||||
},
|
||||
"@babel/helper-replace-supers": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz",
|
||||
"integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz",
|
||||
"integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw=="
|
||||
},
|
||||
"@babel/helper-simple-access": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz",
|
||||
"integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz",
|
||||
"integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g=="
|
||||
},
|
||||
"@babel/helper-skip-transparent-expression-wrappers": {
|
||||
"version": "7.16.0",
|
||||
@@ -129,74 +134,74 @@
|
||||
"integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw=="
|
||||
},
|
||||
"@babel/helper-split-export-declaration": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz",
|
||||
"integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz",
|
||||
"integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw=="
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
|
||||
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
|
||||
"integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw=="
|
||||
},
|
||||
"@babel/helper-validator-option": {
|
||||
"version": "7.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz",
|
||||
"integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
|
||||
"integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ=="
|
||||
},
|
||||
"@babel/helper-wrap-function": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz",
|
||||
"integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA=="
|
||||
"version": "7.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz",
|
||||
"integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw=="
|
||||
},
|
||||
"@babel/helpers": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz",
|
||||
"integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.0.tgz",
|
||||
"integrity": "sha512-Xe/9NFxjPwELUvW2dsukcMZIp6XwPSbI4ojFBJuX5ramHuVE22SVcZIwqzdWo5uCgeTXW8qV97lMvSOjq+1+nQ=="
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz",
|
||||
"integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g=="
|
||||
"version": "7.16.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz",
|
||||
"integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw=="
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz",
|
||||
"integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz",
|
||||
"integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw=="
|
||||
},
|
||||
"@babel/plugin-proposal-async-generator-functions": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz",
|
||||
"integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA=="
|
||||
"version": "7.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz",
|
||||
"integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ=="
|
||||
},
|
||||
"@babel/plugin-proposal-class-properties": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz",
|
||||
"integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz",
|
||||
"integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww=="
|
||||
},
|
||||
"@babel/plugin-proposal-logical-assignment-operators": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz",
|
||||
"integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz",
|
||||
"integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg=="
|
||||
},
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz",
|
||||
"integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz",
|
||||
"integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ=="
|
||||
},
|
||||
"@babel/plugin-proposal-object-rest-spread": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz",
|
||||
"integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz",
|
||||
"integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA=="
|
||||
},
|
||||
"@babel/plugin-proposal-optional-catch-binding": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz",
|
||||
"integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz",
|
||||
"integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA=="
|
||||
},
|
||||
"@babel/plugin-proposal-optional-chaining": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz",
|
||||
"integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz",
|
||||
"integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA=="
|
||||
},
|
||||
"@babel/plugin-syntax-async-generators": {
|
||||
"version": "7.8.4",
|
||||
@@ -214,9 +219,9 @@
|
||||
"integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="
|
||||
},
|
||||
"@babel/plugin-syntax-jsx": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz",
|
||||
"integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz",
|
||||
"integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q=="
|
||||
},
|
||||
"@babel/plugin-syntax-logical-assignment-operators": {
|
||||
"version": "7.10.4",
|
||||
@@ -244,164 +249,179 @@
|
||||
"integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="
|
||||
},
|
||||
"@babel/plugin-transform-arrow-functions": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz",
|
||||
"integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz",
|
||||
"integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ=="
|
||||
},
|
||||
"@babel/plugin-transform-async-to-generator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz",
|
||||
"integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w=="
|
||||
"version": "7.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz",
|
||||
"integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg=="
|
||||
},
|
||||
"@babel/plugin-transform-block-scoped-functions": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz",
|
||||
"integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz",
|
||||
"integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg=="
|
||||
},
|
||||
"@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz",
|
||||
"integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz",
|
||||
"integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ=="
|
||||
},
|
||||
"@babel/plugin-transform-classes": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz",
|
||||
"integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz",
|
||||
"integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ=="
|
||||
},
|
||||
"@babel/plugin-transform-computed-properties": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz",
|
||||
"integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz",
|
||||
"integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw=="
|
||||
},
|
||||
"@babel/plugin-transform-destructuring": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz",
|
||||
"integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz",
|
||||
"integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A=="
|
||||
},
|
||||
"@babel/plugin-transform-exponentiation-operator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz",
|
||||
"integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz",
|
||||
"integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA=="
|
||||
},
|
||||
"@babel/plugin-transform-for-of": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz",
|
||||
"integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz",
|
||||
"integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg=="
|
||||
},
|
||||
"@babel/plugin-transform-literals": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz",
|
||||
"integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz",
|
||||
"integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ=="
|
||||
},
|
||||
"@babel/plugin-transform-modules-commonjs": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz",
|
||||
"integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ=="
|
||||
"version": "7.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz",
|
||||
"integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA=="
|
||||
},
|
||||
"@babel/plugin-transform-object-super": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz",
|
||||
"integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz",
|
||||
"integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw=="
|
||||
},
|
||||
"@babel/plugin-transform-parameters": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz",
|
||||
"integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz",
|
||||
"integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw=="
|
||||
},
|
||||
"@babel/plugin-transform-property-literals": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz",
|
||||
"integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz",
|
||||
"integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw=="
|
||||
},
|
||||
"@babel/plugin-transform-react-display-name": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz",
|
||||
"integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz",
|
||||
"integrity": "sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg=="
|
||||
},
|
||||
"@babel/plugin-transform-react-jsx": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz",
|
||||
"integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz",
|
||||
"integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag=="
|
||||
},
|
||||
"@babel/plugin-transform-react-jsx-development": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.5.tgz",
|
||||
"integrity": "sha512-uQSLacMZSGLCxOw20dzo1dmLlKkd+DsayoV54q3MHXhbqgPzoiGerZQgNPl/Ro8/OcXV2ugfnkx+rxdS0sN5Uw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz",
|
||||
"integrity": "sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A=="
|
||||
},
|
||||
"@babel/plugin-transform-react-pure-annotations": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.5.tgz",
|
||||
"integrity": "sha512-0nYU30hCxnCVCbRjSy9ahlhWZ2Sn6khbY4FqR91W+2RbSqkWEbVu2gXh45EqNy4Bq7sRU+H4i0/6YKwOSzh16A=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz",
|
||||
"integrity": "sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA=="
|
||||
},
|
||||
"@babel/plugin-transform-regenerator": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz",
|
||||
"integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz",
|
||||
"integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q=="
|
||||
},
|
||||
"@babel/plugin-transform-runtime": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz",
|
||||
"integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz",
|
||||
"integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A=="
|
||||
},
|
||||
"@babel/plugin-transform-shorthand-properties": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz",
|
||||
"integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz",
|
||||
"integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg=="
|
||||
},
|
||||
"@babel/plugin-transform-spread": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz",
|
||||
"integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz",
|
||||
"integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg=="
|
||||
},
|
||||
"@babel/plugin-transform-sticky-regex": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz",
|
||||
"integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz",
|
||||
"integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw=="
|
||||
},
|
||||
"@babel/plugin-transform-template-literals": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz",
|
||||
"integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz",
|
||||
"integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA=="
|
||||
},
|
||||
"@babel/plugin-transform-typeof-symbol": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz",
|
||||
"integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz",
|
||||
"integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ=="
|
||||
},
|
||||
"@babel/plugin-transform-unicode-regex": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz",
|
||||
"integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz",
|
||||
"integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q=="
|
||||
},
|
||||
"@babel/preset-react": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.5.tgz",
|
||||
"integrity": "sha512-3kzUOQeaxY/2vhPDS7CX/KGEGu/1bOYGvdRDJ2U5yjEz5o5jmIeTPLoiQBPGjfhPascLuW5OlMiPzwOOuB6txg=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz",
|
||||
"integrity": "sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA=="
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
|
||||
"integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
||||
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ=="
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz",
|
||||
"integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A=="
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
|
||||
"integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w=="
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz",
|
||||
"integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz",
|
||||
"integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz",
|
||||
"integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg=="
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz",
|
||||
"integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw=="
|
||||
},
|
||||
"@jridgewell/resolve-uri": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz",
|
||||
"integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg=="
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz",
|
||||
"integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg=="
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.2.7.tgz",
|
||||
"integrity": "sha512-ZKfRhw6eK2vvdWqpU7DQq49+BZESqh5rmkYpNhuzkz01tapssl2sNNy6uMUIgrTtUWQDijomWJzJRCoevVrfgw=="
|
||||
},
|
||||
"@meteorjs/babel": {
|
||||
"version": "7.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@meteorjs/babel/-/babel-7.15.0.tgz",
|
||||
"integrity": "sha512-XHyjZ1z3glbyGvSVT06re9HK25X2FOrsDE1X/Ph6c/66Pwxf+a2t1TiyxR/WvkHFxBMwDm09xcAZ2WMdl2GfAw=="
|
||||
"version": "7.16.0-beta.0",
|
||||
"resolved": "https://registry.npmjs.org/@meteorjs/babel/-/babel-7.16.0-beta.0.tgz",
|
||||
"integrity": "sha512-XRjYHxFOYlWj/j4aVVM/RYd9Vi/Pgq2etJmb1F+pZIUuUS95Ak166yes1T2X2aRukWdAuyl8nyhZL6EWjoTuYQ=="
|
||||
},
|
||||
"@meteorjs/reify": {
|
||||
"version": "0.23.0",
|
||||
@@ -531,19 +551,19 @@
|
||||
"integrity": "sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA="
|
||||
},
|
||||
"babel-plugin-polyfill-corejs2": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz",
|
||||
"integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA=="
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz",
|
||||
"integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w=="
|
||||
},
|
||||
"babel-plugin-polyfill-corejs3": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz",
|
||||
"integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw=="
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz",
|
||||
"integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ=="
|
||||
},
|
||||
"babel-plugin-polyfill-regenerator": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz",
|
||||
"integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg=="
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz",
|
||||
"integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A=="
|
||||
},
|
||||
"babel-plugin-transform-inline-consecutive-adds": {
|
||||
"version": "0.4.3",
|
||||
@@ -621,9 +641,9 @@
|
||||
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001291",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz",
|
||||
"integrity": "sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA=="
|
||||
"version": "1.0.30001307",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001307.tgz",
|
||||
"integrity": "sha512-+MXEMczJ4FuxJAUp0jvAl6Df0NI/OfW1RWEE61eSmzS7hw6lz4IKutbhbXendwq8BljfFuHtu26VWsg4afQ7Ng=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
@@ -646,9 +666,9 @@
|
||||
"integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA=="
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.20.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.0.tgz",
|
||||
"integrity": "sha512-relrah5h+sslXssTTOkvqcC/6RURifB0W5yhYBdBkaPYa5/2KBMiog3XiD+s3TwEHWxInWVv4Jx2/Lw0vng+IQ==",
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.0.tgz",
|
||||
"integrity": "sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.0.0",
|
||||
@@ -668,9 +688,9 @@
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ=="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.4.25",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.25.tgz",
|
||||
"integrity": "sha512-bTwub9Y/76EiNmfaiJih+hAy6xn7Ns95S4KvI2NuKNOz8TEEKKQUu44xuy0PYMudjM9zdjKRS1bitsUvHTfuUg=="
|
||||
"version": "1.4.65",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.65.tgz",
|
||||
"integrity": "sha512-0/d8Skk8sW3FxXP0Dd6MnBlrwx7Qo9cqQec3BlIAlvKnrmS3pHsIbaroEi+nd0kZkGpQ6apMEre7xndzjlEnLw=="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
@@ -728,9 +748,9 @@
|
||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
||||
"integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw=="
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
|
||||
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA=="
|
||||
},
|
||||
"is-reference": {
|
||||
"version": "1.2.1",
|
||||
@@ -818,9 +838,9 @@
|
||||
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
|
||||
},
|
||||
"regenerate-unicode-properties": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz",
|
||||
"integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA=="
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz",
|
||||
"integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw=="
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.9",
|
||||
@@ -833,19 +853,19 @@
|
||||
"integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw=="
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz",
|
||||
"integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg=="
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz",
|
||||
"integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw=="
|
||||
},
|
||||
"regjsgen": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
|
||||
"integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A=="
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz",
|
||||
"integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA=="
|
||||
},
|
||||
"regjsparser": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz",
|
||||
"integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==",
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz",
|
||||
"integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==",
|
||||
"dependencies": {
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
@@ -855,9 +875,9 @@
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A=="
|
||||
"version": "1.22.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
||||
"integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
@@ -884,15 +904,20 @@
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
|
||||
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA=="
|
||||
},
|
||||
"unicode-canonical-property-names-ecmascript": {
|
||||
"version": "2.0.0",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Package.describe({
|
||||
name: "babel-compiler",
|
||||
summary: "Parser/transpiler for ECMAScript 2015+ syntax",
|
||||
version: '7.8.0'
|
||||
version: '7.9.0-beta261.3'
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
'@meteorjs/babel': '7.15.0',
|
||||
'@meteorjs/babel': '7.16.0-beta.0',
|
||||
'json5': '2.1.1'
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'ecmascript',
|
||||
version: '0.16.1',
|
||||
version: '0.16.2-beta261.3',
|
||||
summary: 'Compiler plugin that supports ES2015+ in all .js files',
|
||||
documentation: 'README.md',
|
||||
});
|
||||
|
||||
@@ -486,10 +486,16 @@ EJSON.equals = (a, b, options) => {
|
||||
return b.equals(a, options);
|
||||
}
|
||||
|
||||
if (a instanceof Array) {
|
||||
if (!(b instanceof Array)) {
|
||||
return false;
|
||||
}
|
||||
// Array.isArray works across iframes while instanceof won't
|
||||
const aIsArray = Array.isArray(a);
|
||||
const bIsArray = Array.isArray(b);
|
||||
|
||||
// if not both or none are array they are not equal
|
||||
if (aIsArray !== bIsArray) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aIsArray && bIsArray) {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,14 @@ Tinytest.add('ejson - some equality tests', test => {
|
||||
test.isFalse(EJSON.equals({a: 1, b: 2, c: 3}, {a: 1, c: 3, b: 4}));
|
||||
test.isFalse(EJSON.equals({a: {}}, {a: {b: 2}}));
|
||||
test.isFalse(EJSON.equals({a: {b: 2}}, {a: {}}));
|
||||
// XXX: Object and Array were previously mistaken, which is why
|
||||
// we add some extra tests for them here
|
||||
test.isTrue(EJSON.equals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]));
|
||||
test.isFalse(EJSON.equals([1, 2, 3, 4, 5], [1, 2, 3, 4]));
|
||||
test.isFalse(EJSON.equals([1,2,3,4], {0: 1, 1: 2, 2: 3, 3: 4}));
|
||||
test.isFalse(EJSON.equals({0: 1, 1: 2, 2: 3, 3: 4}, [1,2,3,4]));
|
||||
test.isFalse(EJSON.equals({}, []));
|
||||
test.isFalse(EJSON.equals([], {}));
|
||||
});
|
||||
|
||||
Tinytest.add('ejson - equality and falsiness', test => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Extended and Extensible JSON library',
|
||||
version: '1.1.1'
|
||||
version: '1.1.2-beta261.3'
|
||||
});
|
||||
|
||||
Package.onUse(function onUse(api) {
|
||||
|
||||
@@ -14,29 +14,34 @@ export const EmailInternals = {
|
||||
NpmModules: {
|
||||
mailcomposer: {
|
||||
version: Npm.require('nodemailer/package.json').version,
|
||||
module: Npm.require('nodemailer/lib/mail-composer')
|
||||
module: Npm.require('nodemailer/lib/mail-composer'),
|
||||
},
|
||||
nodemailer: {
|
||||
version: Npm.require('nodemailer/package.json').version,
|
||||
module: Npm.require('nodemailer')
|
||||
}
|
||||
}
|
||||
module: Npm.require('nodemailer'),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const MailComposer = EmailInternals.NpmModules.mailcomposer.module;
|
||||
|
||||
const makeTransport = function (mailUrlString) {
|
||||
const makeTransport = function(mailUrlString) {
|
||||
const mailUrl = new URL(mailUrlString);
|
||||
|
||||
if (mailUrl.protocol !== 'smtp:' && mailUrl.protocol !== 'smtps:') {
|
||||
throw new Error("Email protocol in $MAIL_URL (" +
|
||||
mailUrlString + ") must be 'smtp' or 'smtps'");
|
||||
throw new Error(
|
||||
'Email protocol in $MAIL_URL (' +
|
||||
mailUrlString +
|
||||
") must be 'smtp' or 'smtps'"
|
||||
);
|
||||
}
|
||||
|
||||
if (mailUrl.protocol === 'smtp:' && mailUrl.port === '465') {
|
||||
Log.debug("The $MAIL_URL is 'smtp://...:465'. " +
|
||||
"You probably want 'smtps://' (The 's' enables TLS/SSL) " +
|
||||
"since '465' is typically a secure port.");
|
||||
Log.debug(
|
||||
"The $MAIL_URL is 'smtp://...:465'. " +
|
||||
"You probably want 'smtps://' (The 's' enables TLS/SSL) " +
|
||||
"since '465' is typically a secure port."
|
||||
);
|
||||
}
|
||||
|
||||
// Allow overriding pool setting, but default to true.
|
||||
@@ -84,15 +89,17 @@ const knownHostsTransport = function(settings = undefined, url = undefined) {
|
||||
}
|
||||
|
||||
if (!wellKnow(settings?.service || service)) {
|
||||
throw new Error('Could not recognize e-mail service. See list at https://nodemailer.com/smtp/well-known/ for services that we can configure for you.');
|
||||
throw new Error(
|
||||
'Could not recognize e-mail service. See list at https://nodemailer.com/smtp/well-known/ for services that we can configure for you.'
|
||||
);
|
||||
}
|
||||
|
||||
const transport = nodemailer.createTransport({
|
||||
service: settings?.service || service,
|
||||
auth: {
|
||||
user: settings?.user || user,
|
||||
pass: settings?.password || password
|
||||
}
|
||||
pass: settings?.password || password,
|
||||
},
|
||||
});
|
||||
|
||||
transport._syncSendMail = Meteor.wrapAsync(transport.sendMail, transport);
|
||||
@@ -106,8 +113,17 @@ const getTransport = function() {
|
||||
// set process.env.MAIL_URL in startup code. Then we store in a cache until
|
||||
// process.env.MAIL_URL changes.
|
||||
const url = process.env.MAIL_URL;
|
||||
if (this.cacheKey === undefined || (this.cacheKey !== url || this.cacheKey !== packageSettings?.service || 'settings')) {
|
||||
if ((packageSettings?.service && wellKnow(packageSettings.service)) || (url && wellKnow(new URL(url).hostname) || wellKnow(url?.split(':')[0] || ''))) {
|
||||
if (
|
||||
this.cacheKey === undefined ||
|
||||
this.cacheKey !== url ||
|
||||
this.cacheKey !== packageSettings?.service ||
|
||||
this.cacheKey !== 'settings'
|
||||
) {
|
||||
if (
|
||||
(packageSettings?.service && wellKnow(packageSettings.service)) ||
|
||||
(url && wellKnow(new URL(url).hostname)) ||
|
||||
wellKnow(url?.split(':')[0] || '')
|
||||
) {
|
||||
this.cacheKey = packageSettings.service || 'settings';
|
||||
this.cache = knownHostsTransport(packageSettings, url);
|
||||
} else {
|
||||
@@ -122,35 +138,37 @@ let nextDevModeMailId = 0;
|
||||
let output_stream = process.stdout;
|
||||
|
||||
// Testing hooks
|
||||
EmailTest.overrideOutputStream = function (stream) {
|
||||
EmailTest.overrideOutputStream = function(stream) {
|
||||
nextDevModeMailId = 0;
|
||||
output_stream = stream;
|
||||
};
|
||||
|
||||
EmailTest.restoreOutputStream = function () {
|
||||
EmailTest.restoreOutputStream = function() {
|
||||
output_stream = process.stdout;
|
||||
};
|
||||
|
||||
const devModeSend = function (mail) {
|
||||
const devModeSend = function(mail) {
|
||||
let devModeMailId = nextDevModeMailId++;
|
||||
|
||||
const stream = output_stream;
|
||||
|
||||
// This approach does not prevent other writers to stdout from interleaving.
|
||||
stream.write("====== BEGIN MAIL #" + devModeMailId + " ======\n");
|
||||
stream.write("(Mail not sent; to enable sending, set the MAIL_URL " +
|
||||
"environment variable.)\n");
|
||||
stream.write('====== BEGIN MAIL #' + devModeMailId + ' ======\n');
|
||||
stream.write(
|
||||
'(Mail not sent; to enable sending, set the MAIL_URL ' +
|
||||
'environment variable.)\n'
|
||||
);
|
||||
const readStream = new MailComposer(mail).compile().createReadStream();
|
||||
readStream.pipe(stream, {end: false});
|
||||
const future = new Future;
|
||||
readStream.on('end', function () {
|
||||
stream.write("====== END MAIL #" + devModeMailId + " ======\n");
|
||||
readStream.pipe(stream, { end: false });
|
||||
const future = new Future();
|
||||
readStream.on('end', function() {
|
||||
stream.write('====== END MAIL #' + devModeMailId + ' ======\n');
|
||||
future.return();
|
||||
});
|
||||
future.wait();
|
||||
};
|
||||
|
||||
const smtpSend = function (transport, mail) {
|
||||
const smtpSend = function(transport, mail) {
|
||||
transport._syncSendMail(mail);
|
||||
};
|
||||
|
||||
@@ -165,7 +183,7 @@ const sendHooks = new Hook();
|
||||
* false to skip sending.
|
||||
* @returns {{ stop: function, callback: function }}
|
||||
*/
|
||||
Email.hookSend = function (f) {
|
||||
Email.hookSend = function(f) {
|
||||
return sendHooks.register(f);
|
||||
};
|
||||
|
||||
@@ -210,13 +228,13 @@ Email.customTransport = undefined;
|
||||
* You can create a `MailComposer` object via
|
||||
* `new EmailInternals.NpmModules.mailcomposer.module`.
|
||||
*/
|
||||
Email.send = function (options) {
|
||||
Email.send = function(options) {
|
||||
if (options.mailComposer) {
|
||||
options = options.mailComposer.mail;
|
||||
}
|
||||
|
||||
let send = true;
|
||||
sendHooks.each(hook => {
|
||||
sendHooks.forEach(hook => {
|
||||
send = hook(options);
|
||||
return send;
|
||||
});
|
||||
@@ -228,7 +246,11 @@ Email.send = function (options) {
|
||||
customTransport({ packageSettings, ...options });
|
||||
return;
|
||||
}
|
||||
if (Meteor.isProduction || process.env.MAIL_URL || Meteor.settings.packages?.email) {
|
||||
if (
|
||||
Meteor.isProduction ||
|
||||
process.env.MAIL_URL ||
|
||||
Meteor.settings.packages?.email
|
||||
) {
|
||||
const transport = getTransport();
|
||||
smtpSend(transport, options);
|
||||
return;
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
Package.describe({
|
||||
summary: "Send email messages",
|
||||
version: "2.2.0"
|
||||
summary: 'Send email messages',
|
||||
version: '2.2.1-beta261.3',
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
nodemailer: "6.6.3",
|
||||
"stream-buffers": "3.0.2"
|
||||
nodemailer: '6.6.3',
|
||||
'stream-buffers': '3.0.2',
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
Package.onUse(function(api) {
|
||||
api.use(['ecmascript', 'logging', 'callback-hook'], 'server');
|
||||
api.mainModule('email.js', 'server');
|
||||
api.export(['Email', 'EmailInternals'], 'server');
|
||||
api.export('EmailTest', 'server', {testOnly: true});
|
||||
api.export('EmailTest', 'server', { testOnly: true });
|
||||
});
|
||||
|
||||
Package.onTest(function (api) {
|
||||
Package.onTest(function(api) {
|
||||
api.use('email', 'server');
|
||||
api.use(['tinytest', 'ecmascript']);
|
||||
api.addFiles('email_tests.js', 'server');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'The Meteor command-line tool',
|
||||
version: '2.6.0',
|
||||
version: '2.6.1-beta.3',
|
||||
});
|
||||
|
||||
Package.includeTool();
|
||||
|
||||
@@ -6,11 +6,36 @@
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
|
||||
"integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA=="
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
"integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.9",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||
@@ -21,6 +46,11 @@
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
|
||||
@@ -7,5 +7,46 @@ Standard Minifier for CSS
|
||||
|
||||
This package provides a minifier plugin used for Meteor apps by default.
|
||||
|
||||
The CSS minifier mostly reduces amount of white-space parsing CSS with
|
||||
ParseCSS.
|
||||
## Post CSS
|
||||
|
||||
This package can optionally run [PostCSS](https://postcss.org/) plugins on the css files in your app. To enable:
|
||||
|
||||
1. Install npm peer dependencies:
|
||||
|
||||
```sh
|
||||
meteor npm install -D postcss postcss-load-config
|
||||
```
|
||||
|
||||
2. Add PostCSS Config. Create a `postcss.config.js` file and add a config:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> The example config enables the `autoprefixer` postcss plugin. You can install the plugin by running `meteor npm install -D autoprefixer`.
|
||||
|
||||
Learn more about [configuring postcss](https://github.com/postcss/postcss-load-config#packagejson) or find a list of [available plugins](https://www.postcss.parts/).
|
||||
|
||||
### Exclude Meteor Packages
|
||||
|
||||
In addition to the css files in your app, PostCSS will also process the css files added from Meteor packages. In case you do not want these files to be processed, or they are not compatible with your PostCSS config, you can have PostCSS ignore them by using the `excludedMeteorPackages` option:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
},
|
||||
excludedMeteorPackages: [
|
||||
'github-config-ui',
|
||||
'constellation:console'
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
### Tailwind CSS
|
||||
|
||||
Tailwind CSS is fully supported. Since HMR applies updates to js files earlier than the css is updated, there can be a delay when using a Tailwind CSS class the first time before the styles are applied.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'standard-minifier-css',
|
||||
version: '1.7.4',
|
||||
version: '1.8.0-beta261.3',
|
||||
summary: 'Standard css minifier used with Meteor apps by default.',
|
||||
documentation: 'README.md'
|
||||
});
|
||||
@@ -14,7 +14,8 @@ Package.registerBuildPlugin({
|
||||
npmDependencies: {
|
||||
"@babel/runtime": "7.15.3",
|
||||
"source-map": "0.7.3",
|
||||
"lru-cache": "6.0.0"
|
||||
"lru-cache": "6.0.0",
|
||||
"micromatch": "4.0.4"
|
||||
},
|
||||
sources: [
|
||||
'plugin/minify-css.js'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sourcemap from "source-map";
|
||||
import { createHash } from "crypto";
|
||||
import LRU from "lru-cache";
|
||||
import { loadPostCss, watchAndHashDeps, usePostCss } from './postcss.js';
|
||||
|
||||
Plugin.registerMinifier({
|
||||
extensions: ["css"],
|
||||
@@ -11,43 +12,90 @@ Plugin.registerMinifier({
|
||||
});
|
||||
|
||||
class CssToolsMinifier {
|
||||
constructor() {
|
||||
this.cache = new LRU({
|
||||
max: 100
|
||||
});
|
||||
|
||||
async processFilesForBundle (files, options) {
|
||||
const mode = options.minifyMode;
|
||||
|
||||
if (! files.length) return;
|
||||
|
||||
const merged = await mergeCss(files);
|
||||
|
||||
if (mode === 'development') {
|
||||
files[0].addStylesheet({
|
||||
data: merged.code,
|
||||
sourceMap: merged.sourceMap,
|
||||
path: 'merged-stylesheets.css'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const minifiedFiles = CssTools.minifyCss(merged.code);
|
||||
|
||||
if (files.length) {
|
||||
minifiedFiles.forEach(function (minified) {
|
||||
files[0].addStylesheet({
|
||||
data: minified
|
||||
});
|
||||
});
|
||||
}
|
||||
this.depsHashCache = Object.create(null);
|
||||
}
|
||||
|
||||
beforeMinify() {
|
||||
this.depsHashCache = Object.create(null);
|
||||
}
|
||||
|
||||
watchAndHashDeps(deps, file) {
|
||||
const cacheKey = JSON.stringify(deps);
|
||||
|
||||
if (cacheKey in this.depsHashCache) {
|
||||
return this.depsHashCache[cacheKey];
|
||||
}
|
||||
|
||||
let hash = watchAndHashDeps(deps, (filePath) => {
|
||||
return file.readAndWatchFileWithHash(filePath).hash;
|
||||
});
|
||||
this.depsHashCache[cacheKey] = hash;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
async minifyFiles (files, mode, postcssConfig) {
|
||||
const cacheKey = createCacheKey(files, mode);
|
||||
const cachedResult = this.cache.get(cacheKey);
|
||||
|
||||
if (
|
||||
cachedResult &&
|
||||
cachedResult.depsCacheKey === this.watchAndHashDeps(cachedResult.deps, files[0])
|
||||
) {
|
||||
return cachedResult.stylesheets;
|
||||
}
|
||||
|
||||
let result = [];
|
||||
const merged = await mergeCss(files, postcssConfig);
|
||||
|
||||
if (mode === 'development') {
|
||||
result = [{
|
||||
data: merged.code,
|
||||
sourceMap: merged.sourceMap,
|
||||
path: 'merged-stylesheets.css'
|
||||
}];
|
||||
} else {
|
||||
const minifiedFiles = CssTools.minifyCss(merged.code);
|
||||
|
||||
result = minifiedFiles.map(minified => ({
|
||||
data: minified
|
||||
}));
|
||||
}
|
||||
|
||||
this.cache.set(cacheKey, {
|
||||
stylesheets: result,
|
||||
deps: merged.deps,
|
||||
depsCacheKey: this.watchAndHashDeps(merged.deps, files[0])
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
async processFilesForBundle(files, { minifyMode }) {
|
||||
if (! files.length) return;
|
||||
|
||||
const { error, postcssConfig } = await loadPostCss();
|
||||
|
||||
if (error) {
|
||||
files[0].error(postcssInfo.error);
|
||||
return;
|
||||
}
|
||||
|
||||
const stylesheets = await this.minifyFiles(files, minifyMode, postcssConfig);
|
||||
|
||||
stylesheets.forEach(stylesheet => {
|
||||
files[0].addStylesheet(stylesheet);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const mergeCache = new LRU({
|
||||
max: 100
|
||||
});
|
||||
|
||||
const hashFiles = Profile("hashFiles", function (files) {
|
||||
const createCacheKey = Profile("createCacheKey", function (files, minifyMode) {
|
||||
const hash = createHash("sha1");
|
||||
hash.update(minifyMode).update("\0");
|
||||
files.forEach(f => {
|
||||
hash.update(f.getSourceHash()).update("\0");
|
||||
});
|
||||
@@ -62,24 +110,41 @@ function disableSourceMappingURLs(css) {
|
||||
// Lints CSS files and merges them into one file, fixing up source maps and
|
||||
// pulling any @import directives up to the top since the CSS spec does not
|
||||
// allow them to appear in the middle of a file.
|
||||
const mergeCss = Profile("mergeCss", async function (css) {
|
||||
const hashOfFiles = hashFiles(css);
|
||||
let merged = mergeCache.get(hashOfFiles);
|
||||
if (merged) {
|
||||
return merged;
|
||||
}
|
||||
|
||||
const mergeCss = Profile("mergeCss", async function (css, postcssConfig) {
|
||||
// Filenames passed to AST manipulator mapped to their original files
|
||||
const originals = {};
|
||||
const deps = [];
|
||||
|
||||
const cssAsts = css.map(function (file) {
|
||||
const astPromises = css.map(async function (file) {
|
||||
const filename = file.getPathInBundle();
|
||||
originals[filename] = file;
|
||||
|
||||
let ast;
|
||||
try {
|
||||
let content = disableSourceMappingURLs(file.getContentsAsString());
|
||||
|
||||
if (usePostCss(file, postcssConfig)) {
|
||||
const result = await postcssConfig.postcss(
|
||||
postcssConfig.plugins
|
||||
).process(content, {
|
||||
// TODO: provide a better way to get the file's path
|
||||
from: process.cwd() + file._source.url?.replace('/__cordova', ''),
|
||||
parser: postcssConfig.options.parser
|
||||
});
|
||||
|
||||
result.warnings().forEach(warning => {
|
||||
warnCb(filename, warning.toString());
|
||||
});
|
||||
result.messages.forEach(message => {
|
||||
if (['dependency', 'dir-dependency'].includes(message.type)) {
|
||||
deps.push(message);
|
||||
}
|
||||
});
|
||||
content = result.css;
|
||||
}
|
||||
|
||||
const parseOptions = { source: filename, position: true };
|
||||
const css = disableSourceMappingURLs(file.getContentsAsString());
|
||||
ast = CssTools.parseCss(css, parseOptions);
|
||||
ast = CssTools.parseCss(content, parseOptions);
|
||||
ast.filename = filename;
|
||||
} catch (e) {
|
||||
if (e.reason) {
|
||||
@@ -90,7 +155,7 @@ const mergeCss = Profile("mergeCss", async function (css) {
|
||||
});
|
||||
} else {
|
||||
// Just in case it's not the normal error the library makes.
|
||||
file.error({message: e.message});
|
||||
file.error({message: e.stack});
|
||||
}
|
||||
|
||||
return { type: "stylesheet", stylesheet: { rules: [] }, filename };
|
||||
@@ -99,12 +164,7 @@ const mergeCss = Profile("mergeCss", async function (css) {
|
||||
return ast;
|
||||
});
|
||||
|
||||
const warnCb = (filename, msg) => {
|
||||
// XXX make this a buildmessage.warning call rather than a random log.
|
||||
// this API would be like buildmessage.error, but wouldn't cause
|
||||
// the build to fail.
|
||||
console.log(`${filename}: warn: ${msg}`);
|
||||
};
|
||||
const cssAsts = await Promise.all(astPromises);
|
||||
|
||||
const mergedCssAst = CssTools.mergeCssAsts(cssAsts, warnCb);
|
||||
|
||||
@@ -116,8 +176,7 @@ const mergeCss = Profile("mergeCss", async function (css) {
|
||||
});
|
||||
|
||||
if (! stringifiedCss.code) {
|
||||
mergeCache.set(hashOfFiles, merged = { code: '' });
|
||||
return merged;
|
||||
return { code: '', deps };
|
||||
}
|
||||
|
||||
// Add the contents of the input files to the source map of the new file
|
||||
@@ -220,10 +279,16 @@ const mergeCss = Profile("mergeCss", async function (css) {
|
||||
return newMap;
|
||||
});
|
||||
|
||||
mergeCache.set(hashOfFiles, merged = {
|
||||
return {
|
||||
code: stringifiedCss.code,
|
||||
sourceMap: newMap.toString()
|
||||
});
|
||||
|
||||
return merged;
|
||||
sourceMap: newMap.toString(),
|
||||
deps
|
||||
};
|
||||
});
|
||||
|
||||
function warnCb (filename, msg) {
|
||||
// XXX make this a buildmessage.warning call rather than a random log.
|
||||
// this API would be like buildmessage.error, but wouldn't cause
|
||||
// the build to fail.
|
||||
console.log(`${filename}: warn: ${msg}`);
|
||||
};
|
||||
|
||||
168
packages/standard-minifier-css/plugin/postcss.js
Normal file
168
packages/standard-minifier-css/plugin/postcss.js
Normal file
@@ -0,0 +1,168 @@
|
||||
import { createHash } from "crypto";
|
||||
import micromatch from 'micromatch';
|
||||
import { performance } from 'perf_hooks';
|
||||
|
||||
var fs = Plugin.fs;
|
||||
var path = Plugin.path;
|
||||
|
||||
const DEBUG_CACHE = process.env.DEBUG_METEOR_POSTCSS_DEP_CACHE === 'true';
|
||||
|
||||
let postcssConfig;
|
||||
let loaded = false;
|
||||
|
||||
const missingPostCssError = new Error([
|
||||
'',
|
||||
`The postcss npm package could not be found in your node_modules`,
|
||||
'directory. Please run the following command to install it:',
|
||||
' meteor npm install postcss@8',
|
||||
'or disable postcss by removing the postcss config.',
|
||||
''
|
||||
].join('\n'));
|
||||
|
||||
export async function loadPostCss() {
|
||||
if (loaded) {
|
||||
return { postcssConfig };
|
||||
}
|
||||
|
||||
let loadConfig;
|
||||
try {
|
||||
loadConfig = require('postcss-load-config');
|
||||
} catch (e) {
|
||||
console.log('no postcss-load-config');
|
||||
// The app doesn't have this package installed
|
||||
// Assuming the app doesn't use PostCSS
|
||||
loaded = true;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
let config;
|
||||
try {
|
||||
config = await loadConfig({ meteor: true });
|
||||
} catch (e) {
|
||||
if (e.message.includes('No PostCSS Config found in')) {
|
||||
// PostCSS is not used by this app
|
||||
loaded = true;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (e.message.includes('Cannot find module \'postcss\'')) {
|
||||
return { error: missingPostCssError };
|
||||
}
|
||||
|
||||
e.message = `While loading postcss config: ${e.message}`;
|
||||
return {
|
||||
error: e
|
||||
};
|
||||
}
|
||||
|
||||
let postcss;
|
||||
try {
|
||||
postcss = require('postcss');
|
||||
} catch (e) {
|
||||
return { error: missingPostCssError };
|
||||
}
|
||||
|
||||
const postcssVersion = require('postcss/package.json').version;
|
||||
const major = parseInt(postcssVersion.split('.')[0], 10);
|
||||
if (major !== 8) {
|
||||
// TODO: should this just be a warning instead?
|
||||
const error = new Error([
|
||||
'',
|
||||
`Found version ${postcssVersion} of postcss in your node_modules`,
|
||||
'directory. standard-minifier-css is only compatible with',
|
||||
'version 8 of PostCSS. Please restart Meteor after installing',
|
||||
'a supported version of PostCSS',
|
||||
''
|
||||
].join('\n'));
|
||||
|
||||
return { error };
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
config.postcss = postcss;
|
||||
postcssConfig = config;
|
||||
|
||||
return { postcssConfig };
|
||||
}
|
||||
|
||||
export function usePostCss(file, postcssConfig) {
|
||||
if (!postcssConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const excludedPackages = postcssConfig.options.excludedMeteorPackages || [];
|
||||
const path = file.getPathInBundle();
|
||||
|
||||
const excluded = excludedPackages.some(name => {
|
||||
return path.includes(`packages/${name.replace(':', '_')}`)
|
||||
});
|
||||
|
||||
return !excluded;
|
||||
}
|
||||
|
||||
export const watchAndHashDeps = Profile(
|
||||
'watchAndHashDeps',
|
||||
function (deps, hashAndWatchFile) {
|
||||
const hash = createHash('sha1');
|
||||
const globsByDir = Object.create(null);
|
||||
let fileCount = 0;
|
||||
let folderCount = 0;
|
||||
let start = performance.now();
|
||||
|
||||
deps.forEach(dep => {
|
||||
if (dep.type === 'dependency') {
|
||||
fileCount += 1;
|
||||
const fileHash = hashAndWatchFile(dep.file);
|
||||
hash.update(fileHash).update('\0');
|
||||
} else if (dep.type === 'dir-dependency') {
|
||||
if (dep.dir in globsByDir) {
|
||||
globsByDir[dep.dir].push(dep.glob || '**');
|
||||
} else {
|
||||
globsByDir[dep.dir] = [dep.glob || '**'];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Object.entries(globsByDir).forEach(([parentDir, globs]) => {
|
||||
const matchers = globs.map(glob => micromatch.matcher(glob));
|
||||
|
||||
function walk(relDir) {
|
||||
const absDir = path.join(parentDir, relDir);
|
||||
hash.update(absDir).update('\0');
|
||||
folderCount += 1;
|
||||
|
||||
const entries = fs.readdirWithTypesSync(absDir);
|
||||
for (const entry of entries) {
|
||||
const relPath = path.join(relDir, entry.name);
|
||||
|
||||
if (entry.isFile() && matchers.some(isMatch => isMatch(relPath))) {
|
||||
const absPath = path.join(absDir, entry.name);
|
||||
fileCount += 1;
|
||||
hash.update(hashAndWatchFile(absPath)).update('\0');
|
||||
} else if (
|
||||
entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.meteor'
|
||||
) {
|
||||
walk(relPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk('./');
|
||||
});
|
||||
|
||||
let digest = hash.digest('hex');
|
||||
|
||||
if (DEBUG_CACHE) {
|
||||
console.log('--- PostCSS Cache Info ---');
|
||||
console.log('Glob deps', JSON.stringify(globsByDir, null, 2));
|
||||
console.log('File dep count', fileCount);
|
||||
console.log('Walked folders', folderCount);
|
||||
console.log('Created dep cache key in', performance.now() - start, 'ms');
|
||||
console.log('--------------------------');
|
||||
}
|
||||
|
||||
return digest;
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'typescript',
|
||||
version: '4.4.1',
|
||||
version: '4.5.4-beta261.3',
|
||||
summary:
|
||||
'Compiler plugin that compiles TypeScript and ECMAScript in .ts and .tsx files',
|
||||
documentation: 'README.md',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"track": "METEOR",
|
||||
"version": "2.6-rc.2",
|
||||
"version": "2.6.1-beta.3",
|
||||
"recommended": false,
|
||||
"official": false,
|
||||
"description": "Meteor experimental release"
|
||||
|
||||
@@ -5,7 +5,7 @@ set -u
|
||||
|
||||
UNAME=$(uname)
|
||||
ARCH=$(uname -m)
|
||||
NODE_VERSION=14.18.3
|
||||
NODE_VERSION=14.19.0
|
||||
MONGO_VERSION_64BIT=5.0.5
|
||||
MONGO_VERSION_32BIT=3.2.22
|
||||
NPM_VERSION=6.14.15
|
||||
|
||||
0
scripts/ci/run-selftest-ci.sh
Normal file → Executable file
0
scripts/ci/run-selftest-ci.sh
Normal file → Executable file
@@ -14,8 +14,8 @@ var packageJson = {
|
||||
pacote: "https://github.com/meteor/pacote/tarball/a81b0324686e85d22c7688c47629d4009000e8b8",
|
||||
"node-gyp": "8.0.0",
|
||||
"node-pre-gyp": "0.15.0",
|
||||
typescript: "4.3.5",
|
||||
"@meteorjs/babel": "7.15.0",
|
||||
typescript: "4.5.4",
|
||||
"@meteorjs/babel": "7.16.0-beta.0",
|
||||
// Keep the versions of these packages consistent with the versions
|
||||
// found in dev-bundle-server-package.js.
|
||||
"meteor-promise": "0.9.0",
|
||||
|
||||
@@ -318,7 +318,7 @@ function statOrNullHelper(path: string, preserveSymlinks = false) {
|
||||
return preserveSymlinks
|
||||
? lstat(path)
|
||||
: stat(path);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code === "ENOENT") {
|
||||
return null;
|
||||
}
|
||||
@@ -329,7 +329,7 @@ function statOrNullHelper(path: string, preserveSymlinks = false) {
|
||||
export function realpathOrNull(path: string) {
|
||||
try {
|
||||
return realpath(path);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
return null;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ export function rm_recursive_async(path: string) {
|
||||
export const rm_recursive = Profile("files.rm_recursive", (path: string) => {
|
||||
try {
|
||||
rimraf.sync(convertToOSPath(path));
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if ((e.code === "ENOTEMPTY" ||
|
||||
e.code === "EPERM") &&
|
||||
canYield()) {
|
||||
@@ -452,7 +452,7 @@ export function mkdir_p(dir: string, mode: number | null = null) {
|
||||
|
||||
try {
|
||||
mkdir(p, mode);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "EEXIST") {
|
||||
if (pathIsDirectory(p)) {
|
||||
// all good, someone else created this directory for us while we were
|
||||
@@ -575,7 +575,7 @@ Profile("files.symlinkWithOverwrite", function symlinkWithOverwrite(
|
||||
|
||||
try {
|
||||
symlink(...args);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code === "EEXIST") {
|
||||
function normalizePath(path: string) {
|
||||
return convertToOSPath(path).replace(/[\/\\]$/, "")
|
||||
@@ -908,7 +908,7 @@ Profile("files.renameDirAlmostAtomically", (fromDir: string, toDir: string) => {
|
||||
try {
|
||||
rename(toDir, garbageDir);
|
||||
cleanupGarbage = true;
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code === 'EXDEV') {
|
||||
// Some (notably Docker) file systems will fail to do a seemingly
|
||||
// harmless operation, such as renaming, on what is apparently the same
|
||||
@@ -926,7 +926,7 @@ Profile("files.renameDirAlmostAtomically", (fromDir: string, toDir: string) => {
|
||||
if (! forceCopy) {
|
||||
try {
|
||||
rename(fromDir, toDir);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
// It's possible that there may not have been a `toDir` to have
|
||||
// advanced warning about this, so we're prepared to handle it again.
|
||||
if (e.code === 'EXDEV') {
|
||||
@@ -1072,7 +1072,7 @@ export function runJavaScript(code: string, {
|
||||
// Pass 'true' as third argument if we want the parse error on
|
||||
// stderr (which we don't).
|
||||
var script = require('vm').createScript(wrapped, stackFilename);
|
||||
} catch (nodeParseError) {
|
||||
} catch (nodeParseError: any) {
|
||||
if (!(nodeParseError instanceof SyntaxError)) {
|
||||
throw nodeParseError;
|
||||
}
|
||||
@@ -1090,7 +1090,7 @@ export function runJavaScript(code: string, {
|
||||
const { parse } = require('@meteorjs/babel');
|
||||
try {
|
||||
parse(wrapped, { strictMode: false });
|
||||
} catch (parseError) {
|
||||
} catch (parseError: any) {
|
||||
if (typeof parseError.loc !== "object") {
|
||||
throw parseError;
|
||||
}
|
||||
@@ -1158,7 +1158,7 @@ export class OfflineError {
|
||||
export function readdirNoDots(path: string) {
|
||||
try {
|
||||
var entries = readdir(path);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code === 'ENOENT') {
|
||||
return [];
|
||||
}
|
||||
@@ -1196,7 +1196,7 @@ export function splitBufferToLines(buffer: Buffer) {
|
||||
export function getLinesOrEmpty(file: string) {
|
||||
try {
|
||||
return getLines(file);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e && e.code === 'ENOENT') {
|
||||
return [];
|
||||
}
|
||||
@@ -1209,7 +1209,7 @@ export function getLinesOrEmpty(file: string) {
|
||||
export function readJSONOrNull(file: string) {
|
||||
try {
|
||||
var raw = readFile(file, 'utf8');
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e && e.code === 'ENOENT') {
|
||||
return null;
|
||||
}
|
||||
@@ -1577,7 +1577,7 @@ export const rename = isWindowsLikeFilesystem() ? function (from: string, to: st
|
||||
rimraf.sync(osTo);
|
||||
wrappedRename(from, to);
|
||||
resolve();
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code !== 'EPERM' && err.code !== 'EACCES') {
|
||||
reject(err);
|
||||
} else if (Date.now() - startTimeMs < timeLimitMs) {
|
||||
@@ -1588,7 +1588,7 @@ export const rename = isWindowsLikeFilesystem() ? function (from: string, to: st
|
||||
}
|
||||
}
|
||||
attempt();
|
||||
}).catch(error => {
|
||||
}).catch((error: any) => {
|
||||
if (error.code === 'EPERM' ||
|
||||
error.code === 'EACCESS') {
|
||||
cp_r(from, to, { preserveSymlinks: true });
|
||||
|
||||
@@ -14,6 +14,7 @@ export {
|
||||
read, read as readSync,
|
||||
readFile, readFile as readFileSync,
|
||||
readdir, readdir as readdirSync,
|
||||
readdirWithTypes as readdirWithTypesSync,
|
||||
readlink, readlink as readlinkSync,
|
||||
realpath, realpath as realpathSync,
|
||||
rename, rename as renameSync,
|
||||
|
||||
@@ -265,7 +265,7 @@ export const optimisticLStatOrNull = makeCheapPathFunction(
|
||||
(path: string) => {
|
||||
try {
|
||||
return optimisticLStat(path);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
dependOnParentDirectory(path);
|
||||
return null;
|
||||
@@ -282,7 +282,7 @@ export const optimisticHashOrNull = makeOptimistic("hashOrNull", (
|
||||
try {
|
||||
return sha1(optimisticReadFile(path, options)) as string;
|
||||
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "EISDIR" &&
|
||||
e.code !== "ENOENT") {
|
||||
throw e;
|
||||
@@ -309,7 +309,7 @@ makeOptimistic("readJsonOrNull", (
|
||||
let contents: string | Buffer;
|
||||
try {
|
||||
contents = optimisticReadFile(path, options);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code === "ENOENT") {
|
||||
dependOnParentDirectory(path);
|
||||
return null;
|
||||
@@ -399,7 +399,7 @@ wrap((absRootDir: string, relDir: string) => {
|
||||
const optimisticIsSymbolicLink = wrap((path: string) => {
|
||||
try {
|
||||
return lstat(path)?.isSymbolicLink();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
dependOnParentDirectory(path);
|
||||
return false;
|
||||
|
||||
@@ -38,7 +38,7 @@ const WATCHER_CLEANUP_DELAY_MS = 30000;
|
||||
// watched folder and create a separate watcher for each subfolder. Until it has a
|
||||
// way for us to filter which folders it walks we will continue to use
|
||||
// pathwatcher to avoid having too many watchers.
|
||||
let watcherLibrary = process.env.METEOR_WATCHER_LIBRARY ||
|
||||
let watcherLibrary = process.env.METEOR_WATCHER_LIBRARY ||
|
||||
(process.platform === 'linux' ? 'pathwatcher' : 'nsfw');
|
||||
|
||||
// Pathwatcher complains (using console.error, ugh) if you try to watch
|
||||
@@ -360,7 +360,7 @@ function watchLibraryWatch(absPath: string, callback: EntryCallback) {
|
||||
if (watcherEnabled && watcherLibrary === 'pathwatcher') {
|
||||
try {
|
||||
return pathwatcher.watch(convertToOSPath(absPath), callback);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
maybeSuggestRaisingWatchLimit(e);
|
||||
// ... ignore the error. We'll still have watchFile, which is good
|
||||
// enough.
|
||||
@@ -430,7 +430,7 @@ export function addWatchRoot(absPath: string) {
|
||||
}
|
||||
|
||||
watchRoots.add(absPath);
|
||||
|
||||
|
||||
// If there already is a watcher for a parent directory, there is no need
|
||||
// to create this watcher.
|
||||
for (const path of watchRoots) {
|
||||
|
||||
@@ -314,7 +314,7 @@ export class WatchSet {
|
||||
export function readFile(absPath: string) {
|
||||
try {
|
||||
return files.readFile(absPath);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
// Rethrow most errors.
|
||||
if (! e || (e.code !== 'ENOENT' && e.code !== 'EISDIR')) {
|
||||
throw e;
|
||||
@@ -340,7 +340,7 @@ function readAndStatDirectory(absPath: string) {
|
||||
// Read the directory.
|
||||
try {
|
||||
var contents = files.readdirWithTypes(absPath);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
// If the path is not a directory, return null; let other errors through.
|
||||
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) {
|
||||
return null;
|
||||
@@ -618,7 +618,7 @@ export class Watcher {
|
||||
} else if (stat.isDirectory()) {
|
||||
try {
|
||||
var dirFiles = files.readdir(absPath);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT" ||
|
||||
err.code === "ENOTDIR") {
|
||||
// The directory was removed or changed type since we called
|
||||
@@ -834,8 +834,8 @@ export function readAndWatchDirectory(
|
||||
) {
|
||||
const contents = readDirectory(options);
|
||||
watchSet.addDirectory({
|
||||
contents,
|
||||
...options,
|
||||
contents,
|
||||
});
|
||||
return contents;
|
||||
}
|
||||
@@ -858,7 +858,7 @@ export function readAndWatchFileWithHash(watchSet: WatchSet, absPath: string) {
|
||||
|
||||
try {
|
||||
result.contents = files.readFile(absPath);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e && e.code === "EISDIR") {
|
||||
// Avoid adding directories to the watchSet as files.
|
||||
return result;
|
||||
|
||||
@@ -1119,10 +1119,8 @@ class Target {
|
||||
|
||||
// Takes a CssOutputResource and returns a string of minified CSS,
|
||||
// or null to indicate no minification occurred.
|
||||
// TODO Cache result by resource hash?
|
||||
minifyCssResource(resource) {
|
||||
if (! minifiersByExt.css ||
|
||||
minifyMode === "development") {
|
||||
minifyCssResource: (resource) => {
|
||||
if (! minifiersByExt.css) {
|
||||
// Indicates the caller should use the original resource.data
|
||||
// without minification.
|
||||
return null;
|
||||
@@ -1142,6 +1140,7 @@ class Target {
|
||||
arch: target.arch,
|
||||
minifier: minifiersByExt.css,
|
||||
minifyMode,
|
||||
watchSet: this.watchSet
|
||||
}).map(file => file.contents("utf8")).join("\n");
|
||||
}
|
||||
});
|
||||
@@ -1691,6 +1690,7 @@ class ClientTarget extends Target {
|
||||
arch: this.arch,
|
||||
minifier: minifierDef,
|
||||
minifyMode,
|
||||
watchSet: this.watchSet
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1896,15 +1896,15 @@ class ClientTarget extends Target {
|
||||
}
|
||||
}
|
||||
|
||||
const { wrap, defaultMakeCacheKey } = require("optimism");
|
||||
const minifyCssFiles = Profile("minifyCssFiles", wrap(function (files, {
|
||||
function minifyCssFiles (files, {
|
||||
arch,
|
||||
minifier,
|
||||
minifyMode,
|
||||
watchSet
|
||||
}) {
|
||||
const inputHashesByCssFile = new Map;
|
||||
const sources = files.map(file => {
|
||||
const cssFile = new CssFile(file, { arch });
|
||||
const cssFile = new CssFile(file, { arch, watchSet });
|
||||
inputHashesByCssFile.set(cssFile, file.hash());
|
||||
return cssFile;
|
||||
});
|
||||
@@ -1943,16 +1943,7 @@ const minifyCssFiles = Profile("minifyCssFiles", wrap(function (files, {
|
||||
return newFile;
|
||||
});
|
||||
}));
|
||||
}, {
|
||||
makeCacheKey(files, { arch, minifier, minifyMode }) {
|
||||
return defaultMakeCacheKey(
|
||||
minifier,
|
||||
arch,
|
||||
minifyMode,
|
||||
hashOfFiles(files),
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
const { createHash } = require("crypto");
|
||||
function hashOfFiles(files) {
|
||||
@@ -3340,6 +3331,13 @@ function bundle({
|
||||
return mergeAppWatchSets();
|
||||
}
|
||||
|
||||
// Call any beforeMinify callbacks defined by minifier plugins
|
||||
minifiers.forEach(minifier => {
|
||||
if (typeof minifier.userPlugin.beforeMinify === 'function') {
|
||||
minifier.userPlugin.beforeMinify();
|
||||
}
|
||||
});
|
||||
|
||||
const targets = Object.create(null);
|
||||
const hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function (
|
||||
if (cacheFilePath) {
|
||||
try {
|
||||
return readFile(cacheFilePath, "utf8");
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
}
|
||||
}
|
||||
@@ -1090,7 +1090,7 @@ export default class ImportScanner {
|
||||
|
||||
try {
|
||||
file.deps = file.deps || this.findImportedModuleIdentifiers(file);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.$ParseError) {
|
||||
(buildmessage as any).error(e.message, {
|
||||
file: file.sourcePath,
|
||||
@@ -1214,7 +1214,7 @@ export default class ImportScanner {
|
||||
private readPackageJson(absPath: string) {
|
||||
try {
|
||||
var info = this.readFile(absPath);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
return null;
|
||||
}
|
||||
@@ -1257,7 +1257,7 @@ export default class ImportScanner {
|
||||
|
||||
try {
|
||||
var info = this.readFile(absPath);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import buildmessage from '../utils/buildmessage.js';
|
||||
import {
|
||||
readAndWatchFileWithHash,
|
||||
} from '../fs/watch';
|
||||
import {
|
||||
optimisticReadFile,
|
||||
optimisticHashOrNull,
|
||||
} from "../fs/optimistic";
|
||||
import {
|
||||
convertToPosixPath
|
||||
} from '../fs/files';
|
||||
const buildPluginModule = require('./build-plugin.js');
|
||||
|
||||
class InputFile extends buildPluginModule.InputFile {
|
||||
@@ -7,6 +17,7 @@ class InputFile extends buildPluginModule.InputFile {
|
||||
|
||||
this._source = source;
|
||||
this._arch = options.arch;
|
||||
this._watchSet = options.watchSet;
|
||||
this._minifiedFiles = [];
|
||||
}
|
||||
|
||||
@@ -75,5 +86,17 @@ export class CssFile extends InputFile {
|
||||
addStylesheet(options) {
|
||||
this._minifiedFiles.push({ ...options });
|
||||
}
|
||||
}
|
||||
|
||||
readAndWatchFileWithHash(path) {
|
||||
const filePath = convertToPosixPath(path);
|
||||
|
||||
const hash = optimisticHashOrNull(filePath);
|
||||
const contents = optimisticReadFile(filePath);
|
||||
this._watchSet.addFile(filePath, hash);
|
||||
|
||||
return {
|
||||
hash,
|
||||
contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"@types/mocha": "^8.2.3",
|
||||
"@types/react": "^17.0.30",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"typescript": "^4.4.4"
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"meteor": {
|
||||
"mainModule": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<body>
|
||||
<div class="production_css">Text for prod</div>
|
||||
<div class="development_css">Text for devel</div>
|
||||
<div class="minified_lazy">Text for imported</div>
|
||||
</body>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
if (Meteor.isClient) {
|
||||
require('./imports/imported.css');
|
||||
|
||||
Meteor.startup(function () {
|
||||
['production_css', 'development_css'].forEach(cls => {
|
||||
['production_css', 'development_css', 'minified_lazy'].forEach(cls => {
|
||||
var color = getComputedStyle(document.querySelectorAll('.' + cls)[0]).color;
|
||||
Meteor.call('print', cls + ': ' + color);
|
||||
});
|
||||
|
||||
3
tools/tests/apps/custom-minifier/imports/imported.css
Normal file
3
tools/tests/apps/custom-minifier/imports/imported.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.lazy-resource {
|
||||
color: rgb(0, 256, 0);
|
||||
}
|
||||
@@ -29,6 +29,7 @@ CustomMinifier.prototype.processFilesForBundle = function (files, options) {
|
||||
data: contents
|
||||
});
|
||||
} else {
|
||||
contents = contents.replace(/lazy-resource/g, 'minified_lazy');
|
||||
file.addStylesheet({
|
||||
data: contents
|
||||
});
|
||||
@@ -37,5 +38,3 @@ CustomMinifier.prototype.processFilesForBundle = function (files, options) {
|
||||
Plugin.nudge();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ selftest.define('custom minifier - devel vs prod', function (options) {
|
||||
|
||||
run.match('production_css: rgb(255, 0, 0)');
|
||||
run.match('development_css: rgb(0, 0, 0)');
|
||||
run.match('minified_lazy: rgb(0, 255, 0)');
|
||||
run.match('Message (client): production_js');
|
||||
|
||||
run.stop();
|
||||
@@ -43,6 +44,7 @@ selftest.define('custom minifier - devel vs prod', function (options) {
|
||||
|
||||
run.match('production_css: rgb(0, 0, 0)');
|
||||
run.match('development_css: rgb(255, 0, 0)');
|
||||
run.match('minified_lazy: rgb(0, 255, 0)');
|
||||
run.match('Message (client): development_js');
|
||||
|
||||
run.stop();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { enterJob } from '../../../utils/buildmessage.js';
|
||||
import { ensureDependencies } from '../../../cli/dev-bundle-helpers.js';
|
||||
|
||||
const NPM_DEPENDENCIES = {
|
||||
puppeteer: '8.0.0'
|
||||
puppeteer: '13.2.0'
|
||||
};
|
||||
|
||||
export default class PuppeteerClient extends Client {
|
||||
|
||||
@@ -20,7 +20,7 @@ export function transform(callback: LineTransformer) {
|
||||
let line = chunk.toString("utf8");
|
||||
try {
|
||||
line = await callback(line);
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
done(error);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user