Merge branch 'devel' into underscore/boilerplate-generator-tests

This commit is contained in:
Harry Adel
2024-10-04 00:03:13 +03:00
committed by GitHub
131 changed files with 3171 additions and 810 deletions

View File

@@ -79,7 +79,7 @@ run_save_node_bin: &run_save_node_bin
build_machine_environment: &build_machine_environment
# Specify that we want an actual machine (ala Circle 1.0), not a Docker image.
docker:
- image: meteor/circleci:2023.12.1-android-34-node-18
- image: meteor/circleci:2024.09.11-android-34-node-20
resource_class: large
environment:
# This multiplier scales the waitSecs for selftests.
@@ -345,6 +345,9 @@ jobs:
if [ -f ./tmp/test-groups/2.txt ]; then TEST_GROUP=$(<./tmp/test-groups/2.txt); elif [ -f ./tmp/test-groups/0.txt ]; then TEST_GROUP=XXXXX; else TEST_GROUP='^co[n-z]'; fi
echo $TEST_GROUP;
eval $PRE_TEST_COMMANDS;
export PATH="/home/circleci/.sdkman/candidates/gradle/8.7/bin:${PATH}"
java --version
gradle --version
./meteor self-test \
"$TEST_GROUP" \
--retries ${METEOR_SELF_TEST_RETRIES} \
@@ -750,7 +753,7 @@ jobs:
Docs:
docker:
# This Node version should match that in the meteor/docs CircleCI config.
- image: meteor/circleci:2023.12.1-android-34-node-20
- image: meteor/circleci:2024.09.11-android-34-node-20
resource_class: large
environment:
CHECKOUT_METEOR_DOCS: /home/circleci/test_docs

View File

