diff --git a/.envrc b/.envrc index a7ec1d87af..7909587fdd 100644 --- a/.envrc +++ b/.envrc @@ -32,6 +32,10 @@ function @generate-dev-bundle { "$ROOT_DIR/scripts/generate-dev-bundle.sh" } +function @init-submodule { + git submodule update --init --recursive +} + ################# # Documentation # ################# diff --git a/README.md b/README.md index 427d010986..b047759578 100644 --- a/README.md +++ b/README.md @@ -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.1-green?logo=meteor&logoColor=white)](https://meteor.com) +[![built with Meteor](https://img.shields.io/badge/Meteor-3.0.2-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) diff --git a/docs/source/api/collections.md b/docs/source/api/collections.md index 7a7c0551d6..a90c3e24ae 100644 --- a/docs/source/api/collections.md +++ b/docs/source/api/collections.md @@ -837,6 +837,7 @@ const handle = cursor.observeChanges({ setTimeout(() => handle.stop(), 5000); ``` +{% apibox "Mongo.getCollection" %} {% apibox "Mongo.ObjectID" %} `Mongo.ObjectID` follows the same API as the [Node MongoDB driver diff --git a/npm-packages/meteor-installer/README.md b/npm-packages/meteor-installer/README.md index 42e72eeefb..b7a04475d5 100644 --- a/npm-packages/meteor-installer/README.md +++ b/npm-packages/meteor-installer/README.md @@ -1,19 +1,62 @@ ## Meteor Installer -Node.js <=14.x and npm <=6.x is recommended. +### Recommended Versions -Install Meteor by running: +- For Meteor 2 (Legacy) + - Use Node.js 14.x + - Use npm 6.x +- For Meteor 3 + - Use Node.js 20.x or higher + - Use npm 9.x or higher + +### Installation + +To install Meteor, run the following command: ```bash -npm install -g meteor +npx meteor ``` -[Read more](https://www.meteor.com/developers/install) +It will install Meteor's latest version, alternatively you can install a specific version by running: -### Meteor version relationship +```bash +npx meteor@ +``` + +This command will execute the Meteor installer without adding it permanently to your global npm packages. + +For more information, visit: + +- [Meteor 2 Installation Guide (Legacy)](https://v2-docs.meteor.com/install.html) +- [**Meteor 3 Installation Guide**](https://v3-docs.meteor.com/about/install.html) + + + + + +### Important Note + +This npm package is not the Meteor framework itself; it is just an installer. Do not include it as a dependency in your project, as doing so may break your deployment. + +### Path Management + +By default, the Meteor installer adds its install path (by default, `~/.meteor/`) to your PATH by updating either your `.bashrc`, `.bash_profile`, or `.zshrc` as appropriate. To disable this behavior, install Meteor by running: + +```bash +npm install -g meteor --ignore-meteor-setup-exec-path +``` + +(or by setting the environment variable `npm_config_ignore_meteor_setup_exec_path=true`) + +### Proxy Configuration + +Set the `https_proxy` or `HTTPS_PROXY` environment variable to a valid proxy URL to download Meteor files through the configured proxy. + +### Meteor Version Compatibility | NPM Package | Meteor Official Release | |-------------|-------------------------| +| 3.0.2 | 3.0.2 | | 3.0.1 | 3.0.1 | | 3.0.0 | 3.0 | | 2.16.0 | 2.16.0 | @@ -59,22 +102,3 @@ npm install -g meteor | 2.3.3 | 2.3.2 | | 2.3.2 | 2.3.1 | | 2.3.1 | 2.2.1 | - -### Important note - -This npm package is not Meteor itself, it is just an installer. You should not include it as a dependency in your project. If you do, your deployment is going to be broken. - -### Path management - -By default, the Meteor installer adds its install path (by default, `~/.meteor/`) to your PATH by updating either your `.bashrc`, `.bash_profile`, or `.zshrc` as appropriate. To disable this behavior, install Meteor by running: - -```bash -npm install -g meteor --ignore-meteor-setup-exec-path -``` - -(or by setting the environment variable `npm_config_ignore_meteor_setup_exec_path=true`) - -### Proxy configuration - -Setting the `https_proxy` or `HTTPS_PROXY` environment variable to a valid proxy URL will cause the -downloader to use the configured proxy to retrieve the Meteor files. diff --git a/npm-packages/meteor-installer/config.js b/npm-packages/meteor-installer/config.js index b302d4020c..3278f89d00 100644 --- a/npm-packages/meteor-installer/config.js +++ b/npm-packages/meteor-installer/config.js @@ -1,7 +1,7 @@ const os = require('os'); const path = require('path'); -const METEOR_LATEST_VERSION = '3.0.1'; +const METEOR_LATEST_VERSION = '3.0.2'; const sudoUser = process.env.SUDO_USER || ''; function isRoot() { return process.getuid && process.getuid() === 0; diff --git a/npm-packages/meteor-installer/install.js b/npm-packages/meteor-installer/install.js index 1598e0b893..9f98f0e8d5 100644 --- a/npm-packages/meteor-installer/install.js +++ b/npm-packages/meteor-installer/install.js @@ -302,7 +302,9 @@ async function setup() { async function setupExecPath() { if (isWindows()) { // set for the current session and beyond - child_process.execSync(`setx path "${meteorPath}/;%path%`); + child_process.execSync( + `powershell -c "$path = (Get-Item 'HKCU:\\Environment').GetValue('Path', '', 'DoNotExpandEnvironmentNames'); [Environment]::SetEnvironmentVariable('PATH', \\"${meteorPath};$path\\", 'User');"`, + ); return; } const exportCommand = `export PATH=${meteorPath}:$PATH`; diff --git a/npm-packages/meteor-installer/package-lock.json b/npm-packages/meteor-installer/package-lock.json index 9a754dc5d0..ceb33825b5 100644 --- a/npm-packages/meteor-installer/package-lock.json +++ b/npm-packages/meteor-installer/package-lock.json @@ -1,12 +1,12 @@ { "name": "meteor", - "version": "3.0.1", + "version": "3.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "meteor", - "version": "3.0.1", + "version": "3.0.2", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -15,7 +15,7 @@ "https-proxy-agent": "^5.0.1", "node-7z": "^2.1.2", "node-downloader-helper": "^2.1.9", - "rimraf": "^3.0.2", + "rimraf": "^6.0.1", "semver": "^7.3.7", "tar": "^6.1.11", "tmp": "^0.2.1" @@ -28,6 +28,83 @@ "npm": ">=10.x" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/7zip-bin": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", @@ -52,18 +129,31 @@ "node": ">=8" } }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/chownr": { @@ -85,10 +175,23 @@ "node": ">=4" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -119,11 +222,33 @@ } } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -146,31 +271,38 @@ "node": ">=8" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -183,21 +315,6 @@ "node": ">= 6" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -211,6 +328,24 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/jackspeak": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", @@ -248,14 +383,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minipass": { @@ -342,21 +481,11 @@ "node": ">=0.10.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "license": "BlueOak-1.0.0" }, "node_modules/path-key": { "version": "3.1.1", @@ -366,16 +495,54 @@ "node": ">=8" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^7.1.3" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -414,6 +581,18 @@ "node": ">=8" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -427,6 +606,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -438,6 +632,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", @@ -476,10 +683,105 @@ "node": ">= 8" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, "node_modules/yallist": { "version": "4.0.0", diff --git a/npm-packages/meteor-installer/package.json b/npm-packages/meteor-installer/package.json index 7da42f06a1..ad6b284884 100644 --- a/npm-packages/meteor-installer/package.json +++ b/npm-packages/meteor-installer/package.json @@ -1,6 +1,6 @@ { "name": "meteor", - "version": "3.0.1", + "version": "3.0.2", "description": "Install Meteor", "main": "install.js", "scripts": { @@ -15,7 +15,7 @@ "https-proxy-agent": "^5.0.1", "node-7z": "^2.1.2", "node-downloader-helper": "^2.1.9", - "rimraf": "^3.0.2", + "rimraf": "^6.0.1", "semver": "^7.3.7", "tar": "^6.1.11", "tmp": "^0.2.1" diff --git a/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json b/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json index 3484049cac..0376b5ea04 100644 --- a/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json +++ b/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json @@ -2,9 +2,9 @@ "lockfileVersion": 4, "dependencies": { "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==" + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==" }, "@types/notp": { "version": "2.0.5", @@ -37,9 +37,9 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" } } } diff --git a/packages/accounts-2fa/2fa-server.js b/packages/accounts-2fa/2fa-server.js index 188d829489..801233d294 100644 --- a/packages/accounts-2fa/2fa-server.js +++ b/packages/accounts-2fa/2fa-server.js @@ -14,7 +14,7 @@ Accounts._check2faEnabled = user => { }; Accounts._is2faEnabledForUser = async () => { - const user = await Meteor.user(); + const user = await Meteor.userAsync(); if (!user) { throw new Meteor.Error('no-logged-user', 'No user logged in.'); } @@ -36,7 +36,7 @@ Accounts._isTokenValid = (secret, code) => { Meteor.methods({ async generate2faActivationQrCode(appName) { check(appName, String); - const user = await Meteor.user(); + const user = await Meteor.userAsync(); if (!user) { throw new Meteor.Error( @@ -74,7 +74,7 @@ Meteor.methods({ }, async enableUser2fa(code) { check(code, String); - const user = await Meteor.user(); + const user = await Meteor.userAsync(); if (!user) { throw new Meteor.Error(400, 'No user logged in.'); diff --git a/packages/accounts-2fa/package.js b/packages/accounts-2fa/package.js index 2f54e8ded4..52efca1c3b 100644 --- a/packages/accounts-2fa/package.js +++ b/packages/accounts-2fa/package.js @@ -1,37 +1,37 @@ Package.describe({ - version: '3.0.0', + version: "3.0.1", summary: - 'Package used to enable two factor authentication through OTP protocol', + "Package used to enable two factor authentication through OTP protocol", }); Npm.depends({ - 'node-2fa': '2.0.3', - 'qrcode-svg': '1.1.0', + "node-2fa": "2.0.3", + "qrcode-svg": "1.1.0", }); -Package.onUse(function(api) { - api.use(['accounts-base'], ['client', 'server']); +Package.onUse(function (api) { + api.use(["accounts-base"], ["client", "server"]); // Export Accounts (etc.) to packages using this one. - api.imply('accounts-base', ['client', 'server']); + api.imply("accounts-base", ["client", "server"]); - api.use('ecmascript'); - api.use('check', 'server'); + api.use("ecmascript"); + api.use("check", "server"); - api.addFiles(['2fa-client.js'], 'client'); - api.addFiles(['2fa-server.js'], 'server'); + api.addFiles(["2fa-client.js"], "client"); + api.addFiles(["2fa-server.js"], "server"); }); -Package.onTest(function(api) { +Package.onTest(function (api) { api.use([ - 'accounts-base', - 'accounts-password', - 'ecmascript', - 'tinytest', - 'random', - 'accounts-2fa', + "accounts-base", + "accounts-password", + "ecmascript", + "tinytest", + "random", + "accounts-2fa", ]); - api.mainModule('server_tests.js', 'server'); - api.mainModule('client_tests.js', 'client'); + api.mainModule("server_tests.js", "server"); + api.mainModule("client_tests.js", "client"); }); diff --git a/packages/accounts-base/accounts_client_tests.js b/packages/accounts-base/accounts_client_tests.js index 96e88b110a..f5466216f5 100644 --- a/packages/accounts-base/accounts_client_tests.js +++ b/packages/accounts-base/accounts_client_tests.js @@ -1,4 +1,5 @@ import {Accounts} from "meteor/accounts-base"; +import { AccountsClient } from './accounts_client'; const username = 'jsmith'; const password = 'password'; @@ -343,3 +344,25 @@ Tinytest.addAsync('accounts - storage', }); } }); + +Tinytest.addAsync('accounts - should only start subscription when connected', async function (test) { + const { conn, messages, cleanup } = await captureConnectionMessagesClient(test); + + const acc = new AccountsClient({ + connection: conn, + }) + + acc.callLoginMethod() + + await Meteor._sleepForMs(100); + + // The sub call needs to come right after `connect` since this is when `status().connected` gets to be true and + // not after `connected` as it is based on the socket connection status. + const expectedMessages = ['connect', 'method', 'sub', 'connected', 'updated', 'result', 'ready'] + + const parsedMessages = messages.map(m => m.msg).filter(Boolean).filter(m => m !== 'added') + + test.equal(parsedMessages, expectedMessages) + + cleanup() +}); \ No newline at end of file diff --git a/packages/accounts-base/accounts_common.js b/packages/accounts-base/accounts_common.js index 61202bad1f..fdd45a2890 100644 --- a/packages/accounts-base/accounts_common.js +++ b/packages/accounts-base/accounts_common.js @@ -19,6 +19,8 @@ const VALID_CONFIG_KEYS = [ 'loginTokenExpirationHours', 'tokenSequenceLength', 'clientStorage', + 'ddpUrl', + 'connection', ]; /** @@ -37,8 +39,7 @@ export class AccountsCommon { // Validate config options keys for (const key of Object.keys(options)) { if (!VALID_CONFIG_KEYS.includes(key)) { - // TODO Consider just logging a debug message instead to allow for additional keys in the settings here? - throw new Meteor.Error(`Accounts.config: Invalid key: ${key}`); + console.error(`Accounts.config: Invalid key: ${key}`); } } @@ -163,6 +164,14 @@ export class AccountsCommon { * @param {MongoFieldSpecifier} options.fields Dictionary of fields to return or exclude. */ user(options) { + if (Meteor.isServer) { + console.warn([ + "`Meteor.user()` is deprecated on the server side.", + " To fetch the current user record on the server,", + " use `Meteor.userAsync()` instead.", + ].join("\n")); + } + const self = this; const userId = self.userId(); const findOne = (...args) => Meteor.isClient @@ -284,8 +293,7 @@ export class AccountsCommon { // Validate config options keys for (const key of Object.keys(options)) { if (!VALID_CONFIG_KEYS.includes(key)) { - // TODO Consider just logging a debug message instead to allow for additional keys in the settings here? - throw new Meteor.Error(`Accounts.config: Invalid key: ${key}`); + console.error(`Accounts.config: Invalid key: ${key}`); } } diff --git a/packages/accounts-base/accounts_reconnect_tests.js b/packages/accounts-base/accounts_reconnect_tests.js index dcee651786..8341cf0a5d 100644 --- a/packages/accounts-base/accounts_reconnect_tests.js +++ b/packages/accounts-base/accounts_reconnect_tests.js @@ -154,7 +154,7 @@ if (Meteor.isClient) { .then((id) => { // 4. the server should still return an id after connection test.isTrue(Meteor.status().connected); - test.isTrue(id); + test.isTrue(id, 'userId exists in the server after reconnect'); }) .finally(done); diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index 067ecc5487..3331bdc307 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -422,7 +422,7 @@ export class AccountsServer extends AccountsCommon { ) ); - methodInvocation.setUserId(userId); + await methodInvocation.setUserId(userId); return { id: userId, @@ -664,7 +664,7 @@ export class AccountsServer extends AccountsCommon { await accounts.destroyToken(this.userId, token); } await accounts._successfulLogout(this.connection, this.userId); - this.setUserId(null); + await this.setUserId(null); }; // Generates a new login token with the same expiration as the diff --git a/packages/accounts-base/accounts_tests.js b/packages/accounts-base/accounts_tests.js index d6340dc076..f6cdf49c71 100644 --- a/packages/accounts-base/accounts_tests.js +++ b/packages/accounts-base/accounts_tests.js @@ -10,14 +10,6 @@ Meteor.methods({ } }); -// XXX it'd be cool to also test that the right thing happens if options -// *are* validated, but Accounts._options is global state which makes this hard -// (impossible?) -Tinytest.add( - 'accounts - config - validates keys', - test => test.throws(() => Accounts.config({ foo: "bar" })) -); - Tinytest.addAsync('accounts - config - token lifetime', async test => { const { loginExpirationInDays } = Accounts._options; Accounts._options.loginExpirationInDays = 2; @@ -487,28 +479,28 @@ Tinytest.addAsync( Accounts._options = {}; // test the field is included by default - let user = await Meteor.user(); + let user = await Meteor.userAsync(); test.isNotUndefined(user[ignoreFieldName], 'included by default'); // test the field is excluded Accounts.config({ defaultFieldSelector: { [ignoreFieldName]: 0 } }); - user = await Meteor.user(); + user = await Meteor.userAsync(); test.isUndefined(user[ignoreFieldName], 'excluded'); - user = await Meteor.user({}); + user = await Meteor.userAsync({}); test.isUndefined(user[ignoreFieldName], 'excluded {}'); // test the field can still be retrieved if required - user = await Meteor.user({ fields: { [ignoreFieldName]: 1 } }); + user = await Meteor.userAsync({ fields: { [ignoreFieldName]: 1 } }); test.isNotUndefined(user[ignoreFieldName], 'field can be retrieved'); test.isUndefined(user.username, 'field can be retrieved username'); // test a combined negative field specifier - user = await Meteor.user({ fields: { username: 0 } }); + user = await Meteor.userAsync({ fields: { username: 0 } }); test.isUndefined(user[ignoreFieldName], 'combined field selector'); test.isUndefined(user.username, 'combined field selector username'); // test an explicit request for the full user object - user = await Meteor.user({ fields: {} }); + user = await Meteor.userAsync({ fields: {} }); test.isNotUndefined(user[ignoreFieldName], 'full selector'); test.isNotUndefined(user.username, 'full selector username'); @@ -516,7 +508,7 @@ Tinytest.addAsync( // Test that a custom field gets retrieved properly Accounts.config({ defaultFieldSelector: { [customField]: 1 } }); - user = await Meteor.user() + user = await Meteor.userAsync() test.isNotUndefined(user[customField]); test.isUndefined(user.username); test.isUndefined(user[ignoreFieldName]); @@ -922,4 +914,3 @@ Tinytest.addAsync('accounts - updateOrCreateUserFromExternalService - Twitter', // cleanup await Meteor.users.removeAsync(u1.id); }); - diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 9ccffc6ddf..863706668c 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,67 +1,67 @@ Package.describe({ - summary: 'A user account system', - version: '3.0.0', + summary: "A user account system", + version: "3.0.1", }); -Package.onUse(api => { - api.use('ecmascript', ['client', 'server']); - api.use('ddp-rate-limiter'); - api.use('localstorage', 'client'); - api.use('tracker', 'client'); - api.use('check', 'server'); - api.use('random', ['client', 'server']); - api.use('ejson', 'server'); - api.use('callback-hook', ['client', 'server']); - api.use('reactive-var', 'client'); - api.use('url', ['client', 'server']); +Package.onUse((api) => { + api.use("ecmascript", ["client", "server"]); + api.use("ddp-rate-limiter"); + api.use("localstorage", "client"); + api.use("tracker", "client"); + api.use("check", "server"); + api.use("random", ["client", "server"]); + api.use("ejson", "server"); + api.use("callback-hook", ["client", "server"]); + api.use("reactive-var", "client"); + api.use("url", ["client", "server"]); // needed for getting the currently logged-in user and handling reconnects - api.use('ddp', ['client', 'server']); + api.use("ddp", ["client", "server"]); // need this because of the Meteor.users collection but in the future // we'd probably want to abstract this away - api.use('mongo', ['client', 'server']); + api.use("mongo", ["client", "server"]); // If the 'blaze' package is loaded, we'll define some helpers like // {{currentUser}}. If not, no biggie. - api.use('blaze', 'client', { weak: true }); + api.use("blaze", "client", { weak: true }); // Allow us to detect 'autopublish', and publish some Meteor.users fields if // it's loaded. - api.use('autopublish', 'server', { weak: true }); + api.use("autopublish", "server", { weak: true }); - api.use('oauth-encryption', 'server', { weak: true }); + api.use("oauth-encryption", "server", { weak: true }); // Though this "Accounts" symbol is the only official Package export for // the accounts-base package, modules that import accounts-base will // have access to anything added to the exports object of the main // module, including AccountsClient and AccountsServer (those symbols // just won't be automatically imported as "global" variables). - api.export('Accounts'); + api.export("Accounts"); // These main modules import all the other modules that comprise the // accounts-base package, and define exports that will be accessible to // modules that import the accounts-base package. - api.mainModule('server_main.js', 'server'); - api.mainModule('client_main.js', 'client'); + api.mainModule("server_main.js", "server"); + api.mainModule("client_main.js", "client"); - api.addAssets('accounts-base.d.ts', 'server'); + api.addAssets("accounts-base.d.ts", "server"); }); -Package.onTest(api => { +Package.onTest((api) => { api.use([ - 'accounts-base', - 'ecmascript', - 'tinytest', - 'random', - 'test-helpers', - 'oauth-encryption', - 'ddp', - 'accounts-password', - 'accounts-2fa', + "accounts-base", + "ecmascript", + "tinytest", + "random", + "test-helpers", + "oauth-encryption", + "ddp", + "accounts-password", + "accounts-2fa", ]); - api.addFiles('accounts_tests_setup.js', 'server'); - api.mainModule('server_tests.js', 'server'); - api.mainModule('client_tests.js', 'client'); + api.addFiles("accounts_tests_setup.js", "server"); + api.mainModule("server_tests.js", "server"); + api.mainModule("client_tests.js", "client"); }); diff --git a/packages/accounts-password/email_tests.js b/packages/accounts-password/email_tests.js index 6c78320c58..16ca358ef5 100644 --- a/packages/accounts-password/email_tests.js +++ b/packages/accounts-password/email_tests.js @@ -150,10 +150,12 @@ const getVerifyEmailToken = (email, test, expect) => { })); }; -const loggedIn = (test, expect) => expect((error) => { +const loggedIn = (test, expect) => { + return expect(async (error) => { test.equal(error, undefined); - test.isTrue(Meteor.user()); + test.isTrue(await Meteor.user()); }); +}; testAsyncMulti("accounts emails - verify email flow", [ function (test, expect) { @@ -169,7 +171,7 @@ testAsyncMulti("accounts emails - verify email flow", [ loggedIn(test, expect)); }, async function (test, expect) { - const u = await Meteor.user(); + const u = await Meteor.userAsync(); test.equal(u.emails.length, 1); test.equal(u.emails[0].address, this.email); test.isFalse(u.emails[0].verified); @@ -187,11 +189,10 @@ testAsyncMulti("accounts emails - verify email flow", [ })); }, function (test, expect) { - Accounts.verifyEmail(verifyEmailToken, - loggedIn(test, expect)); + Accounts.verifyEmail(verifyEmailToken, loggedIn(test, expect)); }, - async function (test, expect) { - const u = await Meteor.user(); + async function (test) { + const u = await Meteor.userAsync(); test.equal(u.emails.length, 1); test.equal(u.emails[0].address, this.email); @@ -201,7 +202,7 @@ testAsyncMulti("accounts emails - verify email flow", [ Accounts.connection.call( "addEmailForTestAndVerify", this.anotherEmail, expect(async (error, result) => { - const u = await Meteor.user(); + const u = await Meteor.userAsync(); test.isFalse(error); test.equal(u.emails.length, 2); @@ -232,7 +233,7 @@ testAsyncMulti("accounts emails - verify email flow", [ Accounts.connection.call( "addEmailForTestAndVerify", this.anotherEmailCaps, expect(async (error, result) => { - const u = await Meteor.user(); + const u = await Meteor.userAsync(); test.isFalse(error); test.equal(u.emails.length, 3); test.equal(u.emails[2].address, this.anotherEmailCaps); @@ -255,7 +256,7 @@ testAsyncMulti("accounts emails - verify email flow", [ loggedIn(test, expect)); }, async function (test, expect) { - const u = await Meteor.user(); + const u = await Meteor.userAsync(); test.equal(u.emails[2].address, this.anotherEmailCaps); test.isTrue(u.emails[2].verified); diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index 19ebc9b5cb..2083f877a0 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,49 +1,49 @@ Package.describe({ - summary: 'Password support for accounts', + summary: "Password support for accounts", // Note: 2.2.0-beta.3 was published during the Meteor 1.6 prerelease // process, so it might be best to skip to 2.3.x instead of reusing // 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.0', + version: "3.0.1", }); Npm.depends({ - bcrypt: '5.0.1', + bcrypt: "5.0.1", }); -Package.onUse(api => { - api.use(['accounts-base', 'sha', 'ejson', 'ddp'], ['client', 'server']); +Package.onUse((api) => { + api.use(["accounts-base", "sha", "ejson", "ddp"], ["client", "server"]); // Export Accounts (etc) to packages using this one. - api.imply('accounts-base', ['client', 'server']); + api.imply("accounts-base", ["client", "server"]); - api.use('email', 'server'); - api.use('random', 'server'); - api.use('check', 'server'); - api.use('ecmascript'); + api.use("email", "server"); + api.use("random", "server"); + api.use("check", "server"); + api.use("ecmascript"); - api.addFiles('email_templates.js', 'server'); - api.addFiles('password_server.js', 'server'); - api.addFiles('password_client.js', 'client'); + api.addFiles("email_templates.js", "server"); + api.addFiles("password_server.js", "server"); + api.addFiles("password_client.js", "client"); }); -Package.onTest(api => { +Package.onTest((api) => { api.use([ - 'accounts-password', - 'sha', - 'tinytest', - 'test-helpers', - 'tracker', - 'accounts-base', - 'random', - 'email', - 'check', - 'ddp', - 'ecmascript', + "accounts-password", + "sha", + "tinytest", + "test-helpers", + "tracker", + "accounts-base", + "random", + "email", + "check", + "ddp", + "ecmascript", ]); - api.addFiles('password_tests_setup.js', 'server'); - api.addFiles('password_tests.js', ['client', 'server']); - api.addFiles('email_tests_setup.js', 'server'); - api.addFiles('email_tests.js', 'client'); + api.addFiles("password_tests_setup.js", "server"); + api.addFiles("password_tests.js", ["client", "server"]); + api.addFiles("email_tests_setup.js", "server"); + api.addFiles("email_tests.js", "client"); }); diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js index 418bf56da7..66fb4f83a8 100644 --- a/packages/accounts-password/password_tests.js +++ b/packages/accounts-password/password_tests.js @@ -701,7 +701,7 @@ if (Meteor.isClient) (() => { // accounts-base/accounts_tests.js, but this is where the tests that // actually log in are. async function (test, expect) { - const clientUser = await Meteor.user(); + const clientUser = await Meteor.userAsync(); Accounts.connection.call('testMeteorUser', expect((err, result) => { test.equal(result._id, clientUser._id); test.equal(result.username, clientUser.username); diff --git a/packages/accounts-twitter/package.js b/packages/accounts-twitter/package.js index 0e8beb4699..405c08d38b 100644 --- a/packages/accounts-twitter/package.js +++ b/packages/accounts-twitter/package.js @@ -1,20 +1,20 @@ Package.describe({ summary: "Login service for Twitter accounts", - version: '1.5.1', + version: "1.5.2", }); -Package.onUse(api => { - api.use('ecmascript'); - api.use('accounts-base', ['client', 'server']); +Package.onUse((api) => { + api.use("ecmascript"); + api.use("accounts-base", ["client", "server"]); // Export Accounts (etc) to packages using this one. - api.imply('accounts-base', ['client', 'server']); - api.use('accounts-oauth', ['client', 'server']); - api.use('twitter-oauth'); - api.imply('twitter-oauth'); + api.imply("accounts-base", ["client", "server"]); + api.use("accounts-oauth", ["client", "server"]); + api.use("twitter-oauth"); + api.imply("twitter-oauth"); - api.use('http@1.0.1', ['client', 'server']); - - api.use(['accounts-ui', 'twitter-config-ui'], ['client', 'server'], { weak: true }); + api.use(["accounts-ui", "twitter-config-ui"], ["client", "server"], { + weak: true, + }); api.addFiles("notice.js"); api.addFiles("twitter.js"); diff --git a/packages/ddp-client/common/livedata_connection.js b/packages/ddp-client/common/livedata_connection.js index c14ae27da3..0c27c5d378 100644 --- a/packages/ddp-client/common/livedata_connection.js +++ b/packages/ddp-client/common/livedata_connection.js @@ -1035,6 +1035,9 @@ export class Connection { // Always queues the call before sending the message // Used, for example, on subscription.[id].stop() to make sure a "sub" message is always called before an "unsub" message // https://github.com/meteor/meteor/issues/13212 + // + // This is part of the actual fix for the rest check: + // https://github.com/meteor/meteor/pull/13236 _sendQueued(obj) { this._send(obj, true); } @@ -1996,7 +1999,7 @@ export class Connection { // add new subscriptions at the end. this way they take effect after // the handlers and we don't see flicker. Object.entries(this._subscriptions).forEach(([id, sub]) => { - this._send({ + this._sendQueued({ msg: 'sub', id: id, name: sub.name, diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 8ca1c9b542..2eb354614c 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,66 +1,69 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '3.0.0', - documentation: null + version: "3.0.1", + documentation: null, }); Npm.depends({ - '@sinonjs/fake-timers': '7.0.5' + "@sinonjs/fake-timers": "7.0.5", }); Package.onUse((api) => { - api.use([ - 'check', - 'random', - 'ejson', - 'tracker', - 'retry', - 'id-map', - 'ecmascript', - 'callback-hook', - 'ddp-common', - 'reload', - 'socket-stream-client', + api.use( + [ + "check", + "random", + "ejson", + "tracker", + "retry", + "id-map", + "ecmascript", + "callback-hook", + "ddp-common", + "reload", + "socket-stream-client", - // we depend on _diffObjects, _applyChanges, - 'diff-sequence', + // we depend on _diffObjects, _applyChanges, + "diff-sequence", - // _idParse, _idStringify. - 'mongo-id' - ], ['client', 'server']); + // _idParse, _idStringify. + "mongo-id", + ], + ["client", "server"] + ); - api.use('reload', 'client', { weak: true }); + api.use("reload", "client", { weak: true }); // For backcompat where things use Package.ddp.DDP, etc - api.export('DDP'); - api.mainModule('client/client.js', 'client'); - api.mainModule('server/server.js', 'server'); + api.export("DDP"); + api.mainModule("client/client.js", "client"); + api.mainModule("server/server.js", "server"); }); Package.onTest((api) => { api.use([ - 'livedata', - 'mongo', - 'test-helpers', - 'ecmascript', - 'underscore', - 'tinytest', - 'random', - 'tracker', - 'reactive-var', - 'mongo-id', - 'diff-sequence', - 'ejson', - 'ddp-common', - 'check' + "livedata", + "mongo", + "test-helpers", + "ecmascript", + "underscore", + "tinytest", + "random", + "tracker", + "reactive-var", + "mongo-id", + "diff-sequence", + "ejson", + "ddp-common", + "check", ]); - api.addFiles('test/stub_stream.js'); - api.addFiles('test/livedata_connection_tests.js'); - api.addFiles('test/livedata_tests.js'); - api.addFiles('test/livedata_test_service.js'); - api.addFiles('test/random_stream_tests.js'); - api.addFiles('test/async_stubs/client.js', 'client'); - api.addFiles('test/async_stubs/server_setup.js', 'server'); - api.addFiles('test/livedata_callAsync_tests.js'); + api.addFiles("test/stub_stream.js"); + api.addFiles("test/livedata_connection_tests.js"); + api.addFiles("test/livedata_tests.js"); + api.addFiles("test/livedata_test_service.js"); + api.addFiles("test/random_stream_tests.js"); + api.addFiles("test/async_stubs/client.js", "client"); + api.addFiles("test/async_stubs/server_setup.js", "server"); + api.addFiles("test/livedata_callAsync_tests.js"); }); diff --git a/packages/ddp-client/test/livedata_test_service.js b/packages/ddp-client/test/livedata_test_service.js index 2bf5b2be38..d22958b183 100644 --- a/packages/ddp-client/test/livedata_test_service.js +++ b/packages/ddp-client/test/livedata_test_service.js @@ -34,9 +34,9 @@ Meteor.methods({ throw e; } }, - setUserId: function(userId) { + async setUserId(userId) { check(userId, Match.OneOf(String, null)); - this.setUserId(userId); + await this.setUserId(userId); } }); @@ -218,14 +218,14 @@ if (Meteor.isServer) { if (Meteor.isServer) { Meteor.methods({ - setUserIdAfterUnblock: function() { + async setUserIdAfterUnblock() { this.unblock(); let threw = false; const originalUserId = this.userId; try { // Calling setUserId after unblock should throw an error (and not mutate // userId). - this.setUserId(originalUserId + 'bla'); + await this.setUserId(originalUserId + 'bla'); } catch (e) { threw = true; } diff --git a/packages/ddp-client/test/livedata_tests.js b/packages/ddp-client/test/livedata_tests.js index 20bfe2c30c..3522b09333 100644 --- a/packages/ddp-client/test/livedata_tests.js +++ b/packages/ddp-client/test/livedata_tests.js @@ -1,8 +1,6 @@ import { DDP } from '../common/namespace.js'; import { Connection } from '../common/livedata_connection.js'; -const _sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - const callWhenSubReady = async (subName, handle, cb = () => {}) => { let control = 0; @@ -12,7 +10,7 @@ const callWhenSubReady = async (subName, handle, cb = () => {}) => { if (control++ === 1000) { throw new Error(`Subscribe to ${subName} is taking too long!`); } - await _sleep(0); + await Meteor._sleepForMs(0); return; } await cb(); diff --git a/packages/ddp-common/method_invocation.js b/packages/ddp-common/method_invocation.js index 12b86e9876..b98352c13e 100644 --- a/packages/ddp-common/method_invocation.js +++ b/packages/ddp-common/method_invocation.js @@ -99,11 +99,11 @@ DDPCommon.MethodInvocation = class MethodInvocation { * @instance * @param {String | null} userId The value that should be returned by `userId` on this connection. */ - setUserId(userId) { + async setUserId(userId) { if (this._calledUnblock) { throw new Error("Can't call setUserId in a method after calling unblock"); } this.userId = userId; - this._setUserId(userId); + await this._setUserId(userId); } }; diff --git a/packages/ddp-common/package.js b/packages/ddp-common/package.js index 6ebab7f152..64348d2433 100644 --- a/packages/ddp-common/package.js +++ b/packages/ddp-common/package.js @@ -1,27 +1,23 @@ Package.describe({ summary: "Code shared beween ddp-client and ddp-server", - version: '1.4.3', - documentation: null + version: "1.4.4", + documentation: null, }); Package.onUse(function (api) { - api.use([ - 'check', - 'random', - 'ecmascript', - 'ejson', - 'tracker', - 'retry', - ], ['client', 'server']); + api.use( + ["check", "random", "ecmascript", "ejson", "tracker", "retry"], + ["client", "server"] + ); - api.addFiles('namespace.js'); + api.addFiles("namespace.js"); - api.addFiles('heartbeat.js', ['client', 'server']); - api.addFiles('utils.js', ['client', 'server']); - api.addFiles('method_invocation.js', ['client', 'server']); - api.addFiles('random_stream.js', ['client', 'server']); + api.addFiles("heartbeat.js", ["client", "server"]); + api.addFiles("utils.js", ["client", "server"]); + api.addFiles("method_invocation.js", ["client", "server"]); + api.addFiles("random_stream.js", ["client", "server"]); - api.export('DDPCommon'); + api.export("DDPCommon"); }); Package.onTest(function (api) { diff --git a/packages/ddp-server/livedata_server.js b/packages/ddp-server/livedata_server.js index fce6e031a1..bdb13eaa52 100644 --- a/packages/ddp-server/livedata_server.js +++ b/packages/ddp-server/livedata_server.js @@ -396,13 +396,6 @@ var Session = function (server, version, socket, options) { }; Object.assign(Session.prototype, { - _checkPublishPromiseBeforeSend(f) { - if (!this._publishCursorPromise) { - f(); - return; - } - this._publishCursorPromise.finally(() => f()); - }, sendReady: function (subscriptionIds) { var self = this; if (self._isSending) { @@ -556,13 +549,11 @@ Object.assign(Session.prototype, { // It should be a JSON object (it will be stringified). send: function (msg) { const self = this; - this._checkPublishPromiseBeforeSend(() => { - if (self.socket) { - if (Meteor._printSentDDP) - Meteor._debug('Sent DDP', DDPCommon.stringifyDDP(msg)); - self.socket.send(DDPCommon.stringifyDDP(msg)); - } - }); + if (self.socket) { + if (Meteor._printSentDDP) + Meteor._debug("Sent DDP", DDPCommon.stringifyDDP(msg)); + self.socket.send(DDPCommon.stringifyDDP(msg)); + } }, // Send a connection error. @@ -627,6 +618,7 @@ Object.assign(Session.prototype, { var processNext = function () { var msg = self.inQueue && self.inQueue.shift(); + if (!msg) { self.workerRunning = false; return; @@ -653,6 +645,7 @@ Object.assign(Session.prototype, { msg, unblock ); + if (Meteor._isPromise(result)) { result.finally(() => unblock()); } else { @@ -782,15 +775,13 @@ Object.assign(Session.prototype, { return; } - var setUserId = function(userId) { - self._setUserId(userId); - }; - var invocation = new DDPCommon.MethodInvocation({ name: msg.method, isSimulation: false, userId: self.userId, - setUserId: setUserId, + setUserId(userId) { + return self._setUserId(userId); + }, unblock: unblock, connection: self.connectionHandle, randomSeed: randomSeed, @@ -823,6 +814,8 @@ Object.assign(Session.prototype, { } } + + const getCurrentMethodInvocationResult = () => DDP._CurrentMethodInvocation.withValue( invocation, @@ -838,6 +831,7 @@ Object.assign(Session.prototype, { keyName: 'getCurrentMethodInvocationResult', } ); + resolve( DDPServer._CurrentWriteFence.withValue( fence, @@ -903,7 +897,7 @@ Object.assign(Session.prototype, { // Sets the current user id in all appropriate contexts and reruns // all subscriptions - _setUserId: function(userId) { + async _setUserId(userId) { var self = this; if (userId !== null && typeof userId !== "string") @@ -938,19 +932,21 @@ Object.assign(Session.prototype, { // DDP._CurrentMethodInvocation set. But DDP._CurrentMethodInvocation is not // expected to be set inside a publish function, so we temporary unset it. // Inside a publish function DDP._CurrentPublicationInvocation is set. - DDP._CurrentMethodInvocation.withValue(undefined, function () { + await DDP._CurrentMethodInvocation.withValue(undefined, async function () { // Save the old named subs, and reset to having no subscriptions. var oldNamedSubs = self._namedSubs; self._namedSubs = new Map(); self._universalSubs = []; - oldNamedSubs.forEach(function (sub, subscriptionId) { - var newSub = sub._recreate(); + + + await Promise.all([...oldNamedSubs].map(async ([subscriptionId, sub]) => { + const newSub = sub._recreate(); self._namedSubs.set(subscriptionId, newSub); // nb: if the handler throws or calls this.error(), it will in fact // immediately send its 'nosub'. This is OK, though. - newSub._runHandler(); - }); + await newSub._runHandler(); + })); // Allow newly-created universal subs to be started on our connection in // parallel with the ones we're spinning up here, and spin up universal @@ -1207,16 +1203,16 @@ Object.assign(Subscription.prototype, { resultOrThenable && typeof resultOrThenable.then === 'function'; if (isThenable) { try { - self._publishHandlerResult(await resultOrThenable); + await self._publishHandlerResult(await resultOrThenable); } catch(e) { self.error(e) } } else { - self._publishHandlerResult(resultOrThenable); + await self._publishHandlerResult(resultOrThenable); } }, - _publishHandlerResult: function (res) { + async _publishHandlerResult (res) { // SPECIAL CASE: Instead of writing their own callbacks that invoke // this.added/changed/ready/etc, the user can just return a collection // cursor or array of cursors from the publish function; we call their @@ -1239,11 +1235,15 @@ Object.assign(Subscription.prototype, { return c && c._publishCursor; }; if (isCursor(res)) { - this._publishCursorPromise = res._publishCursor(self).then(() => { - // _publishCursor only returns after the initial added callbacks have run. - // mark subscription as ready. - self.ready(); - }).catch((e) => self.error(e)); + try { + await res._publishCursor(self); + } catch (e) { + self.error(e); + return; + } + // _publishCursor only returns after the initial added callbacks have run. + // mark subscription as ready. + self.ready(); } else if (_.isArray(res)) { // Check all the elements are cursors if (! _.all(res, isCursor)) { @@ -1254,6 +1254,7 @@ Object.assign(Subscription.prototype, { // XXX we should support overlapping cursors, but that would require the // merge box to allow overlap within a subscription var collectionNames = {}; + for (var i = 0; i < res.length; ++i) { var collectionName = res[i]._getCollectionName(); if (_.has(collectionNames, collectionName)) { @@ -1263,15 +1264,15 @@ Object.assign(Subscription.prototype, { return; } collectionNames[collectionName] = true; - }; + } - this._publishCursorPromise = Promise.all( - res.map(c => c._publishCursor(self)) - ) - .then(() => { - self.ready(); - }) - .catch((e) => self.error(e)); + try { + await Promise.all(res.map(cur => cur._publishCursor(self))); + } catch (e) { + self.error(e); + return; + } + self.ready(); } else if (res) { // Truthy values other than cursors or arrays are probably a // user mistake (possible returning a Mongo document via, say, @@ -1409,7 +1410,6 @@ Object.assign(Subscription.prototype, { ids.add(id); } - this._session._publishCursorPromise = this._publishCursorPromise; this._session.added(this._subscriptionHandle, collectionName, id, fields); }, @@ -1863,25 +1863,22 @@ Object.assign(Server.prototype, { // get the user state from the outer method or publish function, otherwise // don't allow setUserId to be called var userId = null; - var setUserId = function() { + let setUserId = () => { throw new Error("Can't call setUserId on a server initiated method call"); }; var connection = null; var currentMethodInvocation = DDP._CurrentMethodInvocation.get(); var currentPublicationInvocation = DDP._CurrentPublicationInvocation.get(); var randomSeed = null; + if (currentMethodInvocation) { userId = currentMethodInvocation.userId; - setUserId = function(userId) { - currentMethodInvocation.setUserId(userId); - }; + setUserId = (userId) => currentMethodInvocation.setUserId(userId); connection = currentMethodInvocation.connection; randomSeed = DDPCommon.makeRpcSeed(currentMethodInvocation, name); } else if (currentPublicationInvocation) { userId = currentPublicationInvocation.userId; - setUserId = function(userId) { - currentPublicationInvocation._session._setUserId(userId); - }; + setUserId = (userId) => currentPublicationInvocation._session._setUserId(userId); connection = currentPublicationInvocation.connection; } diff --git a/packages/ddp-server/livedata_server_async_tests.js b/packages/ddp-server/livedata_server_async_tests.js index cca7f92845..e01ca85833 100644 --- a/packages/ddp-server/livedata_server_async_tests.js +++ b/packages/ddp-server/livedata_server_async_tests.js @@ -7,7 +7,7 @@ function sleep(ms) { var onSubscription = {}; Meteor.publish('livedata_server_test_sub_async', async function(connectionId) { - await sleep(50); + await Meteor._sleepForMs(50); var callback = onSubscription[connectionId]; if (callback) callback(this); this.stop(); @@ -17,7 +17,7 @@ Meteor.publish('livedata_server_test_sub_context_async', async function( connectionId, userId ) { - await sleep(50); + await Meteor._sleepForMs(50); var callback = onSubscription[connectionId]; var methodInvocation = DDP._CurrentMethodInvocation.get(); var publicationInvocation = DDP._CurrentPublicationInvocation.get(); @@ -99,7 +99,7 @@ let onSubscriptions = {}; Meteor.publish({ async publicationObjectAsync() { - await sleep(50); + await Meteor._sleepForMs(50); let callback = onSubscriptions; if (callback) callback("publicationObjectAsync"); this.stop(); @@ -108,7 +108,7 @@ Meteor.publish({ Meteor.publish({ publication_object_async: async function() { - await sleep(50); + await Meteor._sleepForMs(50); let callback = onSubscriptions; if (callback) callback("publication_object_async"); this.stop(); @@ -116,7 +116,7 @@ Meteor.publish({ }); Meteor.publish('publication_compatibility_async', async function() { - await sleep(50); + await Meteor._sleepForMs(50); let callback = onSubscriptions; if (callback) callback("publication_compatibility_async"); this.stop(); diff --git a/packages/ddp-server/livedata_server_tests.js b/packages/ddp-server/livedata_server_tests.js index 445630b4c4..1b0adfd15c 100644 --- a/packages/ddp-server/livedata_server_tests.js +++ b/packages/ddp-server/livedata_server_tests.js @@ -442,3 +442,66 @@ Tinytest.addAsync("livedata server - waiting for Promise", (test, onComplete) => .then(onComplete); }) ); + +/** + * https://github.com/meteor/meteor/issues/13212 + */ +Tinytest.addAsync('livedata server - publish cursor is properly awaited', async function (test) { + let sub = null; + + const { conn, messages, cleanup } = await captureConnectionMessages(test); + + const coll = new Mongo.Collection('items', { + defineMutationMethods: false, + }); + + for (let i = 0; i < 10; i++) { + await coll.removeAsync({ _id: `item_${i}` }) + await coll.insertAsync({ _id: `item_${i}`, title: `Item #${i}` }); + } + + const publicationName = `publication_${Random.id()}` + + delete Meteor.server.publish_handlers[publicationName]; + + Meteor.publish(publicationName, async function (count) { + return coll.find({}, { limit: count }); + }); + + const reactiveVar = new ReactiveVar(1); + + const computation = Tracker.autorun(() => { + sub = conn.subscribe(publicationName, reactiveVar.get()); + }); + + await Meteor._sleepForMs(100); + + reactiveVar.set(2); + + await Meteor._sleepForMs(100); + + const expectedMessages = ['sub', 'added', 'ready', 'sub', 'unsub', 'added', 'ready', 'nosub'] + + /** + * There shouldn't ever be `removed` messages here, otherwise the UI will glitch + */ + const parsedMessages = messages.map(m => m.msg) + + test.equal(parsedMessages, expectedMessages) + + computation.stop(); + + cleanup() +}); + +function getTestConnections(test) { + return new Promise((resolve, reject) => { + makeTestConnection(test, (clientConn, serverConn) => { + resolve({ clientConn, serverConn }); + }, reject); + }) +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 771ac4909a..2bbd7a97d2 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,61 +1,77 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '3.0.0', - documentation: null + version: "3.0.1", + documentation: null, }); Npm.depends({ "permessage-deflate": "0.1.7", - sockjs: "0.3.24" + sockjs: "0.3.24", }); Package.onUse(function (api) { - api.use(['check', 'random', 'ejson', 'underscore', - 'retry', 'mongo-id', 'diff-sequence', 'ecmascript'], - 'server'); + api.use( + [ + "check", + "random", + "ejson", + "underscore", + "retry", + "mongo-id", + "diff-sequence", + "ecmascript", + ], + "server" + ); // common functionality - api.use('ddp-common', 'server'); // heartbeat - api.use('ddp-rate-limiter', 'server', {weak: true}); + api.use("ddp-common", "server"); // heartbeat + api.use("ddp-rate-limiter", "server", { weak: true }); // Transport - api.use('ddp-client', 'server'); - api.imply('ddp-client'); + api.use("ddp-client", "server"); + api.imply("ddp-client"); - api.use(['webapp', 'routepolicy'], 'server'); + api.use(["webapp", "routepolicy"], "server"); // Detect whether or not the user wants us to audit argument checks. - api.use(['audit-argument-checks'], 'server', {weak: true}); + api.use(["audit-argument-checks"], "server", { weak: true }); // Allow us to detect 'autopublish', so we can print a warning if the user // runs Meteor.publish while it's loaded. - api.use('autopublish', 'server', {weak: true}); + api.use("autopublish", "server", { weak: true }); // If the facts package is loaded, publish some statistics. - api.use('facts-base', 'server', {unordered: true}); + api.use("facts-base", "server", { unordered: true }); - api.use('callback-hook', 'server'); - api.export('DDPServer', 'server'); + api.use("callback-hook", "server"); + api.export("DDPServer", "server"); - api.addFiles('stream_server.js', 'server'); + api.addFiles("stream_server.js", "server"); - api.addFiles('livedata_server.js', 'server'); - api.addFiles('writefence.js', 'server'); - api.addFiles('crossbar.js', 'server'); + api.addFiles("livedata_server.js", "server"); + api.addFiles("writefence.js", "server"); + api.addFiles("crossbar.js", "server"); - api.addFiles('server_convenience.js', 'server'); + api.addFiles("server_convenience.js", "server"); }); - - Package.onTest(function (api) { - api.use('ecmascript', ['client', 'server']); - api.use('livedata', ['client', 'server']); - api.use('mongo', ['client', 'server']); - api.use('test-helpers', ['client', 'server']); - api.use(['underscore', 'tinytest', 'random', 'tracker', 'minimongo', 'reactive-var']); + api.use("ecmascript", ["client", "server"]); + api.use("ejson", ["client", "server"]); + api.use("livedata", ["client", "server"]); + api.use("mongo", ["client", "server"]); + api.use("test-helpers", ["client", "server"]); + api.use([ + "underscore", + "tinytest", + "random", + "tracker", + "minimongo", + "reactive-var", + ]); - api.addFiles('livedata_server_tests.js', 'server'); - api.addFiles('livedata_server_async_tests.js', 'server'); - api.addFiles('session_view_tests.js', ['server']); - api.addFiles('crossbar_tests.js', ['server']); + api.addFiles("livedata_server_tests.js", "server"); + api.addFiles("livedata_server_async_tests.js", "server"); + api.addFiles("session_view_tests.js", ["server"]); + api.addFiles("crossbar_tests.js", ["server"]); }); diff --git a/packages/email/.npm/package/npm-shrinkwrap.json b/packages/email/.npm/package/npm-shrinkwrap.json index adcc3597a7..00cd9f3504 100644 --- a/packages/email/.npm/package/npm-shrinkwrap.json +++ b/packages/email/.npm/package/npm-shrinkwrap.json @@ -2,9 +2,9 @@ "lockfileVersion": 4, "dependencies": { "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==" + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==" }, "@types/nodemailer": { "version": "6.4.14", @@ -57,9 +57,9 @@ "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==" }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" } } } diff --git a/packages/email/email_tests.js b/packages/email/email_tests.js index c2904d0b6b..05cfde3414 100644 --- a/packages/email/email_tests.js +++ b/packages/email/email_tests.js @@ -6,10 +6,6 @@ const CUSTOM_TRANSPORT_SETTINGS = { email: { service: '1on1', user: 'test', password: 'pwd' }, }; -const sleep = (ms) => { - return new Promise((resolve) => setTimeout(resolve, ms)); -}; - // Create dynamic async tests TEST_CASES.forEach(({ title, options, testCalls }) => { Tinytest.addAsync(`${title}`, async function (test, onComplete) { @@ -222,7 +218,7 @@ Tinytest.addAsync( async function (test) { Meteor.settings.packages = CUSTOM_TRANSPORT_SETTINGS; Email.customTransport = async (options) => { - await sleep(3000); + await Meteor._sleepForMs(3000); test.equal(options.from, 'foo@example.com'); test.equal(options.packageSettings?.service, '1on1'); }; diff --git a/packages/email/package.js b/packages/email/package.js index a3e8f0b26a..f4f04f938f 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,25 +1,25 @@ Package.describe({ - summary: 'Send email messages', - version: '3.0.0', + summary: "Send email messages", + version: "3.0.100", }); Npm.depends({ - nodemailer: '6.9.10', - 'stream-buffers': '3.0.2', - '@types/nodemailer': '6.4.14', - 'nodemailer-openpgp' : '2.2.0' + nodemailer: "6.9.10", + "stream-buffers": "3.0.2", + "@types/nodemailer": "6.4.14", + "nodemailer-openpgp": "2.2.0", }); -Package.onUse(function(api) { - api.use(['ecmascript', 'logging', 'callback-hook'], 'server'); - api.addAssets('email.d.ts', 'server'); - api.mainModule('email.js', 'server'); - api.export(['Email', 'EmailInternals'], 'server'); - api.export('EmailTest', 'server', { testOnly: true }); +Package.onUse(function (api) { + api.use(["ecmascript", "logging", "callback-hook"], "server"); + api.addAssets("email.d.ts", "server"); + api.mainModule("email.js", "server"); + api.export(["Email", "EmailInternals"], "server"); + api.export("EmailTest", "server", { testOnly: true }); }); -Package.onTest(function(api) { - api.use('email', 'server'); - api.use(['tinytest', 'ecmascript']); - api.addFiles('email_tests.js', 'server'); +Package.onTest(function (api) { + api.use("email", "server"); + api.use(["tinytest", "ecmascript"]); + api.addFiles("email_tests.js", "server"); }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 58522f44c8..f7bd832589 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'The Meteor command-line tool', - version: '3.0.1', + version: '3.0.2', }); Package.includeTool(); diff --git a/packages/meteor/helpers.js b/packages/meteor/helpers.js index ac6b801d83..3dd1e2a6b1 100644 --- a/packages/meteor/helpers.js +++ b/packages/meteor/helpers.js @@ -85,6 +85,10 @@ Meteor.promisify = function (fn, context, errorFirst) { } return function () { + var self = this; + var filteredArgs = Array.prototype.slice.call(arguments) + .filter(function (i) { return i !== undefined; }); + return new Promise(function (resolve, reject) { var callback = Meteor.bindEnvironment(function (error, result) { var _error = error, _result = result; @@ -100,11 +104,9 @@ Meteor.promisify = function (fn, context, errorFirst) { resolve(_result); }); - var filteredArgs = Array.prototype.slice.call(arguments) - .filter(function (i) { return i !== undefined; }); filteredArgs.push(callback); - return fn.apply(context || this, filteredArgs); + return fn.apply(context || self, filteredArgs); }); }; }; diff --git a/packages/meteor/helpers_test.js b/packages/meteor/helpers_test.js index 78c968fffb..3a2af555f7 100644 --- a/packages/meteor/helpers_test.js +++ b/packages/meteor/helpers_test.js @@ -100,3 +100,24 @@ Tinytest.add("environment - startup", function (test) { }); test.isTrue(called); }); + +Tinytest.addAsync("environment - promisify", async function (test) { + function TestClass(value) { + this.value = value; + } + + TestClass.prototype.method = function (arg1, arg2, callback) { + var value = this.value; + setTimeout(function () { + callback(null, arg1 + arg2 + value); + }, 0); + }; + + TestClass.prototype.methodAsync = Meteor.promisify(TestClass.prototype.method); + + var instance = new TestClass(5); + test.equal(await instance.methodAsync(1, 2), 8); + + var asyncMethodWithContext = Meteor.promisify(instance.method, instance); + test.equal(await asyncMethodWithContext(2, 3), 10); +}); diff --git a/packages/meteor/package.js b/packages/meteor/package.js index 1b5d03777a..10161c44be 100644 --- a/packages/meteor/package.js +++ b/packages/meteor/package.js @@ -2,7 +2,7 @@ Package.describe({ summary: "Core Meteor environment", - version: '2.0.0', + version: '2.0.1', }); Package.registerBuildPlugin({ diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 7b996c6eb9..e2aab4032c 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3301,9 +3301,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { handle = c .find({ tags: "flower" }, { reactive: false }) .observe(makecb("c")); - // TODO: think about this one below. - const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - await sleep(10); + await Meteor._sleepForMs(10); expect("ac4_ac5_"); // This insert shouldn't trigger a callback because it's not reactive. await c.insertAsync({ _id: 6, name: "river", tags: ["flower"] }); diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js index 92916d2dd7..585a8d1ab6 100644 --- a/packages/minimongo/package.js +++ b/packages/minimongo/package.js @@ -1,52 +1,52 @@ Package.describe({ summary: "Meteor's client-side datastore: a port of MongoDB to Javascript", - version: '2.0.0', + version: "2.0.1", }); -Package.onUse(api => { - api.export('LocalCollection'); - api.export('Minimongo'); +Package.onUse((api) => { + api.export("LocalCollection"); + api.export("Minimongo"); - api.export('MinimongoTest', { testOnly: true }); - api.export('MinimongoError', { testOnly: true }); + api.export("MinimongoTest", { testOnly: true }); + api.export("MinimongoError", { testOnly: true }); api.use([ // This package is used to get diff results on arrays and objects - 'diff-sequence', - 'ecmascript', - 'ejson', + "diff-sequence", + "ecmascript", + "ejson", // This package is used for geo-location queries such as $near - 'geojson-utils', - 'id-map', - 'mongo-id', - 'ordered-dict', - 'random', - 'tracker' + "geojson-utils", + "id-map", + "mongo-id", + "ordered-dict", + "random", + "tracker", ]); // Make weak use of Decimal type on client - api.use('mongo-decimal', 'client', {weak: true}); - api.use('mongo-decimal', 'server'); + api.use("mongo-decimal", "client", { weak: true }); + api.use("mongo-decimal", "server"); - api.mainModule('minimongo_client.js', 'client'); - api.mainModule('minimongo_server.js', 'server'); + api.mainModule("minimongo_client.js", "client"); + api.mainModule("minimongo_server.js", "server"); }); -Package.onTest(api => { - api.use('minimongo'); +Package.onTest((api) => { + api.use("minimongo"); api.use([ - 'ecmascript', - 'ejson', - 'mongo-id', - 'ordered-dict', - 'random', - 'reactive-var', - 'test-helpers', - 'tinytest', - 'tracker' + "ecmascript", + "ejson", + "mongo-id", + "ordered-dict", + "random", + "reactive-var", + "test-helpers", + "tinytest", + "tracker", ]); - api.addFiles('minimongo_tests.js'); - api.addFiles('minimongo_tests_client.js', 'client'); - api.addFiles('minimongo_tests_server.js', 'server'); + api.addFiles("minimongo_tests.js"); + api.addFiles("minimongo_tests_client.js", "client"); + api.addFiles("minimongo_tests_server.js", "server"); }); diff --git a/packages/mongo/collection.js b/packages/mongo/collection.js index 98fda708f9..06bc59ae35 100644 --- a/packages/mongo/collection.js +++ b/packages/mongo/collection.js @@ -153,6 +153,8 @@ Mongo.Collection = function Collection(name, options) { is_auto: true, }); } + + Mongo._collections.set(this._name, this); }; Object.assign(Mongo.Collection.prototype, { @@ -1208,6 +1210,28 @@ Object.assign(Mongo.Collection.prototype, { }, }); +Object.assign(Mongo, { + /** + * @summary Retrieve a Meteor collection instance by name. Only collections defined with [`new Mongo.Collection(...)`](#collections) are available with this method. For plain MongoDB collections, you'll want to look at [`rawDatabase()`](#Mongo-Collection-rawDatabase). + * @locus Anywhere + * @memberof Mongo + * @static + * @param {string} name Name of your collection as it was defined with `new Mongo.Collection()`. + * @returns {Mongo.Collection | undefined} + */ + getCollection(name) { + return this._collections.get(name); + }, + + /** + * @summary A record of all defined Mongo.Collection instances, indexed by collection name. + * @type {Map} + * @memberof Mongo + * @protected + */ + _collections: new Map(), +}) + // Convert the callback to not return a result if there is an error function wrapCallback(callback, convertResult) { return ( diff --git a/packages/mongo/collection_tests.js b/packages/mongo/collection_tests.js index 46f422c9b4..a0e9e7fecf 100644 --- a/packages/mongo/collection_tests.js +++ b/packages/mongo/collection_tests.js @@ -464,6 +464,15 @@ Tinytest.addAsync('collection - should not block on cursor mismatch (#12516)', } ); +Tinytest.add('collection - get collection by name', + function (test) { + const collectionName = 'get' + test.id; + const collection = new Mongo.Collection(collectionName); + + test.ok(Mongo.getCollection(collectionName) instanceof Mongo.Collection); + test.equal(Mongo.getCollection(collectionName), collection); + } +); Meteor.isServer && Tinytest.addAsync('collection - simple add', async function(test){ diff --git a/packages/mongo/mongo.d.ts b/packages/mongo/mongo.d.ts index 61abd53458..f624412e75 100644 --- a/packages/mongo/mongo.d.ts +++ b/packages/mongo/mongo.d.ts @@ -83,6 +83,15 @@ export namespace Mongo { defineMutationMethods?: boolean | undefined; } ): Collection; + + /** + * Retrieve a previously defined Mongo.Collection instance by its name. The collection must already have been defined with `new Mongo.Collection(name, ...)`. + * Plain MongoDB collections are not available by this method. + * @param name The name of the collection instance. + */ + getCollection< + TCollection extends Collection | undefined = Collection | undefined + >(name: string): TCollection; } interface Collection { allow = undefined>(options: { diff --git a/packages/mongo/package.js b/packages/mongo/package.js index 2a197cc993..92a52a989f 100644 --- a/packages/mongo/package.js +++ b/packages/mongo/package.js @@ -9,100 +9,115 @@ Package.describe({ summary: "Adaptor for using MongoDB and Minimongo over DDP", - version: '2.0.0', + version: "2.0.1", }); Npm.depends({ - "mongodb-uri": "0.9.7" + "mongodb-uri": "0.9.7", }); Npm.strip({ - mongodb: ["test/"] + mongodb: ["test/"], }); Package.onUse(function (api) { - api.use('npm-mongo', 'server'); - api.use('allow-deny'); + api.use("npm-mongo", "server"); + api.use("allow-deny"); api.use([ - 'random', - 'ejson', - 'minimongo', - 'ddp', - 'tracker', - 'diff-sequence', - 'mongo-id', - 'check', - 'ecmascript', - 'mongo-dev-server', - 'logging' + "random", + "ejson", + "minimongo", + "ddp", + "tracker", + "diff-sequence", + "mongo-id", + "check", + "ecmascript", + "mongo-dev-server", + "logging", ]); // Make weak use of Decimal type on client - api.use('mongo-decimal', 'client', {weak: true}); - api.use('mongo-decimal', 'server'); + api.use("mongo-decimal", "client", { weak: true }); + api.use("mongo-decimal", "server"); //api.use('emitter-promise', 'server'); - api.use('underscore', 'server'); + api.use("underscore", "server"); // Binary Heap data structure is used to optimize oplog observe driver // performance. - api.use('binary-heap', 'server'); + api.use("binary-heap", "server"); // Allow us to detect 'insecure'. - api.use('insecure', {weak: true}); + api.use("insecure", { weak: true }); // Allow us to detect 'autopublish', and publish collections if it's loaded. - api.use('autopublish', 'server', {weak: true}); + api.use("autopublish", "server", { weak: true }); // Allow us to detect 'disable-oplog', which turns off oplog tailing for your // app even if it's configured in the environment. (This package will be // probably be removed before 1.0.) - api.use('disable-oplog', 'server', {weak: true}); + api.use("disable-oplog", "server", { weak: true }); // defaultRemoteCollectionDriver gets its deployConfig from something that is // (for questionable reasons) initialized by the webapp package. - api.use('webapp', 'server', {weak: true}); + api.use("webapp", "server", { weak: true }); // If the facts package is loaded, publish some statistics. - api.use('facts-base', 'server', {weak: true}); + api.use("facts-base", "server", { weak: true }); - api.use('callback-hook', 'server'); + api.use("callback-hook", "server"); // Stuff that should be exposed via a real API, but we haven't yet. - api.export('MongoInternals', 'server'); + api.export("MongoInternals", "server"); api.export("Mongo"); - api.export('ObserveMultiplexer', 'server', {testOnly: true}); + api.export("ObserveMultiplexer", "server", { testOnly: true }); - api.addFiles(['mongo_driver.js', 'oplog_tailing.js', - 'observe_multiplex.js', 'doc_fetcher.js', - 'polling_observe_driver.js','oplog_observe_driver.js', 'oplog_v2_converter.js'], - 'server'); - api.addFiles('local_collection_driver.js', ['client', 'server']); - api.addFiles('remote_collection_driver.js', 'server'); - api.addFiles('collection.js', ['client', 'server']); - api.addFiles('connection_options.js', 'server'); - api.addAssets('mongo.d.ts', 'server'); + api.addFiles( + [ + "mongo_driver.js", + "oplog_tailing.js", + "observe_multiplex.js", + "doc_fetcher.js", + "polling_observe_driver.js", + "oplog_observe_driver.js", + "oplog_v2_converter.js", + ], + "server" + ); + api.addFiles("local_collection_driver.js", ["client", "server"]); + api.addFiles("remote_collection_driver.js", "server"); + api.addFiles("collection.js", ["client", "server"]); + api.addFiles("connection_options.js", "server"); + api.addAssets("mongo.d.ts", "server"); }); Package.onTest(function (api) { - api.use('mongo'); - api.use('check'); - api.use('ecmascript'); - api.use('npm-mongo', 'server'); + 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([ + "tinytest", + "underscore", + "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']); - api.addFiles('upsert_compatibility_test.js', 'server'); - api.addFiles('allow_tests.js', ['client', 'server']); - api.addFiles('collection_tests.js', ['client', 'server']); - api.addFiles('collection_async_tests.js', ['client', 'server']); - api.addFiles('observe_changes_tests.js', ['client', 'server']); - api.addFiles('oplog_tests.js', 'server'); - api.addFiles('oplog_v2_converter_tests.js', 'server'); - api.addFiles('doc_fetcher_tests.js', 'server'); + api.addFiles("mongo_livedata_tests.js", ["client", "server"]); + api.addFiles("upsert_compatibility_test.js", "server"); + api.addFiles("allow_tests.js", ["client", "server"]); + api.addFiles("collection_tests.js", ["client", "server"]); + api.addFiles("collection_async_tests.js", ["client", "server"]); + api.addFiles("observe_changes_tests.js", ["client", "server"]); + api.addFiles("oplog_tests.js", "server"); + api.addFiles("oplog_v2_converter_tests.js", "server"); + api.addFiles("doc_fetcher_tests.js", "server"); }); diff --git a/packages/non-core/less/.versions b/packages/non-core/less/.versions index 848b711c59..efb0c21a2d 100644 --- a/packages/non-core/less/.versions +++ b/packages/non-core/less/.versions @@ -1,58 +1,58 @@ -allow-deny@2.0.0-beta300.6 -babel-compiler@7.11.0-beta300.6 -babel-runtime@1.5.2-beta300.6 -base64@1.0.13-beta300.6 -binary-heap@1.0.12-beta300.6 -blaze@3.0.0-alpha300.17 -boilerplate-generator@2.0.0-beta300.6 -caching-compiler@2.0.0-beta300.6 -callback-hook@1.6.0-beta300.6 -check@1.3.3-beta300.6 -core-runtime@1.0.0-beta300.6 -ddp@1.4.2-beta300.6 -ddp-client@3.0.0-beta300.6 -ddp-common@1.4.1-beta300.6 -ddp-server@3.0.0-beta300.6 -diff-sequence@1.1.3-beta300.6 -dynamic-import@0.7.4-beta300.6 -ecmascript@0.16.8-beta300.6 -ecmascript-runtime@0.8.2-beta300.6 -ecmascript-runtime-client@0.12.2-beta300.6 -ecmascript-runtime-server@0.11.1-beta300.6 -ejson@1.1.4-beta300.6 -facts-base@1.0.2-beta300.6 -fetch@0.1.4-beta300.6 -geojson-utils@1.0.12-beta300.6 -htmljs@2.0.0-alpha300.17 -id-map@1.2.0-beta300.6 -inter-process-messaging@0.1.2-beta300.6 -less@4.1.1-beta300.6 -local-test:less@4.1.1-beta300.6 -logging@1.3.3-beta300.6 -meteor@2.0.0-beta300.6 -minimongo@2.0.0-beta300.6 -modern-browsers@0.1.10-beta300.6 -modules@0.19.1-beta300.6 -modules-runtime@0.13.2-beta300.6 -mongo@2.0.0-beta300.6 -mongo-decimal@0.1.4-beta300.6 -mongo-dev-server@1.1.1-beta300.6 -mongo-id@1.0.9-beta300.6 -npm-mongo@4.16.1-beta300.6 -observe-sequence@2.0.0-alpha300.17 -ordered-dict@1.2.0-beta300.6 -promise@1.0.0-beta300.6 -random@1.2.2-beta300.6 -react-fast-refresh@0.2.8-beta300.6 -reactive-var@1.0.13-beta300.6 -reload@1.3.2-beta300.6 -retry@1.1.1-beta300.6 -routepolicy@1.1.2-beta300.6 -socket-stream-client@0.5.2-beta300.6 -test-helpers@2.0.0-beta300.6 -tinytest@2.0.0-beta300.6 -tracker@1.3.3-beta300.6 -typescript@5.3.3-beta300.6 -underscore@1.0.14-beta300.6 -webapp@2.0.0-beta300.6 -webapp-hashing@1.1.2-beta300.6 +allow-deny@2.0.0 +babel-compiler@7.11.0 +babel-runtime@1.5.2 +base64@1.0.13 +binary-heap@1.0.12 +blaze@3.0.0 +boilerplate-generator@2.0.0 +caching-compiler@2.0.0 +callback-hook@1.6.0 +check@1.4.2 +core-runtime@1.0.0 +ddp@1.4.2 +ddp-client@3.0.0 +ddp-common@1.4.3 +ddp-server@3.0.0 +diff-sequence@1.1.3 +dynamic-import@0.7.4 +ecmascript@0.16.9 +ecmascript-runtime@0.8.2 +ecmascript-runtime-client@0.12.2 +ecmascript-runtime-server@0.11.1 +ejson@1.1.4 +facts-base@1.0.2 +fetch@0.1.5 +geojson-utils@1.0.12 +htmljs@2.0.1 +id-map@1.2.0 +inter-process-messaging@0.1.2 +less@4.1.1 +local-test:less@4.1.1 +logging@1.3.5 +meteor@2.0.0 +minimongo@2.0.0 +modern-browsers@0.1.11 +modules@0.20.1 +modules-runtime@0.13.2 +mongo@2.0.0 +mongo-decimal@0.1.4-beta300.7 +mongo-dev-server@1.1.1 +mongo-id@1.0.9 +npm-mongo@4.17.3 +observe-sequence@2.0.0 +ordered-dict@1.2.0 +promise@1.0.0 +random@1.2.2 +react-fast-refresh@0.2.9 +reactive-var@1.0.13 +reload@1.3.2 +retry@1.1.1 +routepolicy@1.1.2 +socket-stream-client@0.5.3 +test-helpers@2.0.0 +tinytest@1.3.0 +tracker@1.3.4 +typescript@5.4.3 +underscore@1.6.4 +webapp@2.0.0 +webapp-hashing@1.1.2 diff --git a/packages/non-core/less/package.js b/packages/non-core/less/package.js index 97199d48fc..9b243a5b95 100644 --- a/packages/non-core/less/package.js +++ b/packages/non-core/less/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'less', - version: '4.1.1-beta300.6', + version: '4.1.1', summary: 'Leaner CSS language', documentation: 'README.md' }); @@ -8,8 +8,8 @@ Package.describe({ Package.registerBuildPlugin({ name: "compileLessBatch", use: [ - "caching-compiler@2.0.0-beta300.6", - "ecmascript@0.16.8-beta300.6", + "caching-compiler@2.0.0", + "ecmascript@0.16.9", ], sources: [ 'plugin/compile-less.js' diff --git a/packages/npm-mongo/.npm/package/npm-shrinkwrap.json b/packages/npm-mongo/.npm/package/npm-shrinkwrap.json index e529767751..3dc9f41668 100644 --- a/packages/npm-mongo/.npm/package/npm-shrinkwrap.json +++ b/packages/npm-mongo/.npm/package/npm-shrinkwrap.json @@ -56,34 +56,34 @@ } }, "@aws-sdk/client-cognito-identity": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.624.0.tgz", - "integrity": "sha512-imw3bNptHdhcogU3lwSVlQJsRpTxnkT4bQbchS/qX6+fF0Pk6ERZ+Q0YjzitPqTjkeyAWecUT4riyqv2djo+5w==" + "version": "3.631.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.631.0.tgz", + "integrity": "sha512-TXRkgwiLmNpwbiQShtUtSSE4DDHblhjHvtgxtzonzvdlDvYmCmaOwAQgi3HWuHztJtZ9ghf3jKB3N3jxAuKBbA==" }, "@aws-sdk/client-sso": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.624.0.tgz", - "integrity": "sha512-EX6EF+rJzMPC5dcdsu40xSi2To7GSvdGQNIpe97pD9WvZwM9tRNQnNM4T6HA4gjV1L6Jwk8rBlG/CnveXtLEMw==" + "version": "3.631.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.631.0.tgz", + "integrity": "sha512-tpXRQMbbTsKED6GGF0rZbg9Nr0DRCWImopX2lVh4deIeHQfNxeOtq2brqDWiPD593I190xeL/HMChSOmvDXNAw==" }, "@aws-sdk/client-sso-oidc": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.624.0.tgz", - "integrity": "sha512-Ki2uKYJKKtfHxxZsiMTOvJoVRP6b2pZ1u3rcUb2m/nVgBPUfLdl8ZkGpqE29I+t5/QaS/sEdbn6cgMUZwl+3Dg==" + "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==" }, "@aws-sdk/client-sts": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.624.0.tgz", - "integrity": "sha512-k36fLZCb2nfoV/DKK3jbRgO/Yf7/R80pgYfMiotkGjnZwDmRvNN08z4l06L9C+CieazzkgRxNUzyppsYcYsQaw==" + "version": "3.631.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.631.0.tgz", + "integrity": "sha512-Zo/2XDrmNpnSRlQLL8XOCJxuN7UIrGKf4itdjHqtEmD2PqstnYe6IMeEVOELpZ8iktjvsIrVr+qxlIX1QlmgCQ==" }, "@aws-sdk/core": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.624.0.tgz", - "integrity": "sha512-WyFmPbhRIvtWi7hBp8uSFy+iPpj8ccNV/eX86hwF4irMjfc/FtsGVIAeBXxXM/vGCjkdfEzOnl+tJ2XACD4OXg==" + "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==" }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.624.0.tgz", - "integrity": "sha512-gbXaxZP29yzMmEUzsGqUrHpKBnfMBtemvrlufJbaz/MGJNIa5qtJQp7n1LMI5R49DBVUN9s/e9Rf5liyMvlHiw==" + "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==" }, "@aws-sdk/credential-provider-env": { "version": "3.620.1", @@ -96,14 +96,14 @@ "integrity": "sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==" }, "@aws-sdk/credential-provider-ini": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.624.0.tgz", - "integrity": "sha512-mMoNIy7MO2WTBbdqMyLpbt6SZpthE6e0GkRYpsd0yozPt0RZopcBhEh+HG1U9Y1PVODo+jcMk353vAi61CfnhQ==" + "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==" }, "@aws-sdk/credential-provider-node": { - "version": "3.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.624.0.tgz", - "integrity": "sha512-vYyGK7oNpd81BdbH5IlmQ6zfaQqU+rPwsKTDDBeLRjshtrGXOEpfoahVpG9PX0ibu32IOWp4ZyXBNyVrnvcMOw==" + "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==" }, "@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.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.624.0.tgz", - "integrity": "sha512-A02bayIjU9APEPKr3HudrFHEx0WfghoSPsPopckDkW7VBqO4wizzcxr75Q9A3vNX+cwg0wCN6UitTNe6pVlRaQ==" + "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==" }, "@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.624.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.624.0.tgz", - "integrity": "sha512-SX+F5x/w8laQkhXLd1oww2lTuBDJSxzXWyxuOi25a9s4bMDs0V/wOj885Vr6h8QEGi3F8jZ8aWLwpsm2yuk9BA==" + "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==" }, "@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.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", - "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==" + "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==" }, "@aws-sdk/region-config-resolver": { "version": "3.614.0", @@ -161,9 +161,9 @@ "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==" }, "@aws-sdk/util-endpoints": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", - "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==" + "version": "3.631.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.631.0.tgz", + "integrity": "sha512-aavsyk17lK/r6rfVFYLh6/Y0eWvtbclWteJyW9PQLo5mpHPcTj6IbqMN4LHV27Y9IF7oOlbEAQ1CGTfpUlOvTg==" }, "@aws-sdk/util-locate-window": { "version": "3.568.0", @@ -381,9 +381,9 @@ "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==" }, "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==" + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==" }, "@types/webidl-conversions": { "version": "7.0.3", @@ -491,9 +491,9 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, "uuid": { "version": "9.0.1", diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 46d8737ae7..ed72c6995a 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -3,8 +3,8 @@ Package.describe({ summary: "Wrapper around the mongo npm package", - version: '4.17.3', - documentation: null + version: "4.17.4", + documentation: null, }); Npm.depends({ @@ -13,9 +13,6 @@ Npm.depends({ Package.onUse(function (api) { api.addFiles("wrapper.js", "server"); - api.export([ - "NpmModuleMongodb", - "NpmModuleMongodbVersion", - ], "server"); - api.addAssets('index.d.ts', 'server'); + api.export(["NpmModuleMongodb", "NpmModuleMongodbVersion"], "server"); + api.addAssets("index.d.ts", "server"); }); diff --git a/packages/test-helpers/connection_client.js b/packages/test-helpers/connection_client.js new file mode 100644 index 0000000000..828a36857b --- /dev/null +++ b/packages/test-helpers/connection_client.js @@ -0,0 +1,29 @@ +captureConnectionMessagesClient = async function () { + const messages = [] + + const conn = DDP.connect(Meteor.absoluteUrl()); + + const send = conn._stream.send; + + conn._stream.send = function (...args) { + // Messages are not really sent when the socket is not connected, duh + if (conn._stream.currentStatus.connected) { + messages.push(EJSON.parse(args[0])); + } + send.apply(this, args); + } + + conn._stream.on('message', message => { + return messages.push(EJSON.parse(message)); + }); + + function cleanup() { + conn._stream.send = send + } + + return { + conn, + messages, + cleanup + } +}; \ No newline at end of file diff --git a/packages/test-helpers/connection.js b/packages/test-helpers/connection_server.js similarity index 75% rename from packages/test-helpers/connection.js rename to packages/test-helpers/connection_server.js index a78c3dab46..4a360d1e97 100644 --- a/packages/test-helpers/connection.js +++ b/packages/test-helpers/connection_server.js @@ -52,3 +52,34 @@ makeTestConnection = function (test, succeeded, failed) { } ); }; + +createTestConnectionPromise = function (test) { + return new Promise((resolve, reject) => { + makeTestConnection(test, resolve, reject); + }); +}; + +captureConnectionMessages = async function (test) { + const messages = [] + + const conn = await createTestConnectionPromise(test); + + const send = conn._stream.send; + + conn._stream.send = function (...args) { + send.apply(this, args); + messages.push(EJSON.parse(args[0])); + } + + conn._stream.on('message', message => messages.push(EJSON.parse(message))); + + function cleanup() { + conn._stream.send = send + } + + return { + conn, + messages, + cleanup + } +}; \ No newline at end of file diff --git a/packages/test-helpers/package.js b/packages/test-helpers/package.js index f03739d8ae..7f8176ec31 100644 --- a/packages/test-helpers/package.js +++ b/packages/test-helpers/package.js @@ -1,17 +1,17 @@ Package.describe({ summary: "Utility functions for tests", - version: '2.0.0', + version: "2.0.1", }); Package.onUse(function (api) { api.use([ - 'ecmascript', - 'underscore', - 'tracker', - 'ejson', - 'tinytest', - 'random', - 'blaze', + "ecmascript", + "underscore", + "tracker", + "ejson", + "tinytest", + "random", + "blaze", ]); // XXX for connection.js. Not sure this really belongs in @@ -20,35 +20,51 @@ Package.onUse(function (api) { // other package tests and not included in the non-test bundle. One // idea would be to make a new separate package 'ddp-test-helpers' or // the like. - api.use('ddp'); - + api.use("ddp"); api.export([ - 'pollUntil', 'try_all_permutations', - 'SeededRandom', 'clickElement', 'blurElement', - 'focusElement', 'simulateEvent', 'getStyleProperty', 'canonicalizeHtml', - 'renderToDiv', 'clickIt', - 'withCallbackLogger', 'testAsyncMulti', - 'simplePoll', 'runAndThrowIfNeeded', - 'makeTestConnection', 'DomUtils', 'mockBehaviours', 'waitUntil']); + "pollUntil", + "try_all_permutations", + "SeededRandom", + "clickElement", + "blurElement", + "focusElement", + "simulateEvent", + "getStyleProperty", + "canonicalizeHtml", + "renderToDiv", + "clickIt", + "withCallbackLogger", + "testAsyncMulti", + "simplePoll", + "runAndThrowIfNeeded", + "DomUtils", + "mockBehaviours", + "waitUntil", + "makeTestConnection", + "createTestConnectionPromise", + "captureConnectionMessages", + "captureConnectionMessagesClient", + ]); - api.addFiles('try_all_permutations.js'); - api.addFiles('async_multi.js'); - api.addFiles('event_simulation.js'); - api.addFiles('seeded_random.js'); - api.addFiles('canonicalize_html.js'); - api.addFiles('render_div.js'); - api.addFiles('current_style.js'); - api.addFiles('callback_logger.js'); - api.addFiles('mock.js'); - api.addFiles('wait.js'); - api.addFiles('domutils.js', 'client'); - api.addFiles('connection.js', 'server'); + api.addFiles("try_all_permutations.js"); + api.addFiles("async_multi.js"); + api.addFiles("event_simulation.js"); + api.addFiles("seeded_random.js"); + api.addFiles("canonicalize_html.js"); + api.addFiles("render_div.js"); + api.addFiles("current_style.js"); + api.addFiles("callback_logger.js"); + api.addFiles("mock.js"); + api.addFiles("wait.js"); + api.addFiles("domutils.js", "client"); + api.addFiles("connection_server.js", "server"); + api.addFiles("connection_client.js", "client"); }); Package.onTest(function (api) { - api.use('tinytest'); - api.use(['test-helpers', 'underscore']); - api.addFiles('try_all_permutations_test.js', 'client'); - api.addFiles('seeded_random_test.js'); + api.use("tinytest"); + api.use(["test-helpers", "underscore"]); + api.addFiles("try_all_permutations_test.js", "client"); + api.addFiles("seeded_random_test.js"); }); diff --git a/packages/webapp/.npm/package/npm-shrinkwrap.json b/packages/webapp/.npm/package/npm-shrinkwrap.json index b2ed3f94e7..59e90defbd 100644 --- a/packages/webapp/.npm/package/npm-shrinkwrap.json +++ b/packages/webapp/.npm/package/npm-shrinkwrap.json @@ -32,9 +32,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==" + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==" }, "@types/qs": { "version": "6.9.15", @@ -469,9 +469,9 @@ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==" }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, "unpipe": { "version": "1.0.0", diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 2633a677f6..30d027218d 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,46 +1,46 @@ Package.describe({ - summary: 'Serves a Meteor app over HTTP', - version: '2.0.0', + summary: "Serves a Meteor app over HTTP", + version: "2.0.1", }); Npm.depends({ - 'cookie-parser': '1.4.6', - express: '4.18.2', - '@types/express': '4.17.15', - compression: '1.7.4', - errorhandler: '1.5.1', - parseurl: '1.3.3', - send: '0.18.0', - 'stream-to-string': '1.2.1', - qs: '6.11.2', - useragent: '2.3.0', - '@types/connect': '3.4.38', + "cookie-parser": "1.4.6", + express: "4.18.2", + "@types/express": "4.17.15", + compression: "1.7.4", + errorhandler: "1.5.1", + parseurl: "1.3.3", + send: "0.18.0", + "stream-to-string": "1.2.1", + qs: "6.11.2", + useragent: "2.3.0", + "@types/connect": "3.4.38", }); Npm.strip({ - multiparty: ['test/'], - useragent: ['test/'], + multiparty: ["test/"], + useragent: ["test/"], }); // whitelist plugin is now included in the core Cordova.depends({ - 'cordova-plugin-meteor-webapp': '2.0.4', + "cordova-plugin-meteor-webapp": "2.0.4", }); -Package.onUse(function(api) { - api.use('ecmascript'); +Package.onUse(function (api) { + api.use("ecmascript"); api.use( [ - 'logging', - 'underscore', - 'routepolicy', - 'modern-browsers', - 'boilerplate-generator', - 'webapp-hashing', - 'inter-process-messaging', - 'callback-hook', + "logging", + "underscore", + "routepolicy", + "modern-browsers", + "boilerplate-generator", + "webapp-hashing", + "inter-process-messaging", + "callback-hook", ], - 'server' + "server" ); // At response serving time, webapp uses browser-policy if it is loaded. If @@ -48,24 +48,32 @@ Package.onUse(function(api) { // (browser-policy depends on webapp). So we don't explicitly depend in any // way on browser-policy here, but we use it when it is loaded, and it can be // loaded after webapp. - api.mainModule('webapp_server.js', 'server'); - api.export('WebApp', 'server'); - api.export('WebAppInternals', 'server'); - api.export('main', 'server'); + api.mainModule("webapp_server.js", "server"); + api.export("WebApp", "server"); + api.export("WebAppInternals", "server"); + api.export("main", "server"); - api.mainModule('webapp_client.js', 'client'); - api.export('WebApp', 'client'); + api.mainModule("webapp_client.js", "client"); + api.export("WebApp", "client"); - api.mainModule('webapp_cordova.js', 'web.cordova'); - api.addAssets('webapp.d.ts', 'server'); + api.mainModule("webapp_cordova.js", "web.cordova"); + api.addAssets("webapp.d.ts", "server"); }); -Package.onTest(function(api) { - api.use(['tinytest', 'ecmascript', 'webapp', 'http', 'underscore','fetch', 'test-helpers']); - api.addFiles('webapp_tests.js', 'server'); - api.addFiles('webapp_client_tests.js', 'client'); - api.addFiles('socket_file_tests.js', 'server'); +Package.onTest(function (api) { + api.use([ + "tinytest", + "ecmascript", + "webapp", + "http", + "underscore", + "fetch", + "test-helpers", + ]); + api.addFiles("webapp_tests.js", "server"); + api.addFiles("webapp_client_tests.js", "client"); + api.addFiles("socket_file_tests.js", "server"); - api.addAssets('modern_test_asset.js', 'web.browser'); - api.addAssets('legacy_test_asset.js', 'legacy'); + api.addAssets("modern_test_asset.js", "web.browser"); + api.addAssets("legacy_test_asset.js", "legacy"); }); diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index df10b667ae..b8ef390df5 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "3.0-rc.10", + "version": "3.0.2-beta.4", "recommended": false, "official": false, "description": "Meteor experimental release" diff --git a/scripts/admin/meteor-release-official.json b/scripts/admin/meteor-release-official.json index b349a3375d..3905288c22 100644 --- a/scripts/admin/meteor-release-official.json +++ b/scripts/admin/meteor-release-official.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "3.0.1", + "version": "3.0.2", "recommended": false, "official": true, "description": "The Official Meteor Distribution" diff --git a/tools/static-assets/skel-chakra-ui/.meteor/packages b/tools/static-assets/skel-chakra-ui/.meteor/packages index 37f116fa2a..90ce4b06dd 100644 --- a/tools/static-assets/skel-chakra-ui/.meteor/packages +++ b/tools/static-assets/skel-chakra-ui/.meteor/packages @@ -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 -react-meteor-data@3.0.0-beta300.1 # React higher-order component for reactively tracking Meteor data +react-meteor-data # React higher-order component for reactively tracking Meteor data diff --git a/tools/static-assets/skel-react/.meteor/packages b/tools/static-assets/skel-react/.meteor/packages index 37f116fa2a..90ce4b06dd 100644 --- a/tools/static-assets/skel-react/.meteor/packages +++ b/tools/static-assets/skel-react/.meteor/packages @@ -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 -react-meteor-data@3.0.0-beta300.1 # React higher-order component for reactively tracking Meteor data +react-meteor-data # React higher-order component for reactively tracking Meteor data diff --git a/tools/static-assets/skel-tailwind/.meteor/packages b/tools/static-assets/skel-tailwind/.meteor/packages index 37f116fa2a..90ce4b06dd 100644 --- a/tools/static-assets/skel-tailwind/.meteor/packages +++ b/tools/static-assets/skel-tailwind/.meteor/packages @@ -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 -react-meteor-data@3.0.0-beta300.1 # React higher-order component for reactively tracking Meteor data +react-meteor-data # React higher-order component for reactively tracking Meteor data diff --git a/tools/static-assets/skel-typescript/.meteor/packages b/tools/static-assets/skel-typescript/.meteor/packages index 91e12d8bfe..033932891e 100644 --- a/tools/static-assets/skel-typescript/.meteor/packages +++ b/tools/static-assets/skel-typescript/.meteor/packages @@ -19,5 +19,5 @@ hot-module-replacement # Update client in development without reloading the pag ~prototype~ static-html # Define static page content in .html files -react-meteor-data@3.0.0-beta300.1 # React higher-order component for reactively tracking Meteor data +react-meteor-data # React higher-order component for reactively tracking Meteor data zodern:types # Pull in type declarations from other Meteor packages diff --git a/tools/tests/apps/app-config/.meteor/packages b/tools/tests/apps/app-config/.meteor/packages index 2cffaf721d..8f439d128c 100644 --- a/tools/tests/apps/app-config/.meteor/packages +++ b/tools/tests/apps/app-config/.meteor/packages @@ -12,4 +12,4 @@ es5-shim # ECMAScript 5 compatibility for older browsers ecmascript # Enable ECMAScript2015+ syntax in app code shell-server # Server-side component of the `meteor shell` command less # Support .less files for defining CSS styles -meteortesting:mocha@3.0.3-alpha300.11 +meteortesting:mocha@3.0.0 diff --git a/tools/tests/apps/dynamic-import/.meteor/packages b/tools/tests/apps/dynamic-import/.meteor/packages index f702fc725f..7fe131dfa2 100644 --- a/tools/tests/apps/dynamic-import/.meteor/packages +++ b/tools/tests/apps/dynamic-import/.meteor/packages @@ -26,4 +26,4 @@ user:colon-name underscore@1.0.14-alpha300.11 fetch@0.1.3 jquery -meteortesting:mocha@3.0.3-alpha300.11 +meteortesting:mocha@3.0.0 diff --git a/tools/tests/apps/ecmascript-regression/.meteor/packages b/tools/tests/apps/ecmascript-regression/.meteor/packages index 2c648654f5..feccb33d03 100644 --- a/tools/tests/apps/ecmascript-regression/.meteor/packages +++ b/tools/tests/apps/ecmascript-regression/.meteor/packages @@ -20,5 +20,5 @@ hot-module-replacement@0.5.4-alpha300.11 # Update client in development without autopublish@1.0.7 # Publish all data to the clients (for prototyping) insecure@1.0.7 # Allow all DB writes from clients (for prototyping) static-html@1.3.3-alpha300.11 # Define static page content in .html files -react-meteor-data@3.0.0-beta300.1 # React higher-order component for reactively tracking Meteor data -meteortesting:mocha@3.0.3-alpha300.11 +react-meteor-data@3.0.1 # React higher-order component for reactively tracking Meteor data +meteortesting:mocha@3.0.0 diff --git a/tools/tests/apps/ecmascript-regression/.meteor/versions b/tools/tests/apps/ecmascript-regression/.meteor/versions index 831289b98d..c5c8851416 100644 --- a/tools/tests/apps/ecmascript-regression/.meteor/versions +++ b/tools/tests/apps/ecmascript-regression/.meteor/versions @@ -38,8 +38,8 @@ logging@1.3.1 meteor@1.10.0 meteor-base@1.5.1 meteortesting:browser-tests@1.3.4 -meteortesting:mocha@3.0.3-alpha300.11 -meteortesting:mocha-core@8.0.1 +meteortesting:mocha@3.0.0 +meteortesting:mocha-core@8.2.0 minifier-css@1.6.0 minifier-js@2.7.1 minimongo@1.7.0 @@ -58,7 +58,7 @@ ordered-dict@1.1.0 promise@0.12.0 random@1.2.1 react-fast-refresh@0.1.1 -react-meteor-data@3.0.0-beta300.1 +react-meteor-data@3.0.1 reactive-var@1.0.12 reload@1.3.1 retry@1.1.0 diff --git a/tools/tests/apps/modules/.meteor/packages b/tools/tests/apps/modules/.meteor/packages index 774a83c1f6..7612fb6ccc 100644 --- a/tools/tests/apps/modules/.meteor/packages +++ b/tools/tests/apps/modules/.meteor/packages @@ -27,5 +27,5 @@ underscore@1.0.14-beta300.6 import-local-json-module dummy-compiler typescript@5.3.3-beta300.6 -meteortesting:mocha@3.1.0-beta300.0 -meteortesting:mocha-core@8.3.1-beta300.0 +meteortesting:mocha@3.0.0 +meteortesting:mocha-core@8.2.0 diff --git a/v3-docs/docs/generators/changelog/versions/3.0.2.md b/v3-docs/docs/generators/changelog/versions/3.0.2.md new file mode 100644 index 0000000000..197553e675 --- /dev/null +++ b/v3-docs/docs/generators/changelog/versions/3.0.2.md @@ -0,0 +1,58 @@ +## v3.0.2, 2024-08-14 + +### Highlights + +* Bump the patch for some packages, so we publish them using Meteor 3 tooling. [PR #13231] +* Fix subscription still resetting documents [PR #13236] +* Fix auth sub sending ready twice on load [PR #13247] +* Remove version constraints from http package in accounts-twitter [PR #13268] +* Deprecate Meteor.user() usage on server side [PR #13288] + +#### Breaking Changes + +N/A + +#### Internal API changes + +N/A + +#### Migration Steps + +Please run the following command to update your project: + +```bash + +meteor update --release 3.0.2 + +``` + + +#### Meteor Version Release + +* `Bumped packages`: + - accounts-2fa@3.0.1 + - accounts-base@3.0.1 + - accounts-password@3.0.1 + - accounts-twitter@1.5.2 + - ddp-client@3.0.1 + - ddp-common@1.4.4 + - ddp-server@3.0.1 + - email@3.0.1 + - meteor@2.0.1 + - minimongo@2.0.1 + - mongo@2.0.1 + - npm-mongo@4.17.4 + - test-helpers@2.0.1 + - webapp@2.0.1 + + + +#### Special thanks to + +- [@leonardoventurini](https://github.com/leonardoventurini). +- [@StorytellerCZ](https://github.com/StorytellerCZ). + + +For making this great framework even better! + + diff --git a/v3-docs/docs/index.md b/v3-docs/docs/index.md index ccf12f2d83..84434df490 100644 --- a/v3-docs/docs/index.md +++ b/v3-docs/docs/index.md @@ -44,7 +44,7 @@ features: - title: Built-in Accounts icon: 👤 - details: Login and Accounts package ready to use with your app. Never rebuilt an authentication system again. + details: Login and Accounts package ready to use with your app. Never rebuild an authentication system again. - title: Pioneering and Reliable icon: 🏆