Merge branch 'update-node-18' of https://github.com/matheusccastroo/meteor into pr/12663

This commit is contained in:
Gabriel Grubba
2023-08-01 18:55:55 -03:00
49 changed files with 1739 additions and 409 deletions

View File

@@ -48,7 +48,7 @@ Use the same code whether youre developing for web, iOS, Android, or desktop
How about trying a getting started tutorial in your favorite technology?
| [<img align="left" width="25" src="https://www.quantumversity.com/wp-content/uploads/2020/11/Adding-Authentication-to-React-with-Auth0-Login-and-Profile.png"> React](https://react-tutorial.meteor.com/) |
| [<img align="left" width="25" src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"> React](https://react-tutorial.meteor.com/) |
| - |
| [<img align="left" width="25" src="https://progsoft.net/images/blaze-css-icon-3e80acb3996047afd09f1150f53fcd78e98c1e1b.png"> Blaze](https://blaze-tutorial.meteor.com/) |
| [<img align="left" width="25" src="https://vuejs.org/images/logo.png"> Vue](https://vue-tutorial.meteor.com/) |

View File

@@ -1,6 +1,7 @@
title: Meteor API Docs
subtitle: API Docs
versions:
- '2.13'
- '2.12'
- '2.11'
- '2.10'

View File

@@ -0,0 +1,67 @@
## v2.13.0, 2023-07-26
### Highlights
* Handled implicit collection creation oplog message by [radekmie](https://github.com/radekmie) [PR](https://github.com/meteor/meteor/pull/12643).
* Fix upsert logs when using WARN_WHEN_USING_OLD_API flag by [Grubba27](https://github.com/Grubba27) [PR](https://github.com/meteor/meteor/pull/12640).
* Updating mongo types by [Grubba27](https://github.com/Grubba27) [PR](https://github.com/meteor/meteor/pull/12639).
* Fix solid skeleton by [fredmaiaarantes](https://github.com/fredmaiaarantes) [PR](https://github.com/meteor/meteor/pull/12637).
* Setting The Viewport meta tag on skeletons [fredmaiaarantes](https://github.com/fredmaiaarantes) [PR](https://github.com/meteor/meteor/pull/12636).
* Update mongo.d.ts with projection [StorytellerCZ](https://github.com/StorytellerCZ) [PR](https://github.com/meteor/meteor/pull/12635).
* Update guide code for GraphQL [StorytellerCZ](https://github.com/StorytellerCZ) [PR](https://github.com/meteor/meteor/pull/12619).
* Twitter Whitelist issue resolved [Atharshoyeb](https://github.com/Atharshoyeb) [PR](https://github.com/meteor/meteor/pull/12369).
* Node security patch (14.21.4) [PR](https://github.com/meteor/node-v14-esm/pull/1).
* Updated deprecated reference in mongo package by [StorytellerCZ](https://github.com/StorytellerCZ) [PR](https://github.com/meteor/meteor/pull/12653/files).
* Updated BlazeJS git ref in core meteor to 2.7.1 by [Grubba27](https://github.com/Grubba27) [PR](https://github.com/meteor/meteor/pull/12651).
* Added `Meteor.applyAsync` types by [Julusian](https://github.com/Julusian) [PR](https://github.com/meteor/meteor/pull/12645).
#### Breaking Changes
N/A
#### Internal changes
* `ddp-server@get-version`:
- Updated livedata server test to be more easily debbuged.
* `mongo@get-version`:
- Updated deprecated reference in Mongo package.
#### Migration Steps
N/A
#### Meteor Version Release
* `Command line`:
- Updated metatags for skeletons.
- Updated solidjs skeleton to be more idiomatic.
* `meteor@1.11.3`:
- Added types for applyAsync and added more documentation for applyAsync options.
* `mongo@1.16.7`:
- Updated types with projection.
- Fixed wrong upsert logs when using WARN_WHEN_USING_OLD_API flag.
- Handled implicit collection creation oplog message.
* `test-in-console@1.2.5`:
- Adjusted log indentation.
- All errors will be logged to console.
- Will always use puppeteer@20.4.0
* `twitter-oauth@1.3.3`:
- Fixed twitter whitelist issue.
#### Special thanks to
- [@radekmie](https://github.com/radekmie).
- [@Grubba27](https://github.com/Grubba27).
- [@fredmaiaarantes](https://github.com/fredmaiaarantes).
- [@StorytellerCZ](https://github.com/StorytellerCZ).
- [@Atharshoyeb](https://github.com/Atharshoyeb).
- [@Julusian](https://github.com/Julusian).

View File

@@ -356,7 +356,7 @@
- `meteor-tool@3.0.0`:
- Package was bumped due to a dependency update. No code changes were made.
- Changes to how meteor apps are being created [PR](https://github.com/meteor/meteor/pull/12697)
- `meteor@2.0.0`:

View File

@@ -799,6 +799,839 @@ Package was bumped due to a dependency update. No code changes were made.
## v3.0, TBD
### Highlights
#### Breaking Changes
- `accounts-2fa@3.0.0`:
- Some methods are now async. See below:
- `Accounts._is2faEnabledForUser`
- `(Meteor Method) - generate2faActivationQrCode`
- `(Meteor Method) - enableUser2fa`
- `(Meteor Method) - disableUser2fa`
- `(Meteor Method) - has2faEnabled`
- `accounts-base@3.0.0`:
- `methods.removeOtherTokens` is now async
- `Accounts.destroyToken` is now async
- `Accounts.insertUserDoc` is now async
- `Accounts.updateOrCreateUserFromExternalService` is now async
- `Accounts.expirePasswordToken` is now async
- `Accounts.setupUsersCollection` is now async
- `accounts-password@3.0.0`:
- Some server methods are now async:
- `Accounts.sendResetPasswordEmail`
- `Accounts.sendEnrollmentEmail`
- `Accounts.sendVerificationEmail`
- `Accounts.addEmail`
- `Accounts.removeEmail`
- `Accounts.verifyEmail`
- `Accounts.createUserVerifyingEmail`
- `Accounts.createUser`
- `Accounts.generateVerificationToken`
- `Accounts.generateResetToken`
- `Accounts.forgotPassword`
- `Accounts.setPassword`
- `Accounts.changePassword`
- `Accounts.setUsername`
- `Accounts.findUserByEmail`
- `Accounts.findUserByUsername`
- `accounts-passwordless@3.0.0`:
- `Accounts.sendLoginTokenEmail` is now async.
- `allow-deny@2.0.0`:
- Updated to accept async functions.
- `appcache@2.0.0`:
- Updated internal api to use `expressHandlers`
- `autoupdate@2.0.0`:
- Updated api to be async, with asyncronous queueing.
- `babel-compiler@8.0.0`:
- Removed `Promise.await` default transform.
- Added top-level-await to packages.
- `boilerplate-generator@2.0.0`:
- `toHTML` is no longer available (it was already deprecated). Use `toHTMLStream` instead.
- Updated to use `expressHandlers`
- `browser-policy-common@2.0.0`:
- Updated to use `expressHandlers`
- `browser-policy-content@2.0.0`:
- Some methods are now async. See below:
- `BrowserPolicy.content.setPolicy`
- `BrowserPolicy.content.allowInlineScripts`
- `BrowserPolicy.content.disallowInlineScripts`
- `BrowserPolicy.content.disallowAll`
- `BrowserPolicy.setDefaultPolicy`
- `browser-policy@2.0.0`:
Updated to use async methods from `browser-policy-common` and `browser-policy-content`.
- `caching-compiler@2.0.0`:
- `afterLink` is now async.
- Updated to use now async API.
- `callback-hook@2.0.0`:
- Added `forEachAsync` method.
- `check@2.0.0`:
- Removed `fibers` related tests.
- `constraint-solver@2.0.0`:
- Some methods are now async. See below:
- `ConstraintSolver.getVersionCostSteps`
- `ConstraintSolver.analyze`
- `ConstraintSolver.resolve`
- Updated tests to be async.
- Removed a few underscore usage.
- Added updated to use async methods
- `context@1.0.0`:
- Removed `fibers` from package.
- `core-runtime@2.0.0`:
- Created package to load packages and the app.
- This is the pakcages that sets up the Runtime.
- `ddp-client@3.0.0`:
- Added `isAsyncCall` method to know if call is being made by a async method.
- Removed `fibers` from package.
- Updated tests to use async methods.
- `ddp-common@2.0.0`:
- Added `.fence` option.
- `ddp-server@3.0.0`:
- Updated to use async methods.
- Removed `fibers` from package.
- Updated tests to use async methods.
- Turned server implementation to async.
`deprecated`:
- `http`:
- Updated handlers to use `expressHandlers`
- `spiderable`:
- Updated handlers to use `expressHandlers`
- removed `fibers` usage if flag is set to `true`
- `ecmascript-runtime@1.0.0`:
- Added dependency to `@babel/runtime`.
- `ecmascript@1.0.0`:
- Added dependency to `@babel/runtime`.
- Moved runtime tests.
- `email@3.0.0`:
- `Email.send` is no longer available. Use `Email.sendAsync` instead.
- Updated types to reflext async methods and `Email.send` depracation.
- `facts-base@2.0.0`:
- turned unorderd deps on `ddp` to false.
- `id-map@2.0.0`:
- Added `forEachAsync` method.
- `logging@2.0.0`:
- Added dependency to `@babel/runtime`.
- `logic-solver@3.0.0`:
`Logic.disablingAssertions` is now async.
`minMaxWS` is now async.
- `meteor@2.0.0`:
- Async local storage was added to help deal with async methods.
- Added `promiseEmmiter` to help with async methods.
- Removed `fibers` from package.
- `minifier-css@2.0.0`:
- `minifyCss` is now async.
- Removed `fibers` from package.
- `minifier-js@3.0.0`:
- `minifyJs` is now async.
- `terserMinify` no longer takes callbacks
- Removed `fibers` from package.
* `minimongo@2.0.0`:
- `cursor.observe` now returns `isReady` and `isReadyPromise` wich indicates
if the cursor is ready and if the callbacks are have been called.
If you only use it in the `Client` or as a `LocalCollection` things have not
changed.
- `modules@1.0.0`:
- Updated `reify` version.
- `mongo@2.0.0`:
- Updated to unify methods, `update`,`insert`,`remove`, `fetch` are now async, they are
the same as their `*Async` counterpart.
- `ensureIndex` and `createIndex` are now async.
- `blaze@3.0.0`:
- TODO
- `mongo-decimal@`:
- Updated to use `async` methods.
- `oauth`:
- `_endOfPopupResponseTemplate` and `_endOfRedirectResponseTemplate` are no longer a property but now a function that returns a promise of the same value as before
- the following server methods are now async:
- `OAuth._renderOauthResults`
- `OAuth._endOfLoginResponse`
- `OAuth.renderEndOfLoginResponse`
- `OAuth._storePendingCredential`
- `OAuth._retrievePendingCredential`
- `ensureConfigured`
- `_cleanStaleResults`
- `oauth1`:
- the following server methods are now async:
- `OAuth._storeRequestToken`
- `OAuth._retrieveRequestToken`
- `oauth2`:
- `OAuth._requestHandlers['2']` is now async.
- `ordered-dict@2.0.0`:
- Added `forEachAsync` method.
- `promise@1.0.0`:
- Removed `fibers` usage
- `reload-safetybelt@2.0.0`:
- Added `ecmascript` package to `package.js`
- `server-render@1.0.0`:
- Updated usage with `getBoilerplate` that are now `async`.
- `service-configuration@2.0.0`:
- Updated to use `createIndexAsync`.
- `shell-server@1.0.0`:
- Updated to handle promises results.
- `socket-stream-client@1.0.0`:
- Updated tests to handle `async` code.
- `standard-minifier-js@3.0.0`:
- `processFilesForBundle` is now `async`.
- `test-helpers@2.0.0`:
- Updated to use `async` methods.
- Removed `fibers` usage.
- Added possibliy to use `async` tests.
- `test-in-browser@2.0.0`:
- Updated css to be in dark mode.
- `test-in-console@2.0.0`:
- Updated log identation.
- `tinytest@2.0.0`:
- Added `test name` to logs.
- Removed `fibers` usage.
- `underscore@2.0.0`:
- Removed dependency in meteor package.
- `webapp@2.0.0`:
- These methods are now async:
- `WebAppInternals.reloadClientPrograms()`
- `WebAppInternals.pauseClient()`
- `WebAppInternals.generateClientProgram()`
- `WebAppInternals.generateBoilerplate()`
- `WebAppInternals.setInlineScriptsAllowed()`
- `WebAppInternals.enableSubresourceIntegrity()`
- `WebAppInternals.setBundledJsCssUrlRewriteHook()`
- `WebAppInternals.setBundledJsCssPrefix()`
- `WebAppInternals.getBoilerplate`
- Changed engine from connect to express and changed api naming to match express. See below:
- `WebApp.connectHandlers.use(middleware)` is now `WebApp.expressHandlers.use(middleware)`
- `WebApp.rawConnectHandlers.use(middleware)` is now `WebApp.rawExpressHandlers.use(middleware)`
- `WebApp.connectApp` is now `WebApp.expressApp`
- `accounts-facebook@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-github@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-google@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-meetup@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-meteor-developer@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-twitter@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-ui-unstyled@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `accounts-weibo@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `audit-argument-checks@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `autopublish@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `babel-runtime@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `base64@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `binary-heap@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `boilerplate-generator-tests@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `crosswalk@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `ddp@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `ddp-rate-limiter@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `diff-sequence@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `disable-oplog@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `ecmascript-runtime-client@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `ecmascript-runtime-server@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `ejson@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `es5-shim@5.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `facebook-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `facebook-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `facts-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `fetch@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `force-ssl@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `force-ssl-common@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `geojson-utils@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `github-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `github-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `google-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `google-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `hot-code-push@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `insecure@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `inter-process-messaging@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `launch-screen@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `localstorage@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meetup-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meetup-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meteor-base@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meteor-developer-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meteor-developer-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `meteor-tool@3.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `mobile-experience@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `mobile-status-bar@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `modern-browsers@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `modules-runtime@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `mongo-dev-server@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `mongo-id@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `mongo-livedata@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `npm-mongo@5.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `oauth@3.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `oauth-encryption@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `oauth1@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `oauth2@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `package-stats-opt-out@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `package-version-parser@4.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `random@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `rate-limit@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `reactive-dict@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `reactive-var@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `reload@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `retry@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `routepolicy@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `session@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `sha@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `standard-minifier-css@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `standard-minifiers@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `static-html@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `test-server-tests-in-console-once@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `tinytest-harness@1.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `twitter-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `twitter-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `typescript@5.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `underscore-tests@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `url@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `webapp-hashing@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `weibo-config-ui@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
- `weibo-oauth@2.0.0`:
Package was bumped due to a dependency update. No code changes were made.
#### New Public API
- `accounts-base`: (2.9+)
- `Meteor.userAsync()`
- `callback-hook`:forEachAsync
- `forEachAsync`
- `ddp-server`: (2.8+)
- `Meteor.callAsync()`
- `minifier-css`: (2.9+)
- `CssTools.minifyCssAsync()`
- `mongo`:
- `Mongo.Collection`: (2.8+)
- `createCappedCollectionAsync`
- `createIndexAsync`
- `dropCollectionAsync`
- `dropIndexAsync`
- `findOneAsync`
- `insertAsync`
- `removeAsync`
- `updateAsync`
- `upsertAsync`
- `Collection.Cursor`: (2.8+)
- `countAsync`
- `fetchAsync`
- `forEachAsync`
- `mapAsync`
- `[Symbol.asyncIterator]` so this code should work:
```js
for await (const document of collection.find(query, options)) /* ... */
```
#### Internal API changes
`accounts-base`:
- `_attemptLogin`
- `_loginMethod`
- `_runLoginHandlers`
#### New Internal API
`accounts-password`:
- `Accounts._checkPasswordAsync`
#### Special thanks to
## v2.13.0, 2023-05-XX
### Highlights
* Handled implicit collection creation oplog message by [radekmie](https://github.com/radekmie) [PR](https://github.com/meteor/meteor/pull/12643).
* Fix upsert logs when using WARN_WHEN_USING_OLD_API flag by [Grubba27](https://github.com/Grubba27) [PR](https://github.com/meteor/meteor/pull/12640).
* Updating mongo types by [Grubba27](https://github.com/Grubba27) [PR](https://github.com/meteor/meteor/pull/12639).
* Fix solid skeleton by [fredmaiaarantes](https://github.com/fredmaiaarantes) [PR](https://github.com/meteor/meteor/pull/12637).
* Setting The Viewport meta tag on skeletons [fredmaiaarantes](https://github.com/fredmaiaarantes) [PR](https://github.com/meteor/meteor/pull/12636).
* Update mongo.d.ts with projection [StorytellerCZ](https://github.com/StorytellerCZ) [PR](https://github.com/meteor/meteor/pull/12635).
* Update guide code for GraphQL [StorytellerCZ](https://github.com/StorytellerCZ) [PR](https://github.com/meteor/meteor/pull/12619).
* Twitter Whitelist issue resolved [Atharshoyeb](https://github.com/Atharshoyeb) [PR](https://github.com/meteor/meteor/pull/12369).
#### Breaking Changes
N/A
#### Internal API changes
N/A
#### Migration Steps
TODO
#### Meteor Version Release
* `Command line`:
- Updated metatags for skeletons.
- Updated solidjs skeleton to be more idiomatic.
* `mongo@1.16.7`:
TODO
#### Special thanks to
- [@radekmie](https://github.com/radekmie).
- [@Grubba27](https://github.com/Grubba27).
- [@fredmaiaarantes](https://github.com/fredmaiaarantes).
- [@StorytellerCZ](https://github.com/StorytellerCZ).
- [@Atharshoyeb](https://github.com/Atharshoyeb).
## v2.12.0, 2023-04-28
### Highlights
@@ -832,7 +1665,7 @@ N/A
#### Migration Steps
Now if you want to check where do you call old-style api methods
Now if you want to check where do you call old-style api methods
you can use ```WARN_WHEN_USING_OLD_API``` before starting your meteor process.
@@ -841,7 +1674,7 @@ you can use ```WARN_WHEN_USING_OLD_API``` before starting your meteor process.
* `accounts-base@2.2.8`:
- Added `loginServiceConfiguration` type.
- Added the `collection` option property, in order to be able to set the collection for Accounts,
more can be seen in the [discussion](https://github.com/meteor/meteor/discussions/12544#discussioncomment-5240763)
more can be seen in the [discussion](https://github.com/meteor/meteor/discussions/12544#discussioncomment-5240763)
and in the [related issue](https://github.com/meteor/meteor-feature-requests/issues/20).
- `onCreateUserHook` now accept promises and wait if necessary.
@@ -853,7 +1686,7 @@ you can use ```WARN_WHEN_USING_OLD_API``` before starting your meteor process.
* `browser-policy-framing@1.1.2`:
- Added `es5` compatible syntax.
* `browser-policy@1.1.2`:
- Updated test name.
@@ -903,7 +1736,7 @@ you can use ```WARN_WHEN_USING_OLD_API``` before starting your meteor process.
* `mongo@1.16.6`:
- Added `countDocuments` and `estimatedDocumentCount` types.
- Added warning for when old style apis are being used, to use this feature,
- Added warning for when old style apis are being used, to use this feature,
use the variable`WARN_WHEN_USING_OLD_API=true` before starting the Meteor process.
- Oplog driver updated to not throw error when MongoDB server and Meteor client mismatch. [issue](https://github.com/meteor/meteor/issues/12516)

View File

@@ -87,9 +87,17 @@ Create a new Meteor project. By default, it uses [React](https://guide.meteor.co
and makes a subdirectory named *name* and copies in the template app.
You can pass an absolute or relative path.
<h3 id="meteorcreate-flags">Flags</h3>
_This command requires an Internet connection and having git installed._
**Flags for default packages**
<h3 id="meteorcreate-templates">Cloning from project</h3>
You can also create a new Meteor project by cloning an existing project. You can
list them using the command `meteor create --list` it will list all the available
templates. You can then clone them using the command `meteor create --example <template-name> <project-name>`
Or you can use the `--from` flag to clone a project from a git repository. For example
`meteor create --from "https://github.com/meteor/skel-react" <project-name>`
<h3 id="meteorcreate-flags">Flags</h3>
`--prototype`
@@ -100,6 +108,7 @@ For more information about security you can check
it [here](https://guide.meteor.com/security.html#checklist)
It can be used together with other flags that create apps such as `--react` or `--typescript`.
**Flags for default packages**
`--bare`

View File

@@ -3,8 +3,9 @@ subtitle: The Official Guide
github_repo: 'meteor/meteor'
edit_branch: 'devel'
edit_path: 'guide'
content_root: 'content'
content_root: 'source'
versions:
- '2.13'
- '2.12'
- '2.11'
- '2.10'
@@ -30,7 +31,7 @@ versions:
- '1.3'
- '1.2'
versioned-netlify-redirects:
netlify_site_id: meteor-guide
netlify_site_id: meteor-guide
logo:
title:
@@ -56,6 +57,8 @@ sidebar_categories:
- react
- angular
- vue
Integrations:
- flowbite
Mobile:
- cordova
- react-native
@@ -88,7 +91,7 @@ redirects:
'/using-packages.html#using-npm': using-npm-packages.html#using-npm
'/using-packages.html#npm-styles': using-npm-packages.html#npm-styles
'/using-packages.html#npm-shrinkwrap': using-npm-packages.html#npm-shrinkwrap
'/using-packages.html#atmosphere': using-atmosphere-packages.html
'/using-packages.html#atmosphere': using-atmosphere-packages.html
'/using-packages.html#atmosphere-searching': using-atmosphere-packages.html#atmosphere-searching
'/using-packages.html#atmosphere-naming': using-atmosphere-packages.html#atmosphere-naming
'/using-packages.html#installing-atmosphere': using-atmosphere-packages.html#installing-atmosphere
@@ -100,7 +103,7 @@ redirects:
'/using-packages.html#bind-environment': using-npm-packages.html#bind-environment
'/using-packages.html#wrap-async': using-npm-packages.html#wrap-async
'/using-packages.html#promises': using-npm-packages.html#promises
'/using-packages.html#overriding-packages': writing-npm-packages.html#overriding-npm-packages
'/using-packages.html#overriding-packages': writing-npm-packages.html#overriding-npm-packages
'/using-packages.html#npm-overriding': writing-npm-packages.html#overriding-npm-packages
'/using-packages.html#atmosphere-overriding': writing-atmosphere-packages.html#overriding-atmosphere-packages
'/using-packages.html#npm-shrinkpack': using-npm-packages.html#npm-shrinkpack

View File

@@ -0,0 +1,48 @@
---
title: Migrating to Meteor 2.13
description: How to migrate your application to Meteor 2.13.
---
Most of the new features in Meteor 2.13 are either applied directly behind the
scenes (in a backwards compatible manner) or are opt-in. For a complete
breakdown of the changes, please refer to the [changelog](http://docs.meteor.com/changelog.html).
For this release all the changes are for quality of life improvements and
there are no breaking changes.
for more information on the changes in this release, please refer to the
[changelog](http://docs.meteor.com/changelog.html).
<h2 id="older-versions">Migrating from a version older than 2.12?</h2>
If you're migrating from a version of Meteor older than Meteor 2.12, there may
be important considerations not listed in this guide.
Please review the older migration guides for details:
* [Migrating to Meteor 2.12](2.12-migration.html) (from 2.11)
* [Migrating to Meteor 2.11](2.11-migration.html) (from 2.10)
* [Migrating to Meteor 2.10](2.10-migration.html) (from 2.9)
* [Migrating to Meteor 2.9](2.9-migration.html) (from 2.8)
* [Migrating to Meteor 2.8](2.8-migration.html) (from 2.7)
* [Migrating to Meteor 2.7](2.7-migration.html) (from 2.6)
* [Migrating to Meteor 2.6](2.6-migration.html) (from 2.5)
* [Migrating to Meteor 2.5](2.5-migration.html) (from 2.4)
* [Migrating to Meteor 2.4](2.4-migration.html) (from 2.3)
* [Migrating to Meteor 2.3](2.3-migration.html) (from 2.2)
* [Migrating to Meteor 2.2](2.2-migration.html) (from 2.0)
* [Migrating to Meteor 2.0](2.0-migration.html) (from 1.12)
* [Migrating to Meteor 1.12](1.12-migration.html) (from 1.11)
* [Migrating to Meteor 1.11](1.11-migration.html) (from 1.10.2)
* [Migrating to Meteor 1.10.2](1.10.2-migration.html) (from 1.10)
* [Migrating to Meteor 1.10](1.10-migration.html) (from 1.9.3)
* [Migrating to Meteor 1.9.3](1.9.3-migration.html) (from 1.9)
* [Migrating to Meteor 1.9](1.9-migration.html) (from 1.8.3)
* [Migrating to Meteor 1.8.3](1.8.3-migration.html) (from 1.8.2)
* [Migrating to Meteor 1.8.2](1.8.2-migration.html) (from 1.8)
* [Migrating to Meteor 1.8](1.8-migration.html) (from 1.7)
* [Migrating to Meteor 1.7](1.7-migration.html) (from 1.6)
* [Migrating to Meteor 1.6](1.6-migration.html) (from 1.5)
* [Migrating to Meteor 1.5](1.5-migration.html) (from 1.4)
* [Migrating to Meteor 1.4](1.4-migration.html) (from 1.3)
* [Migrating to Meteor 1.3](1.3-migration.html) (from 1.2)

View File

@@ -73,18 +73,37 @@ meteor add apollo
On server you import `getUser` function and include it into the context option when setting up Apollo server:
```javascript
import { ApolloServer } from 'apollo-server-express';
import { ApolloServer } from '@apollo/server';
import { WebApp } from 'meteor/webapp';
import { getUser } from 'meteor/apollo';
import typeDefs from '/imports/apollo/schema.graphql';
import { resolvers } from '/server/resolvers';
import express from 'express';
import { expressMiddleware } from '@apollo/server/express4';
import { json } from 'body-parser'
const context = async ({ req }) => ({
user: await getUser(req.headers.authorization)
})
const server = new ApolloServer({
cache: 'bounded',
typeDefs,
resolvers,
context: async ({ req }) => ({
user: await getUser(req.headers.authorization)
})
});
export async function startApolloServer() {
await server.start();
WebApp.connectHandlers.use(
'/graphql', // Configure the path as you want.
express() // Create new Express router.
.disable('etag') // We don't server GET requests, so there's no need for that.
.disable('x-powered-by') // A small safety measure.
.use(json()) // From `body-parser`.
.use(expressMiddleware(server, { context })), // From `@apollo/server/express4`.
)
}
```
This will make user data available (if user is logged in) as the option in the query:

View File

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

167
guide/source/flowbite.md Normal file
View File

@@ -0,0 +1,167 @@
---
title: Flowbite UI
description: Learn how to install Tailwind CSS with Flowbite for your Meteor.js project to build full-stack JavaScript or TypeScript web, mobile, and desktop applications
---
## Introduction
[Flowbite](https://flowbite.com/) is an open-source library of UI components based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, templates, and more.
It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, but also some more advanced interactive elements such as datepickers.
Using both Meteor.js, Tailwind CSS and Flowbite can help you get started building modern UI web applications by leveraging the extensive framework features of Meteor.js, the utility-first approach of the Tailwind CSS framework and the open-source UI components from the Flowbite Library.
## Requirements
Make sure that you have [Node.js v14](https://nodejs.org/en/) installed on your computer to be able to install Meteor.js, Tailwind CSS and Flowbite using NPX and NPM.
For more information on how to install Meteor.js, check out the [official installation guide](https://docs.meteor.com/install.html#prereqs).
## Create a new meteor project
#### Create a new `meteor` starter project:
The easiest way to create a new Meteor.js project is by first installed the CLI globally:
```bash
npm install -g meteor
```
After you have `meteor` installed globally you can go ahead and create a new project:
```sh
meteor create flowbite-app --tailwind
cd flowbite-app
```
This will create a new `meteor` project with `tailwindcss` support.
No extra configuration needed as we added the `--tailwind` flag when setting up the project.
Now that you have created a new Meteor.js project with Tailwind CSS configured automatically we can proceed with installing Flowbite and Flowbite React to start leveraging the open-source UI components.
## Install Flowbite
1. Install Flowbite and Flowbite React via NPM:
```bash
npm install --save flowbite flowbite-react
```
2. Make sure that you set up the Flowbite plugin and template paths in your `tailwind.config.js` file:
```js
module.exports = {
content: [
'./imports/ui/**/*.{js,jsx,ts,tsx}',
'./client/*.html',
'node_modules/flowbite-react/**/*.{js,jsx,ts,tsx}',
],
theme: {
extend: {},
},
plugins: [require('flowbite/plugin')],
};
```
3. Now that you have installed the packages you can start importing the UI components:
```js
import { Alert } from 'flowbite-react';
export default function MyPage() {
return <Alert color="info">Alert!</Alert>;
}
```
The code above will import the `<Alert>` component that you can use to send feedback messages.
## Flowbite UI components
To get you started you can check out the full collection of React components from the [Flowbite React website](https://flowbite-react.com/) and browse the documentation for the source code of each component.
Here's an example of how you can use the modal and button components by importing them from the Flowbite React package inside your Meteor.js project:
```javascript
import { Button, Modal } from 'flowbite-react';
export default function DefaultModal() {
const [openModal, setOpenModal] = useState<string | undefined>();
const props = { openModal, setOpenModal };
return (
<>
<Button onClick={() => props.setOpenModal('default')}>Toggle modal</Button>
<Modal show={props.openModal === 'default'} onClose={() => props.setOpenModal(undefined)}>
<Modal.Header>Terms of Service</Modal.Header>
<Modal.Body>
<div className="space-y-6">
<p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
With less than a month to go before the European Union enacts new consumer privacy laws for its citizens,
companies around the world are updating their terms of service agreements to comply.
</p>
<p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
The European Unions General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to
ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as
possible of high-risk data breaches that could personally affect them.
</p>
</div>
</Modal.Body>
<Modal.Footer>
<Button onClick={() => props.setOpenModal(undefined)}>I accept</Button>
<Button color="gray" onClick={() => props.setOpenModal(undefined)}>
Decline
</Button>
</Modal.Footer>
</Modal>
</>
)
}
```
Here's another example of how you can use the dropdown component:
```javascript
import { Dropdown } from 'flowbite-react';
<Dropdown label="Dropdown button">
<Dropdown.Item>Dashboard</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Item>Earnings</Dropdown.Item>
<Dropdown.Item>Sign out</Dropdown.Item>
</Dropdown>;
```
Finally, another example on how you can use the navbar component:
```javascript
import { Navbar } from 'flowbite-react';
<Navbar fluid={true} rounded={true}>
<Navbar.Brand href="https://flowbite.com/">
<img
src="https://flowbite.com/docs/images/logo.svg"
className="mr-3 h-6 sm:h-9"
alt="Flowbite Logo"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Flowbite
</span>
</Navbar.Brand>
<Navbar.Toggle />
<Navbar.Collapse>
<Navbar.Link href="/navbars" active={true}>
Home
</Navbar.Link>
<Navbar.Link href="/navbars">About</Navbar.Link>
<Navbar.Link href="/navbars">Services</Navbar.Link>
<Navbar.Link href="/navbars">Pricing</Navbar.Link>
<Navbar.Link href="/navbars">Contact</Navbar.Link>
</Navbar.Collapse>
</Navbar>;
```
To learn more about Flowbite React make sure to check out to the [repository](https://github.com/themesberg/flowbite-react) and the [main website](https://flowbite-react.com/).
## Meteor.js starter project
The Flowbite community has created an open-source Meteor.js starter project that has Tailwind CSS and Flowbite React set up beforehand and you can go ahead and clone it by checking out the [repository on GitHub](https://github.com/meteor/flowbite-meteor-starter).

View File

@@ -276,15 +276,19 @@ if (!this.isSimulation) {
The main thing enabled by the `ValidationError` convention is integration between Methods and the forms that call them. In general, your app is likely to have a one-to-one mapping of forms in the UI to Methods. First, let's define a Method for our business logic:
```js
// Define a regular expression for email and amount validation.
const emailRegEx = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g;
const amountRegEx = /^\d*\.(\d\d)?$/;
// This Method encodes the form validation requirements.
// By defining them in the Method, we do client and server-side
// validation in one place.
export const insert = new ValidatedMethod({
name: 'Invoices.methods.insert',
validate: new SimpleSchema({
email: { type: String, regEx: SimpleSchema.RegEx.Email },
email: { type: String, regEx: emailRegEx },
description: { type: String, min: 5 },
amount: { type: String, regEx: /^\d*\.(\d\d)?$/ }
amount: { type: String, regEx: amountRegEx }
}).validator(),
run(newInvoice) {
// In here, we can be sure that the newInvoice argument is
@@ -300,6 +304,8 @@ export const insert = new ValidatedMethod({
});
```
We encourage you to create custom regEx expressions for security reasons, for fields like `email` and `amout`. For Meteor related functionality, like `IDs`, you can use the `SimpleSchema.RegEx.Id` expression. Check out the [Simple Schema docs](https://github.com/longshotlabs/simpl-schema#regex) for more information.
Let's define an HTML form:
```html

View File

@@ -316,7 +316,7 @@ The primary challenge is properly sharing code between the different application
If you want to create Meteor applications with separate code, you'll have some modules that you'd like to share between them. If those modules are something the wider world could use, you should consider [publishing them to a package system](writing-packages.html), either npm or Atmosphere, depending on whether the code is Meteor-specific or otherwise.
If the code is private, or of no interest to others, it typically makes sense to include the same module in both applications (you *can* do this with [private npm modules](https://www.npmjs.com/private-modules)). There are several ways to do this:
If the code is private, or of no interest to others, it typically makes sense to include the same module in both applications (you *can* do this with [private npm modules](https://docs.npmjs.com/about-private-packages)). There are several ways to do this:
- a straightforward approach is to include the common code as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) of both applications.

View File

@@ -14,6 +14,7 @@ npm install -g meteor
| NPM Package | Meteor Official Release |
|-------------|-------------------------|
| 2.13.0 | 2.13.0 |
| 2.12.1 | 2.12.0 |
| 2.12.0 | 2.12.0 |
| 2.11.0 | 2.11.0 |

View File

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

View File

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

View File

@@ -74,7 +74,7 @@ DDPRateLimiter.setErrorMessageOnRule = (ruleId, message) => {
* - `connectionId`: A string representing the user's DDP connection
* - `clientAddress`: The IP address of the user
*
* Returns unique `ruleId` that can be passed to `removeRule`.
* Returns unique `ruleId` that can be passed to `removeRule` and `setErrorMessageOnRule`
*
* @param {Object} matcher
* Matchers specify which events are counted towards a rate limit. A matcher

View File

@@ -101,7 +101,7 @@ Meteor.publish({
async publicationObjectAsync() {
await sleep(50);
let callback = onSubscriptions;
if (callback) callback();
if (callback) callback("publicationObjectAsync");
this.stop();
},
});
@@ -110,7 +110,7 @@ Meteor.publish({
publication_object_async: async function() {
await sleep(50);
let callback = onSubscriptions;
if (callback) callback();
if (callback) callback("publication_object_async");
this.stop();
},
});
@@ -118,7 +118,7 @@ Meteor.publish({
Meteor.publish('publication_compatibility_async', async function() {
await sleep(50);
let callback = onSubscriptions;
if (callback) callback();
if (callback) callback("publication_compatibility_async");
this.stop();
});
@@ -130,10 +130,12 @@ Tinytest.addAsync('livedata server - async publish object', function(
let testsLength = 0;
onSubscriptions = function(subscription) {
delete onSubscriptions;
clientConn.disconnect();
// for debugging
// console.log('subscription is ok:', subscription)
testsLength++;
if (testsLength == 3) {
delete onSubscriptions;
if (testsLength === 3) {
clientConn.disconnect();
onComplete();
}
};

View File

@@ -159,6 +159,41 @@ export namespace Meteor {
*/
function callAsync(name: string, ...args: any[]): Promise<any>;
interface MethodApplyOptions {
/**
* (Client only) If true, don't send this method until all previous method calls have completed, and don't send any subsequent method calls until this one is completed.
*/
wait?: boolean | undefined;
/**
* (Client only) This callback is invoked with the error or result of the method (just like `asyncCallback`) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.
*/
onResultReceived?:
| ((
error: global_Error | Meteor.Error | undefined,
result?: Result
) => void)
| undefined;
/**
* (Client only) if true, don't send this method again on reload, simply call the callback an error with the error code 'invocation-failed'.
*/
noRetry?: boolean | undefined;
/**
* (Client only) If true then in cases where we would have otherwise discarded the stub's return value and returned undefined, instead we go ahead and return it. Specifically, this is any time other than when (a) we are already inside a stub or (b) we are in Node and no callback was provided. Currently we require this flag to be explicitly passed to reduce the likelihood that stub return values will be confused with server return values; we may improve this in future.
*/
returnStubValue?: boolean | undefined;
/**
* (Client only) If true, exceptions thrown by method stubs will be thrown instead of logged, and the method will not be invoked on the server.
*/
throwStubExceptions?: boolean | undefined;
}
/**
* Invokes a method with a sync stub, passing any number of arguments.
* @param name Name of method to invoke
* @param args Method arguments
* @param options Optional execution options
* @param asyncCallback Optional callback
*/
function apply<
Result extends
| EJSONable
@@ -168,26 +203,35 @@ export namespace Meteor {
>(
name: string,
args: ReadonlyArray<EJSONable | EJSONableProperty>,
options?: {
wait?: boolean | undefined;
onResultReceived?:
| ((
error: global_Error | Meteor.Error | undefined,
result?: Result
) => void)
| undefined;
/**
* (Client only) if true, don't send this method again on reload, simply call the callback an error with the error code 'invocation-failed'.
*/
noRetry?: boolean | undefined;
returnStubValue?: boolean | undefined;
throwStubExceptions?: boolean | undefined;
},
options?: MethodApplyOptions,
asyncCallback?: (
error: global_Error | Meteor.Error | undefined,
result?: Result
) => void
): any;
/**
* Invokes a method with an async stub, passing any number of arguments.
* @param name Name of method to invoke
* @param args Method arguments
* @param options Optional execution options
* @param asyncCallback Optional callback
*/
function applyAsync<
Result extends
| EJSONable
| EJSONable[]
| EJSONableProperty
| EJSONableProperty[]
>(
name: string,
args: ReadonlyArray<EJSONable | EJSONableProperty>,
options?: MethodApplyOptions,
asyncCallback?: (
error: global_Error | Meteor.Error | undefined,
result?: Result
) => void
): Promise<Result>;
/** Method **/
/** Url **/

View File

@@ -538,7 +538,6 @@ ASYNC_CURSOR_METHODS.forEach(method => {
const asyncName = getAsyncMethodName(method);
Cursor.prototype[asyncName] = function(...args) {
try {
this[method].isCalledFromAsync = true;
return Promise.resolve(this[method].apply(this, args));
} catch (error) {
return Promise.reject(error);

View File

@@ -6,24 +6,7 @@ import {
} from "meteor/minimongo/constants";
import { normalizeProjection } from "./mongo_utils";
export function warnUsingOldApi (
methodName,
collectionName,
isCalledFromAsync
){
if (
process.env.WARN_WHEN_USING_OLD_API && // also ensures it is on the server
!isCalledFromAsync // must be true otherwise we should log
) {
if (collectionName === undefined || collectionName.includes('oplog')) return
console.warn(`
Calling method ${collectionName}.${methodName} from old API on server.
This method will be removed, from the server, in version 3.
Trace is below:`)
console.trace()
};
}
/**
* @summary Namespace for MongoDB-related items
* @namespace
@@ -671,14 +654,6 @@ Object.assign(Mongo.Collection.prototype, {
throw new Error('insert requires an argument');
}
// [FIBERS]
// TODO: Remove this when 3.0 is released.
warnUsingOldApi(
"insert",
this._name,
this.insert.isCalledFromAsync
);
this.insert.isCalledFromAsync = false;
// Make a shallow clone of the document, preserving its prototype.
doc = Object.create(
@@ -962,15 +937,6 @@ Object.assign(Mongo.Collection.prototype, {
}
}
// [FIBERS]
// TODO: Remove this when 3.0 is released.
warnUsingOldApi(
"update",
this._name,
this.update.isCalledFromAsync
);
this.update.isCalledFromAsync = false;
selector = Mongo.Collection._rewriteSelector(selector, {
fallbackId: insertedId,
});
@@ -1043,14 +1009,7 @@ Object.assign(Mongo.Collection.prototype, {
return this._callMutatorMethod('remove', [selector]);
}
// [FIBERS]
// TODO: Remove this when 3.0 is released.
warnUsingOldApi(
"remove",
this._name,
this.remove.isCalledFromAsync
);
this.remove.isCalledFromAsync = false;
// it's my collection. descend into the collection1 object
// and propagate any exception.
return this._collection.remove(selector);
@@ -1153,14 +1112,7 @@ Object.assign(Mongo.Collection.prototype, {
var self = this;
if (!self._collection.createIndexAsync)
throw new Error('Can only call createIndexAsync on server collections');
// [FIBERS]
// TODO: Remove this when 3.0 is released.
warnUsingOldApi(
"createIndex",
self._name,
self.createIndex.isCalledFromAsync
);
self.createIndex.isCalledFromAsync = false;
try {
await self._collection.createIndexAsync(index, options);
} catch (e) {
@@ -1292,7 +1244,7 @@ Mongo.Collection.ObjectID = Mongo.ObjectID;
Meteor.Collection = Mongo.Collection;
// Allow deny stuff is now in the allow-deny package
Object.assign(Meteor.Collection.prototype, AllowDeny.CollectionPrototype);
Object.assign(Mongo.Collection.prototype, AllowDeny.CollectionPrototype);
function popCallbackFromArgs(args) {
// Pull off any callback (or perhaps a 'callback' variable that was passed

View File

@@ -471,6 +471,7 @@ Meteor.isServer && Tinytest.addAsync('collection - simple add', async function(t
var collection = new Mongo.Collection(collectionName);
var id = await collection.insertAsync({a: 1});
test.equal((await collection.findOneAsync(id)).a, 1);
await collection.upsertAsync(id, {$set: {a: 2}});
id = await collection.insertAsync({a: 2});
test.equal((await collection.findOneAsync(id)).a, 2);
await collection.removeAsync({});

View File

@@ -30,8 +30,13 @@ export namespace Mongo {
skip?: number | undefined;
/** Maximum number of results to return */
limit?: number | undefined;
/** Dictionary of fields to return or exclude. */
/**
* Dictionary of fields to return or exclude.
* @deprecated use projection instead
*/
fields?: FieldSpecifier | undefined;
/** Dictionary of fields to return or exclude. */
projection?: FieldSpecifier | undefined;
/** (Server only) Overrides MongoDB's default index selection and query optimization process. Specify an index to force its use, either by its name or index specification. */
hint?: NpmModuleMongodb.Hint | undefined;
/** (Client only) Default `true`; pass `false` to disable reactivity */
@@ -176,12 +181,12 @@ export namespace Mongo {
* @param selector The query for filtering the set of documents to count
* @param options All options are listed in [MongoDB documentation](https://mongodb.github.io/node-mongodb-native/4.11/interfaces/CountDocumentsOptions.html). Please note that not all of them are available on the client.
*/
countDocuments(selector?: Selector<T> | ObjectID | string, options?: MongoNpmModule.CountDocumentsOptions): Promise<number>;
countDocuments(selector?: Selector<T> | ObjectID | string, options?: NpmModuleMongodb.CountDocumentsOptions): Promise<number>;
/**
* Gets an estimate of the count of documents in a collection using collection metadata. For an exact count of the documents in a collection see `countDocuments`.
* @param options All options are listed in [MongoDB documentation](https://mongodb.github.io/node-mongodb-native/4.11/interfaces/CountDocumentsOptions.html). Please note that not all of them are available on the client.
*/
estimatedDocumentCount(options?: MongoNpmModule.EstimatedDocumentCountOptions): Promise<number>;
estimatedDocumentCount(options?: NpmModuleMongodb.EstimatedDocumentCountOptions): Promise<number>;
/**
* Insert a document in the collection. Returns its unique _id.
* @param doc The document to insert. May not yet have an _id attribute, in which case Meteor will generate one for you.

View File

@@ -212,6 +212,7 @@ MongoConnection = function (url, options) {
self._oplogHandle = new OplogHandle(options.oplogUrl, self.db.databaseName);
self._docFetcher = new DocFetcher(self);
}
};
MongoConnection.prototype._close = async function() {
@@ -886,7 +887,6 @@ Cursor.prototype.countAsync = async function () {
const methodNameAsync = getAsyncMethodName(methodName);
Cursor.prototype[methodNameAsync] = function (...args) {
try {
this[methodName].isCalledFromAsync = true;
return Promise.resolve(this[methodName](...args));
} catch (error) {
return Promise.reject(error);

View File

@@ -140,8 +140,10 @@ Object.assign(OplogHandle.prototype, {
// find a TS that won't show up in the actual tail stream.
try {
lastEntry = await self._oplogLastEntryConnection.findOneAsync(
OPLOG_COLLECTION, self._baseOplogSelector,
{fields: {ts: 1}, sort: {$natural: -1}});
OPLOG_COLLECTION,
self._baseOplogSelector,
{ projection: { ts: 1 }, sort: { $natural: -1 } }
);
break;
} catch (e) {
// During failover (eg) if we get an exception we should log and retry
@@ -232,7 +234,7 @@ Object.assign(OplogHandle.prototype, {
else resolve(result);
});
});
if (!(isMasterDoc && isMasterDoc.setName)) {
throw Error("$MONGO_OPLOG_URL must be set to the 'local' database of " +
"a Mongo replica set");
@@ -240,7 +242,10 @@ Object.assign(OplogHandle.prototype, {
// Find the last oplog entry.
var lastOplogEntry = await self._oplogLastEntryConnection.findOneAsync(
OPLOG_COLLECTION, {}, {sort: {$natural: -1}, fields: {ts: 1}});
OPLOG_COLLECTION,
{},
{ sort: { $natural: -1 }, projection: { ts: 1 } }
);
var oplogSelector = Object.assign({}, self._baseOplogSelector);
if (lastOplogEntry) {
@@ -320,6 +325,9 @@ Object.assign(OplogHandle.prototype, {
trigger.collection = doc.o.drop;
trigger.dropCollection = true;
trigger.id = null;
} else if ("create" in doc.o && "idIndex" in doc.o) {
// A collection got implicitly created within a transaction. There's
// no need to do anything about it.
} else {
throw Error("Unknown command " + EJSON.stringify(doc));
}

View File

@@ -1,7 +1,7 @@
// Global flag for phantomjs (or other browser) to eval to see if we're done.
DONE = false;
// Failure count for phantomjs exit code
FAILURES = null;
FAILURES = 0;
// Where are the failures
WHERE_FAILED = [];
// Passed count for phantomjs exit code
@@ -9,7 +9,7 @@ PASSED = null;
TEST_STATUS = {
DONE: false,
FAILURES: null,
FAILURES: 0,
PASSED: null,
WHERE_FAILED: []
};
@@ -149,6 +149,7 @@ runTests = function () {
else
log("Test failed with exception");
failed++;
whereFailed.push({ name: name, info: JSON.stringify(event) });
break;
case "finish":
switch (resultSet[name].status) {

View File

@@ -89,11 +89,7 @@ async function getFailCount(page) {
return TEST_STATUS.FAILURES;
}
if (typeof FAILURES === 'undefined') {
return 1;
}
return 0;
return typeof FAILURES !== 'undefined' && FAILURES;
});
}

View File

@@ -13,7 +13,7 @@ var urls = {
};
// https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials
Twitter.whitelistedFields = ['profile_image_url', 'profile_image_url_https', 'lang', 'email'];
Twitter.whitelistedFields = ['profile_image_url', 'profile_image_url_https', 'lang', 'email',"name"];
OAuth.registerService('twitter', 1, urls, async function(oauthBinding) {
const response = await oauthBinding.getAsync('https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true');
@@ -26,7 +26,7 @@ OAuth.registerService('twitter', 1, urls, async function(oauthBinding) {
};
// include helpful fields from twitter
const { identity: fields } = Twitter.whitelistedFields;
const fields = Twitter.whitelistedFields.reduce((o, k) => { if ( identity[k]) o[k] = identity[k]; return o}, {});
Object.assign(serviceData, fields);
return {

View File

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

View File

@@ -18,7 +18,7 @@ then
NODE_URL="https://github.com/meteor/node/archive/${NODE_COMMIT_HASH}.tar.gz"
else
echo "Building Node source from ${NODE_VERSION} src tarball...";
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}.tar.gz"
NODE_URL="https://static.meteor.com/dev-bundle-node-os/v${NODE_VERSION}/node-v${NODE_VERSION}.tar.gz"
fi
else
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TGZ}"

View File

@@ -23,6 +23,47 @@ var projectContextModule = require('../project-context.js');
var release = require('../packaging/release.js');
const { Profile } = require("../tool-env/profile");
const { exec } = require("child_process");
/**
* Run a command in the shell.
* @param command
* @return {Promise<string>}
*/
const runCommand = async (command) => {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.log(red`error: ${ error.message }`);
reject(error);
return;
}
if (stderr) {
console.log(red`stderr: ${ stderr }`);
reject(stderr);
return;
}
resolve(stdout);
});
})
}
/**
*
* @param {Promise<<T>() => T>} fn
* @returns {Promise<[T, null]> | Promise<[null, Error]>}
*/
const tryRun = async (fn) => {
try { return [await fn(), null] } catch (e) { return [null, e] }
}
/**
*
* @param {string} bash command
* @param {[string, null] | [null, Error]}} Result or Error
* @returns
*/
const bash =
(text, ...values) =>
tryRun(() => runCommand(String.raw({ raw: text }, ...values)));
import { ensureDevBundleDependencies } from '../cordova/index.js';
import { CordovaRunner } from '../cordova/runner.js';
@@ -513,6 +554,31 @@ main.registerCommand({
///////////////////////////////////////////////////////////////////////////////
// create
///////////////////////////////////////////////////////////////////////////////
/**
* list of all the available skeletons similar to the property below
* {
* clock: { repo: 'https://github.com/meteor/clock' },
* leaderboard: { repo: 'https://github.com/meteor/leaderboard' },
* }
* @typedef {Object.<string, {repo: string}>} Skeletons
*/
/**
* Resolves into json with
* @returns {Promise<[Skeletons, null]> | Promise<[null, Error]>}
*/
function getExamplesJSON(){
return tryRun(async () => {
const response = await httpHelpers.request({
url: "https://cdn.meteor.com/static/meteor.json",
method: "GET",
useSessionHeader: true,
useAuthHeader: true,
});
return JSON.parse(response.body);
});
}
const DEFAULT_SKELETON = "react";
export const AVAILABLE_SKELETONS = [
"apollo",
@@ -550,7 +616,8 @@ main.registerCommand({
tailwind: { type: Boolean },
'chakra-ui': { type: Boolean },
solid: { type: Boolean },
prototype: { type: Boolean }
prototype: { type: Boolean },
from: { type: String },
},
catalogRefresh: new catalog.Refresh.Never()
}, async function (options) {
@@ -561,10 +628,12 @@ main.registerCommand({
var packageName = options.args[0];
if (options.prototype) {
Console.error(
`The ${Console.command('--prototype')} option is no longer supported for packages.`
`The ${Console.command(
"--prototype"
)} option is no longer supported for packages.`
);
Console.error();
throw new main.ShowUsage;
throw new main.ShowUsage();
}
if (options.list || options.example) {
Console.error("No package examples exist at this time.");
@@ -577,8 +646,9 @@ main.registerCommand({
throw new main.ShowUsage();
}
utils.validatePackageNameOrExit(
packageName, {detailedColonExplanation: true});
utils.validatePackageNameOrExit(packageName, {
detailedColonExplanation: true,
});
// When we create a package, avoid introducing a colon into the file system
// by naming the directory after the package name without the prefix.
@@ -593,8 +663,9 @@ main.registerCommand({
// with at least two colons. Therefore we will at least try to
// discourage people from putting a ton of colons in their package names
// here.
Console.error(packageName +
": Package names may not have more than one colon.");
Console.error(
packageName + ": Package names may not have more than one colon."
);
return 1;
}
@@ -603,7 +674,7 @@ main.registerCommand({
var packageDir;
if (options.appDir) {
packageDir = files.pathResolve(options.appDir, 'packages', fsName);
packageDir = files.pathResolve(options.appDir, "packages", fsName);
} else {
packageDir = files.pathResolve(fsName);
}
@@ -616,8 +687,7 @@ main.registerCommand({
}
var transform = async function (x) {
var xn =
x.replace(/~name~/g, packageName).replace(/~fs-name~/g, fsName);
var xn = x.replace(/~name~/g, packageName).replace(/~fs-name~/g, fsName);
// If we are running from checkout, comment out the line sourcing packages
// from a release, with the latest release filled in (in case they do want
@@ -631,7 +701,7 @@ main.registerCommand({
relString = rel ? rel.version : "no-release";
} else {
xn = xn.replace(/~cc~/g, "");
relString = release.current.getDisplayName({noPrefix: true});
relString = release.current.getDisplayName({ noPrefix: true });
}
// If we are not in checkout, write the current release here.
@@ -639,35 +709,37 @@ main.registerCommand({
};
try {
await files.cp_r(files.pathJoin(__dirnameConverted, '..', 'static-assets', 'skel-pack'), packageDir, {
transformFilename: function (f) {
return transform(f);
},
transformContents: async function (contents, f) {
if ((/(\.html|\.[jt]sx?|\.css)/).test(f)) {
return Buffer.from(await transform(contents.toString()));
} else {
return contents;
}
},
ignore: [/^local$/],
preserveSymlinks: true,
});
await files.cp_r(
files.pathJoin(__dirnameConverted, "..", "static-assets", "skel-pack"),
packageDir,
{
transformFilename: function (f) {
return transform(f);
},
transformContents: async function (contents, f) {
if (/(\.html|\.[jt]sx?|\.css)/.test(f)) {
return Buffer.from(await transform(contents.toString()));
} else {
return contents;
}
},
ignore: [/^local$/],
preserveSymlinks: true,
}
);
} catch (err) {
Console.error("Could not create package: " + err.message);
return 1;
}
var displayPackageDir =
files.convertToOSPath(files.pathRelative(files.cwd(), packageDir));
var displayPackageDir = files.convertToOSPath(
files.pathRelative(files.cwd(), packageDir)
);
// Since the directory can't have colons, the directory name will often not
// match the name of the package exactly, therefore we should tell people
// where it was created.
Console.info(
packageName + ": created in",
Console.path(displayPackageDir)
);
Console.info(packageName + ": created in", Console.path(displayPackageDir));
return 0;
}
@@ -682,47 +754,33 @@ main.registerCommand({
// (In particular, it's not sufficient to create the new app with
// this version of the tools, and then stamp on the correct release
// at the end.)
if (! release.current.isCheckout() && !release.forced) {
if (release.current.name !== await release.latestKnown()) {
if (!release.current.isCheckout() && !release.forced) {
if (release.current.name !== (await release.latestKnown())) {
throw new main.SpringboardToLatestRelease();
}
}
if (options.list) {
Console.info("Available examples:");
_.each(EXAMPLE_REPOSITORIES, function (repoInfo, name) {
const branchInfo = repoInfo.branch ? `/tree/${repoInfo.branch}` : '';
const [json, err] = await getExamplesJSON()
if (err) {
Console.error("Failed to fetch examples:", err.message);
Console.info("Using cached examples.json");
}
const examples = err ? EXAMPLE_REPOSITORIES : json;
_.each(examples, function (repoInfo, name) {
const branchInfo = repoInfo.branch ? `/tree/${repoInfo.branch}` : "";
Console.info(
Console.command(`${name}: ${repoInfo.repo}${branchInfo}`),
Console.options({ indent: 2 }));
Console.options({ indent: 2 })
);
});
Console.info();
Console.info("To create an example, simply", Console.command("git clone"),
"the relevant repository and branch (run",
Console.command("'meteor create --example <name>'"),
" to see the full command).");
return 0;
};
if (options.example) {
const repoInfo = EXAMPLE_REPOSITORIES[options.example];
if (!repoInfo) {
Console.error(`${options.example}: no such example.`);
Console.error(
"List available applications with",
Console.command("'meteor create --list'") + ".");
return 1;
}
const branchOption = repoInfo.branch ? ` -b ${repoInfo.branch}` : '';
const path = options.args.length === 1 ? ` ${options.args[0]}` : '';
Console.info(`To create the ${options.example} example, please run:`);
Console.info(
Console.command(`git clone ${repoInfo.repo}${branchOption}${path}`),
Console.options({ indent: 2 }));
"To create an example, simply",
Console.command("'meteor create <app-name> --example <name>'")
);
return 0;
}
@@ -736,7 +794,8 @@ main.registerCommand({
if (files.findAppDir(appPath)) {
Console.error(
"You can't create a Meteor project inside another Meteor project.");
"You can't create a Meteor project inside another Meteor project."
);
return 1;
}
@@ -748,48 +807,204 @@ main.registerCommand({
appName = files.pathBasename(appPath);
}
var transform = function (x) {
return x.replace(/~name~/g, appName);
};
// These file extensions are usually metadata, not app code
var nonCodeFileExts = ['.txt', '.md', '.json', '.sh'];
var nonCodeFileExts = [".txt", ".md", ".json", ".sh"];
var destinationHasCodeFiles = false;
// If the directory doesn't exist, it clearly doesn't have any source code
// inside itself
if (files.exists(appPath)) {
destinationHasCodeFiles = _.any(files.readdir(appPath),
function thisPathCountsAsAFile(filePath) {
// We don't mind if there are hidden files or directories (this includes
// .git) and we don't need to check for .meteor here because the command
// will fail earlier
var isHidden = /^\./.test(filePath);
if (isHidden) {
// Not code
return false;
}
destinationHasCodeFiles = _.any(
files.readdir(appPath),
function thisPathCountsAsAFile(filePath) {
// We don't mind if there are hidden files or directories (this includes
// .git) and we don't need to check for .meteor here because the command
// will fail earlier
var isHidden = /^\./.test(filePath);
if (isHidden) {
// Not code
return false;
}
// We do mind if there are non-hidden directories, because we don't want
// to recursively check everything to do some crazy heuristic to see if
// we should try to create an app.
var stats = files.stat(files.pathJoin(appPath, filePath));
if (stats.isDirectory()) {
// Could contain code
// We do mind if there are non-hidden directories, because we don't want
// to recursively check everything to do some crazy heuristic to see if
// we should try to create an app.
var stats = files.stat(files.pathJoin(appPath, filePath));
if (stats.isDirectory()) {
// Could contain code
return true;
}
// Check against our file extension white list
var ext = files.pathExtname(filePath);
if (ext == "" || nonCodeFileExts.includes(ext)) {
return false;
}
// Everything not matched above is considered to be possible source code
return true;
}
// Check against our file extension white list
var ext = files.pathExtname(filePath);
if (ext == '' || nonCodeFileExts.includes(ext)) {
return false;
}
// Everything not matched above is considered to be possible source code
return true;
);
}
function cmd(text) {
Console.info(
Console.command(text),
Console.options({
indent: 2,
})
);
}
// Setup fn, which is called after the app is created, to print a message
// about how to run the app.
async function setup() {
// We are actually working with a new meteor project at this point, so
// set up its context.
var projectContext = new projectContextModule.ProjectContext({
projectDir: appPath,
// Write .meteor/versions even if --release is specified.
alwaysWritePackageMap: true,
// examples come with a .meteor/versions file, but we shouldn't take it
// too seriously
allowIncompatibleUpdate: true,
});
await main.captureAndExit(
"=> Errors while creating your project",
async function () {
await projectContext.readProjectMetadata();
if (buildmessage.jobHasMessages()) {
return;
}
await projectContext.releaseFile.write(
release.current.isCheckout() ? "none" : release.current.name
);
if (buildmessage.jobHasMessages()) {
return;
}
// Also, write package version constraints from the current release
// If we are on a checkout, we don't need to do this as running from
// checkout still pins all package versions and if the user updates
// to a real release, the packages file will subsequently get updated
if (!release.current.isCheckout()) {
projectContext.projectConstraintsFile.updateReleaseConstraints(
release.current._manifest
);
}
// Any upgrader that is in this version of Meteor doesn't need to be run on
// this project.
var upgraders = require("../upgraders.js");
projectContext.finishedUpgraders.appendUpgraders(
upgraders.allUpgraders()
);
await projectContext.prepareProjectForBuild();
}
);
// No need to display the PackageMapDelta here, since it would include all of
// the packages (or maybe an unpredictable subset based on what happens to be
// in the template's versions file).
// Since some of the project skeletons include npm `devDependencies`, we need
// to make sure they're included when running `npm install`.
await require("./default-npm-deps.js").install(appPath, {
includeDevDependencies: true,
});
var appNameToDisplay =
appPathAsEntered === "." ? "current directory" : `'${appPathAsEntered}'`;
var message = `Created a new Meteor app in ${appNameToDisplay}`;
message += ".";
Console.info(message + "\n");
// Print a nice message telling people we created their new app, and what to
// do next.
Console.info("To run your new app:");
if (appPathAsEntered !== ".") {
// Wrap the app path in quotes if it contains spaces
const appPathWithQuotesIfSpaces =
appPathAsEntered.indexOf(" ") === -1
? appPathAsEntered
: `'${appPathAsEntered}'`;
// Don't tell people to 'cd .'
cmd("cd " + appPathWithQuotesIfSpaces);
}
cmd("meteor");
Console.info("");
Console.info(
"If you are new to Meteor, try some of the learning resources here:"
);
Console.info(
Console.url("https://www.meteor.com/tutorials"),
Console.options({ indent: 2 })
);
Console.info("");
Console.info(
"When youre ready to deploy and host your new Meteor application, check out Cloud:"
);
Console.info(
Console.url("https://www.meteor.com/cloud"),
Console.options({ indent: 2 })
);
}
/**
*
* @param {string} url
*/
const setupExampleByURL = async (url) => {
const [ok, err] = await bash`git -v`;
if (err) throw new Error("git is not installed");
await bash`git clone --progress ${url} ${appPath} `;
// remove .git folder from the example
await files.rm_recursive_async(files.pathJoin(appPath, ".git"));
await setup();
};
if (options.example) {
const [json, err] = await getExamplesJSON();
if (err) {
Console.error("Failed to fetch examples:", err.message);
Console.info("Using cached examples.json");
}
const examples = err ? EXAMPLE_REPOSITORIES : json;
const repoInfo = examples[options.example];
if (!repoInfo) {
Console.error(`${options.example}: no such example.`);
Console.error(
"List available applications with",
Console.command("'meteor create --list'") + "."
);
return 1;
}
// repoInfo.repo is the URL of the repo, and repoInfo.branch is the branch
await setupExampleByURL(repoInfo.repo);
return 0;
}
if (options.from) {
await setupExampleByURL(options.from);
return 0;
}
var toIgnore = [/^local$/, /^\.id$/];
@@ -799,153 +1014,97 @@ main.registerCommand({
toIgnore.push(/(\.html|\.js|\.css)/);
}
const skeletonExplicitOption = AVAILABLE_SKELETONS.find(skeleton =>
!!options[skeleton]);
const skeleton = skeletonExplicitOption || DEFAULT_SKELETON;
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,
});
// We are actually working with a new meteor project at this point, so
// set up its context.
var projectContext = new projectContextModule.ProjectContext({
projectDir: appPath,
// Write .meteor/versions even if --release is specified.
alwaysWritePackageMap: true,
// examples come with a .meteor/versions file, but we shouldn't take it
// too seriously
allowIncompatibleUpdate: true
});
await main.captureAndExit("=> Errors while creating your project", async function () {
await projectContext.readProjectMetadata();
if (buildmessage.jobHasMessages()) {
return;
}
await projectContext.releaseFile.write(
release.current.isCheckout() ? "none" : release.current.name);
if (buildmessage.jobHasMessages()) {
return;
}
// Also, write package version constraints from the current release
// If we are on a checkout, we don't need to do this as running from
// checkout still pins all package versions and if the user updates
// to a real release, the packages file will subsequently get updated
if (!release.current.isCheckout()) {
projectContext.projectConstraintsFile
.updateReleaseConstraints(release.current._manifest);
}
// Any upgrader that is in this version of Meteor doesn't need to be run on
// this project.
var upgraders = require('../upgraders.js');
projectContext.finishedUpgraders.appendUpgraders(upgraders.allUpgraders());
await projectContext.prepareProjectForBuild();
});
// No need to display the PackageMapDelta here, since it would include all of
// the packages (or maybe an unpredictable subset based on what happens to be
// in the template's versions file).
// Since some of the project skeletons include npm `devDependencies`, we need
// to make sure they're included when running `npm install`.
await require("./default-npm-deps.js").install(
appPath,
{ includeDevDependencies: true }
const skeletonExplicitOption = AVAILABLE_SKELETONS.find(
(skeleton) => !!options[skeleton]
);
const skeleton = skeletonExplicitOption || DEFAULT_SKELETON;
var appNameToDisplay = appPathAsEntered === "." ?
"current directory" : `'${appPathAsEntered}'`;
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");
var message = `Created a new Meteor app in ${appNameToDisplay}`;
await setupExampleByURL(`https://github.com/meteor/skel-${skeleton}`);
} catch (e) {
if (e.message !== "Using prototype 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);
}
message += ".";
Console.info(message + "\n");
// Print a nice message telling people we created their new app, and what to
// do next.
Console.info("To run your new app:");
function cmd(text) {
Console.info(Console.command(text), Console.options({
indent: 2
}));
// 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 setup();
}
if (appPathAsEntered !== ".") {
// Wrap the app path in quotes if it contains spaces
const appPathWithQuotesIfSpaces = appPathAsEntered.indexOf(' ') === -1 ?
appPathAsEntered :
`'${appPathAsEntered}'`;
// Don't tell people to 'cd .'
cmd("cd " + appPathWithQuotesIfSpaces);
}
cmd("meteor");
Console.info("");
Console.info("If you are new to Meteor, try some of the learning resources here:");
Console.info(
Console.url("https://www.meteor.com/tutorials"),
Console.options({ indent: 2 }));
Console.info("");
Console.info("When youre ready to deploy and host your new Meteor application, check out Cloud:");
Console.info(
Console.url("https://www.meteor.com/cloud"),
Console.options({ indent: 2 }));
if (!!skeletonExplicitOption) {
// Notify people about the skeleton options
Console.info([
"",
"To start with a different app template, try one of the following:",
"",
].join("\n"));
Console.info(
[
"",
"To start with a different app template, try one of the following:",
"",
].join("\n")
);
cmd("meteor create --bare # to create an empty app");
cmd("meteor create --minimal # to create an app with as few Meteor packages as possible");
cmd("meteor create --full # to create a more complete scaffolded app");
cmd(
"meteor create --minimal # to create an app with as few Meteor packages as possible"
);
cmd(
"meteor create --full # to create a more complete scaffolded app"
);
cmd("meteor create --react # to create a basic React-based app");
cmd("meteor create --vue # to create a basic Vue3-based app");
cmd("meteor create --vue-2 # to create a basic Vue2-based app");
cmd("meteor create --apollo # to create a basic Apollo + React app");
cmd("meteor create --svelte # to create a basic Svelte app");
cmd("meteor create --typescript # to create an app using TypeScript and React");
cmd(
"meteor create --typescript # to create an app using TypeScript and React"
);
cmd("meteor create --blaze # to create an app using Blaze");
cmd("meteor create --tailwind # to create an app using React and Tailwind");
cmd(
"meteor create --tailwind # to create an app using React and Tailwind"
);
cmd("meteor create --chakra-ui # to create an app Chakra UI and React");
cmd("meteor create --solid # to create a basic Solid app");
}

View File

@@ -1,26 +1,15 @@
export const EXAMPLE_REPOSITORIES = {
clock: { repo: 'https://github.com/meteor/clock' },
leaderboard: { repo: 'https://github.com/meteor/leaderboard' },
localmarket: { repo: 'https://github.com/meteor/localmarket' },
'simple-todos': { repo: 'https://github.com/meteor/simple-todos' },
'simple-todos-react': {
repo: 'https://github.com/meteor/simple-todos-react'
},
'simple-todos-angular': {
repo: 'https://github.com/meteor/simple-todos-angular'
},
todos: { repo: 'https://github.com/meteor/todos' },
'todos-react': {
'repo': 'https://github.com/meteor/todos',
'branch': 'react',
},
'angular-boilerplate': {
repo: 'https://github.com/Urigo/angular-meteor-base.git'
},
simpletasks: { repo: 'https://github.com/fredmaiaarantes/simpletasks' },
chakraui: { repo: 'https://github.com/meteor/examples/blob/main/chakra-ui' },
tailwindcss: { repo: 'https://github.com/meteor/examples/blob/main/tailwindcss' },
wantch: { repo: 'https://github.com/filipenevola/wantch' },
doubleapp: { repo: 'https://github.com/denihs/double-app/' },
"vue-2": { "repo": "https://github.com/meteor/skel-vue-2" },
"vue": { "repo": "https://github.com/meteor/skel-vue" },
"react": { "repo": "https://github.com/meteor/skel-react" },
"full": { "repo": "https://github.com/meteor/skel-full" },
"bare": { "repo": "https://github.com/meteor/skel-bare" },
"blaze": { "repo": "https://github.com/meteor/skel-blaze" },
"chakra-ui": { "repo": "https://github.com/meteor/skel-chakra-ui" },
"apollo": { "repo": "https://github.com/meteor/skel-apollo" },
"minimal": { "repo": "https://github.com/meteor/skel-minimal" },
"solid": { "repo": "https://github.com/meteor/skel-solid" },
"svelte": { "repo": "https://github.com/meteor/skel-svelte" },
"tailwind": { "repo": "https://github.com/meteor/skel-tailwind" },
"typescript": { "repo": "https://github.com/meteor/skel-typescript" },
};

View File

@@ -152,6 +152,7 @@ Options:
Create a new project.
Usage: meteor create [--release <release>] [--bare|--minimal|--full|--react|--vue|--vue-2|--apollo|--svelte|--blaze|--tailwind|--chakra-ui|--solid] <path>
meteor create [--release <release>] --example <example_name> [<path>]
meteor create [--release <release>] --from <git_url> [<path>]
meteor create --list
meteor create --package [<package_name>]
@@ -178,6 +179,7 @@ currently no package examples.
Options:
--package Create a new meteor package instead of an app.
--example Example template to use.
--from Clones a meteor project from a url.
--list Show list of available examples.
--bare Create an empty app.
--minimal Create an app with as few Meteor packages as possible.
@@ -192,7 +194,7 @@ Options:
--tailwind Create a basic react-based app, with tailwind configured.
--chakra-ui Create a basic react-based app, with chakra-ui configured.
--solid Create a basic solid-based app.
--prototype Create a prototype app with the insecure & autopublish packages. Can be used along with other app commands
--prototype Create a prototype app with the insecure & autopublish packages. Can be used along with other app commands
>>> update

View File

@@ -1,7 +1,7 @@
import { parse } from '@meteorjs/babel';
import { analyze as analyzeScope } from 'escope';
import LRU from "lru-cache";
import { Profile } from '../tool-env/profile';
import Visitor from "@meteorjs/reify/lib/visitor.js";
import { findPossibleIndexes } from "@meteorjs/reify/lib/utils.js";
@@ -26,9 +26,23 @@ function tryToParse(source, hash) {
}
let ast;
try {
ast = parse(source);
Profile.time('jsAnalyze.parse', () => {
ast = parse(source, {
strictMode: false,
sourceType: 'module',
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowUndeclaredExports: true,
plugins: [
// Only plugins for stage 3 features are enabled
// Enabling some plugins significantly affects parser performance
'importAttributes',
'explicitResourceManagement',
'decorators'
]
});
});
} catch (e) {
if (typeof e.loc === 'object') {
e.$ParseError = true;
@@ -71,7 +85,10 @@ export function findImportedModuleIdentifiers(source, hash) {
}
const ast = tryToParse(source, hash);
importedIdentifierVisitor.visit(ast, source, possibleIndexes);
Profile.time('findImportedModuleIdentifiersVisitor', () => {
importedIdentifierVisitor.visit(ast, source, possibleIndexes);
});
return importedIdentifierVisitor.identifiers;
}

View File

@@ -1735,6 +1735,9 @@ Object.assign(exports.FinishedUpgraders.prototype, {
appendUpgraders: function (upgraders) {
var self = this;
/**
* @type {string}
*/
var current = null;
try {
current = files.readFile(self.filename, 'utf8');

View File

@@ -1,5 +1,6 @@
<head>
<title>Apollo Skeleton</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -8,10 +8,10 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@apollo/client": "^3.7.5",
"@apollo/server": "^4.3.2",
"@babel/runtime": "^7.20.13",
"body-parser": "^1.20.1",
"@apollo/client": "^3.7.14",
"@apollo/server": "^4.7.1",
"@babel/runtime": "^7.21.5",
"body-parser": "^1.20.2",
"express": "^4.18.2",
"graphql": "^16.6.0",
"meteor-node-stubs": "^1.2.5",

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>Minimal Meteor app</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,36 +1,37 @@
import { LinksCollection } from "../api/links";
import { createSignal, For } from "solid-js";
import { createSignal, For, Show } from "solid-js";
import { Tracker } from "meteor/tracker";
import { Meteor } from "meteor/meteor";
export const Info = () => {
const loading = Meteor.subscribe("links");
const [isLoading, setIsLoading] = createSignal(loading.ready());
const subscription = Meteor.subscribe("links");
const [isReady, setIsReady] = createSignal(subscription.ready());
const [links, setLinks] = createSignal([]);
Tracker.autorun(() => {
setIsLoading(loading.ready());
setLinks(LinksCollection.find().fetch());
Tracker.autorun(async () => {
setIsReady(subscription.ready());
setLinks(await LinksCollection.find().fetchAsync());
});
if (isLoading()) {
return <div>Loading...</div>;
}
return (
<div>
<h2>Learn Meteor!</h2>
<ul>
<For each={links()}>
{(link) => (
<li>
<a href={link.url} target="_blank">
{link.title}
</a>
</li>
)}
</For>
</ul>
</div>
<Show
when={isReady()}
fallback={<div>Loading...</div>}
>
<div>
<h2>Learn Meteor!</h2>
<ul>
<For each={links()}>
{(link) => (
<li>
<a href={link.url} target="_blank">
{link.title}
</a>
</li>
)}
</For>
</ul>
</div>
</Show>
);
};

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,13 +1,6 @@
<head>
<title>~name~</title>
<meta charset="utf-8"/>
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta
name="viewport"
content="width=device-width, height=device-height, viewport-fit=cover, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,5 +1,6 @@
<head>
<title>~name~</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -1,13 +1,6 @@
<head>
<title>~name~</title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, height=device-height, viewport-fit=cover, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

View File

@@ -46,7 +46,7 @@ selftest.define("create main", async function () {
run = s.run("create", "--list");
await run.read('Available');
await run.match('leaderboard');
await run.match('react');
await run.expectExit(0);
});