@@ -72,7 +72,7 @@ Current Core Team:
### Tracking project work
Right now, the best place to track the work being done on Meteor is to take a look at the latest release milestone [here](https://github.com/meteor/meteor/milestones). Also, the [Meteor Roadmap](https://docs.meteor.com/roadmap.html) contains high-level information on the current priorities of the project.
Right now, the best place to track the work being done on Meteor is to take a look at the latest release milestone [here](https://github.com/meteor/meteor/milestones). Also, the [Meteor Roadmap](https://docs.meteor.com/about/roadmap.html) contains high-level information on the current priorities of the project.
## Reporting a bug in Meteor
<a name="reporting-bug"></a>
@@ -134,7 +134,7 @@ for more details on proposing changes to core code.
Feature requests are tracked in the [Discussions](https://github.com/meteor/meteor/discussions).
Meteor is a big project with [many sub-projects](https://github.com/meteor/meteor/tree/devel/packages).
Community is welcome to help in all the sub-projects. We use our [roadmap](https://docs.meteor.com/roadmap.html) to communicate the high-level features we're currently prioritizing.
Community is welcome to help in all the sub-projects. We use our [roadmap](https://docs.meteor.com/about/roadmap.html) to communicate the high-level features we're currently prioritizing.
Every additional feature adds a maintenance cost in addition to its value. This
cost starts with the work of writing the feature or reviewing a community pull
@@ -207,7 +207,7 @@ For more information about how to work with Meteor core, take a look at the [Dev
### Proposing your change
You'll have the best chance of getting a change into core if you can build consensus in the community for it or if it is listed in the [roadmap](https://docs.meteor.com/roadmap.html). Start by creating a well specified Discussion [here](https://github.com/meteor/meteor/discussions).
You'll have the best chance of getting a change into core if you can build consensus in the community for it or if it is listed in the [roadmap](https://docs.meteor.com/about/roadmap.html). Start by creating a well specified Discussion [here](https://github.com/meteor/meteor/discussions).
Help drive discussion and advocate for your feature on the Github ticket (and perhaps the forums). The higher the demand for the feature and the greater the clarity of it's specification will determine the likelihood of a core contributor prioritizing your feature by flagging it with the `ready` label.

View File

@@ -2,4 +2,4 @@
This content was moved to [history.md](./docs/history.md).
Previously the changelog was available to be edited here but it was always published in [https://docs.meteor.com/changelog.html](https://docs.meteor.com/changelog.html).
Previously the changelog was available to be edited here but it was always published in [https://docs.meteor.com/history.html](https://docs.meteor.com/history.html).

View File

@@ -10,7 +10,7 @@
[![Travis CI Status](https://api.travis-ci.com/meteor/meteor.svg?branch=devel)](https://app.travis-ci.com/github/meteor/meteor)
[![CircleCI Status](https://circleci.com/gh/meteor/meteor.svg?style=svg)](https://app.circleci.com/pipelines/github/meteor/meteor?branch=devel)
[![built with Meteor](https://img.shields.io/badge/Meteor-3.0.2-green?logo=meteor&logoColor=white)](https://meteor.com)
[![built with Meteor](https://img.shields.io/badge/Meteor-3.0.3-green?logo=meteor&logoColor=white)](https://meteor.com)
![node-current](https://img.shields.io/node/v/meteor)
![Discord](https://img.shields.io/discord/1247973371040239676)
![Twitter Follow](https://img.shields.io/twitter/follow/meteorjs?style=social)
@@ -24,7 +24,7 @@ Meteor is an **ultra-simple** environment for building **modern** web applicatio
<hr>
- [Official Website](https://www.meteor.com)
- [Installation](https://www.meteor.com/developers/install)
- [Installation](https://docs.meteor.com/about/install.html)
- [Documentation](https://docs.meteor.com/#/full/)
<hr>
@@ -51,7 +51,7 @@ Use the same code whether youre developing for web, iOS, Android, or desktop
How about trying a tutorial to get started with your favorite technology?
| [<img align="left" width="25" src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"> React](https://react-tutorial.meteor.com/) |
| [<img align="left" width="25" src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"> React](https://docs.meteor.com/tutorials/react/) |
| - |
| [<img align="left" width="25" src="https://progsoft.net/images/blaze-css-icon-3e80acb3996047afd09f1150f53fcd78e98c1e1b.png"> Blaze](https://blaze-tutorial.meteor.com/) |
| [<img align="left" width="25" src="https://vuejs.org/images/logo.png"> Vue](https://vue-tutorial.meteor.com/) |
@@ -86,7 +86,7 @@ meteor
* Deploy on [Meteor Cloud](https://www.meteor.com/cloud)
* Discuss on [Forums](https://forums.meteor.com/)
* Join the Meteor community Slack by clicking this [invite link](https://join.slack.com/t/meteor-community/shared_invite/enQtODA0NTU2Nzk5MTA3LWY5NGMxMWRjZDgzYWMyMTEyYTQ3MTcwZmU2YjM5MTY3MjJkZjQ0NWRjOGZlYmIxZjFlYTA5Mjg4OTk3ODRiOTc).
* Join the Meteor Discord by clicking this [invite link](https://discord.gg/hZkTCaVjmT).
* Announcement list. Subscribe in the [footer](https://www.meteor.com/).
@@ -107,4 +107,4 @@ To uninstall Meteor:
rm -rf ~/.meteor
sudo rm /usr/local/bin/meteor
```
To find more information about installation, [read here](https://docs.meteor.com/install.html#uninstall).
To find more information about installation, [read here](https://docs.meteor.com/about/install.html#uninstall).

View File

@@ -1,18 +0,0 @@
hexo.extend.filter.register('after_render:html', function(html) {
const scriptTag = `
<script async
src="https://widget.kapa.ai/kapa-widget.bundle.js"
data-website-id="64051b0e-d79f-4fe7-b3ca-ff5c84075693"
data-project-name="Meteor"
data-project-color="#101926"
data-project-logo="https://avatars.githubusercontent.com/u/789528?s=200&v=4”
data-modal-disclaimer=“This is a custom LLM for answering questions about Meteor. Answers are based on the contents of the docs, answered forum posts, YouTube videos and GitHub issues. Please note that answers are generated by AI and may not be fully accurate, so please use your best judgement."
></script>
`.trim();
if (html.indexOf('</body>') !== -1) {
return html.replace('</body>', scriptTag + '</body>');
}
return html;
});

View File

@@ -0,0 +1,35 @@
/* global hexo */
hexo.extend.filter.register('after_render:html', function (str) {
const warningMessage = `
<div class="warning-banner">
<p>
⚠️ You're browsing the documentation for an old version of Meteor.js.
Check out the <a href="https://docs.meteor.com" target="_blank">v3 docs</a> and <a href="https://v3-migration-docs.meteor.com/" target="_blank">migration guide</a>.
</p>
</div>
`;
const css = `
<style>
.warning-banner {
text-align: center;
background-color: #fff3cd;
border: 1px solid #ffeeba;
color: #856404;
margin-bottom: 20px;
}
.warning-banner a {
color: #0056b3;
text-decoration: underline;
}
.warning-banner a:hover {
color: #003d82;
}
</style>
`;
const injectedContent = css + warningMessage;
return str.replace(/<div class="content">/, `<div class="content" data-injected>${injectedContent}`);
});

View File

@@ -104,7 +104,7 @@ This example from the Todos app defines a schema with a few simple rules:
3. We specify the `incompleteCount` is a number, which on insertion is set to `0` if not otherwise specified.
4. We specify that the `userId`, which is optional, must be a string that looks like the ID of a user document.
We're using the SimpleSchema for Meteor related funcitonality, like IDs, but we encourage you to create custom regEx expressions for security reasons, for fields like `email` or `name`. Check out the [Simple Schema docs](https://github.com/longshotlabs/simpl-schema#regex) for more information.
We're using the SimpleSchema for Meteor related functionality, like IDs, but we encourage you to create custom regEx expressions for security reasons, for fields like `email` or `name`. Check out the [Simple Schema docs](https://github.com/longshotlabs/simpl-schema#regex) for more information.
We attach the schema to the namespace of `Lists` directly, which allows us to check objects against this schema directly whenever we want, such as in a form or [Method](methods.html). In the [next section](#schemas-on-write) we'll see how to use this schema automatically when writing to the collection.

2
meteor
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
BUNDLE_VERSION=20.15.1.1
BUNDLE_VERSION=20.17.0.6
# OS Check. Put here because here is where we download the precompiled

View File

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

View File

@@ -56,6 +56,7 @@ Set the `https_proxy` or `HTTPS_PROXY` environment variable to a valid proxy URL
| NPM Package | Meteor Official Release |
|-------------|-------------------------|
| 3.0.3 | 3.0.3 |
| 3.0.2 | 3.0.2 |
| 3.0.1 | 3.0.1 |
| 3.0.0 | 3.0 |

View File

@@ -1,7 +1,7 @@
const os = require('os');
const path = require('path');
const METEOR_LATEST_VERSION = '3.0.2';
const METEOR_LATEST_VERSION = '3.0.3';
const sudoUser = process.env.SUDO_USER || '';
function isRoot() {
return process.getuid && process.getuid() === 0;

View File

@@ -5,7 +5,7 @@ const Seven = require('node-7z');
const { resolve, dirname } = require('path');
const tar = require('tar');
const { isMac } = require('./config.js');
const { isLinux } = require('./config.js');
function extractWith7Zip(tarPath, destination, onProgress) {
return new Promise((resolve, reject) => {
@@ -49,7 +49,7 @@ function createSymlinks(symlinks, baseDir) {
function extractWithNativeTar(tarPath, destination) {
child_process.execSync(
`tar -xf "${tarPath}" ${
!isMac() ? `--checkpoint-action=ttyout="#%u: %T \r"` : ``
isLinux() ? `--checkpoint-action=ttyout="#%u: %T \r"` : ``
} -C "${destination}"`,
{
cwd: process.cwd(),

View File

@@ -211,8 +211,19 @@ function download() {
}
if (isWindows()) {
decompress();
return;
const hasNativeTar = fs.existsSync(
path.resolve('C:/Windows/System32', 'tar.exe'),
);
if (hasNativeTar) {
// tar works exactly the same as it's bsdtar counterpart on UNIX so continue
console.log(
'Native binary for tar is available on this version of Windows.',
);
console.log('Switching to the native tar.exe binary on Windows.');
} else {
decompress();
return;
}
}
fs.writeFileSync(startedPath, 'Meteor install started');

View File

@@ -1,12 +1,12 @@
{
"name": "meteor",
"version": "3.0.2",
"version": "3.0.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "meteor",
"version": "3.0.2",
"version": "3.0.3",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "meteor",
"version": "3.0.2",
"version": "3.0.3",
"description": "Install Meteor",
"main": "install.js",
"scripts": {

View File

@@ -1,12 +1,12 @@
{
"name": "meteor-node-stubs",
"version": "1.2.9",
"version": "1.2.10",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "meteor-node-stubs",
"version": "1.2.9",
"version": "1.2.10",
"bundleDependencies": [
"@meteorjs/crypto-browserify",
"assert",
@@ -41,7 +41,7 @@
"console-browserify": "^1.2.0",
"constants-browserify": "^1.0.0",
"domain-browser": "^4.23.0",
"elliptic": "^6.5.4",
"elliptic": "^6.5.7",
"events": "^3.3.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",
@@ -55,7 +55,7 @@
"string_decoder": "^1.3.0",
"timers-browserify": "^2.0.12",
"tty-browserify": "0.0.1",
"url": "^0.11.3",
"url": "^0.11.4",
"util": "^0.12.5",
"vm-browserify": "^1.1.2"
},
@@ -361,14 +361,20 @@
"inBundle": true
},
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.1",
"set-function-length": "^1.1.1"
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -452,17 +458,21 @@
}
},
"node_modules/define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
@@ -522,10 +532,11 @@
}
},
"node_modules/elliptic": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz",
"integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==",
"version": "6.5.7",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
@@ -542,6 +553,29 @@
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
"inBundle": true
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -586,16 +620,21 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -633,12 +672,13 @@
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.2"
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -907,10 +947,14 @@
}
},
"node_modules/object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -1082,12 +1126,13 @@
"inBundle": true
},
"node_modules/qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"inBundle": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.4"
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@@ -1181,15 +1226,18 @@
"inBundle": true
},
"node_modules/set-function-length": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
"integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.1",
"get-intrinsic": "^1.2.1",
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -1215,14 +1263,19 @@
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -1278,13 +1331,17 @@
"inBundle": true
},
"node_modules/url": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz",
"integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==",
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
"integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
"punycode": "^1.4.1",
"qs": "^6.11.2"
"qs": "^6.12.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/util": {

View File

@@ -2,7 +2,7 @@
"name": "meteor-node-stubs",
"author": "Ben Newman <ben@meteor.com>",
"description": "Stub implementations of Node built-in modules, a la Browserify",
"version": "1.2.9",
"version": "1.2.10",
"main": "index.js",
"license": "MIT",
"homepage": "https://github.com/meteor/meteor/blob/devel/npm-packages/meteor-node-stubs/README.md",
@@ -18,7 +18,7 @@
"console-browserify": "^1.2.0",
"constants-browserify": "^1.0.0",
"domain-browser": "^4.23.0",
"elliptic": "^6.5.4",
"elliptic": "^6.5.7",
"events": "^3.3.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",
@@ -32,7 +32,7 @@
"string_decoder": "^1.3.0",
"timers-browserify": "^2.0.12",
"tty-browserify": "0.0.1",
"url": "^0.11.3",
"url": "^0.11.4",
"util": "^0.12.5",
"vm-browserify": "^1.1.2"
},

View File

@@ -2,9 +2,9 @@
"lockfileVersion": 4,
"dependencies": {
"@types/node": {
"version": "22.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz",
"integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g=="
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg=="
},
"@types/notp": {
"version": "2.0.5",
@@ -32,14 +32,14 @@
"integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA=="
},
"tslib": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"undici-types": {
"version": "6.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz",
"integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ=="
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
}
}
}

View File

@@ -1519,11 +1519,11 @@ export class AccountsServer extends AccountsCommon {
}
_handleError = (msg, throwError = true, errorCode = 403) => {
const isErrorAmbiguous = this._options.ambiguousErrorMessages ?? Meteor.isProduction;
const isErrorAmbiguous = this._options.ambiguousErrorMessages ?? true;
const error = new Meteor.Error(
errorCode,
isErrorAmbiguous
? "Something went wrong. Please check your credentials."
? 'Something went wrong. Please check your credentials.'
: msg
);
if (throwError) {

View File

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

View File

@@ -67,9 +67,9 @@
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
"debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg=="
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="
},
"delegates": {
"version": "1.0.0",
@@ -178,9 +178,9 @@
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node-addon-api": {
"version": "3.2.1",

View File

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

View File

@@ -1309,7 +1309,7 @@ if (Meteor.isServer) (() => {
password: hashPassword("new-password")
}
),
/Incorrect password/);
/Something went wrong. Please check your credentials./);
});
Tinytest.addAsync(
@@ -1388,7 +1388,7 @@ if (Meteor.isServer) (() => {
password: hashPassword("new-password")
}
),
/Incorrect password/);
/Something went wrong. Please check your credentials./);
});
Tinytest.addAsync('forgotPassword - different error messages returned depending' +

View File

@@ -2,9 +2,9 @@
"lockfileVersion": 4,
"dependencies": {
"@types/node": {
"version": "22.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz",
"integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g=="
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg=="
},
"@types/nodemailer": {
"version": "6.4.14",
@@ -57,9 +57,9 @@
"integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ=="
},
"undici-types": {
"version": "6.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz",
"integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ=="
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
}
}
}

View File

@@ -1,6 +1,6 @@
Package.describe({
summary: "Send email messages",
version: "3.0.100",
version: "3.1.0",
});
Npm.depends({

View File

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

View File

@@ -1,6 +1,46 @@
{
"lockfileVersion": 4,
"dependencies": {
"lodash.clone": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
"integrity": "sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg=="
},
"lodash.has": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz",
"integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g=="
},
"lodash.identity": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-3.0.0.tgz",
"integrity": "sha512-AupTIzdLQxJS5wIYUQlgGyk2XRTfGXA+MCghDHqZk0pzUNYvd3EESS6dkChNauNYVIutcb0dfHw1ri9Q1yPV8Q=="
},
"lodash.isempty": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
"integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg=="
},
"lodash.isobject": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz",
"integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA=="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
"lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
},
"lodash.times": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.times/-/lodash.times-4.3.2.tgz",
"integrity": "sha512-FfaJzl0SA35CRPDh5SWe2BTght6y5KSK7yJv166qIp/8q7qOwBDCvuDZE2RUSMRpBkLF6rZKbLEUoTmaP3qg6A=="
},
"mongodb-uri": {
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz",

View File

@@ -1,3 +1,5 @@
import has from 'lodash.has';
if (Meteor.isServer) {
// Set up allow/deny rules for test collections
@@ -21,7 +23,7 @@ if (Meteor.isServer) {
var fullName = name + idGeneration + nonce;
var collection;
if (_.has(allowCollections, fullName)) {
if (has(allowCollections, fullName)) {
collection = allowCollections[fullName];
if (needToConfigure === true)
throw new Error("collections inconsistently exist");
@@ -126,7 +128,7 @@ if (Meteor.isServer) {
return doc.canInsert2;
},
updateAsync: function(userId, doc, fields, modifier) {
return -1 !== _.indexOf(fields, 'canUpdate2');
return -1 !== fields.indexOf('canUpdate2');
},
removeAsync: function(userId, doc) {
return doc.canRemove2;
@@ -144,22 +146,22 @@ if (Meteor.isServer) {
}, {
insertAsync: function(userId, doc) {
// Don't allow explicit ID to be set by the client.
return _.has(doc, '_id');
return has(doc, '_id');
},
updateAsync: function(userId, doc, fields, modifier) {
return -1 !== _.indexOf(fields, 'verySecret');
return -1 !== fields.indexOf('verySecret');
}
}];
_.each([
[
restrictedCollectionDefaultSecure,
restrictedCollectionDefaultInsecure,
restrictedCollectionForUpdateOptionsTest
], function (collection) {
_.each(allows, function (allow) {
].forEach(function (collection) {
allows.forEach(function (allow) {
collection.allow(allow);
});
_.each(denies, function (deny) {
denies.forEach(function (deny) {
collection.deny(deny);
});
});
@@ -180,12 +182,12 @@ if (Meteor.isServer) {
updateAsync: function(userId, doc) {
// throw fields in doc so that we can inspect them in test
throw new Meteor.Error(
999, "Test: Fields in doc: " + _.keys(doc).sort().join(','));
999, "Test: Fields in doc: " + Object.keys(doc).sort().join(','));
},
removeAsync: function(userId, doc) {
// throw fields in doc so that we can inspect them in test
throw new Meteor.Error(
999, "Test: Fields in doc: " + _.keys(doc).sort().join(','));
999, "Test: Fields in doc: " + Object.keys(doc).sort().join(','));
},
fetch: ['field1']
});
@@ -203,12 +205,12 @@ if (Meteor.isServer) {
updateAsync: function(userId, doc) {
// throw fields in doc so that we can inspect them in test
throw new Meteor.Error(
999, "Test: Fields in doc: " + _.keys(doc).sort().join(','));
999, "Test: Fields in doc: " + Object.keys(doc).sort().join(','));
},
removeAsync: function(userId, doc) {
// throw fields in doc so that we can inspect them in test
throw new Meteor.Error(
999, "Test: Fields in doc: " + _.keys(doc).sort().join(','));
999, "Test: Fields in doc: " + Object.keys(doc).sort().join(','));
},
fetch: ['field1']
});
@@ -222,7 +224,7 @@ if (Meteor.isServer) {
}
if (Meteor.isClient) {
_.each(['STRING', 'MONGO'], function (idGeneration) {
['STRING', 'MONGO'].forEach(function (idGeneration) {
// Set up a bunch of test collections... on the client! They match the ones
// created by setUpAllowTestsCollections.
@@ -730,8 +732,8 @@ if (Meteor.isClient) {
]);
})();
_.each(
[restrictedCollectionDefaultInsecure, restrictedCollectionDefaultSecure],
[restrictedCollectionDefaultInsecure, restrictedCollectionDefaultSecure].forEach(
function(collection) {
var canUpdateId, canRemoveId;
@@ -1078,7 +1080,7 @@ if (Meteor.isServer) {
collection.deny({invalidOption: true});
});
_.each(['insert', 'update', 'remove', 'fetch'], function (key) {
['insert', 'update', 'remove', 'fetch'].forEach(function (key) {
var options = {};
options[key] = true;
test.throws(function () {
@@ -1089,7 +1091,7 @@ if (Meteor.isServer) {
});
});
_.each(['insert', 'update', 'remove'], function (key) {
['insert', 'update', 'remove'].forEach(function (key) {
var options = {};
options[key] = false;
test.throws(function () {
@@ -1100,7 +1102,7 @@ if (Meteor.isServer) {
});
});
_.each(['insert', 'update', 'remove'], function (key) {
['insert', 'update', 'remove'].forEach(function (key) {
var options = {};
options[key] = undefined;
test.throws(function () {
@@ -1111,7 +1113,7 @@ if (Meteor.isServer) {
});
});
_.each(['insert', 'update', 'remove'], function (key) {
['insert', 'update', 'remove'].forEach(function (key) {
var options = {};
options[key] = ['an array']; // this should be a function, not an array
test.throws(function () {

View File

@@ -1,4 +1,6 @@
import { normalizeProjection } from "./mongo_utils";
import has from 'lodash.has';
import identity from 'lodash.identity';
import clone from 'lodash.clone';
/**
* Provide a synchronous Collection API using fibers, backed by
@@ -47,11 +49,11 @@ const APP_FOLDER = 'app';
// inside an EJSON custom type. It should only be called on pure JSON!
var replaceNames = function (filter, thing) {
if (typeof thing === "object" && thing !== null) {
if (_.isArray(thing)) {
return _.map(thing, _.bind(replaceNames, null, filter));
if (Array.isArray(thing)) {
return thing.map(replaceNames.bind(null, filter));
}
var ret = {};
_.each(thing, function (value, key) {
Object.entries(thing).forEach(function ([key, value]) {
ret[filter(key)] = replaceNames(filter, value);
});
return ret;
@@ -85,7 +87,7 @@ var replaceMongoAtomWithMeteor = function (document) {
if (document instanceof MongoDB.Decimal128) {
return Decimal(document.toString());
}
if (document["EJSON$type"] && document["EJSON$value"] && _.size(document) === 2) {
if (document["EJSON$type"] && document["EJSON$value"] && Object.keys(document).length === 2) {
return EJSON.fromJSONValue(replaceNames(unmakeMongoLegal, document));
}
if (document instanceof MongoDB.Timestamp) {
@@ -138,12 +140,12 @@ var replaceTypes = function (document, atomTransformer) {
return replacedTopLevelAtom;
var ret = document;
_.each(document, function (val, key) {
Object.entries(document).forEach(function ([key, val]) {
var valReplaced = replaceTypes(val, atomTransformer);
if (val !== valReplaced) {
// Lazy clone. Shallow copy.
if (ret === document)
ret = _.clone(document);
ret = clone(document);
ret[key] = valReplaced;
}
});
@@ -170,12 +172,12 @@ MongoConnection = function (url, options) {
// Internally the oplog connections specify their own maxPoolSize
// which we don't want to overwrite with any user defined value
if (_.has(options, 'maxPoolSize')) {
if (has(options, 'maxPoolSize')) {
// If we just set this for "server", replSet will override it. If we just
// set it for replSet, it will be ignored if we're not using a replSet.
mongoOptions.maxPoolSize = options.maxPoolSize;
}
if (_.has(options, 'minPoolSize')) {
if (has(options, 'minPoolSize')) {
mongoOptions.minPoolSize = options.minPoolSize;
}
@@ -194,6 +196,11 @@ MongoConnection = function (url, options) {
self._oplogHandle = null;
self._docFetcher = null;
mongoOptions.driverInfo = {
name: 'Meteor',
version: Meteor.release
}
self.client = new MongoDB.MongoClient(url, mongoOptions);
self.db = self.client.db();
@@ -380,8 +387,8 @@ MongoConnection.prototype._refresh = async function (collectionName, selector) {
var specificIds = LocalCollection._idsMatchedBySelector(selector);
if (specificIds) {
for (const id of specificIds) {
await Meteor.refresh(_.extend({id: id}, refreshKey));
}
await Meteor.refresh(Object.assign({id: id}, refreshKey));
};
} else {
await Meteor.refresh(refreshKey);
}
@@ -738,7 +745,7 @@ MongoConnection.prototype.upsertAsync = async function (collectionName, selector
}
return self.updateAsync(collectionName, selector, mod,
_.extend({}, options, {
Object.assign({}, options, {
upsert: true,
_returnObject: true
}));
@@ -898,7 +905,7 @@ Cursor.prototype.countAsync = async function () {
Cursor.prototype.count = function () {
throw new Error(
"count() is not avaible on the server. Please use countAsync() instead."
"count() is not available on the server. Please use countAsync() instead."
);
};
@@ -988,9 +995,10 @@ Cursor.prototype.observeChangesAsync = async function (callbacks, options = {})
};
MongoConnection.prototype._createSynchronousCursor = function(
cursorDescription, options) {
cursorDescription, options = {}) {
var self = this;
options = _.pick(options || {}, 'selfForIteration', 'useTransform');
const { selfForIteration, useTransform } = options;
options = { selfForIteration, useTransform };
var collection = self.rawCollection(cursorDescription.collectionName);
var cursorOptions = cursorDescription.options;
@@ -1195,7 +1203,8 @@ class AsynchronousCursor {
var SynchronousCursor = function (dbCursor, cursorDescription, options, collection) {
var self = this;
options = _.pick(options || {}, 'selfForIteration', 'useTransform');
const { selfForIteration, useTransform } = options;
options = { selfForIteration, useTransform };
self._dbCursor = dbCursor;
self._cursorDescription = cursorDescription;
@@ -1219,7 +1228,7 @@ var SynchronousCursor = function (dbCursor, cursorDescription, options, collecti
self._visitedIds = new LocalCollection._IdMap;
};
_.extend(SynchronousCursor.prototype, {
Object.assign(SynchronousCursor.prototype, {
// Returns a Promise for the next object from the underlying cursor (before
// the Mongo->Meteor type replacement).
_rawNextObjectPromise: function () {
@@ -1246,7 +1255,7 @@ _.extend(SynchronousCursor.prototype, {
if (!doc) return null;
doc = replaceTypes(doc, replaceMongoAtomWithMeteor);
if (!self._cursorDescription.options.tailable && _.has(doc, '_id')) {
if (!self._cursorDescription.options.tailable && has(doc, '_id')) {
// Did Mongo give us duplicate documents in the same cursor? If so,
// ignore this one. (Do this before the transform, since transform might
// return some unrelated value.) We don't do this for tailable cursors,
@@ -1340,7 +1349,7 @@ _.extend(SynchronousCursor.prototype, {
fetch: function () {
var self = this;
return self.map(_.identity);
return self.map(identity);
},
count: function () {
@@ -1432,7 +1441,7 @@ MongoConnection.prototype.tail = function (cursorDescription, docCallback, timeo
lastTS = doc.ts;
docCallback(doc);
} else {
var newSelector = _.clone(cursorDescription.selector);
var newSelector = Object.assign({}, cursorDescription.selector);
if (lastTS) {
newSelector.ts = {$gt: lastTS};
}
@@ -1478,8 +1487,8 @@ Object.assign(MongoConnection.prototype, {
throw Error("You may not observe a cursor with {fields: {_id: 0}}");
}
var observeKey = EJSON.stringify(
_.extend({ordered: ordered}, cursorDescription));
var observeKey = EJSON.stringify(
Object.assign({ordered: ordered}, cursorDescription));
var multiplexer, observeDriver;
var firstHandle = false;
@@ -1487,7 +1496,7 @@ Object.assign(MongoConnection.prototype, {
// Find a matching ObserveMultiplexer, or create a new one. This next block is
// guaranteed to not yield (and it doesn't call anything that can observe a
// new query), so no other calls to this function can interleave with it.
if (_.has(self._observeMultiplexers, observeKey)) {
if (has(self._observeMultiplexers, observeKey)) {
multiplexer = self._observeMultiplexers[observeKey];
} else {
firstHandle = true;
@@ -1507,15 +1516,18 @@ Object.assign(MongoConnection.prototype, {
);
const oplogOptions = self?._oplogHandle?._oplogOptions || {};
const { includeCollections, excludeCollections } = oplogOptions;if (firstHandle) {
const { includeCollections, excludeCollections } = oplogOptions;
if (firstHandle) {
var matcher, sorter;
var canUseOplog = _.all([
var canUseOplog = [
function () {
// At a bare minimum, using the oplog requires us to have an oplog, to
// want unordered callbacks, and to not want a callback on the polls
// that won't happen.
return self._oplogHandle && !ordered &&
!callbacks._testOnlyPollCallback;}, function () {
!callbacks._testOnlyPollCallback;
},
function () {
// We also need to check, if the collection of this Cursor is actually being "watched" by the Oplog handle
// if not, we have to fallback to long polling
if (excludeCollections?.length && excludeCollections.includes(collectionName)) {
@@ -1533,59 +1545,63 @@ Object.assign(MongoConnection.prototype, {
return false;
}
return true;
}, function () {
// We need to be able to compile the selector. Fall back to polling for
// some newfangled $selector that minimongo doesn't support yet.
try {
matcher = new Minimongo.Matcher(cursorDescription.selector);
return true;
} catch (e) {
// XXX make all compilation errors MinimongoError or something
// so that this doesn't ignore unrelated exceptions
return false;
}
}, function () {
// ... and the selector itself needs to support oplog.
return OplogObserveDriver.cursorSupported(cursorDescription, matcher);
}, function () {
// And we need to be able to compile the sort, if any. eg, can't be
// {$natural: 1}.
if (!cursorDescription.options.sort)
return true;
try {
sorter = new Minimongo.Sorter(cursorDescription.options.sort);
return true;
} catch (e) {
// XXX make all compilation errors MinimongoError or something
// so that this doesn't ignore unrelated exceptions
return false;
}
}], function (f) { return f(); }); // invoke each function
var driverClass = canUseOplog ? OplogObserveDriver : PollingObserveDriver;
observeDriver = new driverClass({
cursorDescription: cursorDescription,
mongoHandle: self,
multiplexer: multiplexer,
ordered: ordered,
matcher: matcher, // ignored by polling
sorter: sorter, // ignored by polling
_testOnlyPollCallback: callbacks._testOnlyPollCallback
});
if (observeDriver._init) {
await observeDriver._init();
},
function () {
// We need to be able to compile the selector. Fall back to polling for
// some newfangled $selector that minimongo doesn't support yet.
try {
matcher = new Minimongo.Matcher(cursorDescription.selector);
return true;
} catch (e) {
// XXX make all compilation errors MinimongoError or something
// so that this doesn't ignore unrelated exceptions
return false;
}
},
function () {
// ... and the selector itself needs to support oplog.
return OplogObserveDriver.cursorSupported(cursorDescription, matcher);
},
function () {
// And we need to be able to compile the sort, if any. eg, can't be
// {$natural: 1}.
if (!cursorDescription.options.sort)
return true;
try {
sorter = new Minimongo.Sorter(cursorDescription.options.sort);
return true;
} catch (e) {
// XXX make all compilation errors MinimongoError or something
// so that this doesn't ignore unrelated exceptions
return false;
}
}
].every(f => f()); // invoke each function and check if all return true
// This field is only set for use in tests.
multiplexer._observeDriver = observeDriver;
var driverClass = canUseOplog ? OplogObserveDriver : PollingObserveDriver;
observeDriver = new driverClass({
cursorDescription: cursorDescription,
mongoHandle: self,
multiplexer: multiplexer,
ordered: ordered,
matcher: matcher, // ignored by polling
sorter: sorter, // ignored by polling
_testOnlyPollCallback: callbacks._testOnlyPollCallback
});
if (observeDriver._init) {
await observeDriver._init();
}
self._observeMultiplexers[observeKey] = multiplexer;
// Blocks until the initial adds have been sent.
await multiplexer.addHandleAndSendInitialAdds(observeHandle);
return observeHandle;
},
// This field is only set for use in tests.
multiplexer._observeDriver = observeDriver;
}
self._observeMultiplexers[observeKey] = multiplexer;
// Blocks until the initial adds have been sent.
await multiplexer.addHandleAndSendInitialAdds(observeHandle);
return observeHandle;
},
});
@@ -1605,7 +1621,7 @@ listenAll = async function (cursorDescription, listenCallback) {
return {
stop: function () {
_.each(listeners, function (listener) {
listeners.forEach(function (listener) {
listener.stop();
});
}
@@ -1687,4 +1703,4 @@ MongoConnection.prototype._observeChangesTailable = function (
// operation to interact with capped collections.
MongoInternals.MongoTimestamp = MongoDB.Timestamp;
MongoInternals.Connection = MongoConnection;
MongoInternals.Connection = MongoConnection;

View File

@@ -1,3 +1,7 @@
import isEmpty from 'lodash.isempty';
import isObject from 'lodash.isobject';
import times from 'lodash.times';
// This is a magic collection that fails its writes on the server when
// the selector (or inserted document) contains fail: true.
@@ -83,8 +87,8 @@ var stripId = function (obj) {
var compareResults = function (test, skipIds, actual, expected) {
if (skipIds) {
_.map(actual, stripId);
_.map(expected, stripId);
actual.map(stripId);
expected.map(stripId);
}
// (technically should ignore order in comparison)
test.equal(actual, expected);
@@ -117,7 +121,7 @@ const upsert = async function(coll, useUpdate, query, mod, options, callback) {
if (useUpdate) {
if (callback) {
await callWithCallBack(() =>
coll.updateAsync(query, mod, _.extend({ upsert: true }, options))
coll.updateAsync(query, mod, Object.assign({ upsert: true }, options))
);
return;
}
@@ -125,7 +129,7 @@ const upsert = async function(coll, useUpdate, query, mod, options, callback) {
numberAffected: await coll.updateAsync(
query,
mod,
_.extend({ upsert: true }, options)
Object.assign({ upsert: true }, options)
),
};
}
@@ -205,7 +209,7 @@ var Dog = function (name, color, actions) {
self.name = name;
self.actions = actions || [{name: "wag"}, {name: "swim"}];
};
_.extend(Dog.prototype, {
Object.assign(Dog.prototype, {
getName: function () { return this.name;},
getColor: function () { return this.name;},
equals: function (other) { return other.name === this.name &&
@@ -220,7 +224,7 @@ EJSON.addType("dog", function (o) { return new Dog(o.name, o.color, o.actions);}
// Parameterize tests.
_.each( [ 'MONGO', 'STRING'], function(idGeneration) {
['STRING', 'MONGO'].forEach(function(idGeneration) {
var collectionOptions = { idGeneration: idGeneration};
@@ -404,10 +408,8 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
[2, 8]
);
test.equal(
_.pluck(await coll.find({ run: run }, { sort: { x: -1 } }).fetchAsync(), 'x'),
[4, 1]
);
test.equal(await coll.find({run: run}, {sort: {x: -1}}).mapAsync(doc => doc.x),
[4, 1]);
await expectObserve('', async function() {
var count = await coll.updateAsync(
@@ -426,7 +428,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
);
test.equal(count, 2);
test.equal(
_.pluck(await coll.find({ run: run }, { sort: { x: -1 } }).fetchAsync(), 'x'),
(await coll.find({ run: run }, { sort: { x: -1 } }).fetchAsync()).map(doc => doc.x),
[6, 3]
);
});
@@ -441,8 +443,8 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
async function() {
await coll.updateAsync({ run: run, x: 3 }, { $inc: { x: 10 } }, { multi: true });
test.equal(
_.pluck(await coll.find({ run: run }, { sort: { x: -1 } }).fetchAsync(), 'x'),
[13, 6]
(await coll.find({ run: run }, { sort: { x: -1 } }).fetchAsync()).map(doc => doc.x),
[13, 6]
);
}
);
@@ -545,7 +547,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
return;
}
var max_counters = _.clone(counters);
var max_counters = Object.assign({}, counters);
await finishObserve(async function() {
if (Meteor.isServer) obs._multiplexer._observeDriver._suspendPolling();
@@ -595,7 +597,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
// Did we limit ourselves to one 'moved' message per change,
// rather than O(results) moved messages?
_.each(max_counters, function(v, k) {
Object.entries(max_counters).forEach(([k, v]) => {
test.isTrue(max_counters[k] >= counters[k], k);
});
@@ -1005,12 +1007,15 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
}
);
// compares arrays a and b w/o looking at order
var setsEqual = function(a, b) {
a = _.map(a, EJSON.stringify);
b = _.map(b, EJSON.stringify);
return _.isEmpty(_.difference(a, b)) && _.isEmpty(_.difference(b, a));
};
// compares arrays a and b w/o looking at order
const setsEqual = function (a, b) {
a = a.map(EJSON.stringify);
b = b.map(EJSON.stringify);
const difference = (arr1, arr2) => arr1.filter(x => !arr2.includes(x));
return difference(a, b).length === 0 && difference(b, a).length === 0;
};
// This test mainly checks the correctness of oplog code dealing with limited
// queries. Compitablity with poll-diff is added as well.
@@ -1321,13 +1326,13 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
])
);
test.length(_.keys(o.state), 3);
test.equal(o.state[docId6], { _id: docId6, foo: 22, bar: 24 });
test.equal(o.state[docId11], { _id: docId11, foo: 22, bar: 33.5 });
test.equal(o.state[docId12], { _id: docId12, foo: 22, bar: 43.5 });
clearOutput(o);
testOplogBufferIds([]);
testSafeAppendToBufferFlag(true);
test.length(Object.keys(o.state), 3);
test.equal(o.state[docId6], { _id: docId6, foo: 22, bar: 24 });
test.equal(o.state[docId11], { _id: docId11, foo: 22, bar: 33.5 });
test.equal(o.state[docId12], { _id: docId12, foo: 22, bar: 43.5 });
clearOutput(o);
testOplogBufferIds([]);
testSafeAppendToBufferFlag(true);
var docId13 = await ins({ foo: 22, bar: 50 });
var docId14 = await ins({ foo: 22, bar: 51 });
@@ -1422,10 +1427,10 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
setsEqual(o.output, [{ added: docId4 }, { removed: docId2 }])
);
test.equal(_.size(o.state), 2);
test.equal(o.state[docId4], { _id: docId4, y: -1222 });
test.equal(o.state[docId1], { _id: docId1, y: 1222 });
clearOutput(o);
test.equal(Object.keys(o.state).length, 2);
test.equal(o.state[docId4], {_id: docId4, y: -1222});
test.equal(o.state[docId1], {_id: docId1, y: 1222});
clearOutput(o);
await rem(docId2);
// Becomes [docId4 docId1 | docId3]
@@ -1438,10 +1443,10 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
setsEqual(o.output, [{ added: docId3 }, { removed: docId4 }])
);
test.equal(_.size(o.state), 2);
test.equal(o.state[docId3], { _id: docId3, y: 7222 });
test.equal(o.state[docId1], { _id: docId1, y: 1222 });
clearOutput(o);
test.equal(Object.keys(o.state).length, 2);
test.equal(o.state[docId3], {_id: docId3, y: 7222});
test.equal(o.state[docId1], {_id: docId1, y: 1222});
clearOutput(o);
onComplete();
}
@@ -1821,8 +1826,9 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
'mongo-livedata - transform sets _id if not present, ' + idGeneration,
[
function(test, expect) {
var justId = function(doc) {
return _.omit(doc, '_id');
const justId = function(doc) {
const { _id, ...rest } = doc;
return rest;
};
TRANSFORMS['justId'] = justId;
var collectionOptions = {
@@ -2111,9 +2117,9 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
// This test is duplicated below (with some changes) for async upserts that go
// over the network.
_.each(Meteor.isServer ? [true, false] : [true], function(minimongo) {
_.each([true, false], function(useUpdate) {
_.each([true, false], function(useDirectCollection) {
Meteor.isServer ? [true, false] : [true].forEach(function(minimongo) {
[true, false].forEach(function(useUpdate) {
[true, false].forEach(function(useDirectCollection) {
Tinytest.addAsync(
'mongo-livedata - ' +
(useUpdate ? 'update ' : '') +
@@ -2129,7 +2135,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
// directly calling MongoConnection.upsert().
var skipIds = useUpdate || (!minimongo && useDirectCollection);
if (minimongo)
options = _.extend({}, collectionOptions, { connection: null });
options = Object.assign({}, collectionOptions, { connection: null });
var coll = new Mongo.Collection(
'livedata_upsert_collection_' +
run +
@@ -2356,9 +2362,9 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
// the Mongo.Collection and the MongoConnection.
//
// XXX Rewrite with testAsyncMulti, that would simplify things a lot!
_.each(Meteor.isServer ? [false] : [true, false], function(useNetwork) {
_.each(useNetwork ? [false] : [true, false], function(useDirectCollection) {
_.each([true, false], function(useUpdate) {
Meteor.isServer ? [false] : [true, false].forEach(function(useNetwork) {
useNetwork ? [false] : [true, false].forEach(function(useDirectCollection) {
[true, false].forEach(function(useUpdate) {
Tinytest.addAsync(
asyncUpsertTestName(
useNetwork,
@@ -2399,7 +2405,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
coll = new Mongo.Collection(collName, collectionOptions);
Meteor.subscribe('c-' + collName, next0);
} else {
var opts = _.clone(collectionOptions);
var opts = Object.assign({}, collectionOptions);
if (Meteor.isClient) opts.connection = null;
coll = new Mongo.Collection(collName, opts);
if (useDirectCollection) coll = coll._collection;
@@ -2649,7 +2655,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
// Runs a method and its stub which do some upserts. The method throws an error
// if we don't get the right return values.
if (Meteor.isClient) {
_.each([true, false], function(useUpdate) {
[true, false].forEach(function(useUpdate) {
Tinytest.addAsync(
'mongo-livedata - ' +
(useUpdate ? 'update ' : '') +
@@ -2678,8 +2684,8 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
});
}
_.each(Meteor.isServer ? [true, false] : [true], function(minimongo) {
_.each([true, false], function(useUpdate) {
Meteor.isServer ? [true, false] : [true].forEach(function(minimongo) {
[true, false].forEach(function(useUpdate) {
Tinytest.addAsync(
'mongo-livedata - ' +
(useUpdate ? 'update ' : '') +
@@ -2691,7 +2697,7 @@ _.each( [ 'MONGO', 'STRING'], function(idGeneration) {
var run = test.runId();
var options = collectionOptions;
if (minimongo)
options = _.extend({}, collectionOptions, { connection: null });
options = Object.assign({}, collectionOptions, { connection: null });
var coll = new Mongo.Collection(
'livedata_upsert_by_id_collection_' + run,
options
@@ -2821,7 +2827,7 @@ testAsyncMulti("mongo-livedata - specified _id", [
async function collectionInsert (test, expect, coll, index) {
const id = await coll.insertAsync({name: "foo"});
const o = await coll.findOneAsync(id) || {};
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2833,7 +2839,7 @@ async function collectionUpsert(test, expect, coll, index) {
test.equal(result.numberAffected, 1);
const o = await coll.findOneAsync(upsertId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2841,14 +2847,14 @@ async function collectionUpsertExisting(test, expect, coll, index) {
const id = await coll.insertAsync({ name: 'foo' });
const o = await coll.findOneAsync(id);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
const result = await coll.upsertAsync(id, { $set: { name: 'bar' } });
test.equal(result.insertedId, id);
test.equal(result.numberAffected, 1);
const ob = await coll.findOneAsync(id);
test.isTrue(_.isObject(ob));
test.isTrue(isObject(ob));
test.equal(ob.name, 'bar');
}
@@ -2867,7 +2873,7 @@ async function functionCallsInsert(test, expect, coll, index) {
test.equal(ids[0], stubId);
const o = await coll.findOneAsync(stubId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2885,7 +2891,7 @@ async function functionCallsUpsert(test, expect, coll, index) {
test.equal(result.numberAffected, 1);
const o = await coll.findOneAsync(upsertId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2908,7 +2914,7 @@ async function functionCallsUpsertExisting(test, expect, coll, index) {
test.equal(result.insertedId, undefined);
const ob = await coll.findOneAsync(id);
test.isTrue(_.isObject(ob));
test.isTrue(isObject(ob));
test.equal(ob.name, 'bar');
}
@@ -2927,7 +2933,7 @@ async function functionCalls3Inserts(test, expect, coll, index) {
test.equal(ids[i], stubId);
var o = await coll.findOneAsync(stubId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
}
@@ -2949,7 +2955,7 @@ async function functionChainInsert(test, expect, coll, index) {
await Meteor._sleepForMs(100);
var o = await coll.findOneAsync(stubId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2971,7 +2977,7 @@ async function functionChain2Insert(test, expect, coll, index) {
await Meteor._sleepForMs(100);
const o = await coll.findOneAsync(stubId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
@@ -2989,41 +2995,32 @@ async function functionChain2Upsert(test, expect, coll, index) {
test.equal(result.numberAffected, 1);
await Meteor._sleepForMs(100);
const o = await coll.findOneAsync(upsertId);
test.isTrue(_.isObject(o));
test.isTrue(isObject(o));
test.equal(o.name, 'foo');
}
_.each(
{
collectionInsert: collectionInsert,
collectionUpsert: collectionUpsert,
functionCallsInsert: functionCallsInsert,
functionCallsUpsert: functionCallsUpsert,
functionCallsUpsertExisting: functionCallsUpsertExisting,
functionCalls3Insert: functionCalls3Inserts,
functionChainInsert: functionChainInsert,
functionChain2Insert: functionChain2Insert,
functionChain2Upsert: functionChain2Upsert,
},
function(fn, name) {
_.each([1, 3], function(repetitions) {
_.each([1, 3], function(collectionCount) {
_.each(['STRING', 'MONGO'], function(idGeneration) {
testAsyncMulti(
'mongo-livedata - consistent _id generation ' +
name +
', ' +
repetitions +
' repetitions on ' +
collectionCount +
' collections, idGeneration=' +
idGeneration,
[
function(test, expect) {
var collectionOptions = { idGeneration: idGeneration };
Object.entries({
collectionInsert: collectionInsert,
collectionUpsert: collectionUpsert,
functionCallsInsert: functionCallsInsert,
functionCallsUpsert: functionCallsUpsert,
functionCallsUpsertExisting: functionCallsUpsertExisting,
functionCalls3Insert: functionCalls3Inserts,
functionChainInsert: functionChainInsert,
functionChain2Insert: functionChain2Insert,
functionChain2Upsert: functionChain2Upsert
}).forEach(function([name, fn]) {
[1, 3].forEach(function(repetitions) {
[1, 3].forEach(function(collectionCount) {
['STRING', 'MONGO'].forEach(function(idGeneration) {
testAsyncMulti('mongo-livedata - consistent _id generation ' + name + ', ' + repetitions + ' repetitions on ' + collectionCount + ' collections, idGeneration=' + idGeneration, [function(test, expect) {
var collectionOptions = {
idGeneration: idGeneration
};
var cleanups = (this.cleanups = []);
this.collections = _.times(collectionCount, function() {
this.collections = times(collectionCount, function() {
var collectionName = 'consistentid_' + Random.id();
if (Meteor.isClient) {
Meteor.call(
@@ -3672,7 +3669,7 @@ var TestCustomType = function (head, tail) {
this.myHead = head;
this.myTail = tail;
};
_.extend(TestCustomType.prototype, {
Object.assign(TestCustomType.prototype, {
clone: function () {
return new TestCustomType(this.myHead, this.myTail);
},
@@ -3807,7 +3804,7 @@ testAsyncMulti('mongo-livedata - oplog - update EJSON', [
async function waitUntilOplogCaughtUp() {
var oplogHandle =
MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle;
MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle;
if (oplogHandle)
await oplogHandle.waitUntilCaughtUp();
}
@@ -3816,7 +3813,7 @@ async function waitUntilOplogCaughtUp() {
Meteor.isServer &&
Tinytest.addAsync('mongo-livedata - cursor dedup stop', async function(test) {
var coll = new Mongo.Collection(Random.id());
_.times(100, async function() {
times(100, async function() {
await coll.insertAsync({ foo: 'baz' });
});
var handler = await coll.find({}).observeChanges({
@@ -3899,7 +3896,7 @@ Meteor.isServer &&
toDelete: true,
});
});
test.equal(_.keys(state), [self.id2]);
test.equal(Object.keys(state), [self.id2]);
// Mutate the one in the unpublished buffer and the one below the
// buffer. Before the fix for #2274, this left the observe state machine in
@@ -3912,14 +3909,14 @@ Meteor.isServer &&
{ multi: 1 }
);
});
test.equal(_.keys(state), [self.id2]);
test.equal(Object.keys(state), [self.id2]);
// Now remove the one published document. This should slide up id1 from the
// buffer, but this didn't work before the #2274 fix.
await runInFence(async function() {
await self.coll.removeAsync({ toDelete: true });
});
test.equal(_.keys(state), [self.id1]);
test.equal(Object.keys(state), [self.id1]);
},
]);
@@ -4511,4 +4508,4 @@ Tinytest.addAsync(
}
}
},
);
);

View File

@@ -6,9 +6,9 @@ var makeCollection = function () {
}
};
_.each ([{added: 'added', forceOrdered: true},
([{added: 'added', forceOrdered: true},
{added: 'added', forceOrdered: false},
{added: 'addedBefore', forceOrdered: false}], function (options) {
{added: 'addedBefore', forceOrdered: false}]).forEach(function (options) {
var added = options.added;
var forceOrdered = options.forceOrdered;
@@ -478,7 +478,7 @@ if (Meteor.isServer) {
self.expects = [];
self.insert = async function(fields) {
return coll.insertAsync(
_.extend({ ts: new MongoInternals.MongoTimestamp(0, 0) }, fields)
Object.assign({ ts: new MongoInternals.MongoTimestamp(0, 0) }, fields)
);
};

View File

@@ -1,3 +1,6 @@
import has from 'lodash.has';
import isEmpty from 'lodash.isempty';
let nextObserveHandleId = 1;
ObserveMultiplexer = class {
@@ -67,7 +70,7 @@ ObserveMultiplexer = class {
Package['facts-base'] && Package['facts-base'].Facts.incrementServerFact(
"mongo-livedata", "observe-handles", -1);
if (_.isEmpty(this._handles) &&
if (isEmpty(this._handles) &&
this._addHandleTasksScheduledButNotPerformed === 0) {
await this._stop();
}
@@ -190,7 +193,7 @@ ObserveMultiplexer = class {
return;
// note: docs may be an _IdMap or an OrderedDict
await this._cache.docs.forEachAsync(async (doc, id) => {
if (!_.has(this._handles, handle._id))
if (!has(this._handles, handle._id))
throw Error("handle got removed before sending initial adds!");
const { _id, ...fields } = handle.nonMutatingCallbacks ? doc
: EJSON.clone(doc);
@@ -229,4 +232,4 @@ ObserveHandle = class {
this._stopped = true;
await this._multiplexer.removeHandle(this._id);
}
};
};

View File

@@ -1,3 +1,5 @@
import has from 'lodash.has';
import isEmpty from 'lodash.isempty';
import { oplogV2V1Converter } from "./oplog_v2_converter";
import { check, Match } from 'meteor/check';
@@ -207,7 +209,7 @@ _.extend(OplogObserveDriver.prototype, {
_addPublished: function (id, doc) {
var self = this;
Meteor._noYieldsAllowed(function () {
var fields = _.clone(doc);
var fields = Object.assign({}, doc);
delete fields._id;
self._published.set(id, self._sharedProjectionFn(doc));
self._multiplexer.added(id, self._projectionFn(fields));
@@ -296,7 +298,7 @@ _.extend(OplogObserveDriver.prototype, {
var projectedOld = self._projectionFn(oldDoc);
var changed = DiffSequence.makeChangedFields(
projectedNew, projectedOld);
if (!_.isEmpty(changed))
if (!isEmpty(changed))
self._multiplexer.changed(id, changed);
});
},
@@ -634,7 +636,7 @@ _.extend(OplogObserveDriver.prototype, {
// selector)?
// oplog format has changed on mongodb 5, we have to support both now
// diff is the format in Mongo 5+ (oplog v2)
var isReplace = !_.has(op.o, '$set') && !_.has(op.o, 'diff') && !_.has(op.o, '$unset');
var isReplace = !has(op.o, '$set') && !has(op.o, 'diff') && !has(op.o, '$unset');
// If this modifier modifies something inside an EJSON custom type (ie,
// anything with EJSON$), then we can't try to use
// LocalCollection._modify, since that just mutates the EJSON encoding,
@@ -646,7 +648,7 @@ _.extend(OplogObserveDriver.prototype, {
var bufferedBefore = self._limit && self._unpublishedBuffer.has(id);
if (isReplace) {
self._handleDoc(id, _.extend({_id: id}, op.o));
self._handleDoc(id, Object.assign({_id: id}, op.o));
} else if ((publishedBefore || bufferedBefore) &&
canDirectlyModifyDoc) {
// Oh great, we actually know what the document is, so we can apply
@@ -864,11 +866,11 @@ _.extend(OplogObserveDriver.prototype, {
// the selector, not just the fields we are going to publish (that's the
// "shared" projection). And we don't want to apply any transform in the
// cursor, because observeChanges shouldn't use the transform.
var options = _.clone(self._cursorDescription.options);
var options = Object.assign({}, self._cursorDescription.options);
// Allow the caller to modify the options. Useful to specify different
// skip and limit values.
_.extend(options, optionsOverwrite);
Object.assign(options, optionsOverwrite);
options.fields = self._sharedProjection;
delete options.transform;
@@ -906,7 +908,7 @@ _.extend(OplogObserveDriver.prototype, {
if (!newResults.has(id))
idsToRemove.push(id);
});
_.each(idsToRemove, function (id) {
idsToRemove.forEach(function (id) {
self._removePublished(id);
});
@@ -1044,11 +1046,11 @@ OplogObserveDriver.cursorSupported = function (cursorDescription, matcher) {
};
var modifierCanBeDirectlyApplied = function (modifier) {
return _.all(modifier, function (fields, operation) {
return _.all(fields, function (value, field) {
return Object.entries(modifier).every(function ([operation, fields]) {
return Object.entries(fields).every(function ([field, value]) {
return !/EJSON\$/.test(field);
});
});
};
MongoInternals.OplogObserveDriver = OplogObserveDriver;
MongoInternals.OplogObserveDriver = OplogObserveDriver;

View File

@@ -1,3 +1,6 @@
import isEmpty from 'lodash.isempty';
import has from 'lodash.has';
import { NpmModuleMongodb } from "meteor/npm-mongo";
const { Long } = NpmModuleMongodb;
@@ -358,7 +361,7 @@ Object.assign(OplogHandle.prototype, {
if (doc.o.dropDatabase) {
delete trigger.collection;
trigger.dropDatabase = true;
} else if (_.has(doc.o, "drop")) {
} else if (has(doc.o, "drop")) {
trigger.collection = doc.o.drop;
trigger.dropCollection = true;
trigger.id = null;
@@ -419,7 +422,7 @@ Object.assign(OplogHandle.prototype, {
_setLastProcessedTS: function (ts) {
var self = this;
self._lastProcessedTS = ts;
while (!_.isEmpty(self._catchingUpResolvers) && self._catchingUpResolvers[0].ts.lessThanOrEqual(self._lastProcessedTS)) {
while (!isEmpty(self._catchingUpResolvers) && self._catchingUpResolvers[0].ts.lessThanOrEqual(self._lastProcessedTS)) {
var sequencer = self._catchingUpResolvers.shift();
sequencer.resolver();
}
@@ -432,4 +435,4 @@ Object.assign(OplogHandle.prototype, {
_resetTooFarBehind: function() {
TOO_FAR_BEHIND = process.env.METEOR_OPLOG_TOO_FAR_BEHIND || 2000;
}
});
});

View File

@@ -9,11 +9,19 @@
Package.describe({
summary: "Adaptor for using MongoDB and Minimongo over DDP",
version: "2.0.1",
version: "2.0.2",
});
Npm.depends({
"mongodb-uri": "0.9.7",
"lodash.times": "4.3.2",
"lodash.isempty": "4.4.0",
"lodash.has": "4.5.2",
"lodash.throttle": "4.1.1",
"lodash.once": "4.1.1",
"lodash.identity": "3.0.0",
"lodash.isobject": "3.0.2",
"lodash.clone": "4.5.0"
});
Npm.strip({
@@ -95,20 +103,12 @@ Package.onUse(function (api) {
});
Package.onTest(function (api) {
api.use("mongo");
api.use("check");
api.use("ecmascript");
api.use("npm-mongo", "server");
//api.use('emitter-promise', 'server');
api.use([
"tinytest",
"underscore",
"test-helpers",
"ejson",
"random",
"ddp",
"base64",
]);
api.use('mongo');
api.use('check');
api.use('ecmascript');
api.use('npm-mongo', 'server');
api.use(['tinytest', 'test-helpers', 'ejson', 'random',
'ddp', 'base64']);
// XXX test order dependency: the allow_tests "partial allow" test
// fails if it is run before mongo_livedata_tests.
api.addFiles("mongo_livedata_tests.js", ["client", "server"]);

View File

@@ -1,3 +1,5 @@
import throttle from 'lodash.throttle';
var POLLING_THROTTLE_MS = +process.env.METEOR_POLLING_THROTTLE_MS || 50;
var POLLING_INTERVAL_MS = +process.env.METEOR_POLLING_INTERVAL_MS || 10 * 1000;
@@ -31,7 +33,7 @@ PollingObserveDriver = function (options) {
// Make sure to create a separately throttled function for each
// PollingObserveDriver object.
self._ensurePollIsScheduled = _.throttle(
self._ensurePollIsScheduled = throttle(
self._unthrottledEnsurePollIsScheduled,
self._cursorDescription.options.pollingThrottleMs || POLLING_THROTTLE_MS /* ms */);
@@ -77,7 +79,7 @@ _.extend(PollingObserveDriver.prototype, {
self._cursorDescription.options._pollingInterval || // COMPAT with 1.2
POLLING_INTERVAL_MS;
const intervalHandle = Meteor.setInterval(
_.bind(self._ensurePollIsScheduled, self), pollingInterval);
self._ensurePollIsScheduled.bind(self), pollingInterval);
self._stopCallbacks.push(function () {
Meteor.clearInterval(intervalHandle);
});
@@ -87,10 +89,10 @@ _.extend(PollingObserveDriver.prototype, {
await this._unthrottledEnsurePollIsScheduled();
Package['facts-base'] && Package['facts-base'].Facts.incrementServerFact(
"mongo-livedata", "observe-drivers-polling", 1);
},
// This is always called through _.throttle (except once at startup).
_unthrottledEnsurePollIsScheduled: async function () {
"mongo-livedata", "observe-drivers-polling", 1);
},
// This is always called through _.throttle (except once at startup).
_unthrottledEnsurePollIsScheduled: async function () {
var self = this;
if (self._pollsScheduledButNotStarted > 0)
return;
@@ -220,12 +222,12 @@ _.extend(PollingObserveDriver.prototype, {
await c();
};
_.each(self._stopCallbacks, stopCallbacksCaller);
self._stopCallbacks.forEach(stopCallbacksCaller);
// Release any write fences that are waiting on us.
_.each(self._pendingWrites, async function (w) {
self._pendingWrites.forEach(async function (w) {
await w.committed();
});
Package['facts-base'] && Package['facts-base'].Facts.incrementServerFact(
"mongo-livedata", "observe-drivers-polling", -1);
}
});
});

View File

@@ -1,3 +1,4 @@
import once from 'lodash.once';
import {
ASYNC_COLLECTION_METHODS,
getAsyncMethodName,
@@ -32,7 +33,7 @@ Object.assign(MongoInternals.RemoteCollectionDriver.prototype, {
var self = this;
var ret = {};
REMOTE_COLLECTION_METHODS.forEach(function (m) {
ret[m] = _.bind(self.mongo[m], self.mongo, name);
ret[m] = self.mongo[m].bind(self.mongo, name);
if (!ASYNC_COLLECTION_METHODS.includes(m)) return;
const asyncMethodName = getAsyncMethodName(m);
@@ -60,10 +61,11 @@ Object.assign(MongoInternals.RemoteCollectionDriver.prototype, {
},
});
// Create the singleton RemoteCollectionDriver only on demand, so we
// only require Mongo configuration if it's actually used (eg, not if
// you're only trying to receive data from a remote DDP server.)
MongoInternals.defaultRemoteCollectionDriver = _.once(function () {
MongoInternals.defaultRemoteCollectionDriver = once(function () {
var connectionOptions = {};
var mongoUrl = process.env.MONGO_URL;
@@ -76,7 +78,6 @@ MongoInternals.defaultRemoteCollectionDriver = _.once(function () {
throw new Error("MONGO_URL must be set in environment");
const driver = new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions);
// As many deployment tools, including Meteor Up, send requests to the app in
// order to confirm that the deployment finished successfully, it's required
// to know about a database connection problem before the app starts. Doing so
@@ -87,4 +88,4 @@ MongoInternals.defaultRemoteCollectionDriver = _.once(function () {
});
return driver;
});
});

View File

@@ -1,5 +1,5 @@
core-runtime@1.0.0-alpha300.11
jquery@3.0.1-alpha300.10
meteor@2.0.0-alpha300.10
modules@1.0.0-alpha300.10
modules-runtime@1.0.0-alpha300.10
core-runtime@1.0.0
jquery@3.0.2
meteor@2.0.1
modules@0.20.1
modules-runtime@0.13.2

View File

@@ -1,10 +1,11 @@
Package.describe({
summary: "Manipulate the DOM using CSS selectors",
version: '3.0.1-alpha300.10'
version: '3.0.2'
});
Package.onUse(function (api) {
api.use('modules@0.19.1-alpha300.17');
api.versionsFrom(['2.16', '3.0.3']);
api.use('modules');
// Note that you can `meteor npm install jquery` (any version) into your
// application's node_modules directory, and the meteor/jquery package

View File

@@ -56,34 +56,34 @@
}
},
"@aws-sdk/client-cognito-identity": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.631.0.tgz",
"integrity": "sha512-TXRkgwiLmNpwbiQShtUtSSE4DDHblhjHvtgxtzonzvdlDvYmCmaOwAQgi3HWuHztJtZ9ghf3jKB3N3jxAuKBbA=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.645.0.tgz",
"integrity": "sha512-nBfWDzWBQI1NCHYqBAmiifhdnLRxQYozaq6OjTuRcALjYJbOdFV7t0w9FWGISOq1OnM7r8UdCXlr2bzdyU0tJA=="
},
"@aws-sdk/client-sso": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.631.0.tgz",
"integrity": "sha512-tpXRQMbbTsKED6GGF0rZbg9Nr0DRCWImopX2lVh4deIeHQfNxeOtq2brqDWiPD593I190xeL/HMChSOmvDXNAw=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.645.0.tgz",
"integrity": "sha512-2rc8TjnsNddOeKQ/pfNN7deNvGLXAeKeYtHtGDAiM2qfTKxd2sNcAsZ+JCDLyshuD4xLM5fpUyR0X8As9EAouQ=="
},
"@aws-sdk/client-sso-oidc": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.631.0.tgz",
"integrity": "sha512-afJAssIvsHibVq65qO3Q31NCfSTsPEnyr+PT80uGVAkKev1PJI1AjsxBGUTLtPMV8lrzDzDx5CG9ax1AZ3LG6w=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.645.0.tgz",
"integrity": "sha512-X9ULtdk3cO+1ysurEkJ1MSnu6U00qodXx+IVual+1jXX4RYY1WmQmfo7uDKf6FFkz7wW1DAqU+GJIBNQr0YH8A=="
},
"@aws-sdk/client-sts": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.631.0.tgz",
"integrity": "sha512-Zo/2XDrmNpnSRlQLL8XOCJxuN7UIrGKf4itdjHqtEmD2PqstnYe6IMeEVOELpZ8iktjvsIrVr+qxlIX1QlmgCQ=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.645.0.tgz",
"integrity": "sha512-6azXYtvtnAsPf2ShN9vKynIYVcJOpo6IoVmoMAVgNaBJyllP+s/RORzranYZzckqfmrudSxtct4rVapjLWuAMg=="
},
"@aws-sdk/core": {
"version": "3.629.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.629.0.tgz",
"integrity": "sha512-+/ShPU/tyIBM3oY1cnjgNA/tFyHtlWq+wXF9xEKRv19NOpYbWQ+xzNwVjGq8vR07cCRqy/sDQLWPhxjtuV/FiQ=="
"version": "3.635.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.635.0.tgz",
"integrity": "sha512-i1x/E/sgA+liUE1XJ7rj1dhyXpAKO1UKFUcTTHXok2ARjWTvszHnSXMOsB77aPbmn0fUp1JTx2kHUAZ1LVt5Bg=="
},
"@aws-sdk/credential-provider-cognito-identity": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.631.0.tgz",
"integrity": "sha512-HU6K7m9R95Hu/oQlLgP77h6NmoT6ABEGAUTDZydPV2G9G5LW3ytOjzLNJT9zO99UGb6L3mIn2IB5LtHOzjthGw=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.645.0.tgz",
"integrity": "sha512-Z4By/90TaYQZO1dPR1udYhegFiOlSWnZsJOYSAk4Gdny26Tqb78xVLw9R/33CzFblXC4WVSt4gizXTQ/sYyHNg=="
},
"@aws-sdk/credential-provider-env": {
"version": "3.620.1",
@@ -91,19 +91,19 @@
"integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg=="
},
"@aws-sdk/credential-provider-http": {
"version": "3.622.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.622.0.tgz",
"integrity": "sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg=="
"version": "3.635.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.635.0.tgz",
"integrity": "sha512-iJyRgEjOCQlBMXqtwPLIKYc7Bsc6nqjrZybdMDenPDa+kmLg7xh8LxHsu9088e+2/wtLicE34FsJJIfzu3L82g=="
},
"@aws-sdk/credential-provider-ini": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.631.0.tgz",
"integrity": "sha512-34NmRl6GYlyKTHwiA3C3MjCtmXfoaOXI8b2h7P9eAC8leuIb/51v482g0K6X5P5FqaGY8ZreUq5BMsGjBRr1uQ=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.645.0.tgz",
"integrity": "sha512-LlZW0qwUwNlTaAIDCNpLbPsyXvS42pRIwF92fgtCQedmdnpN3XRUC6hcwSYI7Xru3GGKp3RnceOvsdOaRJORsw=="
},
"@aws-sdk/credential-provider-node": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.631.0.tgz",
"integrity": "sha512-MlYcFknrMQ8RUVe0DMPE09mX8+97s7MLwnVV8l+LFi7m+ZfBz+h6LrohhOXC5elJHf4G3T0r/9Rwct63+zHK/w=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.645.0.tgz",
"integrity": "sha512-eGFFuNvLeXjCJf5OCIuSEflxUowmK+bCS+lK4M8ofsYOEGAivdx7C0UPxNjHpvM8wKd8vpMl5phTeS9BWX5jMQ=="
},
"@aws-sdk/credential-provider-process": {
"version": "3.620.1",
@@ -111,9 +111,9 @@
"integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg=="
},
"@aws-sdk/credential-provider-sso": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.631.0.tgz",
"integrity": "sha512-k3Mj1Fc7faVOGR+qrwROir/8No35G7gbVL5FuY467x3y0ELa/6w0j/0HM+5eqzGABW7pSL/OHONhWKlYwg7Gkw=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.645.0.tgz",
"integrity": "sha512-d6XuChAl5NCsCrUexc6AFb4efPmb9+66iwPylKG+iMTMYgO1ackfy1Q2/f35jdn0jolkPkzKsVyfzsEVoID6ew=="
},
"@aws-sdk/credential-provider-web-identity": {
"version": "3.621.0",
@@ -121,9 +121,9 @@
"integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w=="
},
"@aws-sdk/credential-providers": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.631.0.tgz",
"integrity": "sha512-1yWtgVeEfOogMNLKMADA0f1+zBsKtG5uojU3krQXaq4VDxHgVs0DsFot6BM2/nH8QH49eME7+C2ME9yXGxKBfA=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.645.0.tgz",
"integrity": "sha512-6g9qMngrMCvHNsxmh/1urnWKrvaa2fv55b3bYwPxwJCYAvg/xc7bV8YHL7GS2rJpACG707k9G86DTW+Hab8bJA=="
},
"@aws-sdk/middleware-host-header": {
"version": "3.620.0",
@@ -141,9 +141,9 @@
"integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w=="
},
"@aws-sdk/middleware-user-agent": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.631.0.tgz",
"integrity": "sha512-mpFRFaP9fjXhw8NiRTP+lBPKRKMSKzfCyTXQXrQCSo4fAUaz8LPCc8VdqyoNmx4CLBTRflbEHLx5PfInA0DsrA=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.645.0.tgz",
"integrity": "sha512-NpTAtqWK+49lRuxfz7st9for80r4NriCMK0RfdJSoPFVntjsSQiQ7+2nW2XL05uVY633e9DvCAw8YatX3zd1mw=="
},
"@aws-sdk/region-config-resolver": {
"version": "3.614.0",
@@ -161,9 +161,9 @@
"integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q=="
},
"@aws-sdk/util-endpoints": {
"version": "3.631.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.631.0.tgz",
"integrity": "sha512-aavsyk17lK/r6rfVFYLh6/Y0eWvtbclWteJyW9PQLo5mpHPcTj6IbqMN4LHV27Y9IF7oOlbEAQ1CGTfpUlOvTg=="
"version": "3.645.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.645.0.tgz",
"integrity": "sha512-Oe+xaU4ic4PB1k3pb5VTC1/MWES13IlgpaQw01bVHGfwP6Yv6zZOxizRzca2Y3E+AyR+nKD7vXtHRY+w3bi4bg=="
},
"@aws-sdk/util-locate-window": {
"version": "3.568.0",
@@ -181,44 +181,44 @@
"integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA=="
},
"@mongodb-js/saslprep": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz",
"integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ=="
"version": "1.1.9",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
"integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw=="
},
"@smithy/abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz",
"integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ=="
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.2.tgz",
"integrity": "sha512-b5g+PNujlfqIib9BjkNB108NyO5aZM/RXjfOCXRCqXQ1oPnIkfvdORrztbGgCZdPe/BN/MKDlrGA7PafKPM2jw=="
},
"@smithy/config-resolver": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz",
"integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA=="
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.6.tgz",
"integrity": "sha512-j7HuVNoRd8EhcFp0MzcUb4fG40C7BcyshH+fAd3Jhd8bINNFvEQYBrZoS/SK6Pun9WPlfoI8uuU2SMz8DsEGlA=="
},
"@smithy/core": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.2.tgz",
"integrity": "sha512-in5wwt6chDBcUv1Lw1+QzZxN9fBffi+qOixfb65yK4sDuKG7zAUO9HAFqmVzsZM3N+3tTyvZjtnDXePpvp007Q=="
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.1.tgz",
"integrity": "sha512-7cts7/Oni7aCHebHGiBeWoz5z+vmH+Vx2Z/UW3XtXMslcxI3PEwBZxNinepwZjixS3n12fPc247PHWmjU7ndsQ=="
},
"@smithy/credential-provider-imds": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz",
"integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA=="
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.1.tgz",
"integrity": "sha512-4z/oTWpRF2TqQI3aCM89/PWu3kim58XU4kOCTtuTJnoaS4KT95cPWMxbQfTN2vzcOe96SOKO8QouQW/+ESB1fQ=="
},
"@smithy/fetch-http-handler": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz",
"integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg=="
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.5.tgz",
"integrity": "sha512-DjRtGmK8pKQMIo9+JlAKUt14Z448bg8nAN04yKIvlrrpmpRSG57s5d2Y83npks1r4gPtTRNbAFdQCoj9l3P2KQ=="
},
"@smithy/hash-node": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz",
"integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.4.tgz",
"integrity": "sha512-6FgTVqEfCr9z/7+Em8BwSkJKA2y3krf1em134x3yr2NHWVCo2KYI8tcA53cjeO47y41jwF84ntsEE0Pe6pNKlg=="
},
"@smithy/invalid-dependency": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz",
"integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.4.tgz",
"integrity": "sha512-MJBUrojC4SEXi9aJcnNOE3oNAuYNphgCGFXscaCj2TA/59BTcXhzHACP8jnnEU3n4yir/NSLKzxqez0T4x4tjA=="
},
"@smithy/is-array-buffer": {
"version": "3.0.0",
@@ -226,89 +226,89 @@
"integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="
},
"@smithy/middleware-content-length": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz",
"integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw=="
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.6.tgz",
"integrity": "sha512-AFyHCfe8rumkJkz+hCOVJmBagNBj05KypyDwDElA4TgMSA4eYDZRjVePFZuyABrJZFDc7uVj3dpFIDCEhf59SA=="
},
"@smithy/middleware-endpoint": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz",
"integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.1.tgz",
"integrity": "sha512-Irv+soW8NKluAtFSEsF8O3iGyLxa5oOevJb/e1yNacV9H7JP/yHyJuKST5YY2ORS1+W34VR8EuUrOF+K29Pl4g=="
},
"@smithy/middleware-retry": {
"version": "3.0.14",
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.14.tgz",
"integrity": "sha512-7ZaWZJOjUxa5hgmuMspyt8v/zVsh0GXYuF7OvCmdcbVa/xbnKQoYC+uYKunAqRGTkxjOyuOCw9rmFUFOqqC0eQ=="
"version": "3.0.16",
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.16.tgz",
"integrity": "sha512-08kI36p1yB4CWO3Qi+UQxjzobt8iQJpnruF0K5BkbZmA/N/sJ51A1JJGJ36GgcbFyPfWw2FU48S5ZoqXt0h0jw=="
},
"@smithy/middleware-serde": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz",
"integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.4.tgz",
"integrity": "sha512-1lPDB2O6IJ50Ucxgn7XrvZXbbuI48HmPCcMTuSoXT1lDzuTUfIuBjgAjpD8YLVMfnrjdepi/q45556LA51Pubw=="
},
"@smithy/middleware-stack": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz",
"integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.4.tgz",
"integrity": "sha512-sLMRjtMCqtVcrOqaOZ10SUnlFE25BSlmLsi4bRSGFD7dgR54eqBjfqkVkPBQyrKBortfGM0+2DJoUPcGECR+nQ=="
},
"@smithy/node-config-provider": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz",
"integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ=="
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.5.tgz",
"integrity": "sha512-dq/oR3/LxgCgizVk7in7FGTm0w9a3qM4mg3IIXLTCHeW3fV+ipssSvBZ2bvEx1+asfQJTyCnVLeYf7JKfd9v3Q=="
},
"@smithy/node-http-handler": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz",
"integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg=="
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.0.tgz",
"integrity": "sha512-5TFqaABbiY7uJMKbqR4OARjwI/l4TRoysDJ75pLpVQyO3EcmeloKYwDGyCtgB9WJniFx3BMkmGCB9+j+QiB+Ww=="
},
"@smithy/property-provider": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz",
"integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g=="
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.4.tgz",
"integrity": "sha512-BmhefQbfkSl9DeU0/e6k9N4sT5bya5etv2epvqLUz3eGyfRBhtQq60nDkc1WPp4c+KWrzK721cUc/3y0f2psPQ=="
},
"@smithy/protocol-http": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz",
"integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA=="
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.1.tgz",
"integrity": "sha512-Fm5+8LkeIus83Y8jTL1XHsBGP8sPvE1rEVyKf/87kbOPTbzEDMcgOlzcmYXat2h+nC3wwPtRy8hFqtJS71+Wow=="
},
"@smithy/querystring-builder": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz",
"integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.4.tgz",
"integrity": "sha512-NEoPAsZPdpfVbF98qm8i5k1XMaRKeEnO47CaL5ja6Y1Z2DgJdwIJuJkTJypKm/IKfp8gc0uimIFLwhml8+/pAw=="
},
"@smithy/querystring-parser": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz",
"integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.4.tgz",
"integrity": "sha512-7CHPXffFcakFzhO0OZs/rn6fXlTHrSDdLhIT6/JIk1u2bvwguTL3fMCc1+CfcbXA7TOhjWXu3TcB1EGMqJQwHg=="
},
"@smithy/service-error-classification": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz",
"integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.4.tgz",
"integrity": "sha512-KciDHHKFVTb9A1KlJHBt2F26PBaDtoE23uTZy5qRvPzHPqrooXFi6fmx98lJb3Jl38PuUTqIuCUmmY3pacuMBQ=="
},
"@smithy/shared-ini-file-loader": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz",
"integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.5.tgz",
"integrity": "sha512-6jxsJ4NOmY5Du4FD0enYegNJl4zTSuKLiChIMqIkh+LapxiP7lmz5lYUNLE9/4cvA65mbBmtdzZ8yxmcqM5igg=="
},
"@smithy/signature-v4": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz",
"integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag=="
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.1.tgz",
"integrity": "sha512-SH9J9be81TMBNGCmjhrgMWu4YSpQ3uP1L06u/K9SDrE2YibUix1qxedPCxEQu02At0P0SrYDjvz+y91vLG0KRQ=="
},
"@smithy/smithy-client": {
"version": "3.1.12",
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz",
"integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA=="
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.0.tgz",
"integrity": "sha512-H32nVo8tIX82kB0xI2LBrIcj8jx/3/ITotNLbeG1UL0b3b440YPR/hUvqjFJiaB24pQrMjRbU8CugqH5sV0hkw=="
},
"@smithy/types": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz",
"integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.0.tgz",
"integrity": "sha512-0shOWSg/pnFXPcsSU8ZbaJ4JBHZJPPzLCJxafJvbMVFo9l1w81CqpgUqjlKGNHVrVB7fhIs+WS82JDTyzaLyLA=="
},
"@smithy/url-parser": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz",
"integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.4.tgz",
"integrity": "sha512-XdXfObA8WrloavJYtDuzoDhJAYc5rOt+FirFmKBRKaihu7QtU/METAxJgSo7uMK6hUkx0vFnqxV75urtRaLkLg=="
},
"@smithy/util-base64": {
"version": "3.0.0",
@@ -336,19 +336,19 @@
"integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="
},
"@smithy/util-defaults-mode-browser": {
"version": "3.0.14",
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.14.tgz",
"integrity": "sha512-0iwTgKKmAIf+vFLV8fji21Jb2px11ktKVxbX6LIDPAUJyWQqGqBVfwba7xwa1f2FZUoolYQgLvxQEpJycXuQ5w=="
"version": "3.0.16",
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.16.tgz",
"integrity": "sha512-Os8ddfNBe7hmc5UMWZxygIHCyAqY0aWR8Wnp/aKbti3f8Df/r0J9ttMZIxeMjsFgtVjEryB0q7SGcwBsHk8WEw=="
},
"@smithy/util-defaults-mode-node": {
"version": "3.0.14",
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.14.tgz",
"integrity": "sha512-e9uQarJKfXApkTMMruIdxHprhcXivH1flYCe8JRDTzkkLx8dA3V5J8GZlST9yfDiRWkJpZJlUXGN9Rc9Ade3OQ=="
"version": "3.0.16",
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.16.tgz",
"integrity": "sha512-rNhFIYRtrOrrhRlj6RL8jWA6/dcwrbGYAmy8+OAHjjzQ6zdzUBB1P+3IuJAgwWN6Y5GxI+mVXlM/pOjaoIgHow=="
},
"@smithy/util-endpoints": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz",
"integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg=="
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.0.tgz",
"integrity": "sha512-ilS7/0jcbS2ELdg0fM/4GVvOiuk8/U3bIFXUW25xE1Vh1Ol4DP6vVHQKqM40rCMizCLmJ9UxK+NeJrKlhI3HVA=="
},
"@smithy/util-hex-encoding": {
"version": "3.0.0",
@@ -356,19 +356,19 @@
"integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="
},
"@smithy/util-middleware": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz",
"integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.4.tgz",
"integrity": "sha512-uSXHTBhstb1c4nHdmQEdkNMv9LiRNaJ/lWV2U/GO+5F236YFpdPw+hyWI9Zc0Rp9XKzwD9kVZvhZmEgp0UCVnA=="
},
"@smithy/util-retry": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz",
"integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w=="
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.4.tgz",
"integrity": "sha512-JJr6g0tO1qO2tCQyK+n3J18r34ZpvatlFN5ULcLranFIBZPxqoivb77EPyNTVwTGMEvvq2qMnyjm4jMIxjdLFg=="
},
"@smithy/util-stream": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz",
"integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw=="
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.4.tgz",
"integrity": "sha512-txU3EIDLhrBZdGfon6E9V6sZz/irYnKFMblz4TLVjyq8hObNHNS2n9a2t7GIrl7d85zgEPhwLE0gANpZsvpsKg=="
},
"@smithy/util-uri-escape": {
"version": "3.0.0",
@@ -381,9 +381,9 @@
"integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="
},
"@types/node": {
"version": "22.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz",
"integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g=="
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg=="
},
"@types/webidl-conversions": {
"version": "7.0.3",
@@ -486,14 +486,14 @@
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA=="
},
"tslib": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"undici-types": {
"version": "6.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz",
"integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ=="
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
},
"uuid": {
"version": "9.0.1",

View File

@@ -12,9 +12,9 @@
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="
},
"@types/express": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz",
"integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ=="
},
"@types/express-serve-static-core": {
"version": "4.19.5",
@@ -32,14 +32,14 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
},
"@types/node": {
"version": "22.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz",
"integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g=="
"version": "22.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
"integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA=="
},
"@types/qs": {
"version": "6.9.15",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
"integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg=="
"version": "6.9.16",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz",
"integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A=="
},
"@types/range-parser": {
"version": "1.2.7",
@@ -67,19 +67,14 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"dependencies": {
"bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
},
"qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="
}
}
},
@@ -161,9 +156,9 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="
},
"errorhandler": {
"version": "1.5.1",
@@ -191,31 +186,48 @@
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
},
"express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
"dependencies": {
"cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
},
"qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dependencies": {
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
}
}
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
}
}
},
"finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg=="
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="
},
"forwarded": {
"version": "0.2.0",
@@ -293,9 +305,9 @@
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="
},
"methods": {
"version": "1.1.2",
@@ -360,9 +372,9 @@
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
},
"promise-polyfill": {
"version": "1.1.6",
@@ -380,9 +392,9 @@
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
},
"qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA=="
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="
},
"range-parser": {
"version": "1.2.1",
@@ -390,9 +402,9 @@
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dependencies": {
"bytes": {
"version": "3.1.2",
@@ -412,10 +424,15 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz",
"integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==",
"dependencies": {
"debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -424,9 +441,33 @@
}
},
"serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g=="
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"dependencies": {
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dependencies": {
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
}
}
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
}
}
},
"set-function-length": {
"version": "1.2.2",
@@ -469,9 +510,9 @@
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="
},
"undici-types": {
"version": "6.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz",
"integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ=="
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
},
"unpipe": {
"version": "1.0.0",

View File

@@ -1,18 +1,18 @@
Package.describe({
summary: "Serves a Meteor app over HTTP",
version: "2.0.1",
version: "2.0.2",
});
Npm.depends({
"cookie-parser": "1.4.6",
express: "4.18.2",
"@types/express": "4.17.15",
express: "4.21.0",
"@types/express": "4.17.21",
compression: "1.7.4",
errorhandler: "1.5.1",
parseurl: "1.3.3",
send: "0.18.0",
send: "1.1.0",
"stream-to-string": "1.2.1",
qs: "6.11.2",
qs: "6.13.0",
useragent: "2.3.0",
"@types/connect": "3.4.38",
});

View File

@@ -1,6 +1,6 @@
{
"track": "METEOR",
"version": "3.0.2-beta.4",
"version": "3.0.3-rc.0",
"recommended": false,
"official": false,
"description": "Meteor experimental release"

View File

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

View File

@@ -5,10 +5,10 @@ set -u
UNAME=$(uname)
ARCH=$(uname -m)
NODE_VERSION=20.15.1
NODE_VERSION=20.17.0
MONGO_VERSION_64BIT=7.0.5
MONGO_VERSION_32BIT=3.2.22
NPM_VERSION=10.7.0
NPM_VERSION=10.8.2
if [ "$UNAME" == "Linux" ] ; then

View File

@@ -10,19 +10,19 @@ var packageJson = {
dependencies: {
// Keep the versions of these packages consistent with the versions
// found in dev-bundle-tool-package.js.
promise: "8.1.0",
promise: "8.3.0",
"@meteorjs/reify": "0.25.2",
"@babel/parser": "7.17.0",
"@babel/parser": "7.25.0",
"lru-cache": "6.0.0",
underscore: "1.13.6",
underscore: "1.13.7",
"source-map-support": "https://github.com/meteor/node-source-map-support/tarball/81bce1f99625e62af73338f63afcf2b44c6cfa5e",
"@types/semver": "5.5.0",
semver: "7.5.4"
"@types/semver": "7.5.8",
semver: "7.6.3"
},
// These are only used in dev mode (by shell.js) so end-users can avoid
// needing to install them if they use `npm install --production`.
devDependencies: {
"@types/underscore": "1.11.2",
"@types/underscore": "1.11.15",
split2: "3.2.2",
multipipe: "2.0.1",
chalk: "4.1.2"

View File

@@ -10,7 +10,7 @@ var packageJson = {
dependencies: {
// Explicit dependency because we are replacing it with a bundled version
// and we want to make sure there are no dependencies on a higher version
npm: "10.7.0",
npm: "10.8.2",
"node-gyp": "9.4.0",
"@mapbox/node-pre-gyp": "1.0.11",
typescript: "5.4.5",
@@ -19,18 +19,18 @@ var packageJson = {
// found in dev-bundle-server-package.js.
"@meteorjs/reify": "0.25.2",
// So that Babel can emit require("@babel/runtime/helpers/...") calls.
"@babel/runtime": "7.15.3",
"@babel/runtime": "7.25.0",
// For backwards compatibility with isopackets that still depend on
// babel-runtime rather than @babel/runtime.
"babel-runtime": "7.0.0-beta.3",
"@types/underscore": "1.11.2",
underscore: "1.13.6",
"@types/underscore": "1.11.15",
underscore: "1.13.7",
"source-map-support": "https://github.com/meteor/node-source-map-support/tarball/1912478769d76e5df4c365e147f25896aee6375e",
"@types/semver": "5.5.0",
semver: "7.5.4",
"@types/semver": "7.5.8",
semver: "7.6.3",
request: "2.88.2",
uuid: "3.4.0",
"graceful-fs": "4.2.6",
"graceful-fs": "4.2.11",
fstream: "https://github.com/meteor/fstream/tarball/cf4ea6c175355cec7bee38311e170d08c4078a5d",
tar: "6.1.11",
'tar-fs': "2.1.1",
@@ -41,15 +41,15 @@ var packageJson = {
"source-map": "0.7.4",
chalk: "4.1.2",
// TODO: maybe replace with https://www.npmjs.com/package/better-sqlite3
sqlite3: "5.0.2",
sqlite3: "5.1.7",
inquirer: "8.2.6",
"http-proxy": "1.18.1",
"is-reachable": "3.1.0",
"wordwrap": "1.0.0",
"moment": "2.29.1",
"moment": "2.30.1",
"rimraf": "2.6.2",
"glob": "7.1.6",
ignore: "3.3.7",
ignore: "5.3.2",
// XXX: When we update this, see if it fixes this Github issue:
// https://github.com/jgm/CommonMark/issues/276 . If it does, remove the
// workaround from the tool.
@@ -57,14 +57,14 @@ var packageJson = {
escope: "3.6.0",
split2: "3.2.2",
multipipe: "2.0.1",
pathwatcher: "8.1.0",
pathwatcher: "8.1.2",
"vscode-nsfw": "2.1.8",
// The @wry/context package version must be compatible with the
// version constraint imposed by optimism/package.json.
optimism: "0.16.1",
"@wry/context": "0.6.0",
'lru-cache': '6.0.0',
"anser": "2.0.1",
"anser": "2.1.1",
'xmlbuilder2': '1.8.1',
"ws": "7.4.5",
"open":"8.4.2"

View File

@@ -516,7 +516,8 @@ async function doRunCommand(options) {
open(`http://localhost:${options.port}`)
}
}
}
},
open: options.open,
});
}

View File

@@ -13,11 +13,11 @@ export const CORDOVA_ARCH = "web.cordova";
export const CORDOVA_PLATFORMS = ['ios', 'android'];
const CORDOVA_ANDROID_VERSION = "12.0.1";
const CORDOVA_ANDROID_VERSION = "13.0.0";
export const CORDOVA_DEV_BUNDLE_VERSIONS = {
'cordova-lib': '10.0.0',
'cordova-common': '4.0.2',
'cordova-lib': '12.0.1',
'cordova-common': '5.0.0',
'cordova-create': '2.0.0',
'cordova-registry-mapper': '1.1.15',
'cordova-android': CORDOVA_ANDROID_VERSION,
@@ -25,7 +25,7 @@ export const CORDOVA_DEV_BUNDLE_VERSIONS = {
export const CORDOVA_PLATFORM_VERSIONS = {
'android': CORDOVA_ANDROID_VERSION,
'ios': '7.0.1',
'ios': '7.1.1',
};
export const SWIFT_VERSION = 5;

View File

@@ -342,14 +342,21 @@ export const optimisticReadMeteorIgnore = wrap((dir: string) => {
const meteorIgnorePath = pathJoin(dir, ".meteorignore");
const meteorIgnoreStat = optimisticStatOrNull(meteorIgnorePath);
let ignoreConfig = null;
if (meteorIgnoreStat &&
meteorIgnoreStat.isFile()) {
return ignore().add(
optimisticReadFile(meteorIgnorePath).toString("utf8")
ignoreConfig = ignore().add(
optimisticReadFile(meteorIgnorePath).toString("utf8")
);
}
return null;
const customMeteorIgnore = process.env.METEOR_IGNORE;
if (customMeteorIgnore != null) {
ignoreConfig = ignoreConfig || ignore();
ignoreConfig = ignoreConfig.add(customMeteorIgnore);
}
return ignoreConfig;
});
type LookupPkgJsonType = OptimisticWrapperFunction<

View File

@@ -124,7 +124,7 @@ var maybeShowBanners = async function () {
"=> A patch (" +
catalogUtils.displayRelease(track, patchReleaseVersion) +
") for your current release is available!");
runLog.log(" Check the changelog https://docs.meteor.com/changelog.html and update this project now with 'meteor update --patch'.");
runLog.log(" Check the changelog https://docs.meteor.com/history.html and update this project now with 'meteor update --patch'.");
}
return;
}
@@ -142,7 +142,7 @@ var maybeShowBanners = async function () {
if (shouldShow(futureReleaseKey)) {
runLog.log(
"=> " + catalogUtils.displayRelease(track, futureReleases[0]) +
" is available. Check the changelog https://docs.meteor.com/changelog.html and update this project with 'meteor update'.");
" is available. Check the changelog https://docs.meteor.com/history.html and update this project with 'meteor update'.");
}
return;
}

View File

@@ -1782,11 +1782,36 @@ export class MeteorConfig {
const json = optimisticReadJsonOrNull(this.packageJsonPath);
this._config = json && json.meteor || null;
this.watchSet.addFile(
this.packageJsonPath,
optimisticHashOrNull(this.packageJsonPath)
this.packageJsonPath,
optimisticHashOrNull(this.packageJsonPath)
);
}
const customMeteorConfigClient = process.env.METEOR_CONFIG_CLIENT;
const customMeteorConfigServer = process.env.METEOR_CONFIG_SERVER;
const customMeteorConfigTest = process.env.METEOR_CONFIG_TEST;
const customMeteorConfigTestClient = process.env.METEOR_CONFIG_TEST_CLIENT;
const customMeteorConfigTestServer = process.env.METEOR_CONFIG_TEST_SERVER;
this._config =
customMeteorConfigClient != null ||
customMeteorConfigServer != null ||
customMeteorConfigTest != null ||
customMeteorConfigTestClient != null ||
customMeteorConfigTestServer != null ? {
...this._config || {},
mainModule: {
client: process.env.METEOR_CONFIG_CLIENT || this._config.mainModule.client,
server: process.env.METEOR_CONFIG_SERVER || this._config.mainModule.server,
},
...customMeteorConfigTest && {testModule: customMeteorConfigTest},
...((customMeteorConfigTestClient || customMeteorConfigTestServer) && {
testModule: {
client: customMeteorConfigTestClient || this._config.testModule.client,
server: customMeteorConfigTestServer || this._config.testModule.server,
},
}),
} : this._config;
return this._config;
}

View File

@@ -399,7 +399,11 @@ exports.run = async function (options) {
var runner = new Runner(runOptions);
await runner.init();
// don't wait this on to finish
setTimeout(() => runner.start(), 0);
if (runOptions.open) {
await runner.start();
} else {
setTimeout(() => runner.start(), 0);
}
onBuilt && onBuilt();
var result = await promise;
await runner.stop();

View File

@@ -12,7 +12,7 @@
"@apollo/server": "^4.10.0",
"@babel/runtime": "^7.23.9",
"graphql": "^16.8.1",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View File

@@ -6,6 +6,6 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
}
}

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"jquery": "^3.7.1",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -15,7 +15,7 @@
"@emotion/styled": "^11.9.3",
"@react-icons/all-files": "^4.1.0",
"framer-motion": "^6.4.2",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View File

@@ -8,7 +8,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"jquery": "^3.7.1",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"devDependencies": {
"chai": "^4.2.0"

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View File

@@ -19,4 +19,4 @@ hot-module-replacement # Update client in development without reloading the pag
~prototype~
static-html # Define static page content in .html files
jorgenvatle:vite-bundler@2.0.0-beta.12
jorgenvatle:vite-bundler

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.9",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"solid-js": "^1.8.15"
},
"meteor": {

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"svelte": "^3.59.2"
},
"devDependencies": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"autoprefixer": "^10.4.4",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"postcss": "^8.4.12",
"postcss-load-config": "^3.1.4",
"react": "^17.0.2",

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View File

@@ -18,6 +18,6 @@ shell-server # Server-side component of the `meteor shell` com
hot-module-replacement # Update client in development without reloading the page
static-html # Define static page content in .html files
jorgenvatle:vite-bundler@2.0.0-beta.12
jorgenvatle:vite-bundler
~prototype~

View File

@@ -10,7 +10,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"vue": "^3.3.9",
"vue-meteor-tracker": "^3.0.0-beta.7",
"vue-router": "^4.2.5"
@@ -26,7 +26,7 @@
"@types/meteor": "^2.9.7",
"@vitejs/plugin-vue": "^3.2.0",
"autoprefixer": "^10.4.16",
"meteor-vite": "^1.7.1",
"meteor-vite": "^1.10.3",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"vite": "^3.2.7"

View File

@@ -6,7 +6,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"puppeteer": "^2.1.1"
},
"meteor": {

View File

@@ -3,7 +3,7 @@
"private": true,
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"jquery": "^3.7.1",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": "css-injection-test.js"

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"jquery": "^3.7.1",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": "code.js"

View File

@@ -8,6 +8,6 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
}
}

View File

@@ -10,7 +10,7 @@
"acorn": "^7.4.1",
"arson": "^0.2.6",
"jquery": "^3.7.1",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"moment": "^2.29.4",
"optimism": "^0.11.5",
"private": "^0.1.8",

View File

@@ -8,7 +8,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"puppeteer": "^10.4.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"

View File

@@ -7,7 +7,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"puppeteer": "^2.1.1"
},
"meteor": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"config": "file:../config-package",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@babel/runtime": "^7.23.5",
"external-package": "file:../external-package",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": {

View File

@@ -6,6 +6,6 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
}
}

View File

@@ -19,7 +19,7 @@
"jsx-import-test": "file:imports/links/jsx-import-test",
"lodash-es": "^4.17.21",
"markdown-to-jsx": "4.0.3",
"meteor-node-stubs": "^1.2.7",
"meteor-node-stubs": "^1.2.10",
"mobx": "5.8.0",
"moment": "^2.30.1",
"mssql": "^3.1.1",

View File

@@ -6,6 +6,6 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
}
}

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@babel/runtime": "^7.23.5",
"meteor-node-stubs": "^1.2.7"
"meteor-node-stubs": "^1.2.10"
},
"meteor": {
"mainModule": false,

View File

@@ -7,16 +7,17 @@ export default defineConfig({
head: [
["link", { rel: "icon", href: "/logo.png" }],
[
'script',
"script",
{
async: '',
src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
async: "",
src: "https://widget.kapa.ai/kapa-widget.bundle.js",
"data-website-id": "64051b0e-d79f-4fe7-b3ca-ff5c84075693",
"data-project-name": "Meteor",
"data-project-color": "#36436b",
"data-project-logo": "https://v3-docs.meteor.com/logo.png",
"data-modal-disclaimer": "This is a custom LLM for answering questions about Meteor. Answers are based on the contents of the docs, answered forum posts, YouTube videos and GitHub issues. Please note that answers are generated by AI and may not be fully accurate, so please use your best judgement."
}
"data-modal-disclaimer":
"This is a custom LLM for answering questions about Meteor. Answers are based on the contents of the docs, answered forum posts, YouTube videos and GitHub issues. Please note that answers are generated by AI and may not be fully accurate, so please use your best judgement.",
},
],
],
lastUpdated: true,
@@ -27,81 +28,102 @@ export default defineConfig({
// https://vitepress.dev/reference/default-theme-config
nav: [
{
text: 'Docs',
text: "Docs",
activeMatch: `^/(guide|docs|examples)/`,
items: [
{ text: 'Quick Start', link: '/about/install' },
{ text: 'Examples', link: 'https://github.com/meteor/examples' },
{ text: "Quick Start", link: "/about/install" },
{ text: "Examples", link: "https://github.com/meteor/examples" },
{
text: 'Meteor.js 2 Docs',
link: 'https://v2-docs.meteor.com'
text: "Meteor.js 2 Docs",
link: "https://v2-docs.meteor.com",
},
{
text: 'Migration from Meteor.js 2',
link: 'https://v3-migration-docs.meteor.com'
text: "Migration from Meteor.js 2",
link: "https://v3-migration-docs.meteor.com",
},
{
text: 'Tutorials',
text: "Tutorials",
items: [
{ text: 'Meteor + Vue + vue-meteor-tracker', link: '/tutorials/meteorjs3-vue3-vue-meteor-tracker' },
]
{
text: "Meteor.js 3 + React",
link: "/tutorials/react/index",
},
{
text: "Meteor + Vue + vue-meteor-tracker",
link: "/tutorials/vue/meteorjs3-vue3-vue-meteor-tracker",
},
],
},
]
],
},
{
text: 'Ecosystem',
text: "Ecosystem",
activeMatch: `^/ecosystem/`,
items: [
{
text: 'Community & Help',
text: "Community & Help",
items: [
{
text: 'Meteor Forums',
link: 'https://forums.meteor.com'
text: "Meteor Forums",
link: "https://forums.meteor.com",
},
{
text: 'Meteor Lounge Discord',
link: 'https://discord.gg/hZkTCaVjmT'
text: "Meteor Lounge Discord",
link: "https://discord.gg/hZkTCaVjmT",
},
{
text: 'GitHub Discussions',
link: 'https://github.com/meteor/meteor/discussions'
text: "GitHub Discussions",
link: "https://github.com/meteor/meteor/discussions",
},
]
],
},
{
text: 'Resources',
items: [
{ text: 'Packages on Atmosphere', link: 'https://atmospherejs.com/' },
{ text: 'VS Code Extension', link: 'https://marketplace.visualstudio.com/items?itemName=meteor-toolbox.meteor-toolbox' },
{ text: 'DevTools - Chrome Extension', link: 'https://chromewebstore.google.com/detail/ibniinmoafhgbifjojidlagmggecmpgf' },
{ text: 'DevTools - Firefox Extension', link: 'https://addons.mozilla.org/en-US/firefox/addon/meteor-devtools-evolved/' },
]
},
{
text: 'Learning',
text: "Resources",
items: [
{
text: 'Meteor University',
link: 'https://university.meteor.com'
text: "Packages on Atmosphere",
link: "https://atmospherejs.com/",
},
{
text: 'Youtube Channel',
link: 'https://www.youtube.com/@meteorsoftware'
text: "VS Code Extension",
link: "https://marketplace.visualstudio.com/items?itemName=meteor-toolbox.meteor-toolbox",
},
]
{
text: "DevTools - Chrome Extension",
link: "https://chromewebstore.google.com/detail/ibniinmoafhgbifjojidlagmggecmpgf",
},
{
text: "DevTools - Firefox Extension",
link: "https://addons.mozilla.org/en-US/firefox/addon/meteor-devtools-evolved/",
},
],
},
{
text: 'News',
text: "Learning",
items: [
{ text: 'Blog on Dev.to', link: 'https://dev.to/meteor' },
{ text: 'Blog on Medium', link: 'https://blog.meteor.com' },
{ text: 'Twitter', link: 'https://x.com/meteorjs' },
{ text: 'LinkedIn', link: 'https://www.linkedin.com/company/meteor-software/' },
]
}
]
{
text: "Meteor University",
link: "https://university.meteor.com",
},
{
text: "Youtube Channel",
link: "https://www.youtube.com/@meteorsoftware",
},
],
},
{
text: "News",
items: [
{ text: "Blog on Dev.to", link: "https://dev.to/meteor" },
{ text: "Blog on Medium", link: "https://blog.meteor.com" },
{ text: "Twitter", link: "https://x.com/meteorjs" },
{
text: "LinkedIn",
link: "https://www.linkedin.com/company/meteor-software/",
},
],
},
],
},
{ text: "API", link: "/api/" },
{ text: "Galaxy Cloud", link: "https://www.meteor.com/cloud" },
@@ -133,7 +155,14 @@ export default defineConfig({
text: "Install Meteor",
link: "/about/install",
},
// TODO: Your first app meteor app
{
text: "Web Apps",
link: "/about/web-apps",
},
{
text: "Cordova",
link: "/about/cordova",
},
],
collapsed: true,
},
@@ -219,9 +248,9 @@ export default defineConfig({
link: "/api/package",
},
{
text: 'Top Level Await',
link: '/api/top-level-await'
}
text: "Top Level Await",
link: "/api/top-level-await",
},
],
collapsed: true,
},
@@ -358,7 +387,14 @@ export default defineConfig({
{
text: "Tutorials",
items: [
{ link: "/tutorials/meteorjs3-vue3-vue-meteor-tracker", text: "Meteor + Vue + vue-meteor-tracker" },
{
text: "Meteor.js 3 + React",
link: "/tutorials/react/index",
},
{
link: "/tutorials/vue/meteorjs3-vue3-vue-meteor-tracker",
text: "Meteor + Vue + vue-meteor-tracker",
},
],
collapsed: true,
},
@@ -368,11 +404,11 @@ export default defineConfig({
// TODO: Open issue in Vitepress about this
{ link: "/history", text: "Meteor.js v3 (Current)" },
{
link: "https://docs.meteor.com/changelog",
link: "https://v2-docs.meteor.com/changelog",
text: "Meteor.js v2",
},
{
link: "https://docs.meteor.com/changelog#v112220211012",
link: "https://v2-docs.meteor.com/changelog#v112220211012",
text: "Meteor.js v1",
},
],
@@ -381,23 +417,23 @@ export default defineConfig({
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/meteor/meteor' },
{ icon: 'twitter', link: 'https://x.com/meteorjs' },
{ icon: 'discord', link: 'https://discord.gg/hZkTCaVjmT' }
{ icon: "github", link: "https://github.com/meteor/meteor" },
{ icon: "twitter", link: "https://x.com/meteorjs" },
{ icon: "discord", link: "https://discord.gg/hZkTCaVjmT" },
],
logo: { dark: "/meteor-logo.png", light: "/meteor-blue.png" },
search: {
provider: 'algolia',
provider: "algolia",
options: {
appId: '2RBX3PR26I',
apiKey: '7fcba92008b84946f04369df2afa1744',
indexName: 'meteor_docs_v3',
appId: "2RBX3PR26I",
apiKey: "7fcba92008b84946f04369df2afa1744",
indexName: "meteor_docs_v3",
searchParameters: {
facetFilters: ["lang:en"],
},
}
},
},
footer: {

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import NotFound from './NotFound.vue'
import { useData, useRouter } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, provide } from 'vue'
@@ -50,7 +51,11 @@ provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
</script>
<template>
<DefaultTheme.Layout />
<DefaultTheme.Layout >
<template #not-found>
<NotFound />
</template>
</DefaultTheme.Layout>
</template>
<style>

View File

@@ -0,0 +1,96 @@
<script setup>
import { useRouter } from "vitepress";
import { ref, onMounted } from "vue";
// Dynamically construct the redirect URL based on the current path
const router = useRouter();
const redirectUrl = ref("");
onMounted(() => {
redirectUrl.value = `https://v2-docs.meteor.com${router.route.path}`;
});
</script>
<template>
<div class="custom-404-container">
<h1 class="custom-404-title">404</h1>
<p class="custom-404-subtitle">Page Not Found</p>
<hr class="custom-404-divider" />
<p class="custom-404-message">
It looks like you're trying to access a page that doesn't exist. If you
were looking for something from the older version of our documentation,
you might find it here:
<a :href="redirectUrl" target="_blank" class="custom-404-link">{{
redirectUrl
}}</a
>.
</p>
<a href="/" class="custom-404-button">Take me home</a>
</div>
</template>
<style scoped>
.custom-404-container {
text-align: center;
padding: 100px 20px;
color: #fff;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.custom-404-title {
font-size: 72px;
font-weight: bold;
margin-bottom: 20px;
}
.custom-404-subtitle {
font-size: 24px;
margin-bottom: 20px;
letter-spacing: 2px;
}
.custom-404-divider {
width: 10%;
margin: 20px auto;
border: 0.5px solid #4a4a4a;
}
.custom-404-message {
margin: 0 auto;
max-width: 500px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-text-2);
}
.custom-404-button {
margin-top: 16px;
display: inline-block;
border: 1px solid var(--vp-c-brand-1);
border-radius: 16px;
padding: 3px 16px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand-1);
transition: border-color 0.25s, color 0.25s;
}
.custom-404-link {
color: #ff4c4c;
text-decoration: underline;
transition: color 0.3s ease;
}
.custom-404-link:hover {
color: #ff7878;
}
.custom-404-button:hover {
background-color: #ff4c4c;
color: #fff;
}
</style>

View File

@@ -113,9 +113,13 @@
--vc-c-orange-3: #b35e00;
--vc-c-orange-soft: rgba(255, 126, 23, 0.16);
--vc-c-meteor-red-1: #BF212E;
--vc-c-meteor-red-2: #A01A24;
--vc-c-meteor-red-3: #7F141D;
--vp-c-meteor-red-1: #E9A0A7;
--vp-c-meteor-red-2: #e9b4b8;
--vp-c-meteor-red-3: #f0c8cb;
--vc-c-meteor-red-1: #E9A0A7;
--vc-c-meteor-red-2: #e9b4b8;
--vc-c-meteor-red-3: #f0c8cb;
--vc-c-meteor-red-soft: rgba(191, 33, 46, 0.16);
--vp-c-yellow-1: #f9b44e;

View File

@@ -0,0 +1,204 @@
# Cordova
Meteor allows developers to build mobile applications using web technologies like HTML, CSS, and JavaScript, while also accessing native mobile capabilities. This integration is made with [Apache Cordova](https://cordova.apache.org).
Cordova apps run in a web view, which is like a browser without the UI. Different browser engines have varying implementations and support for web standards. This means the web view your app uses can greatly affect its performance and available features. (For details on supported features across browsers and versions, check caniuse.com.)
There is a [Meteor Cordova guide](https://guide.meteor.com/cordova) available that offers advanced configuration details for Meteor Cordova projects. Feel free to refer to it while we update the information in the new documentation.
This section will summarize the steps needed to set up your environment for Meteor Cordova development, manage development, and generate native artifacts for store uploads.
## Pre-Installation
Before you begin, make sure your development environment meets the following requirements:
### Android
#### Java
For Android development, Cordova requires the JDK.
``` sh
# On Debian/Ubuntu:
sudo apt-get update
sudo apt-get install openjdk-17-jdk
# On Mac OSX
brew install openjdk@17
sudo ln -sfn $(brew --prefix)/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk
# using sdkman
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install java 17
sdk default java 17
java -version # Verify installation
```
Ensure `JAVA_HOME` environment variable is set by adding it to `~/.bashrc` or `~/.zshrc` :
``` sh
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
export PATH=$JAVA_HOME/bin:$PATH
```
Run `echo $JAVA_HOME` to check the current Java version. If it's incorrect, manually set the correct path by finding where Java is installed.
#### Android SDK
For Android builds, you will need the Android SDK. You can install it via [Android Studio](https://developer.android.com/studio).
Once Android Studio is installed, go to **SDK Manager** and install the required SDK packages. The minimum required version is Android SDK 34. Install the `Android SDK Command-line Tools (latest)` as well.
Ensure `ANDROID_HOME` environment variable is set by adding it to `~/.bashrc` or `~/.zshrc` :
```sh
export ANDROID_HOME=$HOME/Library/Android/sdk
export ANDROID_SDK_ROOT=${ANDROID_HOME}
export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$PATH
```
#### Gradle
If Gradle cannot be found install it with:
```sh
# On Mac OSX:
brew install gradle
# On Debian/Ubuntu:
sudo apt-get install gradle
# using sdkman
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install gradle 8.7
gradle --version # Verify installation
```
### iOS
For iOS development, you will need Xcode (macOS only).
Install [Xcode](https://apps.apple.com/us/app/xcode/id497799835?mt=12) from the App Store.
After installing, ensure that the **command-line tools** are installed:
```sh
xcode-select --install
```
Once the download and installation are finished, you'll need to accept the license agreement. When you open Xcode for the first time, a dialog will appear with the agreement for you to review and accept. You can then close Xcode. Or use the next command on the command line.
```sh
sudo xcodebuild -license accept
```
Also, install CocoaPods, which is needed to manage iOS project dependencies:
```sh
sudo gem install cocoapods
```
## Development
Once you have all the prerequisites set up, you can quickly get a mobile project running.
### Add platforms
To develop a mobile app, you need to add the platforms (iOS and Android) for Cordova:
```sh
# Android
meteor add-platform android
# iOS (only works on macOS)
meteor add-platform ios
```
### Run emulator
You can now run the application in development mode using the `meteor run` command:
```sh
# Android
meteor run android
# iOS (only works on macOS)
meteor run ios
```
### Run physical device
To run on a physical device, ensure the device is connected via USB:
```sh
# Android
meteor run android-device
# iOS (only works on macOS)
meteor run ios-device
```
### Open IDE
Once you have set up your Meteor project with Cordova, you may want to run or debug your mobile app using **Android Studio** or **XCode** directly. This can be useful for advanced debugging, custom configurations, or accessing specific platform tools
#### Open in Android Studio
1. Open **Android Studio**
2. Click on **"Open an existing Android Studio project"**
3. Navigate to your Meteor project directory:
`.meteor/local/cordova-build/platforms/android/`
4. Open the project
Now you can manage your app with **Android Studio**, including connecting to physical devices or emulators, reviewing code, using debugging tools, and more.
#### Open in XCode
1. Open **XCode**
2. Navigate to the Meteor project directory:
`.meteor/local/cordova-build/platforms/ios/`
3. Open the project or the `.xcworkspace` file
Now you can manage your app with **XCode**, including connecting to physical devices or emulators, reviewing code, using debugging tools, and more.
## Production
### Build
Once development is complete, youll need to build the actual mobile application (APK/AAB for Android or IPA for iOS) to distribute to users or upload to the app stores.
```sh
meteor build ../build-output --server=https://your-server-url.com
```
### Distribute
After building your Cordova project with Meteor, you can use **Android Studio** for Android and **Xcode** for iOS to handle signing and creating the final artifacts.
#### Android
1. Open **Android Studio**
2. Click on **"Open an existing Android Studio project"**
3. Navigate to your Meteor project directory:
`./build-output/android/project`
4. Open the project
5. Go to **Build > Generate Signed Bundle / APK**
6. Follow the prompts to create or use a keystore, [configure signing](https://developer.android.com/studio/publish/app-signing#sign-apk), and build the APK/ABB.
7. Upload the APK/ABB to Play Store using Google Play Console
#### iOS
1. Open **XCode**
2. Navigate to the Meteor project directory:
`../build-output/ios/project`
3. Open the project or the `.xcworkspace` file
4. [Configure Signing in Xcode](https://developer.apple.com/documentation/xcode/sharing-your-teams-signing-certificates)
5. Go to **Product > Archive** to create an archive of your app
6. In the **Organizer** window, click **Distribute App** and follow the prompts to configure signing and export the IPA file.
7. Upload the IPA file to the App Store or distribute via TestFlight.

View File

@@ -4,81 +4,79 @@ Describes the high-level features and actions for the Meteor project in the near
## Introduction
**Quick update moving items to Finished: June 1, 2023**
**Last updated: August 22nd, 2024.**
**Last new items added: September 14, 2022.**
The description of many items include sentences and ideas from Meteor community members.
The description of many items includes sentences and ideas from Meteor community members.
Contributors are encouraged to focus their efforts on work that aligns with the roadmap then we can work together in these areas.
> As with any roadmap, this is a living document that will evolve as priorities and dependencies shift.
> If you have new feature requests or ideas you should open a new [discussion](https://github.com/meteor/meteor/discussions/new).
### Meteor 3.0 release
- Change how Meteor executes Async code; ([Discussion](https://github.com/meteor/meteor/discussions/11505))
- Provide new async APIs where Fibers are required;
- Mongo package with Async API; ([PR](https://github.com/meteor/meteor/pull/12028))
- Provide async versions for Accounts and core packages;
- Adapt Meteor Promise implementation;
- Enable Top-Level Await (TLA) on Meteor server-side; ([PR](https://github.com/meteor/meteor/pull/12095))
- Support Top-Level Await (TLA) on Reify;
- Remove Fibers dependency from Meteor Public APIs;
- Remove Fibers entirely;
- Update Cordova integration to Meteor 3.0;
- Run Meteor on Node.js 18;
- Change web engine from Connect to Express;
> If you have new feature requests or ideas, you should open a new [discussion](https://github.com/meteor/meteor/discussions/new).
### Next releases
- Improve TypeScript support for Meteor and packages; ([Discussion](https://github.com/meteor/meteor/discussions/12080))
- Linux ARM Support; ([PR](https://github.com/meteor/meteor/pull/11809))
- Improve release quality with test coverage and CI automation;
- Review and help to modernize Meteor tools; ([Discussion](https://github.com/meteor/meteor/discussions/12073))
- Improve support for Windows 11 or adopt Windows with WSL;
- Improve Meteor build time; ([Discussion](https://github.com/meteor/meteor/discussions/11587))
- HTTP/3 Support;
- Tree-shaking; ([PR](https://github.com/meteor/meteor/pull/11164))
- Support package.json exports fields; ([Discussion](https://github.com/meteor/meteor/discussions/11727))
- Improve TypeScript support for Meteor and packages ([Discussion](https://github.com/meteor/meteor/discussions/12080))
> Should be an ongoing effort to improve the TypeScript support in Meteor and packages, as we write new code in TypeScript and get more skin in the game, it should naturally improve. This doesnt mean we will actively refactor working code.
- Performance improvements for Meteor 3.0
> After removing fibers, we became heavily reliant on async resources and consequently Async Hooks/Async Local Storage, which has a performance cost, we need to optimize that.
- Bringing community packages to the core
> Some packages are widely used and should be part of the core, which involves identifying and moving them to the core.
- MongoDB Change Streams support ([Discussion](https://github.com/meteor/meteor/discussions/11842))
> Change Streams is the official way to listen to changes in MongoDB. We should provide a way to use it seamlessly in Meteor. It has been planned for a long time, and now were in a position to do it.
- Integrated support for Vite (Client Bundler, [Discussion](https://github.com/meteor/meteor/discussions/11587))
> Vite is a fast and modern client bundler with an amazing ecosystem. It has many potential benefits for Meteor: build performance, tree-shaking, making our codebase leaner, and focusing on what we do best.
- Replace Babel with ESBuild, Rollup, SWC, or another tool for the server bundle ([Discussion](https://github.com/meteor/meteor/discussions/11587))
> Babel is a great tool, but it's slow and has some limitations; we should consider replacing it with a faster and more modern tool for the server bundle. We could potentially use the same tools Vite uses.
- Support package.json exports fields ([Discussion](https://github.com/meteor/meteor/discussions/11727))
- Tree-shaking
> Tree sharking and exports fields may be implemented by integrating with more modern build tools, see previous items.
- Improve release CI/CD speed and reliability (optimized build times will help)
> Sometimes our CI/CD takes too long to run, causing long queues and delays in our release process and feedback loop, we need to improve that.
- Improve support for Windows 11
> We had many complaints in the past, we need to research and make architectural improvements to make it easier to support Windows, not just punctual fixes.
- Document better Windows with WSL
> It's already possible to use Meteor on Windows with WSL, but we need to document it better
- HTTP/3 Support
> HTTP/3 is the next version of the HTTP protocol. We should support it in Meteor to leverage its performance and security benefits.
### Candidate items
We need to discuss further to decide whether or not to proceed with these implementations.
- Update and fix Meteor Client Bundler or Improve DDP Client;
- Improve Passwordless package; ([Discussion](https://github.com/meteor/meteor/discussions/12075))
- Support building mobile apps using CapacitorJS;
- Bring Redis-oplog to core; ([Repository](https://github.com/Meteor-Community-Packages/redis-oplog))
- MongoDB Change Streams support; ([Discussion](https://github.com/meteor/meteor/discussions/11842))
- Better file upload support via DDP; ([Discussion](https://github.com/meteor/meteor/discussions/11523))
We need to discuss further to decide whether to proceed with these implementations.
### Next educational items
- Create a new Meteor Guide; ([Current Guide](https://guide.meteor.com/))
- Scaling Meteor Apps course; ([Meteor University](https://university.meteor.com/))
- Improve DDP Client
- Improve Passwordless package ([Discussion](https://github.com/meteor/meteor/discussions/12075))
- Integrate with Tauri, it might replace Cordova and Electron in a single tool
- Support building mobile apps using CapacitorJS
- Bring Redis-oplog to core ([Repository](https://github.com/Meteor-Community-Packages/redis-oplog))
- Better file upload support via DDP ([Discussion](https://github.com/meteor/meteor/discussions/11523))
### Finished items
- New Async Tracker; ([Blog Post](https://blog.meteor.com/new-meteor-js-2-10-and-the-async-tracker-feature-ffdbe817c801))
- New Suspense hooks for React + Meteor; ([Blog Post](https://blog.meteor.com/new-suspense-hooks-for-meteor-5391570b3007))
- Release Blaze 2.7 supporting async calls; ([Changelog](https://www.blazejs.org/changelog.html))
- New Scaffold API / generate command; ([Blog Post](https://blog.meteor.com/new-meteor-2-9-and-the-scaffold-api-8b5b2b2b2b2b))
- Types added to the core; ([Blog Post](https://blog.meteor.com/new-meteor-2-8-1-and-adding-types-to-the-core-8a6ee56f0141))
- Update Apollo skeleton NPM dependencies;
- MongoDB 6.0 Support; ([Discussion](https://github.com/meteor/meteor/discussions/12092) / [Blog Post](https://blog.meteor.com/new-meteor-2-11-and-the-new-embedded-mongodb-19767076961b))
- Vite integration;
- SolidJS integration;
- Vue 3 integration; ([Forums](https://forums.meteor.com/t/status-of-vue-3-meteor/57915/25) / [Discussion](https://github.com/meteor/meteor/discussions/11521))
- SolidJS starter template;
- Login and Accounts Course; ([Meteor University](https://university.meteor.com/))
- Updated MongoDB driver to 4.8; ([PR](https://github.com/meteor/meteor/pull/12097))
- Make MongoDB integration stable by fixing critical issues;
- New skeleton for creating Meteor apps with Chakra UI;
- Evaluate and improve support for Meteor in VSCode; ([Repository](https://github.com/matheusccastroo/vscode-meteor-toolbox))
- Release Blaze 2.6.2; ([Blog Post](https://blog.meteor.com/new-meteor-js-2-12-and-the-blaze-2-6-2-release-b72c2a7a593f))
- Change how Meteor executes Async code ([Discussion](https://github.com/meteor/meteor/discussions/11505))
- Provide new async APIs where Fibers are required
- Mongo package with Async API ([PR](https://github.com/meteor/meteor/pull/12028))
- Provide async versions for Accounts and core packages
- Adapt Meteor Promise implementation
- Enable Top-Level Await (TLA) on Meteor server-side ([PR](https://github.com/meteor/meteor/pull/12095))
- Support Top-Level Await (TLA) on Reify
- Remove Fibers dependency from Meteor Public APIs
- Remove Fibers entirely
- Update Cordova integration to Meteor 3.0
- Run Meteor on Node.js v20
- Change web engine from Connect to Express
-----------
For more completed items, refer to our [changelog](https://docs.meteor.com/changelog.html).
For more completed items, refer to our [changelog](https://docs.meteor.com/history.html).

View File

@@ -0,0 +1,54 @@
# Web Apps
Meteor allows developers to build web applications using front-end frameworks like React, Vue, Blaze, Svelte, and Solid.
This section will help you quickly set up a new MeteorJS project using React.
## Step 1: Install Meteor
Ensure you have the latest official Meteor release installed. You can find installation instructions in our [docs](/about/install.html).
## Step 2: Create a New Project
To create a new project with Meteor and React, use the command:
```shell
meteor create myapp
```
This command sets up a Meteor project with React, allowing you to start developing right away.
You can also add the `--react` option to explicitly choose React, but it's already included by default.
If you prefer TypeScript, simply add the `--typescript` option.
```shell
meteor create myapp --typescript
```
### Additional Options
Meteor offers flags to generate different types of apps, like choosing a different front-end framework or configurations during project setup.
Additional options are available in the [Meteor CLI](/cli/#meteor-create-app-name) section.
## Step 3: Run Your Project Locally
Navigate into your project directory and start the Meteor server:
```shell
cd myapp
meteor
```
With no arguments, `meteor` runs the project in the current directory in local development mode.
Your application will be running at `http://localhost:3000/`, ready for you to begin development.
## Getting Help
You can find help for using the Meteor command line. Just run `meteor help` to see a list of common commands.
If you want detailed help about a specific command, run `meteor help <command>`. For example, `meteor help create`.
## Next Steps
- Follow the [React](/tutorials/react/index.html) or [Vue](/tutorials/vue/meteorjs3-vue3-vue-meteor-tracker.html) tutorials. New tutorials are coming soon.
- Read about [Cordova for Mobile Apps](/about/cordova.html).
- Explore the [Meteor Guide](https://guide.meteor.com/).

View File

@@ -6,13 +6,13 @@
:::info You are reading the Meteor 3 documentation!
- Searching for the Meteor 2 documentation? Access the [Meteor 2 Docs](https://docs.meteor.com/).
- Searching for the Meteor 2 documentation? Access the [Meteor 2 Docs](https://v2-docs.meteor.com/).
- Upgrading from Meteor 2? Check out the [Migration Guide](https://v3-migration-docs.meteor.com/).
:::
Meteor is a full-stack JavaScript platform for developing modern web and mobile applications. Meteor includes a key set of technologies for building connected-client reactive applications, a build tool, and a curated set of packages from the Node.js and general JavaScript community.
- Meteor allows you to develop in **one language**, JavaScript, in all environments: application server, web browser, and mobile device.
- Meteor allows you to develop in **one language**, JavaScript or TypeScript, in all environments: application server, web browser, and mobile device.
- Meteor uses **data on the wire**, meaning the server sends data, not HTML, and the client renders it.
@@ -20,15 +20,21 @@ Meteor is a full-stack JavaScript platform for developing modern web and mobile
- Meteor provides **full stack reactivity**, allowing your UI to seamlessly reflect the true state of the world with minimal development effort.
- Meteor offers **flexibility in front-end** development, allowing you to choose your preferred framework such as React, Vue, Blaze, Svelte, or Solid.
- Meteor **simplifies back-end and front-end integration** through Methods, its built-in Remote Procedure Call (RPC) system for seamless communication.
- Meteor includes a **ready-to-use Login and Accounts** package, eliminating the need to rebuild authentication systems for your applications.
## Meteor Resources {#learning-more}
### Learning Meteor
- Start by learning how to install Meteor in the [Installation Section](/about/install.html).
- For beginners, the [Tutorials](https://www.meteor.com/developers/tutorials) are the perfect place to start with Meteor. Build a simple app to manage a task list! Available for [React](https://react-tutorial.meteor.com/), [Blaze](https://blaze-tutorial.meteor.com/), [Svelte](https://svelte-tutorial.meteor.com/), and [Vue 3](https://vue3-tutorial.meteor.com/).
- The tutorials are the perfect place to start. Build a simple app to manage a task list! Available for [React](/tutorials/react/index.html), and [Vue 3](/tutorials/vue/meteorjs3-vue3-vue-meteor-tracker.html). Blaze and Svelte tutorials are coming soon.
- Participate in Meteor's fully professional, engaging and interactive online school. Join [Meteor University](https://university.meteor.com/).
- Participate in Meteor's fully professional, engaging and interactive online school. Join [Meteor University](https://university.meteor.com/). Our courses cover Meteor 2 but most of the content is still relevant.
- Subscribe to our official [Youtube channel](https://www.youtube.com/@meteorsoftware) and watch the latest MeteorJS videos and presentations.
@@ -46,8 +52,8 @@ Meteor is a full-stack JavaScript platform for developing modern web and mobile
### Join Our Community
- Participate in the [Official Forum](https://forums.meteor.com) for project news, support, community discussions, and updates on core features.
- Participate in the [Official Forum](https://forums.meteor.com) for project news, support, and community discussions.
- Join the discussion and stay updated with announcements on the official [Meteor Lounge Discord](https://discord.gg/hZkTCaVjmT).
- Join the discussion and live streams on the official [Meteor Lounge Discord](https://discord.gg/hZkTCaVjmT).
- Engage with peers in the [Meteor Slack Community](https://join.slack.com/t/meteor-community/shared_invite/enQtODA0NTU2Nzk5MTA3LWY5NGMxMWRjZDgzYWMyMTEyYTQ3MTcwZmU2YjM5MTY3MjJkZjQ0NWRjOGZlYmIxZjFlYTA5Mjg4OTk3ODRiOTc) for technical support, meeting new developers, and exchanging ideas.
- Engage with peers in the [Meteor Slack Community](https://join.slack.com/t/meteor-community/shared_invite/enQtODA0NTU2Nzk5MTA3LWY5NGMxMWRjZDgzYWMyMTEyYTQ3MTcwZmU2YjM5MTY3MjJkZjQ0NWRjOGZlYmIxZjFlYTA5Mjg4OTk3ODRiOTc).

View File

@@ -1175,11 +1175,16 @@ option:
You can pass any MongoDB valid option, these are just examples using
certificates configurations.
If you're using a certificate and having authentication errors when trying to connect to a database other than `admin`, make sure to provide the flags `&ssl=true&authSource=admin`. You MONGO_URL string should look like this:
```
mongodb://<username>:<password>@[server-1],[server-2],[server-3]/my-database?replicaSet=my-replica&ssl=true&authSource=admin
```
### Mongo Oplog Options {#mongo-oplog-options}
> Oplog options were introduced in Meteor 2.15.1
If you set the [`MONGO_OPLOG_URL`](https://docs.meteor.com/environment-variables.html#MONGO-OPLOG-URL) env var, Meteor will use MongoDB's Oplog to show efficient, real time updates to your users via your subscriptions.
If you set the [`MONGO_OPLOG_URL`](/cli/environment-variables.html#mongo-oplog-url) env var, Meteor will use MongoDB's Oplog to show efficient, real time updates to your users via your subscriptions.
Due to how Meteor's Oplog implementation is built behind the scenes, if you have certain collections where you expect **big amounts of write operations**, this might lead to **big CPU spikes on your meteor app server, even if you have no publications/subscriptions on any data/documents of these collections**. For more information on this, please have a look into [this blog post from 2016](https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908), [this github discussion from 2022](https://github.com/meteor/meteor/discussions/11842) or [this meteor forums post from 2023](https://forums.meteor.com/t/cpu-spikes-due-to-oplog-updates-without-subscriptions/60028).

View File

@@ -943,7 +943,7 @@ Returns a handle that can be used by `Meteor.clearInterval`.
## Enviroment variables {#envs}
teor runs most app code within Fibers, which allows keeping track of the context a function is running in. `Meteor.EnvironmentVariable` works with `Meteor.bindEnvironment`, promises, and many other Meteor API's to preserve the context in async code. Some examples of how it is used in Meteor are to store the current user in methods, and record which arguments have been checked when using `audit-argument-checks`.
Meteor implements `Meteor.EnvironmentVariable` with AsyncLocalStorage, which allows for maintaining context across asynchronous boundaries. `Meteor.EnvironmentVariable` works with `Meteor.bindEnvironment`, promises, and many other Meteor API's to preserve the context in async code. Some examples of how it is used in Meteor are to store the current user in methods, and record which arguments have been checked when using `audit-argument-checks`.
```js
import { Meteor } from "meteor/meteor";

View File

@@ -150,4 +150,4 @@
### [webapp](https://github.com/meteor/meteor/tree/devel/packages/webapp) {#webapp}
### [webapp-hashing](https://github.com/meteor/meteor/tree/devel/packages/webapp-hashing) {#webapp-hashing}
### [weibo-config-ui](https://github.com/meteor/meteor/tree/devel/packages/weibo-config-ui) {#weibo-config-ui}
### [weibo-oauth](https://github.com/meteor/meteor/tree/devel/packages/weibo-oauth) {#weibo-oauth}
### [weibo-oauth](https://github.com/meteor/meteor/tree/devel/packages/weibo-oauth) {#weibo-oauth}

View File

@@ -1,13 +1,13 @@
# Top Level Await
[Top level await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await) (TLA) allows you to use `await` in the top level of a module or file instead of only in async functions. One way to view it is as if every file runs inside an `async` function.
[Top-level await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await) (TLA) allows you to use `await` in the top-level of a module or file instead of only in async functions. One way to view it is as if every file runs inside an `async` function.
Here is an example of using top level await on the server. When this file is loaded, the `await` will cause the module to wait for the count before the code in the rest of the module is run.
Here is an example of using top-level await on the server. When this file is loaded, the `await` will cause the module to wait for the count before the code in the rest of the module is run.
```js
const Links = new Mongo.Collection('links');
// Async code using top level await.
// Async code using top-level await.
// The module waits for this to finish before continuing
const count = await Links.find().countAsync();
@@ -16,29 +16,29 @@ if (count === 0) {
}
```
In previous versions of Meteor, async code using fibers could be run in the top level of a module. Top level await allows writing similar code that works without fibers. There are a few differences that this article will cover.
Before Meteor 3, async code using fibers could run at the top level of a module. Top-level await allows similar code to work without fibers. This article will cover a few differences.
Meteor's implementation of top level await tries to closely follow the specification. There currently are some differences with how Meteor handles circular dependencies.
Meteor's implementation of top-level await tries to closely follow the specification. However, there are currently some differences in how Meteor handles circular dependencies.
## Using Top Level Await
Top level await can be used in any app or package that uses the `ecmascript`, `typescript`, or `coffeescript` packages, or that uses any other build plugin that compiles top level await using reify.
Generally, if you can use ECMAScript modules, then you can also use top level await.
Top-level await can be used in any app or package that uses the `ecmascript`, `typescript`, or `coffeescript` packages, or that uses any other build plugin that compiles top-level await using reify.
Generally, if you can use ECMAScript modules, then you can also use top-level await.
There are some extra considerations when using top level await in packages. They are covered later in this article.
There are some extra considerations when using top-level await in packages. They are covered later in this article.
Top level await is only enabled by default on the server. You can enable it for the client by setting the env var `METEOR_ENABLE_CLIENT_TOP_LEVEL_AWAIT` to `true`. There are a couple known issues with using TLA on the client:
Top-level await is only enabled by default on the server. You can enable it for the client by setting the env var `METEOR_ENABLE_CLIENT_TOP_LEVEL_AWAIT` to `true`. There are a couple known issues with using TLA on the client:
1. It breaks any files in `/client/compatibility` since it now wraps those files in a function
2. Hot module replacement has not been updated to work with TLA
## Async Modules
With top level await, some modules are considered async, which affects how they behave. There are two ways a module can become an async module:
1. It uses top level await
With top-level await, some modules are considered async, which affects how they behave. There are two ways a module can become an async module:
1. It uses top-level await
2. It imports a module that is async
For example, this module (`setup.js`) would be async because it uses top level await:
For example, this module (`setup.js`) would be async because it uses top-level await:
```js
await setupLanguages();
@@ -50,7 +50,7 @@ This module (`main.js`) would be sync:
console.log('in main.js');
```
However, if it imports `setup.js` which does use top level await, then `main.js` also becomes async.
However, if it imports `setup.js` which does use top-level await, then `main.js` also becomes async.
```js
import './setup.js';
@@ -67,10 +67,10 @@ When using `require` to load an async module, instead of directly returning a mo
const promise = require('./init.js');
```
If you are using `require`, this does mean you need to be careful when adding or removing top level await in a file since you also have to update where the module is required.
Since a module becomes async if it depends on an async module, this could affect more than just the individual modules using top level await.
If you are using `require`, this does mean you need to be careful when adding or removing top-level await in a file since you also have to update where the module is required.
Since a module becomes async if it depends on an async module, this could affect more than just the individual modules using top-level await.
When possible, you can use ecmascript import syntax or dynamic imports instead so you don't have to worry about which modules are sync or async.
When possible, you can use ECMAScript import syntax or dynamic imports instead so you don't have to worry about which modules are sync or async.
## Nested Imports
@@ -88,13 +88,13 @@ export function showNotification(message) {
}
```
This is a feature unique to Meteor, so the top level await specification wasn't written to work with nested imports. Using nested imports to import a sync module continues to work, but it will throw an error if used to import an async module. You can use `require` or dynamic imports for async modules in these situations.
This feature is unique to Meteor, so the top-level await specification wasn't written to work with nested imports. Using nested imports to import a sync module continues to work, but it will throw an error if used to import an async module. You can use `require` or dynamic imports for async modules in these situations.
## Using in Packages
Top level await is only supported starting in Meteor 3. Published build plugins are able to use top level await in older Meteor versions since the runtime is bundled when they are published, though in development they require Meteor 3.
Top-level await is only supported starting in Meteor 3. Published build plugins are able to use top-level await in older Meteor versions since the runtime is bundled when they are published, though in development they require Meteor 3.
If you want to ensure your package only runs in versions of Meteor that support top level await, you can have your package use `isobuild:top-level-await`:
If you want to ensure your package only runs in versions of Meteor that support top-level await, you can have your package use `isobuild:top-level-await`:
```js
Package.onUse(function (api) {
@@ -103,17 +103,17 @@ Package.onUse(function (api) {
});
```
When importing a package that does not have a lazy main module, it will work the same whether a package uses top level await or not. This is true even when using `require`. This allows packages to add or remove top level await without it being a breaking change.
When importing a package that does not have a lazy main module, it will work the same whether a package uses top-level await or not. This is true even when using `require`. This allows packages to add or remove top-level await without it being a breaking change.
There are a couple cases where adding or removing top level await from a module in a package could be considered a breaking change:
There are a couple of cases where adding or removing top-level await from a module in a package could be considered a breaking change:
1. If specific modules are require'd from a package. For example: `require('meteor/zodern:aurorae/svelte.js')`. When importing a specific module from a package, `require` changes its behavior based on if the module is async or not.
2. If a package that has lazy main modules is require'd. Unlike normal packages, `require` will return a promise if the lazy main module is an async module. Changing if the lazy main module is async or not should be considered a breaking change for the package.
## Module and Package Execution Order
Normally, modules are run one at a time. This was even true when using async code with fibers in the root of a module. However, top level await is different - it allows siblings (modules that do not depend on each other) to sometimes run in parallel. This can allow the app to load faster, which is especially important on the client. However, this could cause code to run in an unexpected order if you are used to how Meteor worked with fibers.
Normally, modules are run one at a time. This was even true when using async code with fibers in the root of a module. However, top-level await is different - it allows siblings (modules that do not depend on each other) to sometimes run in parallel. This can allow the app to load faster, which is especially important on the client. However, this could cause code to run in an unexpected order if you are used to how Meteor works with fibers.
This is also applies to packages. Packages that do not directly or indirectly depend on each other are able to load in parallel if they use top level await.
This also applies to packages. Packages that do not directly or indirectly depend on each other can load in parallel if they use top-level await.
Modules that are eagerly evaluated (added in packages with `api.addFiles`, or outside of `imports` in apps that do not have a main module) and not directly imported continue to run one at a time, even if they use top level await, since it is common for these modules to implicitly depend on the previous modules.
Modules that are eagerly evaluated (added in packages with `api.addFiles`, or outside of `imports` in apps that do not have a main module) and not directly imported continue to run one at a time, even if they use top-level await since it is common for these modules to implicitly depend on the previous modules.

View File

@@ -67,7 +67,7 @@ const sourceCode = `https://github.com/meteor/meteor/blob/devel/packages/${props
<td>{{ showTypes(param.type.names) }}</td>
<template v-if="param.name === 'options'">
<td>
<span v-html="param.description"></span>
<span v-if="param.description" v-html="param.description"></span>
<button v-if="(props.options?.length || -1) > 0" type="button" @click="toggleOptionsTable">
{{ isOptionsTableOpen ? "Close" : "Open" }} options table
<Caret :is-open="isOptionsTableOpen" />
@@ -110,6 +110,9 @@ const sourceCode = `https://github.com/meteor/meteor/blob/devel/packages/${props
table {
text-align: center;
}
table td {
padding: 6px 12px;
}
.options-table {
--easing-dur: calc(var(--vc-auto-duration) * 1.5) cubic-bezier(0.33, 1, 0.68, 1);

View File

@@ -73,8 +73,12 @@ const primitiveDefault = {
const comma = `<span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span>`;
const br = `<br/>`;
const escapeHtml = (str) => {
return str.replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
const typeComment = (type) =>{
return `<span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/** </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">@returns</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> {${type}}</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span>`
return `<span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/** </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">@returns</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ${escapeHtml(type)}</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span>`
}
const comment = (text = " // this param is optional ") =>

View File

@@ -130,6 +130,12 @@ export function filterMap(filter, apiList) {
const newLinks = {};
for (const key in apiList[api]) {
const links = apiList[api][key];
// We get the shouldGoTo link here as well.
// In this case we just added it and continue
if (!Array.isArray(links)) {
newLinks[key] = links;
continue;
}
const newLinksArray = links.filter((link) => {
return link.toLowerCase().includes(filter.toLowerCase());
});

View File

@@ -0,0 +1,60 @@
## v3.0.3, 2024-09-11
### Highlights
- Fixed `Meteor.userId` only being invoked with `bindEnvironment`.
- Updated to Node `20.17.x`.
- Fixed an issue where `meteor --open` opens the browser before the app is started.
- Investigated and addressed the error when installing the `jam:method` package.
- Improved the message for new available versions when running an app.
- Updated the documentation link inside `install.sh`.
- Resolved the issue where subscriptions stopped after a parameter change.
- Added MongoDB connection telemetry.
- Bumped the `email` package to prevent update errors.
- Cordova package updates
#### Breaking Changes
N/A
#### Internal API changes
- Some internal changes to how async contexts are handled, ensuring better performance and garbage collection.
#### Migration Steps
Please run the following command to update your project:
```bash
meteor update --release 3.0.3
```
If you've had your Meteor installation for over a year, we suggest reinstalling it to avoid any package installation issues. You can do this by running a few quick commands:
```bash
npx meteor uninstall // or rm -rf ~/.meteor
npx meteor
```
#### Meteor Version Release
* `Bumped packages`:
- accounts-base@3.0.2
- accounts-password@3.0.2
- email@3.1.0
- mongo@2.0.2
#### Special thanks to
- [@ayewo](https://github.com/ayewo).
- [@denihs](https://github.com/denihs).
- [@harryadel](https://github.com/harryadel).
- [@kbarr1212](https://github.com/kbarr1212).
- [@leonardoventurini](https://github.com/leonardoventurini).
- [@nachocodoner](https://github.com/nachocodoner).

View File

@@ -0,0 +1,120 @@
## 1: Creating the app
### 1.1: Install Meteor {#install-meteor}
First, we need to install Meteor.
If you don't have Meteor installed, you can install it by running:
```shell
npx meteor
```
### 1.2: Create Meteor Project {#create-meteor-project}
The easiest way to setup Meteor with React is by using the command `meteor create` with the option `--react` and your project name (you can also omit the `--react` option since it is the default):
```shell
meteor create simple-todos-react
```
Meteor will create all the necessary files for you.
The files located in the `client` directory are setting up your client side (web), you can see for example `client/main.jsx` where Meteor is rendering your App main component into the HTML.
Also, check the `server` directory where Meteor is setting up the server side (Node.js), you can see the `server/main.js` is initializing your MongoDB database with some data. You don't need to install MongoDB as Meteor provides an embedded version of it ready for you to use.
You can now run your Meteor app using:
```shell
meteor run
```
Don't worry, Meteor will keep your app in sync with all your changes from now on.
Your React code will be located inside the `imports/ui` directory, and `App.jsx` file is the root component of your React To-do app.
Take a quick look at all the files created by Meteor, you don't need to understand them now but it's good to know where they are.
### 1.3: Create Task Component {#create-task-component}
You will make your first change now. Create a new file called `Task.jsx` in your `ui` folder.
This file will export a React component called `Task` that will represent one task in your To-Do list.
::: code-group
```js [imports/ui/Task.jsx]
import React from "react";
export const Task = ({ task }) => {
return <li>{task.text}</li>;
};
```
:::
As this component will be inside a list you are returning a `li` element.
### 1.4: Create Sample Tasks {#create-sample-tasks}
As you are not connecting to your server and your database yet let's define some sample data which will be used shortly to render a list of tasks. It will be an array, and you can call it `tasks`.
::: code-group
```js [imports/ui/App.jsx]
import React from 'react';
const tasks = [
{_id: 1, text: 'First Task'},
{_id: 2, text: 'Second Task'},
{_id: 3, text: 'Third Task'},
];
export const App = () => ...
```
:::
You can put anything as your `text` property on each task. Be creative!
### 1.5: Render Sample Tasks {#render-sample-tasks}
Now we can implement some simple rendering logic with React. We can now use our previous `Task` component to render our list items.
In React you can use `{` `}` to write Javascript code between them.
See below that you will use a `.map` function from the `Array` object to iterate over your sample tasks.
::: code-group
```js [imports/ui/App.jsx]
import React from 'react';
import { Task } from './Task';
const tasks = ..;
export const App = () => (
<div>
<h1>Welcome to Meteor!</h1>
<ul>
{ tasks.map(task => <Task key={ task._id } task={ task }/>) }
</ul>
</div>
);
```
:::
Remember to add the `key` property to your task, otherwise React will emit a warning because it will see many components of the same type as siblings. Without a key, it will be hard for React to re-render one of them if necessary.
> You can read more about React and Keys [here](https://reactjs.org/docs/lists-and-keys.html#keys).
Remove the `Hello` and `Info` from your `App` component, remember to also remove the imports for them at the top of the file. Remove the `Hello.jsx` and `Info.jsx` files as well.
### 1.6: Hot Module Replacement {#hot-module-replacement}
Meteor by default when using React is already adding for you a package called `hot-module-replacement`. This package updates the javascript modules in a running app that were modified during a rebuild. Reduces the feedback cycle while developing so you can view and test changes quicker (it even updates the app before the build has finished). You are also not going to lose the state, your app code will be updated and your state will be the same.
In the next step, we are going to work with our MongoDB database to store our tasks.

View File

@@ -0,0 +1,191 @@
## 2: Collections
Meteor already sets up MongoDB for you. In order to use our database, we need to create a _collection_, which is where we will store our _documents_, in our case our `tasks`.
> You can read more about collections [here](https://v3-docs.meteor.com/api/collections.html).
In this step, we will implement all the necessary code to have a basic collection for our tasks up and running using React hooks.
### 2.1: Create Tasks Collection {#create-tasks-collection}
We can create a new collection to store our tasks by creating a new file at `imports/api/TasksCollection.js` which instantiates a new Mongo collection and exports it.
::: code-group
```js [imports/api/TasksCollection.js]
import { Mongo } from "meteor/mongo";
export const TasksCollection = new Mongo.Collection("tasks");
```
:::
Notice that we stored the file in the `imports/api` directory, which is a place to store API-related code, like publications and methods. You can name this folder as you want, this is just a choice.
You can delete the `links.js` file in this folder as we are not going to use this collection.
> You can read more about app structure and imports/exports [here](http://guide.meteor.com/structure.html).
### 2.2: Initialize Tasks Collection {#initialize-tasks-collection}
For our collection to work, you need to import it in the server so it sets some plumbing up.
You can either use `import "/imports/api/TasksCollection"` or `import { TasksCollection } from "/imports/api/TasksCollection"` if you are going to use on the same file, but make sure it is imported.
Now it is easy to check if there is data or not in our collection, otherwise, we can insert some sample data easily as well.
You don't need to keep the old content of `server/main.js`.
::: code-group
```js [server/main.js]
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "/imports/api/TasksCollection";
const insertTask = (taskText) =>
TasksCollection.insertAsync({ text: taskText });
Meteor.startup(async () => {
if ((await TasksCollection.find().countAsync()) === 0) {
[
"First Task",
"Second Task",
"Third Task",
"Fourth Task",
"Fifth Task",
"Sixth Task",
"Seventh Task",
].forEach(insertTask);
}
});
```
:::
So you are importing the `TasksCollection` and adding a few tasks to it iterating over an array of strings and for each string calling a function to insert this string as our `text` field in our `task` document.
### 2.3: Render Tasks Collection {#render-tasks-collection}
Now comes the fun part, you will render the tasks using a React Function Component and a Hook called `useTracker` from a package called [react-meteor-data](https://atmospherejs.com/meteor/react-meteor-data).
> Meteor works with Meteor packages and NPM packages, usually, Meteor packages are using Meteor internals or other Meteor packages.
This package is already included in the React skeleton (`meteor create yourproject`) so you don't need to add it but you can always add Meteor packages running `meteor add package-name`:
```shell
meteor add react-meteor-data
```
Now you are ready to import code from this package, when importing code from a Meteor package the only difference from NPM modules is that you need to prepend `meteor/` in the from part of your import.
The `useTracker` function exported by `react-meteor-data` is a React Hook that allows you to have reactivity in your React components. Every time the data changes through reactivity your component will re-render. Cool, right?
> For more information about React Hooks read [here](https://reactjs.org/docs/hooks-faq.html).
::: code-group
```javascript [imports/ui/App.jsx]
import React from "react";
import { useTracker } from "meteor/react-meteor-data";
import { TasksCollection } from "/imports/api/TasksCollection";
import { Task } from "./Task";
export const App = () => {
const tasks = useTracker(() => TasksCollection.find({}).fetch());
return (
<div>
<h1>Welcome to Meteor!</h1>
<ul>
{tasks.map((task) => (
<Task key={task._id} task={task} />
))}
</ul>
</div>
);
};
```
:::
But wait! Something is missing. If you run your app now, you'll see that you don't render any tasks.
That's because we need to publish our data to the client.
Fist, create a publication for our tasks:
`imports/api/TasksPublications.js`
```javascript
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "./TasksCollection";
Meteor.publish("tasks", () => {
return TasksCollection.find();
});
```
Now, we need to import this file in our server:
::: code-group
```js [server/main.js]
...
import { TasksCollection } from '/imports/api/TasksCollection';
import "../imports/api/TasksPublications"; // [!code highlight]
const insertTask = taskText => TasksCollection.insertAsync({ text: taskText });
...
```
:::
The only thing left is subscribe to this publication:
`imports/ui/App.jsx`
```javascript
import React from 'react';
import { useTracker, useSubscribe } from 'meteor/react-meteor-data'; // [!code highlight]
import { TasksCollection } from '/imports/api/TasksCollection';
import { Task } from './Task';
export const App = () => {
const isLoading = useSubscribe("tasks"); // [!code highlight]
const tasks = useTracker(() => TasksCollection.find({}).fetch());
if (isLoading()) {
return <div>Loading...</div>;
}
...
}
```
As you can see, when subscribing to a publication using `useSubscribe` you'll get a `isLoading` function, that you can use to render some loading component before the data is ready.
> For more information on Publications/Subscriptions, please check our [docs](https://v3-docs.meteor.com/api/meteor.html#pubsub).
See how your app should look like now:
<img width="200px" src="/tutorials/react/assets/collections-tasks-list.png"/>
You can change your data on MongoDB in the server and your app will react and re-render for you.
You can connect to your MongoDB running `meteor mongo` in the terminal from your app folder or using a Mongo UI client, like [NoSQLBooster](https://nosqlbooster.com/downloads). Your embedded MongoDB is running in port `3001`.
See how to connect:
<img width="500px" src="/tutorials/react/assets/collections-connect-db.png"/>
See your database:
<img width="500px" src="/tutorials/react/assets/collections-see-database.png"/>
You can double-click your collection to see the documents stored on it:
<img width="500px" src="/tutorials/react/assets/collections-documents.png"/>
In the next step, we are going to create tasks using a form.

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