diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b714c9285..6736ff3860 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -79,7 +79,7 @@ run_save_node_bin: &run_save_node_bin build_machine_environment: &build_machine_environment # Specify that we want an actual machine (ala Circle 1.0), not a Docker image. docker: - - image: meteor/circleci:2024.09.11-android-34-node-20 + - image: meteor/circleci:2025.07.8-android-35-node-22 resource_class: large environment: # This multiplier scales the waitSecs for selftests. @@ -756,7 +756,7 @@ jobs: Docs: docker: # This Node version should match that in the meteor/docs CircleCI config. - - image: meteor/circleci:2024.09.11-android-34-node-20 + - image: meteor/circleci:2025.07.8-android-35-node-22 resource_class: large environment: CHECKOUT_METEOR_DOCS: /home/circleci/test_docs diff --git a/.travis.yml b/.travis.yml index 622ed6cadd..3e63726f4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: jammy sudo: required services: xvfb node_js: - - "22.16.0" + - "22.17.0" cache: directories: - ".meteor" diff --git a/docs/history.md b/docs/history.md index 243ea1da7d..2f932f7780 100644 --- a/docs/history.md +++ b/docs/history.md @@ -8,6 +8,123 @@ [//]: # (go to meteor/docs/generators/changelog/docs) +## v3.3.1, 05-08-2025 + +### Highlights + +- **MongoDB Driver Upgrades** + - Upgraded core MongoDB driver to `6.16.0` to address latest issues reported [#13710](https://github.com/meteor/meteor/pull/13710) + - Introduced `npm-mongo-legacy` to maintain compatibility with MongoDB 3.6 via `mongodb@6.9.0` [#13736](https://github.com/meteor/meteor/pull/13736) + - Mitigated a cursor leak issue by synchronizing `next()` and `close()` operations [#13786](https://github.com/meteor/meteor/pull/13786) + +- **Improved SWC integration** + - Fixed edge cases in config cache invalidation [#13809](https://github.com/meteor/meteor/pull/13809) + - Ensured `@swc/helpers` is consistently used for better bundle size and performance [#13820](https://github.com/meteor/meteor/pull/13820) + - Updated to SWC `1.12.14` [#13851](https://github.com/meteor/meteor/pull/13851) + +- **Tooling and Build System** + - Fixed regression affecting rebuild behavior [#13810](https://github.com/meteor/meteor/pull/13810) + - Addressed issues getting performance profiles in mounted volumes [#13827](https://github.com/meteor/meteor/pull/13827) + - Fallback to Babel parser when Acorn fails to parse source code [#13844](https://github.com/meteor/meteor/pull/13844) + +- **Mobile Support** + - Upgraded Cordova platform to version 14 [#13837](https://github.com/meteor/meteor/pull/13837) + +- **Developer Experience** + - Added TypeScript types for `isModern` and `getMinimumBrowserVersions` functions [#13704](https://github.com/meteor/meteor/pull/13704) + - Enhanced CLI help output and documented admin commands [#13826](https://github.com/meteor/meteor/pull/13826) + +- **Vite Tooling** + - Updated official Meteor + Vite skeletons [#13835](https://github.com/meteor/meteor/pull/13835) + +- **Runtime & Dependencies** + - Updated to Node.js `22.18.0` and NPM `10.9.3` [#13877](https://github.com/meteor/meteor/pull/13877) + - Bumped `meteor-node-stubs` to `1.2.21` [#13825](https://github.com/meteor/meteor/pull/13825) + +All Merged PRs@[GitHub PRs 3.3.1](https://github.com/meteor/meteor/pulls?q=is%3Apr+is%3Amerged+base%3Arelease-3.3.1) + +#### Breaking Changes + +##### MongoDB Driver Upgrades + +If you're using MongoDB 3.6 or earlier, install the new legacy package: + +```bash +meteor add npm-mongo-legacy +``` +This will pin the MongoDB driver to 6.9.0 for compatibility. + +If you’re on MongoDB 4+, the default [MongoDB driver 6.16.0](https://github.com/mongodb/node-mongodb-native/releases/tag/v6.16.0) is applied automatically. + +Please migrate your database as soon as possible to MongoDB 5 onward, as [MongoDB driver 6.17.0](https://github.com/mongodb/node-mongodb-native/releases/tag/v6.17.0) will drop MongoDB 4 support. We’ll keep offering `npm-mongo-legacy` so you can keep getting Meteor updates with your existing MongoDB legacy version. + +##### Cordova Upgrade + +The Cordova platform has been upgraded to version 14. Refer to the [Cordova Changelog](https://cordova.apache.org/announcements/2025/03/26/cordova-android-14.0.0.html) for more details on the changes and migration steps. + +#### Internal API changes + +N/A + +#### Migration Steps + +Please run the following command to update your project: + +```bash +meteor update --release 3.3.1 +``` + +--- + +While this is a patch release, Meteor 3.3, a recent minor update, introduced a modern build stack that’s now the default for new apps. Here’s how you can migrate to it. + +**Add this to your `package.json` to enable the new modern build stack:** + +```json +"meteor": { + "modern": true +} +``` + +Check the docs for help with the SWC migration, especially if your project uses many Babel plugins. + +[Modern Transpiler: SWC docs](https://docs.meteor.com/about/modern-build-stack/transpiler-swc.html) + +If you find any issues, please report them to the [Meteor issues tracker](https://github.com/meteor/meteor). + +#### Bumped Meteor Packages + +- babel-compiler@7.12.1 +- callback-hook@1.6.1 +- ecmascript@0.16.12 +- minifier-js@3.0.3 +- minimongo@2.0.3 +- modern-browsers@0.2.3 +- mongo@2.1.3 +- npm-mongo-legacy@6.9.0 +- npm-mongo@6.16.0 +- standard-minifier-js@3.1.1 +- tinytest@1.3.2 +- typescript@5.6.5 +- meteor-tool@3.3.1 + +#### Bumped NPM Packages + +- meteor-node-stubs@1.2.21 + +#### Special thanks to + +✨✨✨ + +- [@nachocodoner](https://github.com/nachocodoner) +- [@italojs](https://github.com/italojs) +- [@StorytellerCZ](https://github.com/StorytellerCZ) +- [@JorgenVatle](https://github.com/JorgenVatle) +- [@welkinwong](https://github.com/welkinwong) +- [@Saksham-Goel1107](https://github.com/Saksham-Goel1107) + +✨✨✨ + ## v3.3.0, 2025-06-11 ### Highlights diff --git a/docs/package-lock.json b/docs/package-lock.json index 7965d6e9ba..9d4a412012 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -4,16 +4,41 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true }, + "@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true + }, + "@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "requires": { + "@babel/types": "^7.28.0" + } + }, + "@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + } + }, "@jsdoc/salty": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.6.tgz", - "integrity": "sha512-aA+awb5yoml8TQ3CzI5Ue7sM3VMRC4l1zJJW4fgZ8OCL1wshJZhNzaf0PL85DSnOUw6QuFgeHGD/eq/xwwAF2g==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz", + "integrity": "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==", "dev": true, "requires": { "lodash": "^4.17.21" @@ -26,31 +51,31 @@ "dev": true }, "@meteorjs/meteor-theme-hexo": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@meteorjs/meteor-theme-hexo/-/meteor-theme-hexo-2.0.8.tgz", - "integrity": "sha512-LQIFN05wBMjX7SXgW5CFVTfolDWMuknoypwQ0czl/44LYRBR4/LYZUgX6c+1vLjloJb+5+2HTvMGlVN9Wo1MKA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@meteorjs/meteor-theme-hexo/-/meteor-theme-hexo-2.0.9.tgz", + "integrity": "sha512-8ncpsN8MAe1F7cJBtcPgH3JE36WV03oo5mPkA1yMdRmv2kq8AQpKnd4ok0U1cr5NIIBMupLtsHDLm8PhTQcUdw==", "dev": true }, "@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "requires": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@types/linkify-it": "^5", + "@types/mdurl": "^2" } }, "@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, "JSONStream": { @@ -75,16 +100,6 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, "acorn": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", @@ -239,9 +254,9 @@ "optional": true }, "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", "dev": true, "optional": true }, @@ -479,9 +494,9 @@ } }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -506,9 +521,9 @@ "dev": true }, "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "cache-base": { @@ -537,17 +552,38 @@ } }, "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "optional": true, "requires": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + } + }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "optional": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, + "call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "optional": true, + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" } }, "camel-case": { @@ -801,18 +837,26 @@ } }, "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "concat-map": { @@ -1040,6 +1084,18 @@ "domelementtype": "1" } }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "optional": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1092,14 +1148,11 @@ } }, "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "optional": true, - "requires": { - "get-intrinsic": "^1.2.4" - } + "optional": true }, "es-errors": { "version": "1.3.0", @@ -1108,6 +1161,16 @@ "dev": true, "optional": true }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "optional": true, + "requires": { + "es-errors": "^1.3.0" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1323,17 +1386,33 @@ "dev": true }, "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "optional": true, "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "optional": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" } }, "get-value": { @@ -1401,14 +1480,11 @@ "dev": true }, "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "optional": true, - "requires": { - "get-intrinsic": "^1.1.3" - } + "optional": true }, "graceful-fs": { "version": "4.2.11", @@ -1480,17 +1556,10 @@ "es-define-property": "^1.0.0" } }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "optional": true - }, "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "optional": true }, @@ -2390,9 +2459,9 @@ }, "dependencies": { "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "requires": { "nice-try": "^1.0.4", @@ -2416,12 +2485,6 @@ "striptags": "^3.1.1" } }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -2652,12 +2715,12 @@ "dev": true }, "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "requires": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" } }, "is-data-descriptor": { @@ -2839,21 +2902,21 @@ "optional": true }, "jsdoc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", - "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", + "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==", "dev": true, "requires": { "@babel/parser": "^7.20.15", "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^12.2.3", + "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", @@ -2861,12 +2924,6 @@ "underscore": "~1.13.2" }, "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -2886,9 +2943,9 @@ "dev": true }, "underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", "dev": true } } @@ -2901,13 +2958,14 @@ "optional": true }, "json-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", - "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", + "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", "dev": true, "optional": true, "requires": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" @@ -3005,12 +3063,12 @@ } }, "linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "requires": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "locate-path": { @@ -3157,16 +3215,17 @@ } }, "markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "requires": { "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "dependencies": { "argparse": { @@ -3176,9 +3235,9 @@ "dev": true }, "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true } } @@ -3189,6 +3248,19 @@ "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "optional": true + }, "math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", @@ -3196,9 +3268,9 @@ "dev": true }, "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "micromatch": { @@ -3239,6 +3311,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "optional": true, "requires": { "mime-db": "1.52.0" } @@ -3302,25 +3375,25 @@ "dev": true }, "moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", "dev": true, "requires": { "moment": "^2.29.4" } }, "morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", + "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", "dev": true, "requires": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", - "on-headers": "~1.0.2" + "on-headers": "~1.1.0" } }, "ms": { @@ -3342,9 +3415,9 @@ } }, "nan": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", - "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "dev": true, "optional": true }, @@ -3395,9 +3468,9 @@ "optional": true }, "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true }, "neo-async": { @@ -3561,9 +3634,9 @@ } }, "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true }, "once": { @@ -3754,6 +3827,12 @@ "dev": true, "optional": true }, + "punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true + }, "qs": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.1.tgz", @@ -4124,12 +4203,12 @@ } }, "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "requires": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -4201,9 +4280,9 @@ "dev": true }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "requires": { "debug": "2.6.9", @@ -4245,15 +4324,23 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "requires": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" + }, + "dependencies": { + "encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true + } } }, "set-blocking": { @@ -4789,15 +4876,15 @@ "optional": true }, "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, "optional": true }, diff --git a/docs/package.json b/docs/package.json index 79c7f3bf31..f8aea85ac7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -6,6 +6,8 @@ "version": "3.9.0" }, "devDependencies": { + "@meteorjs/meteor-hexo-config": "1.0.14", + "@meteorjs/meteor-theme-hexo": "^2.0.9", "canonical-json": "0.0.4", "chexo": "1.0.7", "handlebars": "4.7.7", @@ -17,15 +19,13 @@ "hexo-server": "1.0.0", "hexo-versioned-netlify-redirects": "1.1.0", "jsdoc": "^4.0.2", - "@meteorjs/meteor-hexo-config": "1.0.14", - "@meteorjs/meteor-theme-hexo": "2.0.8", "showdown": "1.9.1", "underscore": "1.13.1" }, "scripts": { "list-core-packages": "node ./generators/packages-listing/script.js", "generate-history": "node ./generators/changelog/script.js", - "build": "npm run list-core-packages && npm run generate-history && jsdoc/jsdoc.sh && chexo @meteorjs/meteor-hexo-config -- generate", + "build": "npm run list-core-packages && jsdoc/jsdoc.sh && chexo @meteorjs/meteor-hexo-config -- generate", "clean": "hexo clean; rm data/data.js data/names.json", "test": "npm run clean; npm run build", "predeploy": "npm run build", diff --git a/meteor b/meteor index e452f7b273..65372bf258 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=22.16.0.1 +BUNDLE_VERSION=22.18.0.2 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. diff --git a/npm-packages/eslint-plugin-meteor/scripts/dev-bundle-tool-package.js b/npm-packages/eslint-plugin-meteor/scripts/dev-bundle-tool-package.js index 0ce217a8f2..aedf49c8c0 100644 --- a/npm-packages/eslint-plugin-meteor/scripts/dev-bundle-tool-package.js +++ b/npm-packages/eslint-plugin-meteor/scripts/dev-bundle-tool-package.js @@ -10,7 +10,7 @@ var packageJson = { dependencies: { // Explicit dependency because we are replacing it with a bundled version // and we want to make sure there are no dependencies on a higher version - npm: "10.9.2", + npm: "10.9.3", pacote: "https://github.com/meteor/pacote/tarball/a81b0324686e85d22c7688c47629d4009000e8b8", "node-gyp": "9.4.0", "@mapbox/node-pre-gyp": "1.0.11", diff --git a/npm-packages/meteor-installer/config.js b/npm-packages/meteor-installer/config.js index d820e33456..de877591e7 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.3'; +const METEOR_LATEST_VERSION = '3.3.1'; const sudoUser = process.env.SUDO_USER || ''; function isRoot() { return process.getuid && process.getuid() === 0; diff --git a/npm-packages/meteor-installer/package-lock.json b/npm-packages/meteor-installer/package-lock.json index a813defb08..4ac843a7c7 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.3.0", + "version": "3.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "meteor", - "version": "3.3.0", + "version": "3.3.1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/npm-packages/meteor-installer/package.json b/npm-packages/meteor-installer/package.json index 5be1ef790a..3733b29f27 100644 --- a/npm-packages/meteor-installer/package.json +++ b/npm-packages/meteor-installer/package.json @@ -1,6 +1,6 @@ { "name": "meteor", - "version": "3.3.0", + "version": "3.3.1", "description": "Install Meteor", "main": "install.js", "scripts": { diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index 506f865117..10749cd588 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -25,11 +25,18 @@ var BCp = BabelCompiler.prototype; var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; +function getMeteorConfig() { + return Plugin?.getMeteorConfig() || {}; +} + // Check if verbose mode is enabled either in the provided config or in extraFeatures -BCp.isVerbose = function(config) { +BCp.isVerbose = function(config = getMeteorConfig()) { if (config?.modern?.transpiler?.verbose) { return true; } + if (config?.modern?.verbose) { + return true; + } if (config?.verbose) { return true; } @@ -80,47 +87,13 @@ function compileWithSwc(source, swcOptions = {}, { features }) { }; }); } -const DEFAULT_MODERN = { - transpiler: true, -}; -const normalizeModern = (r = false) => Object.fromEntries( - Object.entries(DEFAULT_MODERN).map(([k, def]) => [ - k, - r === true - ? def - : r === false || r?.[k] === false - ? false - : typeof r?.[k] === 'object' - ? { ...r[k] } - : def, - ]), -); - -let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); - -let lastModifiedMeteorConfig; -let lastModifiedMeteorConfigTime; BCp.initializeMeteorAppConfig = function () { - if (!lastModifiedMeteorConfig && !fs.existsSync(`${getMeteorAppDir()}/package.json`)) { - return; + const meteorConfig = getMeteorConfig(); + if (this.isVerbose()) { + logConfigBlock('Meteor Config', meteorConfig); } - const currentLastModifiedConfigTime = fs - .statSync(`${getMeteorAppDir()}/package.json`) - ?.mtime?.getTime(); - if (currentLastModifiedConfigTime !== lastModifiedMeteorConfigTime) { - lastModifiedMeteorConfigTime = currentLastModifiedConfigTime; - lastModifiedMeteorConfig = getMeteorAppPackageJson()?.meteor; - lastModifiedMeteorConfig = lastModifiedMeteorConfig != null ? { - ...lastModifiedMeteorConfig, - modern: normalizeModern(modernForced || lastModifiedMeteorConfig?.modern), - } : {}; - - if (this.isVerbose(lastModifiedMeteorConfig)) { - logConfigBlock('Meteor Config', lastModifiedMeteorConfig); - } - } - return lastModifiedMeteorConfig; + return meteorConfig; }; let lastModifiedSwcConfig; @@ -139,7 +112,9 @@ BCp.initializeMeteorAppSwcrc = function () { let currentLastModifiedConfigTime; if (hasSwcJs) { // For dynamic JS files, first get the resolved configuration - const resolvedConfig = lastModifiedSwcConfig || getMeteorAppSwcrc(swcFile); + const resolvedConfig = lastModifiedSwcConfigTime?.includes(`${fileModTime}`) + ? lastModifiedSwcConfig || getMeteorAppSwcrc(swcFile) + : getMeteorAppSwcrc(swcFile); // Calculate a hash of the resolved configuration to detect changes const contentHash = crypto .createHash('sha256') @@ -158,9 +133,11 @@ BCp.initializeMeteorAppSwcrc = function () { lastModifiedSwcConfigTime = currentLastModifiedConfigTime; lastModifiedSwcConfig = getMeteorAppSwcrc(swcFile); - if (this.isVerbose(lastModifiedMeteorConfig)) { - logConfigBlock('SWC Config', lastModifiedSwcConfig); + if (this.isVerbose()) { + logConfigBlock('SWC Custom Config', lastModifiedSwcConfig); } + + this._swcIncompatible = {}; } return lastModifiedSwcConfig; }; @@ -168,13 +145,49 @@ BCp.initializeMeteorAppSwcrc = function () { let lastModifiedSwcLegacyConfig; BCp.initializeMeteorAppLegacyConfig = function () { const swcLegacyConfig = convertBabelTargetsForSwc(Babel.getMinimumModernBrowserVersions()); - if (this.isVerbose(lastModifiedMeteorConfig) && !lastModifiedSwcLegacyConfig) { + if (this.isVerbose() && !lastModifiedSwcLegacyConfig) { logConfigBlock('SWC Legacy Config', swcLegacyConfig); } lastModifiedSwcLegacyConfig = swcLegacyConfig; return lastModifiedSwcConfig; }; +// Helper function to check if @swc/helpers is available +function hasSwcHelpers() { + return fs.existsSync(`${getMeteorAppDir()}/node_modules/@swc/helpers`); +} + +// Helper function to log friendly messages about SWC helpers +function logSwcHelpersStatus(isAvailable) { + const label = color('[SWC Helpers]', 36); + + if (isAvailable) { + // Green message for when helpers are available + console.log(`${label} ${color('✓ @swc/helpers is available in your project!', 32)}`); + console.log(` ${color('Benefits:', 32)}`); + console.log(` ${color('• Smaller bundle size: External helpers reduce code duplication', 32)}`); + console.log(` ${color('• Faster loads: less code to parse on first download', 32)}`); + console.log(` ${color('• Optional caching: separate vendor chunk can be cached by browsers', 32)}`); + } else { + // Yellow message for when helpers are not available + console.log(`${label} ${color('⚠ @swc/helpers is not available in your project', 33)}`); + console.log(` ${color('Suggestion:', 33)}`); + console.log(` ${color('• Add @swc/helpers to your project:', 33)}`); + console.log(` ${color('meteor npm install --save @swc/helpers', 33)}`); + console.log(` ${color('• This will reduce bundle size and improve performance', 33)}`); + } + console.log(); +} + +let hasSwcHelpersAvailable = false; +BCp.initializeMeteorAppSwcHelpersAvailable = function () { + hasSwcHelpersAvailable = hasSwcHelpers(); + if (this.isVerbose()) { + logSwcHelpersStatus(hasSwcHelpersAvailable); + } + return hasSwcHelpersAvailable; +}; + BCp.processFilesForTarget = function (inputFiles) { var compiler = this; @@ -184,6 +197,7 @@ BCp.processFilesForTarget = function (inputFiles) { this.initializeMeteorAppConfig(); this.initializeMeteorAppSwcrc(); this.initializeMeteorAppLegacyConfig(); + this.initializeMeteorAppSwcHelpersAvailable(); inputFiles.forEach(function (inputFile) { if (inputFile.supportsLazyCompilation) { @@ -314,6 +328,11 @@ BCp.processOneFileForTarget = function (inputFile, source) { jsx: hasJSXSupport, tsx: hasTSXSupport, }, + ...(hasSwcHelpersAvailable && + (packageName == null || + !['modules-runtime'].includes(packageName)) && { + externalHelpers: true, + }), }, module: { type: 'es6' }, minify: false, @@ -355,37 +374,38 @@ BCp.processOneFileForTarget = function (inputFile, source) { const isPackageCode = packageName != null; const isLegacyWebArch = arch.includes('legacy'); - const config = lastModifiedMeteorConfig?.modern?.transpiler; - const hasModernTranspiler = config != null && config !== false; + const transpConfig = getMeteorConfig()?.modern?.transpiler; + const hasModernTranspiler = transpConfig != null && transpConfig !== false; const shouldSkipSwc = !hasModernTranspiler || - (isAppCode && config?.excludeApp === true) || - (isNodeModulesCode && config?.excludeNodeModules === true) || - (isPackageCode && config?.excludePackages === true) || - (isLegacyWebArch && config?.excludeLegacy === true) || + (isAppCode && transpConfig?.excludeApp === true) || + (isNodeModulesCode && transpConfig?.excludeNodeModules === true) || + (isPackageCode && transpConfig?.excludePackages === true) || + (isLegacyWebArch && transpConfig?.excludeLegacy === true) || (isAppCode && - Array.isArray(config?.excludeApp) && - isExcludedConfig(inputFilePath, config?.excludeApp || [])) || + Array.isArray(transpConfig?.excludeApp) && + isExcludedConfig(inputFilePath, transpConfig?.excludeApp || [])) || (isNodeModulesCode && - Array.isArray(config?.excludeNodeModules) && - (isExcludedConfig(inputFilePath, config?.excludeNodeModules || []) || + Array.isArray(transpConfig?.excludeNodeModules) && + (isExcludedConfig(inputFilePath, transpConfig?.excludeNodeModules || []) || isExcludedConfig( inputFilePath.replace('node_modules/', ''), - config?.excludeNodeModules || [], + transpConfig?.excludeNodeModules || [], true, ))) || (isPackageCode && - Array.isArray(config?.excludePackages) && - (isExcludedConfig(packageName, config?.excludePackages || []) || + Array.isArray(transpConfig?.excludePackages) && + (isExcludedConfig(packageName, transpConfig?.excludePackages || []) || isExcludedConfig( `${packageName}/${inputFilePath}`, - config?.excludePackages || [], + transpConfig?.excludePackages || [], ))); const cacheKey = [ toBeAdded.hash, lastModifiedSwcConfigTime, isLegacyWebArch ? 'legacy' : '', + hasSwcHelpersAvailable, ] .filter(Boolean) .join('-'); @@ -402,7 +422,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { compilation = this.readFromSwcCache({ cacheKey }); // Return cached result if found. if (compilation) { - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc: true, inputFilePath, @@ -432,7 +452,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { usedSwc = false; } - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc, inputFilePath, @@ -448,7 +468,7 @@ BCp.processOneFileForTarget = function (inputFile, source) { babelOptions = setupBabelOptions(); compilation = compileWithBabel(source, babelOptions, cacheOptions); - if (this.isVerbose(config)) { + if (this.isVerbose()) { logTranspilation({ usedSwc: false, inputFilePath, diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 4a45656d27..4fdba21272 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -1,14 +1,14 @@ Package.describe({ name: "babel-compiler", summary: "Parser/transpiler for ECMAScript 2015+ syntax", - version: '7.12.0', + version: '7.12.1', }); Npm.depends({ '@meteorjs/babel': '7.20.1', 'json5': '2.2.3', 'semver': '7.6.3', - "@meteorjs/swc-core": "1.1.3", + "@meteorjs/swc-core": "1.12.14", }); Package.onUse(function (api) { diff --git a/packages/callback-hook/hook.js b/packages/callback-hook/hook.js index ecc9c2ccfb..d1156f79fd 100644 --- a/packages/callback-hook/hook.js +++ b/packages/callback-hook/hook.js @@ -124,20 +124,6 @@ export class Hook { } } - async forEachAsync(iterator) { - const ids = Object.keys(this.callbacks); - for (let i = 0; i < ids.length; ++i) { - const id = ids[i]; - // check to see if the callback was removed during iteration - if (hasOwn.call(this.callbacks, id)) { - const callback = this.callbacks[id]; - if (!await iterator(callback)) { - break; - } - } - } - } - /** * For each registered callback, call the passed iterator function with the callback. * diff --git a/packages/callback-hook/package.js b/packages/callback-hook/package.js index 4b4f756266..6f9e9ac68a 100644 --- a/packages/callback-hook/package.js +++ b/packages/callback-hook/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Register callbacks on a hook", - version: '1.6.0', + version: '1.6.1', }); Package.onUse(function (api) { diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index a8fd89363d..3236405da8 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.16.11', + version: '0.16.12', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md', }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 88f7661c70..00beae7bc0 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.3.0", + version: "3.3.1", }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 310391016c..22d44ba09e 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: '3.0.2', + version: '3.0.3', }); Npm.depends({ diff --git a/packages/minimongo/common.js b/packages/minimongo/common.js index 7a08e569b1..2c97a941e5 100644 --- a/packages/minimongo/common.js +++ b/packages/minimongo/common.js @@ -2,6 +2,7 @@ import LocalCollection from './local_collection.js'; export const hasOwn = Object.prototype.hasOwnProperty; +export class MiniMongoQueryError extends Error {} // Each element selector contains: // - compileElementSelector, a function with args: // - operand - the "right hand side" of the operator @@ -24,7 +25,7 @@ export const ELEMENT_OPERATORS = { if (!(Array.isArray(operand) && operand.length === 2 && typeof operand[0] === 'number' && typeof operand[1] === 'number')) { - throw Error('argument to $mod must be an array of two numbers'); + throw new MiniMongoQueryError('argument to $mod must be an array of two numbers'); } // XXX could require to be ints or round or something @@ -38,7 +39,7 @@ export const ELEMENT_OPERATORS = { $in: { compileElementSelector(operand) { if (!Array.isArray(operand)) { - throw Error('$in needs an array'); + throw new MiniMongoQueryError('$in needs an array'); } const elementMatchers = operand.map(option => { @@ -47,7 +48,7 @@ export const ELEMENT_OPERATORS = { } if (isOperatorObject(option)) { - throw Error('cannot nest $ under $in'); + throw new MiniMongoQueryError('cannot nest $ under $in'); } return equalityElementMatcher(option); @@ -74,7 +75,7 @@ export const ELEMENT_OPERATORS = { // does. operand = 0; } else if (typeof operand !== 'number') { - throw Error('$size needs a number'); + throw new MiniMongoQueryError('$size needs a number'); } return value => Array.isArray(value) && value.length === operand; @@ -112,16 +113,16 @@ export const ELEMENT_OPERATORS = { 'maxKey': 127, }; if (!hasOwn.call(operandAliasMap, operand)) { - throw Error(`unknown string alias for $type: ${operand}`); + throw new MiniMongoQueryError(`unknown string alias for $type: ${operand}`); } operand = operandAliasMap[operand]; } else if (typeof operand === 'number') { if (operand === 0 || operand < -1 || (operand > 19 && operand !== 127)) { - throw Error(`Invalid numerical $type code: ${operand}`); + throw new MiniMongoQueryError(`Invalid numerical $type code: ${operand}`); } } else { - throw Error('argument to $type is not a number or a string'); + throw new MiniMongoQueryError('argument to $type is not a number or a string'); } return value => ( @@ -168,7 +169,7 @@ export const ELEMENT_OPERATORS = { $regex: { compileElementSelector(operand, valueSelector) { if (!(typeof operand === 'string' || operand instanceof RegExp)) { - throw Error('$regex has to be a string or RegExp'); + throw new MiniMongoQueryError('$regex has to be a string or RegExp'); } let regexp; @@ -180,7 +181,7 @@ export const ELEMENT_OPERATORS = { // ones (eg, Mongo supports x and s). Ideally we would implement x and s // by transforming the regexp, but not today... if (/[^gim]/.test(valueSelector.$options)) { - throw new Error('Only the i, m, and g regexp options are supported'); + throw new MiniMongoQueryError('Only the i, m, and g regexp options are supported'); } const source = operand instanceof RegExp ? operand.source : operand; @@ -198,7 +199,7 @@ export const ELEMENT_OPERATORS = { dontExpandLeafArrays: true, compileElementSelector(operand, valueSelector, matcher) { if (!LocalCollection._isPlainObject(operand)) { - throw Error('$elemMatch need an object'); + throw new MiniMongoQueryError('$elemMatch need an object'); } const isDocMatcher = !isOperatorObject( @@ -353,7 +354,7 @@ const VALUE_OPERATORS = { // $options just provides options for $regex; its logic is inside $regex $options(operand, valueSelector) { if (!hasOwn.call(valueSelector, '$regex')) { - throw Error('$options needs a $regex'); + throw new MiniMongoQueryError('$options needs a $regex'); } return everythingMatcher; @@ -361,14 +362,14 @@ const VALUE_OPERATORS = { // $maxDistance is basically an argument to $near $maxDistance(operand, valueSelector) { if (!valueSelector.$near) { - throw Error('$maxDistance needs a $near'); + throw new MiniMongoQueryError('$maxDistance needs a $near'); } return everythingMatcher; }, $all(operand, valueSelector, matcher) { if (!Array.isArray(operand)) { - throw Error('$all requires array'); + throw new MiniMongoQueryError('$all requires array'); } // Not sure why, but this seems to be what MongoDB does. @@ -379,7 +380,7 @@ const VALUE_OPERATORS = { const branchedMatchers = operand.map(criterion => { // XXX handle $all/$elemMatch combination if (isOperatorObject(criterion)) { - throw Error('no $ expressions in $all'); + throw new MiniMongoQueryError('no $ expressions in $all'); } // This is always a regexp or equality selector. @@ -392,7 +393,7 @@ const VALUE_OPERATORS = { }, $near(operand, valueSelector, matcher, isRoot) { if (!isRoot) { - throw Error('$near can\'t be inside another $ operator'); + throw new MiniMongoQueryError('$near can\'t be inside another $ operator'); } matcher._hasGeoQuery = true; @@ -433,7 +434,7 @@ const VALUE_OPERATORS = { maxDistance = valueSelector.$maxDistance; if (!isIndexable(operand)) { - throw Error('$near argument must be coordinate pair or GeoJSON'); + throw new MiniMongoQueryError('$near argument must be coordinate pair or GeoJSON'); } point = pointToArray(operand); @@ -549,12 +550,12 @@ const andBranchedMatchers = andSomeMatchers; function compileArrayOfDocumentSelectors(selectors, matcher, inElemMatch) { if (!Array.isArray(selectors) || selectors.length === 0) { - throw Error('$and/$or/$nor must be nonempty array'); + throw new MiniMongoQueryError('$and/$or/$nor must be nonempty array'); } return selectors.map(subSelector => { if (!LocalCollection._isPlainObject(subSelector)) { - throw Error('$or/$and/$nor entries need to be full objects'); + throw new MiniMongoQueryError('$or/$and/$nor entries need to be full objects'); } return compileDocumentSelector(subSelector, matcher, {inElemMatch}); @@ -576,7 +577,7 @@ export function compileDocumentSelector(docSelector, matcher, options = {}) { // Outer operators are either logical operators (they recurse back into // this function), or $where. if (!hasOwn.call(LOGICAL_OPERATORS, key)) { - throw new Error(`Unrecognized logical operator: ${key}`); + throw new MiniMongoQueryError(`Unrecognized logical operator: ${key}`); } matcher._isSimple = false; @@ -682,7 +683,7 @@ function distanceCoordinatePairs(a, b) { // for equality with that thing. export function equalityElementMatcher(elementSelector) { if (isOperatorObject(elementSelector)) { - throw Error('Can\'t create equalityValueSelector for operator object'); + throw new MiniMongoQueryError('Can\'t create equalityValueSelector for operator object'); } // Special-case: null and undefined are equal (if you got undefined in there @@ -759,7 +760,7 @@ function getOperandBitmask(operand, selector) { } // bad operand - throw Error( + throw new MiniMongoQueryError( `operand to ${selector} must be a numeric bitmask (representable as a ` + 'non-negative 32-bit signed integer), a bindata bitmask or an array with ' + 'bit positions (non-negative integers)' @@ -813,12 +814,11 @@ function insertIntoDocument(document, key, value) { (existingKey.length > key.length && existingKey.indexOf(`${key}.`) === 0) || (key.length > existingKey.length && key.indexOf(`${existingKey}.`) === 0) ) { - throw new Error( - `cannot infer query fields to set, both paths '${existingKey}' and ` + - `'${key}' are matched` + throw new MiniMongoQueryError( + `cannot infer query fields to set, both paths '${existingKey}' and '${key}' are matched` ); } else if (existingKey === key) { - throw new Error( + throw new MiniMongoQueryError( `cannot infer query fields to set, path '${key}' is matched twice` ); } @@ -863,7 +863,7 @@ export function isOperatorObject(valueSelector, inconsistentOK) { theseAreOperators = thisIsOperator; } else if (theseAreOperators !== thisIsOperator) { if (!inconsistentOK) { - throw new Error( + throw new MiniMongoQueryError( `Inconsistent operator: ${JSON.stringify(valueSelector)}` ); } @@ -1132,7 +1132,7 @@ function operatorBranchedMatcher(valueSelector, matcher, isRoot) { ); } - throw new Error(`Unrecognized operator: ${operator}`); + throw new MiniMongoQueryError(`Unrecognized operator: ${operator}`); }); return andBranchedMatchers(operatorMatchers); @@ -1232,7 +1232,7 @@ function populateDocumentWithObject(document, key, value) { // Literal (possibly empty) object ( or empty object ) // Don't allow mixing '$'-prefixed with non-'$'-prefixed fields if (keys.length !== unprefixedKeys.length) { - throw new Error(`unknown operator: ${unprefixedKeys[0]}`); + throw new MiniMongoQueryError(`unknown operator: ${unprefixedKeys[0]}`); } validateObject(value, key); diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js index 280fea958b..d29b90c5ac 100644 --- a/packages/minimongo/package.js +++ b/packages/minimongo/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's client-side datastore: a port of MongoDB to Javascript", - version: "2.0.2", + version: "2.0.3", }); Package.onUse((api) => { diff --git a/packages/modern-browsers/modern.d.ts b/packages/modern-browsers/modern.d.ts index 69f1268f74..efa33b82e8 100644 --- a/packages/modern-browsers/modern.d.ts +++ b/packages/modern-browsers/modern.d.ts @@ -1,4 +1,12 @@ +export declare function isModern( + browser: { name: string, major: number, minor?: number, patch?: number } +): boolean; + export declare function setMinimumBrowserVersions( versions: Record, - source: string + source?: string ): void; + +export declare function getMinimumBrowserVersions(): Record>; + +export declare function calculateHashOfMinimumVersions(): string; \ No newline at end of file diff --git a/packages/modern-browsers/package.js b/packages/modern-browsers/package.js index 5187b13a29..ca05f1f8a3 100644 --- a/packages/modern-browsers/package.js +++ b/packages/modern-browsers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'modern-browsers', - version: '0.2.2', + version: '0.2.3', summary: 'API for defining the boundary between modern and legacy ' + 'JavaScript clients', diff --git a/packages/mongo/asynchronous_cursor.js b/packages/mongo/asynchronous_cursor.js index e40491f983..0c2668560a 100644 --- a/packages/mongo/asynchronous_cursor.js +++ b/packages/mongo/asynchronous_cursor.js @@ -8,6 +8,8 @@ import { replaceMongoAtomWithMeteor, replaceTypes } from './mongo_common'; * This is an internal implementation detail and is created lazily by the main Cursor class. */ export class AsynchronousCursor { + _closing = false; + _pendingNext = null; constructor(dbCursor, cursorDescription, options) { this._dbCursor = dbCursor; this._cursorDescription = cursorDescription; @@ -36,10 +38,19 @@ export class AsynchronousCursor { // Returns a Promise for the next object from the underlying cursor (before // the Mongo->Meteor type replacement). async _rawNextObjectPromise() { + if (this._closing) { + // Prevent next() after close is called + return null; + } try { - return this._dbCursor.next(); + this._pendingNext = this._dbCursor.next(); + const result = await this._pendingNext; + this._pendingNext = null; + return result; } catch (e) { console.error(e); + } finally { + this._pendingNext = null; } } @@ -74,24 +85,24 @@ export class AsynchronousCursor { // _nextObjectPromise) or rejected if the cursor doesn't return within // timeoutMS ms. _nextObjectPromiseWithTimeout(timeoutMS) { - if (!timeoutMS) { - return this._nextObjectPromise(); - } const nextObjectPromise = this._nextObjectPromise(); - const timeoutErr = new Error('Client-side timeout waiting for next object'); - const timeoutPromise = new Promise((resolve, reject) => { - setTimeout(() => { - reject(timeoutErr); + if (!timeoutMS) { + return nextObjectPromise; + } + + const timeoutPromise = new Promise(resolve => { + // On timeout, close the cursor. + const timeoutId = setTimeout(() => { + resolve(this.close()); }, timeoutMS); - }); - return Promise.race([nextObjectPromise, timeoutPromise]) - .catch((err) => { - if (err === timeoutErr) { - this.close(); - return; - } - throw err; + + // If the `_nextObjectPromise` returned first, cancel the timeout. + nextObjectPromise.finally(() => { + clearTimeout(timeoutId); }); + }); + + return Promise.race([nextObjectPromise, timeoutPromise]); } async forEach(callback, thisArg) { @@ -123,7 +134,16 @@ export class AsynchronousCursor { } // Mostly usable for tailable cursors. - close() { + async close() { + this._closing = true; + // If there's a pending next(), wait for it to finish or abort + if (this._pendingNext) { + try { + await this._pendingNext; + } catch (e) { + // ignore + } + } this._dbCursor.close(); } diff --git a/packages/mongo/collection/collection.js b/packages/mongo/collection/collection.js index adfb6ce731..23cb81f7f0 100644 --- a/packages/mongo/collection/collection.js +++ b/packages/mongo/collection/collection.js @@ -3,7 +3,8 @@ import { AsyncMethods } from './methods_async'; import { SyncMethods } from './methods_sync'; import { IndexMethods } from './methods_index'; import { - ID_GENERATORS, normalizeOptions, + ID_GENERATORS, + normalizeOptions, setupAutopublish, setupConnection, setupDriver, @@ -11,7 +12,6 @@ import { validateCollectionName } from './collection_utils'; import { ReplicationMethods } from './methods_replication'; -import { watchChangeStream } from './watch_change_stream'; /** * @summary Namespace for MongoDB-related items @@ -393,7 +393,3 @@ Meteor.Collection = Mongo.Collection; // Allow deny stuff is now in the allow-deny package Object.assign(Mongo.Collection.prototype, AllowDeny.CollectionPrototype); - -// Só agora que Mongo.Collection existe, adicionamos o método ao prototype -Object.assign(Mongo.Collection.prototype, { watchChangeStream }); - diff --git a/packages/mongo/collection/collection_utils.js b/packages/mongo/collection/collection_utils.js index a0f7442ded..e6c79646d5 100644 --- a/packages/mongo/collection/collection_utils.js +++ b/packages/mongo/collection/collection_utils.js @@ -88,12 +88,17 @@ export function normalizeOptions(options) { options.connection = options.manager; } + const cleanedOptions = Object.fromEntries( + Object.entries(options || {}).filter(([_, v]) => v !== undefined), + ); + + // 2) Spread defaults first, then only the defined overrides return { connection: undefined, idGeneration: 'STRING', transform: null, _driver: undefined, _preventAutopublish: false, - ...options, + ...cleanedOptions, }; } diff --git a/packages/mongo/collection/watch_change_stream.js b/packages/mongo/collection/watch_change_stream.js deleted file mode 100644 index a4e8ae7b95..0000000000 --- a/packages/mongo/collection/watch_change_stream.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @summary Watches the MongoDB collection using Change Streams. - * @locus Server - * @memberof Mongo.Collection - * @instance - * @param {Array} [pipeline] Optional aggregation pipeline to filter Change Stream events. - * @param {Object} [options] Optional settings for the Change Stream. - * @returns {ChangeStream} The MongoDB ChangeStream instance. - * @throws {Error} If called on a client/minimongo collection. - * - * @example - * const changeStream = MyCollection.watchChangeStream([ - * { $match: { 'operationType': 'insert' } } - * ]); - * changeStream.on('change', (change) => { - * console.log('Change detected:', change); - * }); - */ - -export function watchChangeStream(pipeline = [], options = {}) { - // Only available on server - if (typeof Package === 'undefined' || !this.rawCollection) { - throw new Error('watchChangeStream is only available on server collections'); - } - const raw = this.rawCollection(); - if (!raw.watch) { - throw new Error('Underlying collection does not support watch (Change Streams)'); - } - console.log('[watchChangeStream] Chamando raw.watch() com pipeline:', JSON.stringify(pipeline, null, 2), 'e options:', JSON.stringify(options, null, 2)); - return raw.watch(pipeline, options); -} diff --git a/packages/mongo/mongo_connection.js b/packages/mongo/mongo_connection.js index 114b8de9aa..b093bcfa00 100644 --- a/packages/mongo/mongo_connection.js +++ b/packages/mongo/mongo_connection.js @@ -1,5 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { CLIENT_ONLY_METHODS, getAsyncMethodName } from 'meteor/minimongo/constants'; +import { MiniMongoQueryError } from 'meteor/minimongo/common'; import path from 'path'; import { AsynchronousCursor } from './asynchronous_cursor'; import { Cursor } from './cursor'; @@ -886,6 +887,9 @@ Object.assign(MongoConnection.prototype, { } catch (e) { // XXX make all compilation errors MinimongoError or something // so that this doesn't ignore unrelated exceptions + if (e instanceof MiniMongoQueryError) { + throw e; + } return false; } }, diff --git a/packages/mongo/package.js b/packages/mongo/package.js index d91ad2f78b..0360964b5a 100644 --- a/packages/mongo/package.js +++ b/packages/mongo/package.js @@ -9,7 +9,7 @@ Package.describe({ summary: "Adaptor for using MongoDB and Minimongo over DDP", - version: "2.1.2", + version: "2.1.3", }); Npm.depends({ diff --git a/packages/mongo/tests/collection_tests.js b/packages/mongo/tests/collection_tests.js index a0e9e7fecf..e8841c5892 100644 --- a/packages/mongo/tests/collection_tests.js +++ b/packages/mongo/tests/collection_tests.js @@ -485,3 +485,58 @@ Meteor.isServer && Tinytest.addAsync('collection - simple add', async function(t test.equal((await collection.findOneAsync(id)).a, 2); await collection.removeAsync({}); }); + +Tinytest.addAsync('collection - default idGeneration when not provided', async function(test) { + if (!Meteor.isServer) { + return; + } + // Create a collection without specifying idGeneration option + var collectionName = 'defaultIdGeneration' + test.id; + var collection = new Mongo.Collection(collectionName, { idGeneration: undefined }); + + // Insert a document + var id = await collection.insertAsync({a: 1}); + + // Verify that the _id is a string + test.isTrue(typeof id === 'string', 'Document _id should be a string when no idGeneration option is provided'); + test.isFalse(id instanceof Mongo.ObjectID, 'Document _id should not be a Mongo.ObjectID when no idGeneration option is provided'); + + // Clean up + await collection.removeAsync({}); +}); + +Tinytest.addAsync('collection - compare default idGeneration with explicit idGeneration', async function(test) { + if (!Meteor.isServer) { + return; + } + // Create a collection without specifying idGeneration option + var defaultCollectionName = 'defaultIdGeneration2' + test.id; + var defaultCollection = new Mongo.Collection(defaultCollectionName, { idGeneration: undefined }); + + // Create a collection with explicit STRING idGeneration + var stringCollectionName = 'stringIdGeneration' + test.id; + var stringCollection = new Mongo.Collection(stringCollectionName, { idGeneration: 'STRING' }); + + // Create a collection with MONGO idGeneration + var mongoCollectionName = 'mongoIdGeneration' + test.id; + var mongoCollection = new Mongo.Collection(mongoCollectionName, { idGeneration: 'MONGO' }); + + // Insert documents + var defaultId = await defaultCollection.insertAsync({a: 1}); + var stringId = await stringCollection.insertAsync({a: 1}); + var mongoId = await mongoCollection.insertAsync({a: 1}); + + // Verify default behaves like STRING + test.isTrue(typeof defaultId === 'string', 'Default idGeneration should produce string IDs'); + test.isTrue(typeof stringId === 'string', 'STRING idGeneration should produce string IDs'); + test.isFalse(defaultId instanceof Mongo.ObjectID, 'Default idGeneration should not produce Mongo.ObjectID'); + test.isFalse(stringId instanceof Mongo.ObjectID, 'STRING idGeneration should not produce Mongo.ObjectID'); + + // Verify MONGO produces ObjectIDs + test.isTrue(mongoId instanceof Mongo.ObjectID, 'MONGO idGeneration should produce Mongo.ObjectID'); + + // Clean up + await defaultCollection.removeAsync({}); + await stringCollection.removeAsync({}); + await mongoCollection.removeAsync({}); +}); diff --git a/packages/mongo/tests/mongo_livedata_tests.js b/packages/mongo/tests/mongo_livedata_tests.js index c17202dd21..0578665f80 100644 --- a/packages/mongo/tests/mongo_livedata_tests.js +++ b/packages/mongo/tests/mongo_livedata_tests.js @@ -4298,9 +4298,10 @@ Tinytest.addAsync( await Collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); await Collection.updateAsync({ _id: 'b' }, { $set: { num: 2 } }); + if(Meteor.isClient) Meteor._sleepForMs(100); // wait for async operations to complete items = await Collection.find().fetchAsync(); itemIds = items.map(_item => _item.num); - + test.equal(itemIds, [1, 2]); await Collection.removeAsync({ _id: 'a' }); diff --git a/packages/mongo/tests/oplog_tests.js b/packages/mongo/tests/oplog_tests.js index eb6f5eb3df..2ffb0c32eb 100644 --- a/packages/mongo/tests/oplog_tests.js +++ b/packages/mongo/tests/oplog_tests.js @@ -1,3 +1,5 @@ +import { MiniMongoQueryError } from 'meteor/minimongo/common'; + var randomId = Random.id(); var OplogCollection = new Mongo.Collection("oplog-" + randomId); @@ -9,11 +11,16 @@ Tinytest.addAsync('mongo-livedata - oplog - cursorSupported', async function( var supported = async function(expected, selector, options) { var cursor = OplogCollection.find(selector, options); - var handle = await cursor.observeChanges({ added: function() {} }); - // If there's no oplog at all, we shouldn't ever use it. - if (!oplogEnabled) expected = false; - test.equal(!!handle._multiplexer._observeDriver._usesOplog, expected); - handle.stop(); + try { + var handle = await cursor.observeChanges({ added: function() {} }); + // If there's no oplog at all, we shouldn't ever use it. + if (!oplogEnabled) expected = false; + test.equal(!!handle._multiplexer._observeDriver._usesOplog, !!expected); + handle.stop(); + } catch(e){ + if (e instanceof MiniMongoQueryError) return test.isFalse(expected); + else test.fail(e.message); + } }; await supported(true, 'asdf'); diff --git a/packages/non-core/blaze b/packages/non-core/blaze index 0856ca8bf7..92a7d9ca78 160000 --- a/packages/non-core/blaze +++ b/packages/non-core/blaze @@ -1 +1 @@ -Subproject commit 0856ca8bf7730fbe1944142642a0c5be82fb9999 +Subproject commit 92a7d9ca7810655fb066274c54537d298fc1bca1 diff --git a/packages/npm-mongo-legacy/README.md b/packages/npm-mongo-legacy/README.md new file mode 100644 index 0000000000..39675814ec --- /dev/null +++ b/packages/npm-mongo-legacy/README.md @@ -0,0 +1,4 @@ +# npm-mongo-legacy +[Source code of released version](https://github.com/meteor/meteor/tree/devel/packages/npm-mongo-legacy) +*** + diff --git a/packages/npm-mongo-legacy/index.d.ts b/packages/npm-mongo-legacy/index.d.ts new file mode 100644 index 0000000000..d7ab3d7558 --- /dev/null +++ b/packages/npm-mongo-legacy/index.d.ts @@ -0,0 +1,3 @@ +import * as NpmModuleMongodb from 'mongodb'; +declare const NpmModuleMongodbVersion: string; +export { NpmModuleMongodb, NpmModuleMongodbVersion }; diff --git a/packages/npm-mongo-legacy/package.js b/packages/npm-mongo-legacy/package.js new file mode 100644 index 0000000000..50bf8dd77d --- /dev/null +++ b/packages/npm-mongo-legacy/package.js @@ -0,0 +1,18 @@ +// This has been moved out of the `mongo` package so it can be used by the tool +// via isopacket, without having to also load ddp-server. + +Package.describe({ + summary: "Wrapper around the mongo npm package (legacy)", + version: "6.9.0", + documentation: null, +}); + +Npm.depends({ + mongodb: "6.9.0", +}); + +Package.onUse(function (api) { + api.addFiles("wrapper.js", "server"); + api.export(["NpmModuleMongodb", "NpmModuleMongodbVersion"], "server"); + api.addAssets("index.d.ts", "server"); +}); diff --git a/packages/npm-mongo-legacy/wrapper.js b/packages/npm-mongo-legacy/wrapper.js new file mode 100644 index 0000000000..e341493895 --- /dev/null +++ b/packages/npm-mongo-legacy/wrapper.js @@ -0,0 +1,11 @@ +const oldNoDeprecationValue = process.noDeprecation; +try { + // Silence deprecation warnings introduced in a patch update to mongodb: + // https://github.com/meteor/meteor/pull/9942#discussion_r218564879 + process.noDeprecation = true; + NpmModuleMongodb = Npm.require('mongodb'); +} finally { + process.noDeprecation = oldNoDeprecationValue; +} + +NpmModuleMongodbVersion = Npm.require('mongodb/package.json').version; diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index 8b45db0032..be29b54a9a 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -3,12 +3,12 @@ Package.describe({ summary: "Wrapper around the mongo npm package", - version: "6.10.2", + version: "6.16.0", documentation: null, }); Npm.depends({ - mongodb: "6.9.0" + mongodb: "6.16.0" }); Package.onUse(function (api) { diff --git a/packages/npm-mongo/wrapper.js b/packages/npm-mongo/wrapper.js index e341493895..fd01b4fd0d 100644 --- a/packages/npm-mongo/wrapper.js +++ b/packages/npm-mongo/wrapper.js @@ -1,11 +1,49 @@ +const { MongoClient, MongoCompatibilityError } = Npm.require('mongodb'); + +function connect(client) { + return client.connect() + .catch(error => { + if (error.cause instanceof MongoCompatibilityError && error.message.includes('maximum wire version')) { + console.warn(`[DEPRECATION] Legacy MongoDB version detected, using mongo-legacy package: ${error.message} + Warning: MongoDB versions <= 3.6 are deprecated. Some Meteor features may not work properly with this version. + It is recommended to use MongoDB >= 4.`); + if (!Package['npm-mongo-legacy']) { + throw new Error('Please, install npm-mongo-legacy package to use this version of MongoDB running "meteor add npm-mongo-legacy", then move the listed package inside .meteor/packages to the top.'); + } + return false + } + }) +} + +if (process.env.MONGO_URL && (/^mongodb(\+srv)?:\/\//.test(process.env.MONGO_URL))) { + try { + connect(new MongoClient(process.env.MONGO_URL, { + tls: true, + tlsAllowInvalidCertificates: true, + })).then(client => { + if (client) client.close(); + }); + } catch (e) { + console.warn('Invalid MongoDB connection string in MONGO_URL:', process.env.MONGO_URL); + } +} + +const useLegacyMongo = !!Package['npm-mongo-legacy'] const oldNoDeprecationValue = process.noDeprecation; + +useLegacyMongo && console.log('WARN: npm-mongo-legacy package detected, using package for mongo <= 3.6'); + try { // Silence deprecation warnings introduced in a patch update to mongodb: // https://github.com/meteor/meteor/pull/9942#discussion_r218564879 process.noDeprecation = true; - NpmModuleMongodb = Npm.require('mongodb'); + NpmModuleMongodb = useLegacyMongo + ? Package['npm-mongo-legacy'].NpmModuleMongodb + : Npm.require('mongodb'); } finally { process.noDeprecation = oldNoDeprecationValue; } -NpmModuleMongodbVersion = Npm.require('mongodb/package.json').version; +NpmModuleMongodbVersion = useLegacyMongo + ? Package['npm-mongo-legacy'].NpmModuleMongodbVersion + : Npm.require('mongodb/package.json').version; diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index cbb25a00bb..6f23b6e939 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '3.1.0', + version: '3.1.1', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); @@ -12,7 +12,7 @@ Package.registerBuildPlugin({ 'ecmascript' ], npmDependencies: { - '@meteorjs/swc-core': '1.1.3', + '@meteorjs/swc-core': '1.12.14', 'acorn': '8.10.0', "@babel/runtime": "7.18.9", '@babel/parser': '7.22.7', diff --git a/packages/standard-minifier-js/plugin/minify-js.js b/packages/standard-minifier-js/plugin/minify-js.js index e3fb61182d..0fe5ca613f 100644 --- a/packages/standard-minifier-js/plugin/minify-js.js +++ b/packages/standard-minifier-js/plugin/minify-js.js @@ -1,17 +1,4 @@ import { extractModuleSizesTree } from "./stats.js"; -import fs from 'fs'; - -export function getConfig() { - try{ - const meteorAppDir = process.cwd(); - const packageJson = fs.readFileSync(`${meteorAppDir}/package.json`, 'utf8'); - const meteorConfig = JSON.parse(packageJson).meteor; - return meteorConfig; - } catch (error) { - console.log(error); - return {}; - } -}; const statsEnabled = process.env.DISABLE_CLIENT_STATS !== 'true' @@ -26,9 +13,7 @@ const Meteor = typeof global.Meteor !== 'undefined' ? global.Meteor : { // Profile for test and production environments let Profile; -if (typeof global.Profile !== 'undefined') { - Profile = global.Profile; -} else if (typeof Plugin !== 'undefined' && Plugin.Profile) { +if (typeof Plugin !== 'undefined' && Plugin.Profile) { Profile = Plugin.Profile; } else { Profile = function (label, func) { @@ -41,6 +26,10 @@ if (typeof global.Profile !== 'undefined') { } } +function getMeteorConfig() { + return Plugin?.getMeteorConfig() || {}; +} + let swc; // Register the minifier only when Plugin is available (not in tests) @@ -54,11 +43,6 @@ if (typeof Plugin !== 'undefined') { } export class MeteorMinifier { - - constructor() { - this.config = getConfig(); - } - _minifyWithSWC(file) { return Profile('_minifyWithSWC', () => { swc = swc || require('@meteorjs/swc-core'); @@ -120,9 +104,14 @@ export class MeteorMinifier { minifyOneFile(file) { return Profile('minifyOneFile', () => { - const modern = this.config && (this.config.modern === true || (this.config.modern && this.config.modern.minifier === true)); + const meteorConfig = getMeteorConfig(); + const modern = + meteorConfig && + (meteorConfig?.modern === true || + (meteorConfig?.modern && + meteorConfig?.modern?.minifier === true)); // check if config is an empty object - if(this.config && Object.keys(this.config).length === 0 || !modern) { + if(meteorConfig && Object.keys(meteorConfig).length === 0 || !modern) { Meteor._debug(`Minifying using Terser | file: ${file.getPathInBundle()}`); return this._minifyWithTerser(file); } diff --git a/packages/tinytest/package.js b/packages/tinytest/package.js index e869b316ea..db464f3bf2 100644 --- a/packages/tinytest/package.js +++ b/packages/tinytest/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Tiny testing framework", - version: '1.3.1', + version: '1.3.2', }); Npm.depends({ diff --git a/packages/tinytest/tinytest.js b/packages/tinytest/tinytest.js index afa1391207..b66097aafb 100644 --- a/packages/tinytest/tinytest.js +++ b/packages/tinytest/tinytest.js @@ -74,7 +74,7 @@ export class TestCaseResults { var frame = stack[i]; // Heuristic: use the OUTERMOST line which is in a :tests.js // file (this is less likely to be a test helper function). - const fileName = frame.getFileName(); + const fileName = frame?.getFileName ? frame.getFileName() : null; if (fileName && fileName.match(/:tests\.js/)) { doc.filename = fileName; doc.line = frame.getLineNumber(); diff --git a/packages/typescript/package.js b/packages/typescript/package.js index b84968210d..2f4d514837 100644 --- a/packages/typescript/package.js +++ b/packages/typescript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'typescript', - version: '5.6.4', + version: '5.6.5', summary: 'Compiler plugin that compiles TypeScript and ECMAScript in .ts and .tsx files', documentation: 'README.md', diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 04dd922851..2432e8857d 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "3.3-rc.0", + "version": "3.3.1-rc.2", "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 75cf5a5520..3b26432a73 100644 --- a/scripts/admin/meteor-release-official.json +++ b/scripts/admin/meteor-release-official.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "3.3", + "version": "3.3.1", "recommended": false, "official": true, "description": "The Official Meteor Distribution" diff --git a/scripts/build-dev-bundle-common.sh b/scripts/build-dev-bundle-common.sh index a00f7e4f2b..6f06d676a6 100644 --- a/scripts/build-dev-bundle-common.sh +++ b/scripts/build-dev-bundle-common.sh @@ -5,10 +5,10 @@ set -u UNAME=$(uname) ARCH=$(uname -m) -NODE_VERSION=22.16.0 +NODE_VERSION=22.18.0 MONGO_VERSION_64BIT=7.0.16 MONGO_VERSION_32BIT=3.2.22 -NPM_VERSION=10.9.2 +NPM_VERSION=10.9.3 if [ "$UNAME" == "Linux" ] ; then diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 6996b8f674..b8043936a5 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -10,7 +10,7 @@ var packageJson = { dependencies: { // Explicit dependency because we are replacing it with a bundled version // and we want to make sure there are no dependencies on a higher version - npm: "10.9.2", + npm: "10.9.3", "node-gyp": "10.2.0", "@mapbox/node-pre-gyp": "1.0.11", typescript: "5.6.3", diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 240dbdcd3a..d81c03ffb5 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -1,3 +1,5 @@ +import { getMeteorConfig } from "../tool-env/meteor-config"; + var main = require('./main.js'); var _ = require('underscore'); var files = require('../fs/files'); @@ -261,51 +263,6 @@ export function parseRunTargets(targets) { }); }; -const DEFAULT_MODERN = { - transpiler: true, - webArchOnly: true, - watcher: true, -}; - -const normalizeModern = (r = false) => Object.fromEntries( - Object.entries(DEFAULT_MODERN).map(([k, def]) => [ - k, - r === true - ? def - : r === false || r?.[k] === false - ? false - : typeof r?.[k] === 'object' - ? { ...r[k] } - : def, - ]), -); - - -let modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); -let meteorConfig; - -function getMeteorConfig(appDir) { - if (meteorConfig) return meteorConfig; - const packageJsonPath = files.pathJoin(appDir, 'package.json'); - if (!files.exists(packageJsonPath)) { - return false; - } - const packageJsonFile = files.readFile(packageJsonPath, 'utf8'); - const packageJson = JSON.parse(packageJsonFile); - meteorConfig = packageJson?.meteor; - return meteorConfig; -} - -function isModernArchsOnlyEnabled(appDir) { - const meteorConfig = getMeteorConfig(appDir); - return normalizeModern(modernForced || meteorConfig?.modern).webArchOnly !== false; -} - -export function isModernWatcherEnabled(appDir) { - const meteorConfig = getMeteorConfig(appDir); - return normalizeModern(modernForced || meteorConfig?.modern).watcher !== false; -} - function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { const platforms = (options.platforms || []); const isBuildMode = platforms?.length > 0; @@ -325,7 +282,7 @@ function filterWebArchs(webArchs, excludeArchsOption, appDir, options) { if (!isCordovaDev) { const excludeArchsOptions = excludeArchsOption ? excludeArchsOption.trim().split(/\s*,\s*/) : []; const hasExcludeArchsOptions = (excludeArchsOptions?.length || 0) > 0; - const hasModernArchsOnlyEnabled = appDir && isModernArchsOnlyEnabled(appDir); + const hasModernArchsOnlyEnabled = appDir && getMeteorConfig()?.modern?.webArchOnly !== false; if (hasExcludeArchsOptions && hasModernArchsOnlyEnabled) { console.warn('modern.webArchOnly and --exclude-archs are both active. If both are set, --exclude-archs takes priority.'); } @@ -1246,71 +1203,85 @@ main.registerCommand({ toIgnore.push(/(\.html|\.js|\.css)/); } - try { - // Prototype option should use local skeleton. - // Maybe we should use a different skeleton for prototype - if (options.prototype) throw new Error("Using prototype option"); - // if using the release option we should use the default skeleton - // using it as it was before 2.x - if (release.explicit) throw new Error("Using release option"); + const copyFromLocalSkeleton = async () => { + await files.cp_r( + skeletonPath, + appPath, + { + transformFilename: function (f) { + return transform(f); + }, + transformContents: function (contents, f) { + // check if this app is just for prototyping if it is then we need to add autopublish and insecure in the packages file + if (/packages/.test(f)) { + const prototypePackages = () => + "autopublish # Publish all data to the clients (for prototyping)\n" + + "insecure # Allow all DB writes from clients (for prototyping)"; - await setupExampleByURL(`https://github.com/meteor/skel-${skeleton}`); - } catch (e) { + // XXX: if there is the need to add more options maybe we should have a better abstraction for this if-else + if (options.prototype) { + return Buffer.from( + contents.toString().replace(/~prototype~/g, prototypePackages()) + ); + } else { + return Buffer.from(contents.toString().replace(/~prototype~/g, "")); + } + } + if (/(\.html|\.[jt]sx?|\.css)/.test(f)) { + return Buffer.from(transform(contents.toString())); + } else { + return contents; + } + }, + ignore: toIgnore, + preserveSymlinks: true, + } + ); + }; - if ( - e.message !== "Using prototype option" && - e.message !== "Using release option" - ) { - // something has happened while creating the app using git clone - Console.error( - `Something has happened while creating your app using git clone. + // Check if the local skeleton path exists + const skeletonPath = files.pathJoin( + __dirnameConverted, + "..", + "static-assets", + `skel-${skeleton}` + ); + + const useLocalSkeleton = files.exists(skeletonPath) || + options.prototype || + release.explicit; + if (useLocalSkeleton) { + // Use local skeleton + await copyFromLocalSkeleton(); + } else { + try { + // Prototype option should use local skeleton. + // Maybe we should use a different skeleton for prototype + if (options.prototype) throw new Error("Using prototype option"); + // if using the release option we should use the default skeleton + // using it as it was before 2.x + if (release.explicit) throw new Error("Using release option"); + + // If local skeleton doesn't exist, use setupExampleByURL + await setupExampleByURL(`https://github.com/meteor/skel-${skeleton}`); + } catch (e) { + if ( + e.message !== "Using prototype option" && + e.message !== "Using release option" + ) { + // something has happened while creating the app using git clone + Console.error( + `Something has happened while creating your app using git clone. Will use cached version of skeletons. Error message: `, - e.message - ); + e.message + ); + } + // For prototype or release options, use local skeleton + await copyFromLocalSkeleton(); } - - // TODO: decide if this should stay here or not. - await files.cp_r( - files.pathJoin( - __dirnameConverted, - "..", - "static-assets", - `skel-${skeleton}` - ), - appPath, - { - transformFilename: function (f) { - return transform(f); - }, - transformContents: function (contents, f) { - // check if this app is just for prototyping if it is then we need to add autopublish and insecure in the packages file - if (/packages/.test(f)) { - const prototypePackages = () => - "autopublish # Publish all data to the clients (for prototyping)\n" + - "insecure # Allow all DB writes from clients (for prototyping)"; - - // XXX: if there is the need to add more options maybe we should have a better abstraction for this if-else - if (options.prototype) { - return Buffer.from( - contents.toString().replace(/~prototype~/g, prototypePackages()) - ); - } else { - return Buffer.from(contents.toString().replace(/~prototype~/g, "")); - } - } - if (/(\.html|\.[jt]sx?|\.css)/.test(f)) { - return Buffer.from(transform(contents.toString())); - } else { - return contents; - } - }, - ignore: toIgnore, - preserveSymlinks: true, - } - ); - await setupMessages(); } + await setupMessages(); Console.info(""); }); @@ -3436,20 +3407,58 @@ const setupBenchmarkSuite = async (profilingPath) => { if (await files.exists(profilingPath)) { return; } + + // Check git availability and version const [okGitVersion, errGitVersion] = await bash`git --version`; if (errGitVersion) throw new Error("git is not installed"); - const parsedGitVersion = semver.coerce(okGitVersion.match(/\d+\.\d+\.\d+/)[0] || '')?.version; - const checkInvalidGitVersion = parsedGitVersion == null || semver.lt(parsedGitVersion, '2.25.0'); - if (checkInvalidGitVersion) { + const parsedGitVersion = semver.coerce(okGitVersion.match(/\d+\.\d+\.\d+/)?.[0] || '')?.version; + if (!parsedGitVersion || semver.lt(parsedGitVersion, '2.25.0')) { throw new Error("git version is too old. Please upgrade to at least 2.25"); } - // Set GIT_TERMINAL_PROMPT=0 to disable prompting + // Check tar availability + const [okTar, errTar] = await bash`tar --version`; + const hasTar = !errTar; + + // Disable interactive git prompts process.env.GIT_TERMINAL_PROMPT = 0; const repoUrl = "https://github.com/meteor/performance"; const branch = "v3.3.0"; + + let tarFailed = false; + + // If tar is available, prefer tar-based extraction + if (hasTar) { + const tempDir = "/tmp/meteor-performance-benchmark-suite"; + const tarCommand = [ + `rm -rf ${tempDir}`, + `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${tempDir}`, + `cd ${tempDir}`, + `git sparse-checkout init --cone`, + `git sparse-checkout set scripts`, + `git checkout ${branch}`, + `mkdir -p ${profilingPath}/scripts`, + `tar -czf /tmp/scripts.tar.gz -C ./scripts .`, + `tar -xzf /tmp/scripts.tar.gz -C ${profilingPath}/scripts`, + `rm -rf ${tempDir}`, + `rm -f /tmp/scripts.tar.gz` + ].join(" && "); + + const [okTarClone, errTarClone] = await bash`${tarCommand}`; + if (!errTarClone) { + Console.info("Meteor profiling suite cloned to: " + Console.path(profilingPath)); + return; + } else { + Console.warn("Tar-based cloning failed. Will attempt standard git clone..."); + tarFailed = errTarClone; + } + } else { + Console.warn("Tar not available. Will use standard git clone..."); + } + + // Fallback to plain git clone const gitCommand = [ `mkdir -p ${profilingPath}`, `git clone --no-checkout --depth 1 --filter=tree:0 --sparse --progress --branch ${branch} --single-branch ${repoUrl} ${profilingPath}`, @@ -3457,18 +3466,22 @@ const setupBenchmarkSuite = async (profilingPath) => { `git sparse-checkout init --cone`, `git sparse-checkout set scripts`, `git checkout ${branch}`, - `find ${profilingPath} -maxdepth 1 -type f -delete`, + `find ${profilingPath} -maxdepth 1 -type f -delete` ].join(" && "); - const [, errClone] = await bash`${gitCommand}`; - const errorMessage = errClone && typeof errClone === "string" ? errClone : errClone?.message; - if (errorMessage && errorMessage.includes("Cloning into")) { - throw new Error("error cloning benchmark"); + + const [okClone, errClone] = await bash`${gitCommand}`; + if (errClone) { + let combinedMessage = "Git clone failed."; + if (tarFailed) { + combinedMessage = `Tar-based cloning also failed:\n${tarFailed}\n\nGit fallback failed:\n${errClone}`; + } + throw new Error(combinedMessage); } - // remove .git folder from the example + + // Remove .git folder if present await files.rm_recursive_async(files.pathJoin(profilingPath, ".git")); - Console.info( - "Meteor profiling suite cloned to: " + Console.path(profilingPath), - ); + + Console.info("Meteor profiling suite cloned to: " + Console.path(profilingPath)); }; async function doBenchmarkCommand(options) { diff --git a/tools/cli/help.txt b/tools/cli/help.txt index d0c16928be..7f9e083861 100644 --- a/tools/cli/help.txt +++ b/tools/cli/help.txt @@ -492,7 +492,7 @@ Note that you must have mongosh installed to use this option. Options: --url, -U return a Mongo database URL --verbose, -v to show the errors that have occurred while connecting to the - database + database Currently, this feature can only be used when developing locally. The opened Mongo shell connects to the current project's local @@ -816,7 +816,16 @@ Usage: meteor admin [args] Rarely used commands for administering official Meteor services. Commands: -{{commands}} + + make-bootstrap-tarballs + recommend-release + change-homepage + set-unmigrated + set-banners + list-organizations + members + set-latest-readme + get-machine See 'meteor help admin ' for details on an admin command. @@ -875,12 +884,12 @@ for replacing the names, we offer $$PascalName$$, $$camelName$$, $$name$$. This is a MeteorJS project command. Options: - --help Show help. - --path The path to the folder where the files will be generated. Default is the current folder. - --templatePath Path to the template file check https://docs.meteor.com/commandline.html#meteorgenerate-templating for more info. - --replaceFn Replace function to replace the names in the template. Check https://docs.meteor.com/commandline.html#meteorgenerate-templating for more info. - --methods Generate methods. - --publications Generate publications. + --help Show help. + --path The path to the folder where the files will be generated. Default is the current folder. + --templatePath Path to the template file check https://docs.meteor.com/commandline.html#meteorgenerate-templating for more info. + --replaceFn Replace function to replace the names in the template. Check https://docs.meteor.com/commandline.html#meteorgenerate-templating for more info. + --methods Generate methods. + --publications Generate publications. >>> publish-release diff --git a/tools/cli/main.js b/tools/cli/main.js index 6888765ad9..b73e2b7868 100644 --- a/tools/cli/main.js +++ b/tools/cli/main.js @@ -287,12 +287,16 @@ main.captureAndExit = async function (header, title, f) { // NB: files required up to this point may not define commands -const { isModernWatcherEnabled } = require('./commands.js'); +const { initMeteorConfig } = require('../tool-env/meteor-config'); +require('./commands.js'); require('./commands-packages.js'); require('./commands-packages-query.js'); require('./commands-cordova.js'); require('./commands-aliases.js'); +// Initialize meteorConfig globally +initMeteorConfig(); + /////////////////////////////////////////////////////////////////////////////// // Record all the top-level commands as JSON /////////////////////////////////////////////////////////////////////////////// @@ -865,7 +869,9 @@ makeGlobalAsyncLocalStorage().run({}, async function () { var appDir = files.findAppDir(); if (appDir) { appDir = files.pathResolve(appDir); - global.modernWatcher = isModernWatcherEnabled(appDir); + + // Renitialize meteorConfig globally when having appDir context + initMeteorConfig(appDir); } await require('../tool-env/isopackets.js').ensureIsopacketsLoadable(); diff --git a/tools/cordova/index.js b/tools/cordova/index.js index 1230faba92..e1acabacb6 100644 --- a/tools/cordova/index.js +++ b/tools/cordova/index.js @@ -13,11 +13,11 @@ export const CORDOVA_ARCH = "web.cordova"; export const CORDOVA_PLATFORMS = ['ios', 'android']; -const CORDOVA_ANDROID_VERSION = "13.0.0"; +const CORDOVA_ANDROID_VERSION = "14.0.1"; export const CORDOVA_DEV_BUNDLE_VERSIONS = { - 'cordova-lib': '12.0.1', - 'cordova-common': '5.0.0', + 'cordova-lib': '12.0.2', + 'cordova-common': '5.0.1', 'cordova-create': '2.0.0', 'cordova-registry-mapper': '1.1.15', 'cordova-android': CORDOVA_ANDROID_VERSION, diff --git a/tools/fs/safe-watcher.ts b/tools/fs/safe-watcher.ts index 492bd03028..07fe605fb7 100644 --- a/tools/fs/safe-watcher.ts +++ b/tools/fs/safe-watcher.ts @@ -4,6 +4,7 @@ import { watch as watchLegacy, addWatchRoot as addWatchRootLegacy, closeAllWatch import { Profile } from "../tool-env/profile"; import { statOrNull, lstat, toPosixPath, convertToOSPath, pathRelative, watchFile, unwatchFile, pathResolve, pathDirname } from "./files"; +import { getMeteorConfig } from "../tool-env/meteor-config"; // Register process exit handlers to ensure subscriptions are properly cleaned up const registerExitHandlers = () => { @@ -380,7 +381,7 @@ function startNewEntry(absPath: string): Entry { */ export function watch (absPath: string, callback: ChangeCallback): SafeWatcher { // @ts-ignore - if (!global.modernWatcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return watchLegacy(absPath, callback); } @@ -444,7 +445,7 @@ const watchModern = */ export function addWatchRoot(absPath: string) { // @ts-ignore - if (!global.modernWatcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return addWatchRootLegacy(absPath); } @@ -477,7 +478,7 @@ async function safeUnsubscribeSub(root: string) { export async function closeAllWatchers() { // @ts-ignore - if (!global.modernWatcher) { + if (!getMeteorConfig()?.modern?.watcher) { // @ts-ignore return closeAllWatchersLegacy(); } diff --git a/tools/isobuild/import-scanner.ts b/tools/isobuild/import-scanner.ts index e05900b2f2..7aff1ee0e6 100644 --- a/tools/isobuild/import-scanner.ts +++ b/tools/isobuild/import-scanner.ts @@ -46,6 +46,7 @@ import { import { wrap } from "optimism"; const { compile: reifyCompile } = require("@meteorjs/reify/lib/compiler"); const { parse: reifyAcornParse } = require("@meteorjs/reify/lib/parsers/acorn"); +const { parse: reifyBabelParse } = require("@meteorjs/reify/lib/parsers/babel"); import Resolver, { Resolution } from "./resolver"; import LRUCache from 'lru-cache'; @@ -87,14 +88,32 @@ const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function ( } const isLegacy = isLegacyArch(bundleArch); - let result = reifyCompile(stripHashBang(source), { - parse: reifyAcornParse, + const reifyOptions = { generateLetDeclarations: !isLegacy, avoidModernSyntax: isLegacy, enforceStrictMode: false, dynamicImport: true, ast: false, - }).code; + }; + + let result; + try { + // First attempt: use Acorn + result = reifyCompile(stripHashBang(source), { + ...reifyOptions, + parse: reifyAcornParse, + }).code; + } catch (acornError) { + // Fallback: use Babel parser + // acorn may throw SyntaxError due to the lack of support for + // some features, but babel should still be able to parse the file + // For example, acorn don’t support JSX, only with acorn-jsx, + // but it isn’t included in Reify. + result = reifyCompile(stripHashBang(source), { + ...reifyOptions, + parse: reifyBabelParse, + }).code; + } if (cacheFilePath) { Promise.resolve().then( diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 99549c5d25..aa397e0a80 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -1,3 +1,5 @@ +import { getMeteorConfig } from "../tool-env/meteor-config"; + var compiler = require('./compiler.js'); var archinfo = require('../utils/archinfo'); var _ = require('underscore'); @@ -514,6 +516,9 @@ Object.assign(Isopack.prototype, { var Plugin = { name: pluginName, + // Share the meteorConfig object as part of plugin API + getMeteorConfig: getMeteorConfig, + // 'extension' is a file extension without the separation dot // (eg 'js', 'coffee', 'coffee.md') // diff --git a/tools/project-context.js b/tools/project-context.js index c14dce5cfa..f114f3a38a 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1,3 +1,4 @@ +import { normalizeModernConfig, setMeteorConfig } from "./tool-env/meteor-config"; var assert = require("assert"); var _ = require('underscore'); @@ -492,6 +493,8 @@ Object.assign(ProjectContext.prototype, { self.meteorConfig = new MeteorConfig({ appDirectory: self.projectDir, }); + self.meteorConfig._ensureInitialized(); + if (buildmessage.jobHasMessages()) { return; } @@ -1217,7 +1220,16 @@ Object.assign(exports.ProjectConstraintsFile.prototype, { constraint: constraintToAdd, trailingSpaceAndComment: '' }; - self._constraintLines.push(lineRecord); + if (constraintToAdd.package === 'npm-mongo-legacy') { + const mongoIdx = self._constraintLines.findIndex(lr => lr.constraint && lr.constraint.package === 'mongo'); + if (mongoIdx > -1) { + self._constraintLines.splice(mongoIdx, 0, lineRecord); + } else { + self._constraintLines.push(lineRecord); + } + } else { + self._constraintLines.push(lineRecord); + } self._constraintMap[constraintToAdd.package] = lineRecord; self._modified = true; return; @@ -1811,6 +1823,13 @@ export class MeteorConfig { }, }), } : this._config; + const modernForced = JSON.parse(process.env.METEOR_MODERN || "false"); + // Reinitialize meteorConfig globally for project context + // Updates config when package.json changes trigger rebuilds + setMeteorConfig({ + ...(this._config || {}), + modern: normalizeModernConfig(modernForced || this._config?.modern || false), + }); return this._config; } @@ -1818,18 +1837,14 @@ export class MeteorConfig { // General utility for querying the "meteor" section of package.json. // TODO Implement an API for setting these values? get(...keys) { - let config = this._ensureInitialized(); - let filteredConfig = keys.length ? {} : config; - if (config) { - keys.every(key => { - if (config && _.has(config, key)) { - filteredConfig = config[key]; - return true; - } - return false; - }); - return filteredConfig; - } + const config = this._ensureInitialized(); + if (!config) return undefined; + + return keys.reduce((cur, key) => { + return (cur != null && _.has(cur, key)) + ? cur[key] + : undefined; + }, config); } getNodeModulesToRecompileByArch() { diff --git a/tools/static-assets/server/runtime.js b/tools/static-assets/server/runtime.js index 9a1c6b15ef..3c15a6f9d1 100644 --- a/tools/static-assets/server/runtime.js +++ b/tools/static-assets/server/runtime.js @@ -48,13 +48,15 @@ module.exports = function enable ({ cachePath, createLoader = true } = {}) { const reifyVersion = require("@meteorjs/reify/package.json").version; const reifyAcornParse = require("@meteorjs/reify/lib/parsers/acorn").parse; + const reifyBabelParse = require("@meteorjs/reify/lib/parsers/babel").parse; const reifyCompile = require("@meteorjs/reify/lib/compiler").compile; function compileContent (content) { let identical = true; + let result; try { - const result = reifyCompile(content, { + result = reifyCompile(content, { parse: reifyAcornParse, generateLetDeclarations: false, ast: false, @@ -63,9 +65,20 @@ module.exports = function enable ({ cachePath, createLoader = true } = {}) { identical = false; content = result.code; } - } finally { - return { content, identical }; + } catch (acornError) { + // Fallback: Babel + result = reifyCompile(content, { + parse: reifyBabelParse, + generateLetDeclarations: false, + ast: false, + }); + if (!result.identical) { + identical = false; + content = result.code; + } } + + return { content, identical }; } const _compile = Mp._compile; diff --git a/tools/static-assets/skel-apollo/package.json b/tools/static-assets/skel-apollo/package.json index 211e19310a..8af983a7cb 100644 --- a/tools/static-assets/skel-apollo/package.json +++ b/tools/static-assets/skel-apollo/package.json @@ -11,6 +11,7 @@ "@apollo/client": "^3.9.2", "@apollo/server": "^4.10.0", "@babel/runtime": "^7.23.9", + "@swc/helpers": "^0.5.17", "graphql": "^16.8.1", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", diff --git a/tools/static-assets/skel-blaze/package.json b/tools/static-assets/skel-blaze/package.json index 3845c0046d..e197964537 100644 --- a/tools/static-assets/skel-blaze/package.json +++ b/tools/static-assets/skel-blaze/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "jquery": "^3.7.1", "meteor-node-stubs": "^1.2.12" }, diff --git a/tools/static-assets/skel-chakra-ui/package.json b/tools/static-assets/skel-chakra-ui/package.json index fdcb9c2717..99b3e13d76 100644 --- a/tools/static-assets/skel-chakra-ui/package.json +++ b/tools/static-assets/skel-chakra-ui/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "@chakra-ui/icons": "^1.1.7", "@chakra-ui/react": "^1.8.8", "@emotion/react": "^11.9.3", diff --git a/tools/static-assets/skel-full/package.json b/tools/static-assets/skel-full/package.json index 953198e35f..1abdbdd683 100644 --- a/tools/static-assets/skel-full/package.json +++ b/tools/static-assets/skel-full/package.json @@ -7,10 +7,18 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "jquery": "^3.7.1", "meteor-node-stubs": "^1.2.12" }, "devDependencies": { "chai": "^4.2.0" + }, + "meteor": { + "mainModule": { + "client": "client/main.js", + "server": "server/main.js" + }, + "modern": true } } diff --git a/tools/static-assets/skel-minimal/package.json b/tools/static-assets/skel-minimal/package.json index 903c3e9bb7..74d5a9b271 100644 --- a/tools/static-assets/skel-minimal/package.json +++ b/tools/static-assets/skel-minimal/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12" }, "meteor": { diff --git a/tools/static-assets/skel-react/package.json b/tools/static-assets/skel-react/package.json index b49bf5903e..ee33ff775c 100644 --- a/tools/static-assets/skel-react/package.json +++ b/tools/static-assets/skel-react/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/tools/static-assets/skel-solid/client/entry-meteor.js b/tools/static-assets/skel-solid/client/entry-meteor.js index e69de29bb2..0ec3ddc121 100644 --- a/tools/static-assets/skel-solid/client/entry-meteor.js +++ b/tools/static-assets/skel-solid/client/entry-meteor.js @@ -0,0 +1,14 @@ +/** + * Entrypoint for the Meteor client + * + * Generally, this file can be left empty. Vite will add imports for + * lazy-loaded Meteor packages to this file to ensure they aren't omitted from + * the final production bundle. + * + * Use ./main.js as the primary entrypoint for your client code to take full + * advantage of Vite's plugin and build system. + * + * This can also be a good place to put code that you don't want Vite to + * process, for example, if you run into a compatibility issue or need to use + * nested imports which Vite doesn't support. + */ \ No newline at end of file diff --git a/tools/static-assets/skel-solid/client/main.js b/tools/static-assets/skel-solid/client/main.js new file mode 100644 index 0000000000..44bcc64d55 --- /dev/null +++ b/tools/static-assets/skel-solid/client/main.js @@ -0,0 +1 @@ +import '../imports/ui/main'; \ No newline at end of file diff --git a/tools/static-assets/skel-solid/client/main.jsx b/tools/static-assets/skel-solid/client/main.jsx deleted file mode 100644 index 97d382a9bd..0000000000 --- a/tools/static-assets/skel-solid/client/main.jsx +++ /dev/null @@ -1 +0,0 @@ -// main entry point is in imports/ui/main.jsx diff --git a/tools/static-assets/skel-solid/client/main.css b/tools/static-assets/skel-solid/imports/ui/main.css similarity index 100% rename from tools/static-assets/skel-solid/client/main.css rename to tools/static-assets/skel-solid/imports/ui/main.css diff --git a/tools/static-assets/skel-solid/imports/ui/main.jsx b/tools/static-assets/skel-solid/imports/ui/main.jsx index 99eb6c43d7..044f1aee69 100644 --- a/tools/static-assets/skel-solid/imports/ui/main.jsx +++ b/tools/static-assets/skel-solid/imports/ui/main.jsx @@ -2,6 +2,7 @@ import { render } from 'solid-js/web'; import { App } from './App'; import { Meteor } from "meteor/meteor"; +import './main.css'; Meteor.startup(() => { render(() => , document.getElementById('root')); diff --git a/tools/static-assets/skel-solid/package.json b/tools/static-assets/skel-solid/package.json index bb50ecbd9b..17401d9c1b 100644 --- a/tools/static-assets/skel-solid/package.json +++ b/tools/static-assets/skel-solid/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.9", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "picocolors": "^1.1.1", "solid-js": "^1.9.4" diff --git a/tools/static-assets/skel-solid/server/entry-meteor.js b/tools/static-assets/skel-solid/server/entry-meteor.js index e69de29bb2..8a066f8e94 100644 --- a/tools/static-assets/skel-solid/server/entry-meteor.js +++ b/tools/static-assets/skel-solid/server/entry-meteor.js @@ -0,0 +1,12 @@ +/** + * Entrypoint for the Meteor server + * Generally, this file can be left empty. Vite will add imports for your app's + * server bundle here during both development and production build. + * + * Use ./main.js as the primary entrypoint for your app to take full advantage + * of Vite's plugin and build system. + * + * This can also be a good place to put code that you don't want Vite to + * process, for example, if you run into a compatibility issue or need to use + * nested imports. + */ \ No newline at end of file diff --git a/tools/static-assets/skel-solid/vite.config.js b/tools/static-assets/skel-solid/vite.config.mjs similarity index 91% rename from tools/static-assets/skel-solid/vite.config.js rename to tools/static-assets/skel-solid/vite.config.mjs index 5752984348..e0215dbb10 100644 --- a/tools/static-assets/skel-solid/vite.config.js +++ b/tools/static-assets/skel-solid/vite.config.mjs @@ -8,7 +8,7 @@ export default defineConfig({ solidPlugin(), solidSvg({ defaultExport: 'component' }), meteor({ - clientEntry: 'imports/ui/main.jsx', + clientEntry: 'client/main.js', serverEntry: 'server/main.js', enableExperimentalFeatures: true, stubValidation: { diff --git a/tools/static-assets/skel-svelte/package.json b/tools/static-assets/skel-svelte/package.json index c1d703791d..0929124049 100644 --- a/tools/static-assets/skel-svelte/package.json +++ b/tools/static-assets/skel-svelte/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "svelte": "^3.59.2" }, diff --git a/tools/static-assets/skel-tailwind/package.json b/tools/static-assets/skel-tailwind/package.json index e4b556a821..73971202ba 100644 --- a/tools/static-assets/skel-tailwind/package.json +++ b/tools/static-assets/skel-tailwind/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "autoprefixer": "^10.4.4", "meteor-node-stubs": "^1.2.12", "postcss": "^8.4.12", diff --git a/tools/static-assets/skel-typescript/package.json b/tools/static-assets/skel-typescript/package.json index 90c078b082..77ff7934bf 100644 --- a/tools/static-assets/skel-typescript/package.json +++ b/tools/static-assets/skel-typescript/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@babel/runtime": "^7.23.5", + "@swc/helpers": "^0.5.17", "meteor-node-stubs": "^1.2.12", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/tools/static-assets/skel-vue/client/entry-meteor.js b/tools/static-assets/skel-vue/client/entry-meteor.js index e69de29bb2..0ec3ddc121 100644 --- a/tools/static-assets/skel-vue/client/entry-meteor.js +++ b/tools/static-assets/skel-vue/client/entry-meteor.js @@ -0,0 +1,14 @@ +/** + * Entrypoint for the Meteor client + * + * Generally, this file can be left empty. Vite will add imports for + * lazy-loaded Meteor packages to this file to ensure they aren't omitted from + * the final production bundle. + * + * Use ./main.js as the primary entrypoint for your client code to take full + * advantage of Vite's plugin and build system. + * + * This can also be a good place to put code that you don't want Vite to + * process, for example, if you run into a compatibility issue or need to use + * nested imports which Vite doesn't support. + */ \ No newline at end of file diff --git a/tools/static-assets/skel-vue/client/main.css b/tools/static-assets/skel-vue/client/main.css deleted file mode 100644 index b5c61c9567..0000000000 --- a/tools/static-assets/skel-vue/client/main.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/tools/static-assets/skel-vue/client/main.js b/tools/static-assets/skel-vue/client/main.js index 97d382a9bd..403d8a2d2a 100644 --- a/tools/static-assets/skel-vue/client/main.js +++ b/tools/static-assets/skel-vue/client/main.js @@ -1 +1 @@ -// main entry point is in imports/ui/main.jsx +import '../imports/ui/main' \ No newline at end of file diff --git a/tools/static-assets/skel-vue/imports/ui/App.vue b/tools/static-assets/skel-vue/imports/ui/App.vue index 7a775391cb..19a68a1ea1 100644 --- a/tools/static-assets/skel-vue/imports/ui/App.vue +++ b/tools/static-assets/skel-vue/imports/ui/App.vue @@ -1,5 +1,5 @@