Initial Save

This commit is contained in:
jackbeeby
2025-03-28 12:30:19 +11:00
parent e381994f19
commit d8773925e8
9910 changed files with 982718 additions and 0 deletions

14
node_modules/subscriptions-transport-ws/AUTHORS generated vendored Normal file
View File

@@ -0,0 +1,14 @@
Authors
Jonas Helfer <helfer@users.noreply.github.com>
Jonas Helfer <jonas@helfer.email>
Amanda Jin Liu <ajliu72@gmail.com>
Robin Ricard <ricard.robin@gmail.com>
Sashko Stubailo <s.stubailo@gmail.com>
Sashko Stubailo <sashko@stubailo.com>
Hagai Cohen <DxCx@users.noreply.github.com>
Kamil Kisiela <kamil.kisiela@gmail.com>
Francois Valdy <gluck@users.noreply.github.com>
Daniel Rinehart <NeoPhi@users.noreply.github.com>
Lukas Fittl <lfittl@users.noreply.github.com>

232
node_modules/subscriptions-transport-ws/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,232 @@
# Changelog
## v0.10.0 (2021-06-08)
- Same contents as v0.9.19 (published before v0.9.19 before realizing it would be helpful if the new version was picked up by packages looking for `^0.9`).
## v0.9.19 (2021-06-08)
- Bump `ws` dependency to allow v6 and v7. Note that there are breaking changes in `ws` [`6.0.0`](https://github.com/websockets/ws/releases/tag/6.0.0) and [`7.0.0`](https://github.com/websockets/ws/releases/tag/7.0.0); for example, messages over 100MiB are rejected, and (in v7) the behavior of sending messages while the connection is starting or ending has changed. We are publishing this package to allow users of Apollo Server 2 to avoid seeing [this CVE](https://www.npmjs.com/advisories/1748) in their `npm audit`. However, note that (a) this CVE does not affect the subscriptions client, just the server and (b) Apollo Server 3 will remove its superficial integration with this package entirely. We encourage users of Apollo Server 2 to disable the integration with this unmaintained package via `new ApolloServer({subscriptions: false})`, and consider packages such as `graphql-ws` to power GraphQL subscriptions until such time as Apollo Server has more fully integrated subscriptions support.
## v0.9.18 (2020-08-17)
### Bug Fixes
- Do not send GQL_STOP when unsubscribing after GQL_COMPLETE is received. <br/>
[@onhate](https://github.com/onhate) in [#775](https://github.com/apollographql/subscriptions-transport-ws/pull/775)
- Clear WebSocket event listeners on close. <br/>
[@tretne](https://github.com/tretne) in [#615](https://github.com/apollographql/subscriptions-transport-ws/pull/615)
- Fix `MessageTypes` TS import errors. <br/>
[@sneko](https://github.com/sneko) in [#412](https://github.com/apollographql/subscriptions-transport-ws/issues/412)
- Ensure `promisedParams` errors are not handled twice. <br/>
[@benjie](https://github.com/benjie) in [#514](https://github.com/apollographql/subscriptions-transport-ws/pull/514)
- Fix invalid `formatResponse` console error. <br/>
[@renatorib](https://github.com/renatorib) in [#761](https://github.com/apollographql/subscriptions-transport-ws/pull/761)
- Destructure the correct error object in `MessageTypes.GQL_START`. <br/>
[@gregbty](https://github.com/gregbty) in [#588](https://github.com/apollographql/subscriptions-transport-ws/pull/588)
- Inline source in sourcemap files to fix broken source lookups. <br/>
[@alexkirsz](https://github.com/alexkirsz) in [#513](https://github.com/apollographql/subscriptions-transport-ws/pull/513)
### New Features
- Add `minTimeout` option for client. <br/>
[@jedwards1211](https://github.com/jedwards1211) in [#675](https://github.com/apollographql/subscriptions-transport-ws/pull/675)
- Accept extra WebSocket client arguments. <br/>
[@GingerBear](https://github.com/GingerBear) in [#561](https://github.com/apollographql/subscriptions-transport-ws/pull/561)
- Support server-defined payload in GQL_CONNECTION_ACK message. <br/>
[@mattkrick](https://github.com/mattkrick) in [#347](https://github.com/apollographql/subscriptions-transport-ws/pull/347)
## v0.9.17
- Bump `graphql` peer/dev deps. <br/>
[@hwillson](https://github.com/hwillson) in [#778](https://github.com/apollographql/subscriptions-transport-ws/pull/778)
## v0.9.16
- Add ability to set custom WebSocket protocols for client. <br/>
[@pkosiec](https://github.com/pkosiec) in [#477](https://github.com/apollographql/subscriptions-transport-ws/pull/477)
## v0.9.15
- Add support for `graphql` and `@types/graphql` 14. <br/>
[@caiquecastro](https://github.com/caiquecastro) in [#464](https://github.com/apollographql/subscriptions-transport-ws/pull/464)
## v0.9.14
- Allow dynamically specifying/overriding the schema in the object returned from `onOperation` [PR #447](https://github.com/apollographql/subscriptions-transport-ws/pull/447)
## v0.9.13
- Allow connectionParams to be a Promise [PR #443](https://github.com/apollographql/subscriptions-transport-ws/pull/443)
## v0.9.12
- use lightweight lodash alternatives [Issue #430](https://github.com/apollographql/subscriptions-transport-ws/issues/430)
- applies fix suggested by @pandemosth regarding "No subscription is made on reconnect" and "Duplicate subscription made on reconnect" described in [Issue #295](https://github.com/apollographql/subscriptions-transport-ws/issues/295#issuecomment-398184429)
## v0.9.11
- allow using custom WebSocket server implementation [PR #374](https://github.com/apollographql/subscriptions-transport-ws/pull/374)
## v0.9.10
- upgrade ws and eventemitter3
## v0.9.9
- fix issue with @types/graphql@0.13
## v0.9.8
- added `error` event to handle connection errors and debug network troubles [PR #341](https://github.com/apollographql/subscriptions-transport-ws/pull/341).
- added feature inactivityTimeout [PR #390](https://github.com/apollographql/subscriptions-transport-ws/pull/390)
## v0.9.7
- change default timeout from 10s to 30s [PR #368](https://github.com/apollographql/subscriptions-transport-ws/pull/368)
- pass `request` (`upgradeReq`) to `ConnectionContext` [PR #369](https://github.com/apollographql/subscriptions-transport-ws/pull/369)
- pass `ConnectionContext` to `onDisconnect()` as second argument [PR #369](https://github.com/apollographql/subscriptions-transport-ws/pull/369)
## v0.9.6
- fix shallow cloning on contexts which are classes
- upgrade to support graphql 0.13.X
- bump iterall version [PR #362](https://github.com/apollographql/subscriptions-transport-ws/pull/362)
## v0.9.5
- docs(setup): Fix dead link to subscriptions-to-schema
- upgrade to support graphql 0.12.X
## v0.9.4
- fix unhandledRejection error in GQL_START handling if initPromise rejected [PR #310](https://github.com/apollographql/subscriptions-transport-ws/pull/310)
## v0.9.3
- fix unhandledRejection error in GQL_STOP handling if initPromise rejected [PR #309](https://github.com/apollographql/subscriptions-transport-ws/pull/309)
- fix return of init error message to legacy clients [PR #309](https://github.com/apollographql/subscriptions-transport-ws/pull/309)
## v0.9.2
- fix format of keep alive message sent to legacy clients. [PR #297](https://github.com/apollographql/subscriptions-transport-ws/pull/297)
- fix(isPromise): Made checks for promises in server.ts loose to allow for augmented and polyfilled promises. [PR #304](https://github.com/apollographql/subscriptions-transport-ws/pull/304)
## v0.9.1
- docs(KEEP_ALIVE): Updated protocol docs to explain the correct server implementation of `GQL_CONNECTION_INIT`, `GQL_CONNECTION_ACK` and `GQL_CONNECTION_KEEP_ALIVE` [PR #279](https://github.com/apollographql/subscriptions-transport-ws/pull/279)
- docs(language-typos): Update documentation to remove some language typos [PR #282](https://github.com/apollographql/subscriptions-transport-ws/pull/282)
- fix(typescript-2.5.x-typings): Fix a couple of typing changes required by latest typing files with TypeScript 2.5.X. [PR #285](https://github.com/apollographql/subscriptions-transport-ws/pull/285)
- test(NA): fixed run condition on tests for gql_data with errors [PR #289](https://github.com/apollographql/subscriptions-transport-ws/pull/289)
## v0.9.0
- docs(README): Fix example for subscribe and subscribeToMore [PR #273](https://github.com/apollographql/subscriptions-transport-ws/pull/273)
- Add support for GraphQL 0.11.0 [PR #261](https://github.com/apollographql/subscriptions-transport-ws/pull/261)
- **BREAKING CHANGE**: Remove support for Subscription Manager [PR #261](https://github.com/apollographql/subscriptions-transport-ws/pull/261)
- **BREAKING CHANGE**: Remove support for all deprecated API [PR #272](https://github.com/apollographql/subscriptions-transport-ws/pull/272)
## v0.8.3
- docs(README): Fix options example for subscribe methods [PR #266](https://github.com/apollographql/subscriptions-transport-ws/pull/266)
- Gracefully unsubscribe to all pending operations before a requested close by the user [PR #245](https://github.com/apollographql/subscriptions-transport-ws/pull/245)
- Add `close` method to server [PR #257](https://github.com/apollographql/subscriptions-transport-ws/pull/257)
- Bugfix: Observer callbacks should be optional [PR #256](https://github.com/apollographql/subscriptions-transport-ws/pull/256)
## v0.8.2
- Add request interface as a preparation for Apollo 2.0 [PR #242](https://github.com/apollographql/subscriptions-transport-ws/pull/242)
- Add Validation step to server [PR #241](https://github.com/apollographql/subscriptions-transport-ws/pull/241)
- Call operation handler before delete the operation on operation complete [PR #239](https://github.com/apollographql/subscriptions-transport-ws/pull/239)
## v0.8.1
- Send first keep alive message right after the ack [PR #223](https://github.com/apollographql/subscriptions-transport-ws/pull/223)
- Return after first post-install when it should install dev dependencies [PR #218](https://github.com/apollographql/subscriptions-transport-ws/pull/218)
- On installing from branch install dev dependencies only if dist folder isn't found [PR #219](https://github.com/apollographql/subscriptions-transport-ws/pull/219)
## v0.8.0
- Expose opId `onOperationComplete` method [PR #211](https://github.com/apollographql/subscriptions-transport-ws/pull/211)
- Fix to make library able to be installed from a branch [PR #208](https://github.com/apollographql/subscriptions-transport-ws/pull/208)
- Fix for non forced closes (now it wont send connection_terminate) [PR #197](https://github.com/apollographql/subscriptions-transport-ws/pull/197)
- A lot of connection's flow improvements (on connect, on disconnect and on reconnect) [PR #197](https://github.com/apollographql/subscriptions-transport-ws/pull/197)
- Require specific lodash/assign module instead of entire package, so memory impact is reduced [PR #196](https://github.com/apollographql/subscriptions-transport-ws/pull/196)
- docs(README): Fix onEvent(eventName, callback, thisContext) list of eventName [PR #205](https://github.com/apollographql/subscriptions-transport-ws/pull/205)
## v0.7.3
- Fix for first subscription is never unsubscribed [PR #179](https://github.com/apollographql/subscriptions-transport-ws/pull/179)
## v0.7.2
- Increase default keep-alive timeout to 30s [PR #177](https://github.com/apollographql/subscriptions-transport-ws/pull/177)
- Operation key is now `string` instead of `number` [PR #176](https://github.com/apollographql/subscriptions-transport-ws/pull/176)
## v0.7.1
- Fix for reconnect after manual close [PR #164](https://github.com/apollographql/subscriptions-transport-ws/pull/164)
- test(disconnect): added tests for client-server flow for unsubscribe and disconnect [PR #163](https://github.com/apollographql/subscriptions-transport-ws/pull/163)
- Various dependencies updates [PR #152](https://github.com/apollographql/subscriptions-transport-ws/pull/152) [PR #162](https://github.com/apollographql/subscriptions-transport-ws/pull/162)
- docs(README): fix docs [PR #151](https://github.com/apollographql/subscriptions-transport-ws/pull/151)
## v0.7.0
- Client exposes new asyncronous middleware to modify `OperationOptions` [PR #78](https://github.com/apollographql/subscriptions-transport-ws/pull/78)
- Added `WebSocketServer` error handler to prevent uncaught exceptions. Fixes [Issue #94](https://github.com/apollographql/subscriptions-transport-ws/issues/94)
- Updated `ws` dependency to the lastest.
- Introduce lazy mode for connection, and accept function as `connectionParams` [PR #131](https://github.com/apollographql/subscriptions-transport-ws/pull/131)
- Extend transport protocol to support GraphQL queries and mutations over WebSocket [PR #108](https://github.com/apollographql/subscriptions-transport-ws/pull/108)
- Added built-in support for `subscribe` from `graphql-js` [PR #133](https://github.com/apollographql/subscriptions-transport-ws/pull/133)
- Fixed infinity reconnects when server accepts connections but its in an error state. [PR #135](https://github.com/apollographql/subscriptions-transport-ws/pull/135)
- Force close client-side socket when using `close()`, and ignore reconnect logic. [PR #137](https://github.com/apollographql/subscriptions-transport-ws/pull/137)
- Added new connection events to give a more accurate control over the connection state [PR #139](https://github.com/apollographql/subscriptions-transport-ws/pull/139). Fixes [Issue #136](https://github.com/apollographql/subscriptions-transport-ws/issues/136).
- Replaced `Object.assign` by `lodash.assign` to extend browser support [PR #144](https://github.com/apollographql/subscriptions-transport-ws/pull/144). Fixes [Issue #141](https://github.com/apollographql/subscriptions-transport-ws/issues/141)
## v0.6.0
- Enabled Greenkeeper and updated dependencies, includes major version bump of ws [PR #90](https://github.com/apollographql/subscriptions-transport-ws/pull/90)
## v0.6.0
- Protocol update to support queries, mutations and also subscriptions. [PR #108](https://github.com/apollographql/subscriptions-transport-ws/pull/108)
- Added support in the server for GraphQL Executor. [PR #108](https://github.com/apollographql/subscriptions-transport-ws/pull/108)
- Added support in the server executor for `graphql-js subscribe`. [PR #846](https://github.com/graphql/graphql-js/pull/846)
## v0.5.5
- Remove dependency on `graphql-tag/printer` per [graphql-tag#54](https://github.com/apollographql/graphql-tag/issues/54) [PR #98](https://github.com/apollographql/subscriptions-transport-ws/pull/98)
## v0.5.4
- Ensure INIT is sent before SUBSCRIPTION_START even when client reconnects [PR #85](https://github.com/apollographql/subscriptions-transport-ws/pull/85)
- Allow data and errors in payload of SUBSCRIPTION_DATA [PR #84](https://github.com/apollographql/subscriptions-transport-ws/pull/84)
- Expose `index.js` as entrypoint for server/NodeJS application to allow NodeJS clients to use `SubscriptionClient` [PR #91](https://github.com/apollographql/subscriptions-transport-ws/pull/91)
- Fixed a bug with missing error message on `INIT_FAIL` message [#88](https://github.com/apollographql/subscriptions-transport-ws/issues/88)
## v0.5.3
- Fixed a bug with `browser` declaration on package.json ([Issue #79](https://github.com/apollographql/subscriptions-transport-ws/issues/79))
## v0.5.2
- Updated dependencies versions
- Fixed typings issue with missing `index.d.ts` file. [PR #73](https://github.com/apollographql/subscriptions-transport-ws/pull/73)
- Transpiling client.js to target browsers using webpack. [PR #77](https://github.com/apollographql/subscriptions-transport-ws/pull/77)
## v0.5.1
- Only attempt reconnect on closed connection. Fixes [Issue #70](https://github.com/apollographql/subscriptions-transport-ws/issues/70)
## v0.5.0
- Updated `graphql-subscriptions@0.3.0`.
- Added `addGraphQLSubscriptions` - use it to extend your network interface to work with `SubscriptionsClient` instance. [PR #64](https://github.com/apollographql/subscriptions-transport-ws/pull/64)
- Client now uses native WebSocket by default, and has optional field to provide another implementation (for NodeJS clients)[PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
- Client now support INIT with custom object, so you can use if for authorization, or any other init params. [PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
- Server and client are now separated with `browser` and `main` fields of `package.json`. [PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
- Client exposes workflow events for connect, disconnect and reconnect. [PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
- Server exposes new events: `onUnsubscribe`, `onSubscribe`, `onConnect` and `onDisconnect`. [PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
- Use `ws` package on server side, and expose it's options from server constructor. [PR #53](https://github.com/apollographql/subscriptions-transport-ws/pull/53)
## v0.4.0
- Don't throw in the server on certain unsub messages.
[PR #54](https://github.com/apollostack/subscriptions-transport-ws/pull/54)
- Moved typings to `@types/graphql`.
[PR #60](https://github.com/apollostack/subscriptions-transport-ws/pull/60)
## v0.3.1
- Server now passes back subscriptionManager errors encountered during publish.
[PR #42](https://github.com/apollostack/subscriptions-transport-ws/pull/42)
## v0.3.0
- (SEMVER-MINOR) Bump graphql-subscriptions dependency to ^0.2.0 which changes the setupFunctions format
- Fix missing unsubscription from first (id = 0) subscription
## v0.2.6
- Add `reconnect` and `reconnectionAttempts` options to the constructor which will enable reconnection with exponential backoff.
## v0.2.5
- Pass WebSocketRequest to onSubscribe to support reading HTTP headers when creating a subscription
## v0.2.4
- Server reports back an error on an unparsable client message
- Server reports back an error on an unsupported client message type
- Fix intermittent failure in timeout test case
- Standardize server and client errors handling to always create an array of errors with a message property

View File

@@ -0,0 +1,82 @@
# Apollo Contributor Guide
Excited about Apollo and want to make it better? Were excited too!
Apollo is a community of developers just like you, striving to create the best tools and libraries around GraphQL. We welcome anyone who wants to contribute or provide constructive feedback, no matter the age or level of experience. If you want to help but don't know where to start, let us know, and we'll find something for you.
Oh, and if you haven't already, sign up for the [Apollo Slack](http://www.apollodata.com/#slack).
Here are some ways to contribute to the project, from easiest to most difficult:
* [Reporting bugs](#reporting-bugs)
* [Improving the documentation](#improving-the-documentation)
* [Responding to issues](#responding-to-issues)
* [Small bug fixes](#small-bug-fixes)
* [Suggesting features](#suggesting-features)
* [Big pull requests](#big-prs)
## Issues
### Reporting bugs
If you encounter a bug, please file an issue on GitHub via the repository of the sub-project you think contains the bug. If an issue you have is already reported, please add additional information or add a 👍 reaction to indicate your agreement.
While we will try to be as helpful as we can on any issue reported, please include the following to maximize the chances of a quick fix:
1. **Intended outcome:** What you were trying to accomplish when the bug occurred, and as much code as possible related to the source of the problem.
2. **Actual outcome:** A description of what actually happened, including a screenshot or copy-paste of any related error messages, logs, or other output that might be related. Places to look for information include your browser console, server console, and network logs. Please avoid non-specific phrases like “didnt work” or “broke”.
3. **How to reproduce the issue:** Instructions for how the issue can be reproduced by a maintainer or contributor. Be as specific as possible, and only mention what is necessary to reproduce the bug. If possible, try to isolate the exact circumstances in which the bug occurs and avoid speculation over what the cause might be.
Creating a good reproduction really helps contributors investigate and resolve your issue quickly. In many cases, the act of creating a minimal reproduction illuminates that the source of the bug was somewhere outside the library in question, saving time and effort for everyone.
### Improving the documentation
Improving the documentation, examples, and other open source content can be the easiest way to contribute to the library. If you see a piece of content that can be better, open a PR with an improvement, no matter how small! If you would like to suggest a big change or major rewrite, wed love to hear your ideas but please open an issue for discussion before writing the PR.
### Responding to issues
In addition to reporting issues, a great way to contribute to Apollo is to respond to other peoples' issues and try to identify the problem or help them work around it. If youre interested in taking a more active role in this process, please go ahead and respond to issues. And don't forget to say "Hi" on Apollo Slack!
### Small bug fixes
For a small bug fix change (less than 20 lines of code changed), feel free to open a pull request. Well try to merge it as fast as possible and ideally publish a new release on the same day. The only requirement is, make sure you also add a test that verifies the bug you are trying to fix.
### Suggesting features
Most of the features in Apollo came from suggestions by you, the community! We welcome any ideas about how to make Apollo better for your use case. Unless there is overwhelming demand for a feature, it might not get implemented immediately, but please include as much information as possible that will help people have a discussion about your proposal:
1. **Use case:** What are you trying to accomplish, in specific terms? Often, there might already be a good way to do what you need and a new feature is unnecessary, but its hard to know without information about the specific use case.
2. **Could this be a plugin?** In many cases, a feature might be too niche to be included in the core of a library, and is better implemented as a companion package. If there isnt a way to extend the library to do what you want, could we add additional plugin APIs? Its important to make the case for why a feature should be part of the core functionality of the library.
3. **Is there a workaround?** Is this a more convenient way to do something that is already possible, or is there some blocker that makes a workaround unfeasible?
Feature requests will be labeled as such, and we encourage using GitHub issues as a place to discuss new features and possible implementation designs. Please refrain from submitting a pull request to implement a proposed feature until there is consensus that it should be included. This way, you can avoid putting in work that cant be merged in.
Once there is a consensus on the need for a new feature, proceed as listed below under “Big PRs”.
## Big PRs
This includes:
- Big bug fixes
- New features
For significant changes to a repository, its important to settle on a design before starting on the implementation. This way, we can make sure that major improvements get the care and attention they deserve. Since big changes can be risky and might not always get merged, its good to reduce the amount of possible wasted effort by agreeing on an implementation design/plan first.
1. **Open an issue.** Open an issue about your bug or feature, as described above.
2. **Reach consensus.** Some contributors and community members should reach an agreement that this feature or bug is important, and that someone should work on implementing or fixing it.
3. **Agree on intended behavior.** On the issue, reach an agreement about the desired behavior. In the case of a bug fix, it should be clear what it means for the bug to be fixed, and in the case of a feature, it should be clear what it will be like for developers to use the new feature.
4. **Agree on implementation plan.** Write a plan for how this feature or bug fix should be implemented. What modules need to be added or rewritten? Should this be one pull request or multiple incremental improvements? Who is going to do each part?
5. **Submit PR.** In the case where multiple dependent patches need to be made to implement the change, only submit one at a time. Otherwise, the others might get stale while the first is reviewed and merged. Make sure to avoid “while were here” type changes - if something isnt relevant to the improvement at hand, it should be in a separate PR; this especially includes code style changes of unrelated code.
6. **Review.** At least one core contributor should sign off on the change before its merged. Look at the “code review” section below to learn about factors are important in the code review. If you want to expedite the code being merged, try to review your own code first!
7. **Merge and release!**
### Code review guidelines
Its important that every piece of code in Apollo packages is reviewed by at least one core contributor familiar with that codebase. Here are some things we look for:
1. **Required CI checks pass.** This is a prerequisite for the review, and it is the PR author's responsibility. As long as the tests dont pass, the PR won't get reviewed.
2. **Simplicity.** Is this the simplest way to achieve the intended goal? If there are too many files, redundant functions, or complex lines of code, suggest a simpler way to do the same thing. In particular, avoid implementing an overly general solution when a simple, small, and pragmatic fix will do.
3. **Testing.** Do the tests ensure this code wont break when other stuff changes around it? When it does break, will the tests added help us identify which part of the library has the problem? Did we cover an appropriate set of edge cases? Look at the test coverage report if there is one. Are all significant code paths in the new code exercised at least once?
4. **No unnecessary or unrelated changes.** PRs shouldnt come with random formatting changes, especially in unrelated parts of the code. If there is some refactoring that needs to be done, it should be in a separate PR from a bug fix or feature, if possible.
5. **Code has appropriate comments.** Code should be commented, or written in a clear “self-documenting” way.
6. **Idiomatic use of the language.** In TypeScript, make sure the typings are specific and correct. In ES2015, make sure to use imports rather than require and const instead of var, etc. Ideally a linter enforces a lot of this, but use your common sense and follow the style of the surrounding code.

22
node_modules/subscriptions-transport-ws/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 - 2016 Meteor Development Group, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

110
node_modules/subscriptions-transport-ws/PROTOCOL.md generated vendored Normal file
View File

@@ -0,0 +1,110 @@
# GraphQL over WebSocket Protocol
## Client-server communication
Each message has a `type` field, which defined in the protocol of this package, as well as associated fields inside `payload` field, depending on the message type, and `id` field so the client can identify each response from the server.
Each WebSocket message is represented in JSON structure, and being stringified before sending it over the network.
This is the structure of each message:
```typescript
export interface OperationMessage {
payload?: any;
id?: string;
type: string;
}
```
### Client -> Server
#### GQL_CONNECTION_INIT
Client sends this message after plain websocket connection to start the communication with the server
The server will response only with `GQL_CONNECTION_ACK` + `GQL_CONNECTION_KEEP_ALIVE` (if used) or `GQL_CONNECTION_ERROR` to this message.
- `payload: Object` : optional parameters that the client specifies in `connectionParams`
#### GQL_START
Client sends this message to execute GraphQL operation
- `id: string` : The id of the GraphQL operation to start
- `payload: Object`:
* `query: string` : GraphQL operation as string or parsed GraphQL document node
* `variables?: Object` : Object with GraphQL variables
* `operationName?: string` : GraphQL operation name
#### GQL_STOP
Client sends this message in order to stop a running GraphQL operation execution (for example: unsubscribe)
- `id: string` : operation id
#### GQL_CONNECTION_TERMINATE
Client sends this message to terminate the connection.
### Server -> Client
#### GQL_CONNECTION_ERROR
The server may responses with this message to the `GQL_CONNECTION_INIT` from client, indicates the server rejected the connection.
It server also respond with this message in case of a parsing errors of the message (which does not disconnect the client, just ignore the message).
- `payload: Object`: the server side error
#### GQL_CONNECTION_ACK
The server may responses with this message to the `GQL_CONNECTION_INIT` from client, indicates the server accepted the connection.
May optionally include a payload.
#### GQL_DATA
The server sends this message to transfter the GraphQL execution result from the server to the client, this message is a response for `GQL_START` message.
For each GraphQL operation send with `GQL_START`, the server will respond with at least one `GQL_DATA` message.
- `id: string` : ID of the operation that was successfully set up
- `payload: Object` :
* `data: any`: Execution result
* `errors?: Error[]` : Array of resolvers errors
#### GQL_ERROR
Server sends this message upon a failing operation, before the GraphQL execution, usually due to GraphQL validation errors (resolver errors are part of `GQL_DATA` message, and will be added as `errors` array)
- `payload: Error` : payload with the error attributed to the operation failing on the server
- `id: string` : operation ID of the operation that failed on the server
#### GQL_COMPLETE
Server sends this message to indicate that a GraphQL operation is done, and no more data will arrive for the specific operation.
- `id: string` : operation ID of the operation that completed
#### GQL_CONNECTION_KEEP_ALIVE
Server message that should be sent right after each `GQL_CONNECTION_ACK` processed and then periodically to keep the client connection alive.
The client starts to consider the keep alive message only upon the first received keep alive message from the server.
### Messages Flow
This is a demonstration of client-server communication, in order to get a better understanding of the protocol flow:
#### Session Init Phase
The phase initializes the connection between the client and server, and usually will also build the server-side `context` for the execution.
- Client connected immediately, or stops and wait if using lazy mode (until first operation execution)
- Client sends `GQL_CONNECTION_INIT` message to the server.
- Server calls `onConnect` callback with the init arguments, waits for init to finish and returns it's return value with `GQL_CONNECTION_ACK` + `GQL_CONNECTION_KEEP_ALIVE` (if used), or `GQL_CONNECTION_ERROR` in case of `false` or thrown exception from `onConnect` callback.
- Client gets `GQL_CONNECTION_ACK` + `GQL_CONNECTION_KEEP_ALIVE` (if used) and waits for the client's app to create subscriptions.
#### Connected Phase
This phase called per each operation the client request to execute:
- App creates a subscription using `subscribe` or `query` client's API, and the `GQL_START` message sent to the server.
- Server calls `onOperation` callback, and responds with `GQL_DATA` in case of zero errors, or `GQL_ERROR` if there is a problem with the operation (is might also return `GQL_ERROR` with `errors` array, in case of resolvers errors).
- Client get `GQL_DATA` and handles it.
- Server calls `onOperationDone` if the operation is a query or mutation (for subscriptions, this called when unsubscribing)
- Server sends `GQL_COMPLETE` if the operation is a query or mutation (for subscriptions, this sent when unsubscribing)
For subscriptions:
- App triggers `PubSub`'s publication method, and the server publishes the event, passing it through the `subscribe` executor to create GraphQL execution result
- Client receives `GQL_DATA` with the data, and handles it.
- When client unsubscribe, the server triggers `onOperationDone` and sends `GQL_COMPLETE` message to the client.
When client done with executing GraphQL, it should close the connection and terminate the session using `GQL_CONNECTION_TERMINATE` message.

335
node_modules/subscriptions-transport-ws/README.md generated vendored Normal file
View File

@@ -0,0 +1,335 @@
# graphql-ws
The `subscriptions-transport-ws` library is not being actively maintained. It is recommended that you use the [graphql-ws](https://github.com/enisdenjo/graphql-ws) library instead. For details read the [GraphQL over WebSockets](https://the-guild.dev/blog/graphql-over-websockets) announcement.
# subscriptions-transport-ws
[![npm version](https://badge.fury.io/js/subscriptions-transport-ws.svg)](https://badge.fury.io/js/subscriptions-transport-ws) [![GitHub license](https://img.shields.io/github/license/apollostack/subscriptions-transport-ws.svg)](https://github.com/apollostack/subscriptions-transport-ws/blob/license/LICENSE)
**(Work in progress!)**
A GraphQL WebSocket server and client to facilitate GraphQL queries, mutations and subscriptions over WebSocket.
> `subscriptions-transport-ws` is an extension for GraphQL, and you can use it with any GraphQL client and server (not only Apollo).
See [GitHunt-API](https://github.com/apollostack/GitHunt-API) and [GitHunt-React](https://github.com/apollostack/GitHunt-React) for an example server and client integration.
# Getting Started
Start by installing the package, using Yarn or NPM.
Using Yarn:
$ yarn add subscriptions-transport-ws
Or, using NPM:
$ npm install --save subscriptions-transport-ws
> Note that you need to use this package on both GraphQL client and server.
> This command also installs this package's dependencies, including `graphql-subscriptions`.
## Server
Starting with the server, create a new simple `PubSub` instance. We will later use this `PubSub` to publish and subscribe to data changes.
```js
import { PubSub } from 'graphql-subscriptions';
export const pubsub = new PubSub();
```
Now, create `SubscriptionServer` instance, with your GraphQL `schema`, `execute` and `subscribe` (from `graphql-js` package):
```js
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { execute, subscribe } from 'graphql';
import { schema } from './my-schema';
const WS_PORT = 5000;
// Create WebSocket listener server
const websocketServer = createServer((request, response) => {
response.writeHead(404);
response.end();
});
// Bind it to port and start listening
websocketServer.listen(WS_PORT, () => console.log(
`Websocket Server is now running on http://localhost:${WS_PORT}`
));
const subscriptionServer = SubscriptionServer.create(
{
schema,
execute,
subscribe,
},
{
server: websocketServer,
path: '/graphql',
},
);
```
### Creating Your Subscriptions
Please refer to [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) documentation for how to create your GraphQL subscriptions, and how to publish data.
## Client (browser)
When using this package for client side, you can choose either use HTTP request for Queries and Mutation and use the WebSocket for subscriptions only, or create a full transport that handles all type of GraphQL operations over the socket.
### Full WebSocket Transport
To start with a full WebSocket transport, that handles all types of GraphQL operations, import and create an instance of `SubscriptionClient`.
Then, create your `ApolloClient` instance and use the `SubscriptionsClient` instance as network interface:
```js
import { SubscriptionClient } from 'subscriptions-transport-ws';
import ApolloClient from 'apollo-client';
const GRAPHQL_ENDPOINT = 'ws://localhost:3000/graphql';
const client = new SubscriptionClient(GRAPHQL_ENDPOINT, {
reconnect: true,
});
const apolloClient = new ApolloClient({
networkInterface: client,
});
```
### Hybrid WebSocket Transport
To start with a hybrid WebSocket transport, that handles only `subscription`s over WebSocket, create your `SubscriptionClient` and a regular HTTP network interface, then extend your network interface to use the WebSocket client for GraphQL subscriptions:
```js
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws';
import ApolloClient, {createNetworkInterface} from 'apollo-client';
// Create regular NetworkInterface by using apollo-client's API:
const networkInterface = createNetworkInterface({
uri: 'http://localhost:3000' // Your GraphQL endpoint
});
// Create WebSocket client
const wsClient = new SubscriptionClient(`ws://localhost:5000/`, {
reconnect: true,
connectionParams: {
// Pass any arguments you want for initialization
}
});
// Extend the network interface with the WebSocket
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient
);
// Finally, create your ApolloClient instance with the modified network interface
const apolloClient = new ApolloClient({
networkInterface: networkInterfaceWithSubscriptions
});
```
Now, when you want to use subscriptions in client side, use your `ApolloClient` instance, with [`subscribe`](https://www.apollographql.com/docs/react/api/apollo-client#ApolloClient.subscribe) or `query` [`subscribeToMore`](https://www.apollographql.com/docs/react/api/apollo-client#ObservableQuery.subscribeToMore):
```js
apolloClient.subscribe({
query: gql`
subscription onNewItem {
newItemCreated {
id
}
}`,
variables: {}
}).subscribe({
next (data) {
// Notify your application with the new arrived data
}
});
```
```js
apolloClient.query({
query: ITEM_LIST_QUERY,
variables: {}
}).subscribeToMore({
document: gql`
subscription onNewItem {
newItemCreated {
id
}
}`,
variables: {},
updateQuery: (prev, { subscriptionData, variables }) => {
// Perform updates on previousResult with subscriptionData
return updatedResult;
}
});
```
If you don't use any package/modules loader, you can still use this package, by using `unpkg` service, and get the client side package from:
```
https://unpkg.com/subscriptions-transport-ws@VERSION/browser/client.js
```
> Replace VERSION with the latest version of the package.
## Use it with GraphiQL
You can use this package's power with GraphiQL, and subscribe to live-data stream inside GraphiQL.
If you are using the latest version of `graphql-server` flavors (`graphql-server-express`, `graphql-server-koa`, etc...), you already can use it! Make sure to specify `subscriptionsEndpoint` in GraphiQL configuration, and that's it!
For example, `graphql-server-express` users need to add the following:
```js
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: `YOUR_SUBSCRIPTION_ENDPOINT_HERE`,
}));
```
If you are using older version, or another GraphQL server, start by modifying GraphiQL static HTML, and add this package and it's fetcher from CDN:
```html
<script src="//unpkg.com/subscriptions-transport-ws@0.5.4/browser/client.js"></script>
<script src="//unpkg.com/graphiql-subscriptions-fetcher@0.0.2/browser/client.js"></script>
```
Then, create `SubscriptionClient` and define the fetcher:
```js
let subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient('SUBSCRIPTION_WS_URL_HERE', {
reconnect: true
});
let myCustomFetcher = window.GraphiQLSubscriptionsFetcher.graphQLFetcher(subscriptionsClient, graphQLFetcher);
```
> `graphQLFetcher` is the default fetcher, and we use it as fallback for non-subscription GraphQL operations.
And replace your GraphiQL creation logic to use the new fetcher:
```js
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: myCustomFetcher, // <-- here
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName,
query: ${safeSerialize(queryString)},
response: ${safeSerialize(resultString)},
variables: ${safeSerialize(variablesString)},
operationName: ${safeSerialize(operationName)},
}),
document.body
);
```
# API Docs
## SubscriptionClient
### `Constructor(url, options, webSocketImpl)`
- `url: string` : url that the client will connect to, starts with `ws://` or `wss://`
- `options?: Object` : optional, object to modify default client behavior
* `timeout?: number` : how long the client should wait in ms for a keep-alive message from the server (default 30000 ms), this parameter is ignored if the server does not send keep-alive messages. This will also be used to calculate the max connection time per connect/reconnect
* `minTimeout?: number`: the minimum amount of time the client should wait for a connection to be made (default 1000 ms)
* `lazy?: boolean` : use to set lazy mode - connects only when first subscription created, and delay the socket initialization
* `connectionParams?: Object | Function | Promise<Object>` : object that will be available as first argument of `onConnect` (in server side), if passed a function - it will call it and send the return value, if function returns as promise - it will wait until it resolves and send the resolved value.
* `reconnect?: boolean` : automatic reconnect in case of connection error
* `reconnectionAttempts?: number` : how much reconnect attempts
* `connectionCallback?: (error) => {}` : optional, callback that called after the first init message, with the error (if there is one)
* `inactivityTimeout?: number` : how long the client should wait in ms, when there are no active subscriptions, before disconnecting from the server. Set to 0 to disable this behavior. (default 0)
- `webSocketImpl?: Object` - optional, constructor for W3C compliant WebSocket implementation. Use this when your environment does not have a built-in native WebSocket (for example, with NodeJS client)
### Methods
#### `request(options) => Observable<ExecutionResult>`: returns observable to execute the operation.
- `options: {OperationOptions}`
* `query: string` : GraphQL subscription
* `variables: Object` : GraphQL subscription variables
* `operationName: string` : operation name of the subscription
* `context: Object` : use to override context for a specific call
#### `unsubscribeAll() => void` - unsubscribes from all active subscriptions.
#### `on(eventName, callback, thisContext) => Function`
- `eventName: string`: the name of the event, available events are: `connecting`, `connected`, `reconnecting`, `reconnected`, `disconnected` and `error`
- `callback: Function`: function to be called when websocket connects and initialized.
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onConnected(callback, thisContext) => Function` - shorthand for `.on('connected', ...)`
- `callback: Function(payload)`: function to be called when websocket connects and initialized, after ACK message returned from the server. Includes payload from server, if any.
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onReconnected(callback, thisContext) => Function` - shorthand for `.on('reconnected', ...)`
- `callback: Function(payload)`: function to be called when websocket reconnects and initialized, after ACK message returned from the server. Includes payload from server, if any.
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onConnecting(callback, thisContext) => Function` - shorthand for `.on('connecting', ...)`
- `callback: Function`: function to be called when websocket starts it's connection
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onReconnecting(callback, thisContext) => Function` - shorthand for `.on('reconnecting', ...)`
- `callback: Function`: function to be called when websocket starts it's reconnection
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onDisconnected(callback, thisContext) => Function` - shorthand for `.on('disconnected', ...)`
- `callback: Function`: function to be called when websocket disconnected.
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
#### `onError(callback, thisContext) => Function` - shorthand for `.on('error', ...)`
- `callback: Function`: function to be called when an error occurs.
- `thisContext: any`: `this` context to use when calling the callback function.
- => Returns an `off` method to cancel the event subscription.
### `close() => void` - closes the WebSocket connection manually, and ignores `reconnect` logic if it was set to `true`.
### `use(middlewares: MiddlewareInterface[]) => SubscriptionClient` - adds middleware to modify `OperationOptions` per each request
- `middlewares: MiddlewareInterface[]` - Array contains list of middlewares (implemented `applyMiddleware` method) implementation, the `SubscriptionClient` will use the middlewares to modify `OperationOptions` for every operation
### `status: number` : returns the current socket's `readyState`
## SubscriptionServer
### `Constructor(options, socketOptions | socketServer)`
- `options: {ServerOptions}`
* `rootValue?: any` : Root value to use when executing GraphQL root operations
* `schema?: GraphQLSchema` : GraphQL schema object. If not provided, you have to return the schema as a property on the object returned from `onOperation`.
* `execute?: (schema, document, rootValue, contextValue, variableValues, operationName) => Promise<ExecutionResult> | AsyncIterator<ExecutionResult>` : GraphQL `execute` function, provide the default one from `graphql` package. Return value of `AsyncItrator` is also valid since this package also support reactive `execute` methods.
* `subscribe?: (schema, document, rootValue, contextValue, variableValues, operationName) => Promise<ExecutionResult | AsyncIterator<ExecutionResult>>` : GraphQL `subscribe` function, provide the default one from `graphql` package.
* `onOperation?: (message: SubscribeMessage, params: ExecutionParams, webSocket: WebSocket)` : optional method to create custom params that will be used when resolving this operation. It can also be used to dynamically resolve the schema that will be used for the particular operation.
* `onOperationComplete?: (webSocket: WebSocket, opId: string)` : optional method that called when a GraphQL operation is done (for query and mutation it's immediately, and for subscriptions when unsubscribing)
* `onConnect?: (connectionParams: Object, webSocket: WebSocket, context: ConnectionContext)` : optional method that called when a client connects to the socket, called with the `connectionParams` from the client, if the return value is an object, its elements will be added to the context. return `false` or throw an exception to reject the connection. May return a Promise.
* `onDisconnect?: (webSocket: WebSocket, context: ConnectionContext)` : optional method that called when a client disconnects
* `keepAlive?: number` : optional interval in ms to send `KEEPALIVE` messages to all clients
- `socketOptions: {WebSocket.IServerOptions}` : options to pass to the WebSocket object (full docs [here](https://github.com/websockets/ws/blob/master/doc/ws.md))
* `server?: HttpServer` - existing HTTP server to use (use without `host`/`port`)
* `host?: string` - server host
* `port?: number` - server port
* `path?: string` - endpoint path
- `socketServer: {WebSocket.Server}` : a configured server if you need more control. Can be used for integration testing with in-memory WebSocket implementation.
## How it works?
* For GraphQL WebSocket protocol docs, [click here](https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md)
* This package also uses `AsyncIterator` internally using [iterall](https://github.com/leebyron/iterall), for more information [click here](https://github.com/ReactiveX/IxJS), or [the proposal](https://github.com/tc39/proposal-async-iteration)
The current version of this transport, also support a previous version of the protocol.
[You can find the old protocol docs here](https://github.com/apollographql/subscriptions-transport-ws/blob/cacb8692f3601344a4101d802443d046d73f8b23/README.md#client-server-communication)

2617
node_modules/subscriptions-transport-ws/browser/client.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
import { ListenerFn } from 'eventemitter3';
import { ExecutionResult } from 'graphql/execution/execute';
import { DocumentNode } from 'graphql/language/ast';
export interface Observer<T> {
next?: (value: T) => void;
error?: (error: Error) => void;
complete?: () => void;
}
export interface Observable<T> {
subscribe(observer: Observer<T>): {
unsubscribe: () => void;
};
}
export interface OperationOptions {
query?: string | DocumentNode;
variables?: Object;
operationName?: string;
[key: string]: any;
}
export declare type FormatedError = Error & {
originalError?: any;
};
export interface Operation {
options: OperationOptions;
handler: (error: Error[], result?: any) => void;
}
export interface Operations {
[id: string]: Operation;
}
export interface Middleware {
applyMiddleware(options: OperationOptions, next: Function): void;
}
export declare type ConnectionParams = {
[paramName: string]: any;
};
export declare type ConnectionParamsOptions = ConnectionParams | Function | Promise<ConnectionParams>;
export interface ClientOptions {
connectionParams?: ConnectionParamsOptions;
minTimeout?: number;
timeout?: number;
reconnect?: boolean;
reconnectionAttempts?: number;
connectionCallback?: (error: Error[], result?: any) => void;
lazy?: boolean;
inactivityTimeout?: number;
wsOptionArguments?: any[];
}
export declare class SubscriptionClient {
client: any;
operations: Operations;
private url;
private nextOperationId;
private connectionParams;
private minWsTimeout;
private wsTimeout;
private unsentMessagesQueue;
private reconnect;
private reconnecting;
private reconnectionAttempts;
private backoff;
private connectionCallback;
private eventEmitter;
private lazy;
private inactivityTimeout;
private inactivityTimeoutId;
private closedByUser;
private wsImpl;
private wsProtocols;
private wasKeepAliveReceived;
private tryReconnectTimeoutId;
private checkConnectionIntervalId;
private maxConnectTimeoutId;
private middlewares;
private maxConnectTimeGenerator;
private wsOptionArguments;
constructor(url: string, options?: ClientOptions, webSocketImpl?: any, webSocketProtocols?: string | string[]);
get status(): any;
close(isForced?: boolean, closedByUser?: boolean): void;
request(request: OperationOptions): Observable<ExecutionResult>;
on(eventName: string, callback: ListenerFn, context?: any): Function;
onConnected(callback: ListenerFn, context?: any): Function;
onConnecting(callback: ListenerFn, context?: any): Function;
onDisconnected(callback: ListenerFn, context?: any): Function;
onReconnected(callback: ListenerFn, context?: any): Function;
onReconnecting(callback: ListenerFn, context?: any): Function;
onError(callback: ListenerFn, context?: any): Function;
unsubscribeAll(): void;
applyMiddlewares(options: OperationOptions): Promise<OperationOptions>;
use(middlewares: Middleware[]): SubscriptionClient;
private getConnectionParams;
private executeOperation;
private getObserver;
private createMaxConnectTimeGenerator;
private clearCheckConnectionInterval;
private clearMaxConnectTimeout;
private clearTryReconnectTimeout;
private clearInactivityTimeout;
private setInactivityTimeout;
private checkOperationOptions;
private buildMessage;
private formatErrors;
private sendMessage;
private sendMessageRaw;
private generateOperationId;
private tryReconnect;
private flushUnsentMessagesQueue;
private checkConnection;
private checkMaxConnectTimeout;
private connect;
private processReceivedData;
private unsubscribe;
}

560
node_modules/subscriptions-transport-ws/dist/client.js generated vendored Normal file
View File

@@ -0,0 +1,560 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubscriptionClient = void 0;
var _global = typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : {});
var NativeWebSocket = _global.WebSocket || _global.MozWebSocket;
var Backoff = require("backo2");
var eventemitter3_1 = require("eventemitter3");
var is_string_1 = require("./utils/is-string");
var is_object_1 = require("./utils/is-object");
var printer_1 = require("graphql/language/printer");
var getOperationAST_1 = require("graphql/utilities/getOperationAST");
var symbol_observable_1 = require("symbol-observable");
var protocol_1 = require("./protocol");
var defaults_1 = require("./defaults");
var message_types_1 = require("./message-types");
var SubscriptionClient = (function () {
function SubscriptionClient(url, options, webSocketImpl, webSocketProtocols) {
var _a = (options || {}), _b = _a.connectionCallback, connectionCallback = _b === void 0 ? undefined : _b, _c = _a.connectionParams, connectionParams = _c === void 0 ? {} : _c, _d = _a.minTimeout, minTimeout = _d === void 0 ? defaults_1.MIN_WS_TIMEOUT : _d, _e = _a.timeout, timeout = _e === void 0 ? defaults_1.WS_TIMEOUT : _e, _f = _a.reconnect, reconnect = _f === void 0 ? false : _f, _g = _a.reconnectionAttempts, reconnectionAttempts = _g === void 0 ? Infinity : _g, _h = _a.lazy, lazy = _h === void 0 ? false : _h, _j = _a.inactivityTimeout, inactivityTimeout = _j === void 0 ? 0 : _j, _k = _a.wsOptionArguments, wsOptionArguments = _k === void 0 ? [] : _k;
this.wsImpl = webSocketImpl || NativeWebSocket;
if (!this.wsImpl) {
throw new Error('Unable to find native implementation, or alternative implementation for WebSocket!');
}
this.wsProtocols = webSocketProtocols || protocol_1.GRAPHQL_WS;
this.connectionCallback = connectionCallback;
this.url = url;
this.operations = {};
this.nextOperationId = 0;
this.minWsTimeout = minTimeout;
this.wsTimeout = timeout;
this.unsentMessagesQueue = [];
this.reconnect = reconnect;
this.reconnecting = false;
this.reconnectionAttempts = reconnectionAttempts;
this.lazy = !!lazy;
this.inactivityTimeout = inactivityTimeout;
this.closedByUser = false;
this.backoff = new Backoff({ jitter: 0.5 });
this.eventEmitter = new eventemitter3_1.EventEmitter();
this.middlewares = [];
this.client = null;
this.maxConnectTimeGenerator = this.createMaxConnectTimeGenerator();
this.connectionParams = this.getConnectionParams(connectionParams);
this.wsOptionArguments = wsOptionArguments;
if (!this.lazy) {
this.connect();
}
}
Object.defineProperty(SubscriptionClient.prototype, "status", {
get: function () {
if (this.client === null) {
return this.wsImpl.CLOSED;
}
return this.client.readyState;
},
enumerable: false,
configurable: true
});
SubscriptionClient.prototype.close = function (isForced, closedByUser) {
if (isForced === void 0) { isForced = true; }
if (closedByUser === void 0) { closedByUser = true; }
this.clearInactivityTimeout();
if (this.client !== null) {
this.closedByUser = closedByUser;
if (isForced) {
this.clearCheckConnectionInterval();
this.clearMaxConnectTimeout();
this.clearTryReconnectTimeout();
this.unsubscribeAll();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_TERMINATE, null);
}
this.client.close();
this.client.onopen = null;
this.client.onclose = null;
this.client.onerror = null;
this.client.onmessage = null;
this.client = null;
this.eventEmitter.emit('disconnected');
if (!isForced) {
this.tryReconnect();
}
}
};
SubscriptionClient.prototype.request = function (request) {
var _a;
var getObserver = this.getObserver.bind(this);
var executeOperation = this.executeOperation.bind(this);
var unsubscribe = this.unsubscribe.bind(this);
var opId;
this.clearInactivityTimeout();
return _a = {},
_a[symbol_observable_1.default] = function () {
return this;
},
_a.subscribe = function (observerOrNext, onError, onComplete) {
var observer = getObserver(observerOrNext, onError, onComplete);
opId = executeOperation(request, function (error, result) {
if (error === null && result === null) {
if (observer.complete) {
observer.complete();
}
}
else if (error) {
if (observer.error) {
observer.error(error[0]);
}
}
else {
if (observer.next) {
observer.next(result);
}
}
});
return {
unsubscribe: function () {
if (opId) {
unsubscribe(opId);
opId = null;
}
},
};
},
_a;
};
SubscriptionClient.prototype.on = function (eventName, callback, context) {
var handler = this.eventEmitter.on(eventName, callback, context);
return function () {
handler.off(eventName, callback, context);
};
};
SubscriptionClient.prototype.onConnected = function (callback, context) {
return this.on('connected', callback, context);
};
SubscriptionClient.prototype.onConnecting = function (callback, context) {
return this.on('connecting', callback, context);
};
SubscriptionClient.prototype.onDisconnected = function (callback, context) {
return this.on('disconnected', callback, context);
};
SubscriptionClient.prototype.onReconnected = function (callback, context) {
return this.on('reconnected', callback, context);
};
SubscriptionClient.prototype.onReconnecting = function (callback, context) {
return this.on('reconnecting', callback, context);
};
SubscriptionClient.prototype.onError = function (callback, context) {
return this.on('error', callback, context);
};
SubscriptionClient.prototype.unsubscribeAll = function () {
var _this = this;
Object.keys(this.operations).forEach(function (subId) {
_this.unsubscribe(subId);
});
};
SubscriptionClient.prototype.applyMiddlewares = function (options) {
var _this = this;
return new Promise(function (resolve, reject) {
var queue = function (funcs, scope) {
var next = function (error) {
if (error) {
reject(error);
}
else {
if (funcs.length > 0) {
var f = funcs.shift();
if (f) {
f.applyMiddleware.apply(scope, [options, next]);
}
}
else {
resolve(options);
}
}
};
next();
};
queue(__spreadArrays(_this.middlewares), _this);
});
};
SubscriptionClient.prototype.use = function (middlewares) {
var _this = this;
middlewares.map(function (middleware) {
if (typeof middleware.applyMiddleware === 'function') {
_this.middlewares.push(middleware);
}
else {
throw new Error('Middleware must implement the applyMiddleware function.');
}
});
return this;
};
SubscriptionClient.prototype.getConnectionParams = function (connectionParams) {
return function () { return new Promise(function (resolve, reject) {
if (typeof connectionParams === 'function') {
try {
return resolve(connectionParams.call(null));
}
catch (error) {
return reject(error);
}
}
resolve(connectionParams);
}); };
};
SubscriptionClient.prototype.executeOperation = function (options, handler) {
var _this = this;
if (this.client === null) {
this.connect();
}
var opId = this.generateOperationId();
this.operations[opId] = { options: options, handler: handler };
this.applyMiddlewares(options)
.then(function (processedOptions) {
_this.checkOperationOptions(processedOptions, handler);
if (_this.operations[opId]) {
_this.operations[opId] = { options: processedOptions, handler: handler };
_this.sendMessage(opId, message_types_1.default.GQL_START, processedOptions);
}
})
.catch(function (error) {
_this.unsubscribe(opId);
handler(_this.formatErrors(error));
});
return opId;
};
SubscriptionClient.prototype.getObserver = function (observerOrNext, error, complete) {
if (typeof observerOrNext === 'function') {
return {
next: function (v) { return observerOrNext(v); },
error: function (e) { return error && error(e); },
complete: function () { return complete && complete(); },
};
}
return observerOrNext;
};
SubscriptionClient.prototype.createMaxConnectTimeGenerator = function () {
var minValue = this.minWsTimeout;
var maxValue = this.wsTimeout;
return new Backoff({
min: minValue,
max: maxValue,
factor: 1.2,
});
};
SubscriptionClient.prototype.clearCheckConnectionInterval = function () {
if (this.checkConnectionIntervalId) {
clearInterval(this.checkConnectionIntervalId);
this.checkConnectionIntervalId = null;
}
};
SubscriptionClient.prototype.clearMaxConnectTimeout = function () {
if (this.maxConnectTimeoutId) {
clearTimeout(this.maxConnectTimeoutId);
this.maxConnectTimeoutId = null;
}
};
SubscriptionClient.prototype.clearTryReconnectTimeout = function () {
if (this.tryReconnectTimeoutId) {
clearTimeout(this.tryReconnectTimeoutId);
this.tryReconnectTimeoutId = null;
}
};
SubscriptionClient.prototype.clearInactivityTimeout = function () {
if (this.inactivityTimeoutId) {
clearTimeout(this.inactivityTimeoutId);
this.inactivityTimeoutId = null;
}
};
SubscriptionClient.prototype.setInactivityTimeout = function () {
var _this = this;
if (this.inactivityTimeout > 0 && Object.keys(this.operations).length === 0) {
this.inactivityTimeoutId = setTimeout(function () {
if (Object.keys(_this.operations).length === 0) {
_this.close();
}
}, this.inactivityTimeout);
}
};
SubscriptionClient.prototype.checkOperationOptions = function (options, handler) {
var query = options.query, variables = options.variables, operationName = options.operationName;
if (!query) {
throw new Error('Must provide a query.');
}
if (!handler) {
throw new Error('Must provide an handler.');
}
if ((!is_string_1.default(query) && !getOperationAST_1.getOperationAST(query, operationName)) ||
(operationName && !is_string_1.default(operationName)) ||
(variables && !is_object_1.default(variables))) {
throw new Error('Incorrect option types. query must be a string or a document,' +
'`operationName` must be a string, and `variables` must be an object.');
}
};
SubscriptionClient.prototype.buildMessage = function (id, type, payload) {
var payloadToReturn = payload && payload.query ? __assign(__assign({}, payload), { query: typeof payload.query === 'string' ? payload.query : printer_1.print(payload.query) }) :
payload;
return {
id: id,
type: type,
payload: payloadToReturn,
};
};
SubscriptionClient.prototype.formatErrors = function (errors) {
if (Array.isArray(errors)) {
return errors;
}
if (errors && errors.errors) {
return this.formatErrors(errors.errors);
}
if (errors && errors.message) {
return [errors];
}
return [{
name: 'FormatedError',
message: 'Unknown error',
originalError: errors,
}];
};
SubscriptionClient.prototype.sendMessage = function (id, type, payload) {
this.sendMessageRaw(this.buildMessage(id, type, payload));
};
SubscriptionClient.prototype.sendMessageRaw = function (message) {
switch (this.status) {
case this.wsImpl.OPEN:
var serializedMessage = JSON.stringify(message);
try {
JSON.parse(serializedMessage);
}
catch (e) {
this.eventEmitter.emit('error', new Error("Message must be JSON-serializable. Got: " + message));
}
this.client.send(serializedMessage);
break;
case this.wsImpl.CONNECTING:
this.unsentMessagesQueue.push(message);
break;
default:
if (!this.reconnecting) {
this.eventEmitter.emit('error', new Error('A message was not sent because socket is not connected, is closing or ' +
'is already closed. Message was: ' + JSON.stringify(message)));
}
}
};
SubscriptionClient.prototype.generateOperationId = function () {
return String(++this.nextOperationId);
};
SubscriptionClient.prototype.tryReconnect = function () {
var _this = this;
if (!this.reconnect || this.backoff.attempts >= this.reconnectionAttempts) {
return;
}
if (!this.reconnecting) {
Object.keys(this.operations).forEach(function (key) {
_this.unsentMessagesQueue.push(_this.buildMessage(key, message_types_1.default.GQL_START, _this.operations[key].options));
});
this.reconnecting = true;
}
this.clearTryReconnectTimeout();
var delay = this.backoff.duration();
this.tryReconnectTimeoutId = setTimeout(function () {
_this.connect();
}, delay);
};
SubscriptionClient.prototype.flushUnsentMessagesQueue = function () {
var _this = this;
this.unsentMessagesQueue.forEach(function (message) {
_this.sendMessageRaw(message);
});
this.unsentMessagesQueue = [];
};
SubscriptionClient.prototype.checkConnection = function () {
if (this.wasKeepAliveReceived) {
this.wasKeepAliveReceived = false;
return;
}
if (!this.reconnecting) {
this.close(false, true);
}
};
SubscriptionClient.prototype.checkMaxConnectTimeout = function () {
var _this = this;
this.clearMaxConnectTimeout();
this.maxConnectTimeoutId = setTimeout(function () {
if (_this.status !== _this.wsImpl.OPEN) {
_this.reconnecting = true;
_this.close(false, true);
}
}, this.maxConnectTimeGenerator.duration());
};
SubscriptionClient.prototype.connect = function () {
var _a;
var _this = this;
this.client = new ((_a = this.wsImpl).bind.apply(_a, __spreadArrays([void 0, this.url, this.wsProtocols], this.wsOptionArguments)))();
this.checkMaxConnectTimeout();
this.client.onopen = function () { return __awaiter(_this, void 0, void 0, function () {
var connectionParams, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.status === this.wsImpl.OPEN)) return [3, 4];
this.clearMaxConnectTimeout();
this.closedByUser = false;
this.eventEmitter.emit(this.reconnecting ? 'reconnecting' : 'connecting');
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.connectionParams()];
case 2:
connectionParams = _a.sent();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_INIT, connectionParams);
this.flushUnsentMessagesQueue();
return [3, 4];
case 3:
error_1 = _a.sent();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_ERROR, error_1);
this.flushUnsentMessagesQueue();
return [3, 4];
case 4: return [2];
}
});
}); };
this.client.onclose = function () {
if (!_this.closedByUser) {
_this.close(false, false);
}
};
this.client.onerror = function (err) {
_this.eventEmitter.emit('error', err);
};
this.client.onmessage = function (_a) {
var data = _a.data;
_this.processReceivedData(data);
};
};
SubscriptionClient.prototype.processReceivedData = function (receivedData) {
var parsedMessage;
var opId;
try {
parsedMessage = JSON.parse(receivedData);
opId = parsedMessage.id;
}
catch (e) {
throw new Error("Message must be JSON-parseable. Got: " + receivedData);
}
if ([message_types_1.default.GQL_DATA,
message_types_1.default.GQL_COMPLETE,
message_types_1.default.GQL_ERROR,
].indexOf(parsedMessage.type) !== -1 && !this.operations[opId]) {
this.unsubscribe(opId);
return;
}
switch (parsedMessage.type) {
case message_types_1.default.GQL_CONNECTION_ERROR:
if (this.connectionCallback) {
this.connectionCallback(parsedMessage.payload);
}
break;
case message_types_1.default.GQL_CONNECTION_ACK:
this.eventEmitter.emit(this.reconnecting ? 'reconnected' : 'connected', parsedMessage.payload);
this.reconnecting = false;
this.backoff.reset();
this.maxConnectTimeGenerator.reset();
if (this.connectionCallback) {
this.connectionCallback();
}
break;
case message_types_1.default.GQL_COMPLETE:
var handler = this.operations[opId].handler;
delete this.operations[opId];
handler.call(this, null, null);
break;
case message_types_1.default.GQL_ERROR:
this.operations[opId].handler(this.formatErrors(parsedMessage.payload), null);
delete this.operations[opId];
break;
case message_types_1.default.GQL_DATA:
var parsedPayload = !parsedMessage.payload.errors ?
parsedMessage.payload : __assign(__assign({}, parsedMessage.payload), { errors: this.formatErrors(parsedMessage.payload.errors) });
this.operations[opId].handler(null, parsedPayload);
break;
case message_types_1.default.GQL_CONNECTION_KEEP_ALIVE:
var firstKA = typeof this.wasKeepAliveReceived === 'undefined';
this.wasKeepAliveReceived = true;
if (firstKA) {
this.checkConnection();
}
if (this.checkConnectionIntervalId) {
clearInterval(this.checkConnectionIntervalId);
this.checkConnection();
}
this.checkConnectionIntervalId = setInterval(this.checkConnection.bind(this), this.wsTimeout);
break;
default:
throw new Error('Invalid message type!');
}
};
SubscriptionClient.prototype.unsubscribe = function (opId) {
if (this.operations[opId]) {
delete this.operations[opId];
this.setInactivityTimeout();
this.sendMessage(opId, message_types_1.default.GQL_STOP, undefined);
}
};
return SubscriptionClient;
}());
exports.SubscriptionClient = SubscriptionClient;
//# sourceMappingURL=client.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
declare const MIN_WS_TIMEOUT = 1000;
declare const WS_TIMEOUT = 30000;
export { MIN_WS_TIMEOUT, WS_TIMEOUT, };

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WS_TIMEOUT = exports.MIN_WS_TIMEOUT = void 0;
var MIN_WS_TIMEOUT = 1000;
exports.MIN_WS_TIMEOUT = MIN_WS_TIMEOUT;
var WS_TIMEOUT = 30000;
exports.WS_TIMEOUT = WS_TIMEOUT;
//# sourceMappingURL=defaults.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":";;;AAAA,IAAM,cAAc,GAAG,IAAI,CAAC;AAI1B,wCAAc;AAHhB,IAAM,UAAU,GAAG,KAAK,CAAC;AAIvB,gCAAU","sourcesContent":["const MIN_WS_TIMEOUT = 1000;\nconst WS_TIMEOUT = 30000;\n\nexport {\n MIN_WS_TIMEOUT,\n WS_TIMEOUT,\n};\n"]}

View File

@@ -0,0 +1,4 @@
export * from './client';
export * from './server';
export { default as MessageTypes } from './message-types';
export * from './protocol';

18
node_modules/subscriptions-transport-ws/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./client"), exports);
__exportStar(require("./server"), exports);
var message_types_1 = require("./message-types");
Object.defineProperty(exports, "MessageTypes", { enumerable: true, get: function () { return message_types_1.default; } });
__exportStar(require("./protocol"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAyB;AACzB,2CAAyB;AACzB,iDAA0D;AAAjD,6GAAA,OAAO,OAAgB;AAChC,6CAA2B","sourcesContent":["export * from './client';\nexport * from './server';\nexport { default as MessageTypes } from './message-types';\nexport * from './protocol';\n"]}

View File

@@ -0,0 +1,2 @@
import { ConnectionContext } from '../server';
export declare const parseLegacyProtocolMessage: (connectionContext: ConnectionContext, message: any) => any;

View File

@@ -0,0 +1,72 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseLegacyProtocolMessage = void 0;
var message_types_1 = require("../message-types");
exports.parseLegacyProtocolMessage = function (connectionContext, message) {
var messageToReturn = message;
switch (message.type) {
case message_types_1.default.INIT:
connectionContext.isLegacy = true;
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.GQL_CONNECTION_INIT });
break;
case message_types_1.default.SUBSCRIPTION_START:
messageToReturn = {
id: message.id,
type: message_types_1.default.GQL_START,
payload: {
query: message.query,
operationName: message.operationName,
variables: message.variables,
},
};
break;
case message_types_1.default.SUBSCRIPTION_END:
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.GQL_STOP });
break;
case message_types_1.default.GQL_CONNECTION_ACK:
if (connectionContext.isLegacy) {
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.INIT_SUCCESS });
}
break;
case message_types_1.default.GQL_CONNECTION_ERROR:
if (connectionContext.isLegacy) {
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.INIT_FAIL, payload: message.payload.message ? { error: message.payload.message } : message.payload });
}
break;
case message_types_1.default.GQL_ERROR:
if (connectionContext.isLegacy) {
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.SUBSCRIPTION_FAIL });
}
break;
case message_types_1.default.GQL_DATA:
if (connectionContext.isLegacy) {
messageToReturn = __assign(__assign({}, message), { type: message_types_1.default.SUBSCRIPTION_DATA });
}
break;
case message_types_1.default.GQL_COMPLETE:
if (connectionContext.isLegacy) {
messageToReturn = null;
}
break;
case message_types_1.default.SUBSCRIPTION_SUCCESS:
if (!connectionContext.isLegacy) {
messageToReturn = null;
}
break;
default:
break;
}
return messageToReturn;
};
//# sourceMappingURL=parse-legacy-protocol.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parse-legacy-protocol.js","sourceRoot":"","sources":["../../src/legacy/parse-legacy-protocol.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,kDAA4C;AAE/B,QAAA,0BAA0B,GAAG,UAAC,iBAAoC,EAAE,OAAY;IAC3F,IAAI,eAAe,GAAG,OAAO,CAAC;IAE9B,QAAQ,OAAO,CAAC,IAAI,EAAE;QACpB,KAAK,uBAAY,CAAC,IAAI;YACpB,iBAAiB,CAAC,QAAQ,GAAG,IAAI,CAAC;YAClC,eAAe,yBAAQ,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,mBAAmB,GAAE,CAAC;YACzE,MAAM;QACR,KAAK,uBAAY,CAAC,kBAAkB;YAClC,eAAe,GAAG;gBAChB,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,IAAI,EAAE,uBAAY,CAAC,SAAS;gBAC5B,OAAO,EAAE;oBACP,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B;aACF,CAAC;YACF,MAAM;QACR,KAAK,uBAAY,CAAC,gBAAgB;YAChC,eAAe,yBAAQ,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,QAAQ,GAAE,CAAC;YAC9D,MAAM;QACR,KAAK,uBAAY,CAAC,kBAAkB;YAClC,IAAI,iBAAiB,CAAC,QAAQ,EAAE;gBAC9B,eAAe,yBAAQ,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,YAAY,GAAE,CAAC;aACnE;YACD,MAAM;QACR,KAAK,uBAAY,CAAC,oBAAoB;YACpC,IAAI,iBAAiB,CAAC,QAAQ,EAAE;gBAC9B,eAAe,yBACV,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,SAAS,EACxC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,GACxF,CAAC;aACH;YACD,MAAM;QACR,KAAK,uBAAY,CAAC,SAAS;YACzB,IAAI,iBAAiB,CAAC,QAAQ,EAAE;gBAC9B,eAAe,yBAAQ,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,iBAAiB,GAAE,CAAC;aACxE;YACD,MAAM;QACR,KAAK,uBAAY,CAAC,QAAQ;YACxB,IAAI,iBAAiB,CAAC,QAAQ,EAAE;gBAC9B,eAAe,yBAAQ,OAAO,KAAE,IAAI,EAAE,uBAAY,CAAC,iBAAiB,GAAE,CAAC;aACxE;YACD,MAAM;QACR,KAAK,uBAAY,CAAC,YAAY;YAC5B,IAAI,iBAAiB,CAAC,QAAQ,EAAE;gBAC9B,eAAe,GAAG,IAAI,CAAC;aACxB;YACD,MAAM;QACR,KAAK,uBAAY,CAAC,oBAAoB;YACpC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE;gBAC/B,eAAe,GAAG,IAAI,CAAC;aACxB;YACD,MAAM;QACR;YACE,MAAM;KACT;IAED,OAAO,eAAe,CAAC;AACzB,CAAC,CAAC","sourcesContent":["import { ConnectionContext } from '../server';\nimport MessageTypes from '../message-types';\n\nexport const parseLegacyProtocolMessage = (connectionContext: ConnectionContext, message: any) => {\n let messageToReturn = message;\n\n switch (message.type) {\n case MessageTypes.INIT:\n connectionContext.isLegacy = true;\n messageToReturn = { ...message, type: MessageTypes.GQL_CONNECTION_INIT };\n break;\n case MessageTypes.SUBSCRIPTION_START:\n messageToReturn = {\n id: message.id,\n type: MessageTypes.GQL_START,\n payload: {\n query: message.query,\n operationName: message.operationName,\n variables: message.variables,\n },\n };\n break;\n case MessageTypes.SUBSCRIPTION_END:\n messageToReturn = { ...message, type: MessageTypes.GQL_STOP };\n break;\n case MessageTypes.GQL_CONNECTION_ACK:\n if (connectionContext.isLegacy) {\n messageToReturn = { ...message, type: MessageTypes.INIT_SUCCESS };\n }\n break;\n case MessageTypes.GQL_CONNECTION_ERROR:\n if (connectionContext.isLegacy) {\n messageToReturn = {\n ...message, type: MessageTypes.INIT_FAIL,\n payload: message.payload.message ? { error: message.payload.message } : message.payload,\n };\n }\n break;\n case MessageTypes.GQL_ERROR:\n if (connectionContext.isLegacy) {\n messageToReturn = { ...message, type: MessageTypes.SUBSCRIPTION_FAIL };\n }\n break;\n case MessageTypes.GQL_DATA:\n if (connectionContext.isLegacy) {\n messageToReturn = { ...message, type: MessageTypes.SUBSCRIPTION_DATA };\n }\n break;\n case MessageTypes.GQL_COMPLETE:\n if (connectionContext.isLegacy) {\n messageToReturn = null;\n }\n break;\n case MessageTypes.SUBSCRIPTION_SUCCESS:\n if (!connectionContext.isLegacy) {\n messageToReturn = null;\n }\n break;\n default:\n break;\n }\n\n return messageToReturn;\n};\n"]}

View File

@@ -0,0 +1,22 @@
export default class MessageTypes {
static GQL_CONNECTION_INIT: string;
static GQL_CONNECTION_ACK: string;
static GQL_CONNECTION_ERROR: string;
static GQL_CONNECTION_KEEP_ALIVE: string;
static GQL_CONNECTION_TERMINATE: string;
static GQL_START: string;
static GQL_DATA: string;
static GQL_ERROR: string;
static GQL_COMPLETE: string;
static GQL_STOP: string;
static SUBSCRIPTION_START: string;
static SUBSCRIPTION_DATA: string;
static SUBSCRIPTION_SUCCESS: string;
static SUBSCRIPTION_FAIL: string;
static SUBSCRIPTION_END: string;
static INIT: string;
static INIT_SUCCESS: string;
static INIT_FAIL: string;
static KEEP_ALIVE: string;
constructor();
}

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MessageTypes = (function () {
function MessageTypes() {
throw new Error('Static Class');
}
MessageTypes.GQL_CONNECTION_INIT = 'connection_init';
MessageTypes.GQL_CONNECTION_ACK = 'connection_ack';
MessageTypes.GQL_CONNECTION_ERROR = 'connection_error';
MessageTypes.GQL_CONNECTION_KEEP_ALIVE = 'ka';
MessageTypes.GQL_CONNECTION_TERMINATE = 'connection_terminate';
MessageTypes.GQL_START = 'start';
MessageTypes.GQL_DATA = 'data';
MessageTypes.GQL_ERROR = 'error';
MessageTypes.GQL_COMPLETE = 'complete';
MessageTypes.GQL_STOP = 'stop';
MessageTypes.SUBSCRIPTION_START = 'subscription_start';
MessageTypes.SUBSCRIPTION_DATA = 'subscription_data';
MessageTypes.SUBSCRIPTION_SUCCESS = 'subscription_success';
MessageTypes.SUBSCRIPTION_FAIL = 'subscription_fail';
MessageTypes.SUBSCRIPTION_END = 'subscription_end';
MessageTypes.INIT = 'init';
MessageTypes.INIT_SUCCESS = 'init_success';
MessageTypes.INIT_FAIL = 'init_fail';
MessageTypes.KEEP_ALIVE = 'keepalive';
return MessageTypes;
}());
exports.default = MessageTypes;
//# sourceMappingURL=message-types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"message-types.js","sourceRoot":"","sources":["../src/message-types.ts"],"names":[],"mappings":";;AAAA;IAqDE;QACE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;IAtDa,gCAAmB,GAAG,iBAAiB,CAAC;IACxC,+BAAkB,GAAG,gBAAgB,CAAC;IACtC,iCAAoB,GAAG,kBAAkB,CAAC;IAG1C,sCAAyB,GAAG,IAAI,CAAC;IAEjC,qCAAwB,GAAG,sBAAsB,CAAC;IAClD,sBAAS,GAAG,OAAO,CAAC;IACpB,qBAAQ,GAAG,MAAM,CAAC;IAClB,sBAAS,GAAG,OAAO,CAAC;IACpB,yBAAY,GAAG,UAAU,CAAC;IAC1B,qBAAQ,GAAG,MAAM,CAAC;IAMlB,+BAAkB,GAAG,oBAAoB,CAAC;IAI1C,8BAAiB,GAAG,mBAAmB,CAAC;IAIxC,iCAAoB,GAAG,sBAAsB,CAAC;IAI9C,8BAAiB,GAAG,mBAAmB,CAAC;IAIxC,6BAAgB,GAAG,kBAAkB,CAAC;IAItC,iBAAI,GAAG,MAAM,CAAC;IAId,yBAAY,GAAG,cAAc,CAAC;IAI9B,sBAAS,GAAG,WAAW,CAAC;IAIxB,uBAAU,GAAG,WAAW,CAAC;IAKzC,mBAAC;CAAA,AAxDD,IAwDC;kBAxDoB,YAAY","sourcesContent":["export default class MessageTypes {\n public static GQL_CONNECTION_INIT = 'connection_init'; // Client -> Server\n public static GQL_CONNECTION_ACK = 'connection_ack'; // Server -> Client\n public static GQL_CONNECTION_ERROR = 'connection_error'; // Server -> Client\n\n // NOTE: The keep alive message type does not follow the standard due to connection optimizations\n public static GQL_CONNECTION_KEEP_ALIVE = 'ka'; // Server -> Client\n\n public static GQL_CONNECTION_TERMINATE = 'connection_terminate'; // Client -> Server\n public static GQL_START = 'start'; // Client -> Server\n public static GQL_DATA = 'data'; // Server -> Client\n public static GQL_ERROR = 'error'; // Server -> Client\n public static GQL_COMPLETE = 'complete'; // Server -> Client\n public static GQL_STOP = 'stop'; // Client -> Server\n\n // NOTE: The following message types are deprecated and will be removed soon.\n /**\n * @deprecated\n */\n public static SUBSCRIPTION_START = 'subscription_start';\n /**\n * @deprecated\n */\n public static SUBSCRIPTION_DATA = 'subscription_data';\n /**\n * @deprecated\n */\n public static SUBSCRIPTION_SUCCESS = 'subscription_success';\n /**\n * @deprecated\n */\n public static SUBSCRIPTION_FAIL = 'subscription_fail';\n /**\n * @deprecated\n */\n public static SUBSCRIPTION_END = 'subscription_end';\n /**\n * @deprecated\n */\n public static INIT = 'init';\n /**\n * @deprecated\n */\n public static INIT_SUCCESS = 'init_success';\n /**\n * @deprecated\n */\n public static INIT_FAIL = 'init_fail';\n /**\n * @deprecated\n */\n public static KEEP_ALIVE = 'keepalive';\n\n constructor() {\n throw new Error('Static Class');\n }\n}\n"]}

View File

@@ -0,0 +1,3 @@
declare const GRAPHQL_WS = "graphql-ws";
declare const GRAPHQL_SUBSCRIPTIONS = "graphql-subscriptions";
export { GRAPHQL_WS, GRAPHQL_SUBSCRIPTIONS, };

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GRAPHQL_SUBSCRIPTIONS = exports.GRAPHQL_WS = void 0;
var GRAPHQL_WS = 'graphql-ws';
exports.GRAPHQL_WS = GRAPHQL_WS;
var GRAPHQL_SUBSCRIPTIONS = 'graphql-subscriptions';
exports.GRAPHQL_SUBSCRIPTIONS = GRAPHQL_SUBSCRIPTIONS;
//# sourceMappingURL=protocol.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";;;AAAA,IAAM,UAAU,GAAG,YAAY,CAAC;AAQ9B,gCAAU;AAHZ,IAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAIpD,sDAAqB","sourcesContent":["const GRAPHQL_WS = 'graphql-ws';\n// NOTE: This protocol is deprecated and will be removed soon.\n/**\n * @deprecated\n */\nconst GRAPHQL_SUBSCRIPTIONS = 'graphql-subscriptions';\n\nexport {\n GRAPHQL_WS,\n GRAPHQL_SUBSCRIPTIONS,\n};\n"]}

View File

@@ -0,0 +1,82 @@
/// <reference types="node" />
import * as WebSocket from 'ws';
import { ExecutionResult, GraphQLSchema, DocumentNode, ValidationContext, GraphQLFieldResolver } from 'graphql';
import { IncomingMessage } from 'http';
export declare type ExecutionIterator = AsyncIterator<ExecutionResult>;
export interface ExecutionParams<TContext = any> {
query: string | DocumentNode;
variables: {
[key: string]: any;
};
operationName: string;
context: TContext;
formatResponse?: Function;
formatError?: Function;
callback?: Function;
schema?: GraphQLSchema;
}
export declare type ConnectionContext = {
initPromise?: Promise<any>;
isLegacy: boolean;
socket: WebSocket;
request: IncomingMessage;
operations: {
[opId: string]: ExecutionIterator;
};
};
export interface OperationMessagePayload {
[key: string]: any;
query?: string;
variables?: {
[key: string]: any;
};
operationName?: string;
}
export interface OperationMessage {
payload?: OperationMessagePayload;
id?: string;
type: string;
}
export declare type ExecuteFunction = (schema: GraphQLSchema, document: DocumentNode, rootValue?: any, contextValue?: any, variableValues?: {
[key: string]: any;
}, operationName?: string, fieldResolver?: GraphQLFieldResolver<any, any>) => ExecutionResult | Promise<ExecutionResult> | AsyncIterator<ExecutionResult>;
export declare type SubscribeFunction = (schema: GraphQLSchema, document: DocumentNode, rootValue?: any, contextValue?: any, variableValues?: {
[key: string]: any;
}, operationName?: string, fieldResolver?: GraphQLFieldResolver<any, any>, subscribeFieldResolver?: GraphQLFieldResolver<any, any>) => AsyncIterator<ExecutionResult> | Promise<AsyncIterator<ExecutionResult> | ExecutionResult>;
export interface ServerOptions {
rootValue?: any;
schema?: GraphQLSchema;
execute?: ExecuteFunction;
subscribe?: SubscribeFunction;
validationRules?: Array<(context: ValidationContext) => any> | ReadonlyArray<any>;
onOperation?: Function;
onOperationComplete?: Function;
onConnect?: Function;
onDisconnect?: Function;
keepAlive?: number;
}
export declare class SubscriptionServer {
private onOperation;
private onOperationComplete;
private onConnect;
private onDisconnect;
private wsServer;
private execute;
private subscribe;
private schema;
private rootValue;
private keepAlive;
private closeHandler;
private specifiedRules;
static create(options: ServerOptions, socketOptionsOrServer: WebSocket.ServerOptions | WebSocket.Server): SubscriptionServer;
constructor(options: ServerOptions, socketOptionsOrServer: WebSocket.ServerOptions | WebSocket.Server);
get server(): WebSocket.Server;
close(): void;
private loadExecutor;
private unsubscribe;
private onClose;
private onMessage;
private sendKeepAlive;
private sendMessage;
private sendError;
}

299
node_modules/subscriptions-transport-ws/dist/server.js generated vendored Normal file
View File

@@ -0,0 +1,299 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubscriptionServer = void 0;
var WebSocket = require("ws");
var message_types_1 = require("./message-types");
var protocol_1 = require("./protocol");
var is_object_1 = require("./utils/is-object");
var graphql_1 = require("graphql");
var empty_iterable_1 = require("./utils/empty-iterable");
var iterall_1 = require("iterall");
var is_subscriptions_1 = require("./utils/is-subscriptions");
var parse_legacy_protocol_1 = require("./legacy/parse-legacy-protocol");
var isWebSocketServer = function (socket) { return socket.on; };
var SubscriptionServer = (function () {
function SubscriptionServer(options, socketOptionsOrServer) {
var _this = this;
var onOperation = options.onOperation, onOperationComplete = options.onOperationComplete, onConnect = options.onConnect, onDisconnect = options.onDisconnect, keepAlive = options.keepAlive;
this.specifiedRules = options.validationRules || graphql_1.specifiedRules;
this.loadExecutor(options);
this.onOperation = onOperation;
this.onOperationComplete = onOperationComplete;
this.onConnect = onConnect;
this.onDisconnect = onDisconnect;
this.keepAlive = keepAlive;
if (isWebSocketServer(socketOptionsOrServer)) {
this.wsServer = socketOptionsOrServer;
}
else {
this.wsServer = new WebSocket.Server(socketOptionsOrServer || {});
}
var connectionHandler = (function (socket, request) {
socket.upgradeReq = request;
if (socket.protocol === undefined ||
(socket.protocol.indexOf(protocol_1.GRAPHQL_WS) === -1 && socket.protocol.indexOf(protocol_1.GRAPHQL_SUBSCRIPTIONS) === -1)) {
socket.close(1002);
return;
}
var connectionContext = Object.create(null);
connectionContext.initPromise = Promise.resolve(true);
connectionContext.isLegacy = false;
connectionContext.socket = socket;
connectionContext.request = request;
connectionContext.operations = {};
var connectionClosedHandler = function (error) {
if (error) {
_this.sendError(connectionContext, '', { message: error.message ? error.message : error }, message_types_1.default.GQL_CONNECTION_ERROR);
setTimeout(function () {
connectionContext.socket.close(1011);
}, 10);
}
_this.onClose(connectionContext);
if (_this.onDisconnect) {
_this.onDisconnect(socket, connectionContext);
}
};
socket.on('error', connectionClosedHandler);
socket.on('close', connectionClosedHandler);
socket.on('message', _this.onMessage(connectionContext));
});
this.wsServer.on('connection', connectionHandler);
this.closeHandler = function () {
_this.wsServer.removeListener('connection', connectionHandler);
_this.wsServer.close();
};
}
SubscriptionServer.create = function (options, socketOptionsOrServer) {
return new SubscriptionServer(options, socketOptionsOrServer);
};
Object.defineProperty(SubscriptionServer.prototype, "server", {
get: function () {
return this.wsServer;
},
enumerable: false,
configurable: true
});
SubscriptionServer.prototype.close = function () {
this.closeHandler();
};
SubscriptionServer.prototype.loadExecutor = function (options) {
var execute = options.execute, subscribe = options.subscribe, schema = options.schema, rootValue = options.rootValue;
if (!execute) {
throw new Error('Must provide `execute` for websocket server constructor.');
}
this.schema = schema;
this.rootValue = rootValue;
this.execute = execute;
this.subscribe = subscribe;
};
SubscriptionServer.prototype.unsubscribe = function (connectionContext, opId) {
if (connectionContext.operations && connectionContext.operations[opId]) {
if (connectionContext.operations[opId].return) {
connectionContext.operations[opId].return();
}
delete connectionContext.operations[opId];
if (this.onOperationComplete) {
this.onOperationComplete(connectionContext.socket, opId);
}
}
};
SubscriptionServer.prototype.onClose = function (connectionContext) {
var _this = this;
Object.keys(connectionContext.operations).forEach(function (opId) {
_this.unsubscribe(connectionContext, opId);
});
};
SubscriptionServer.prototype.onMessage = function (connectionContext) {
var _this = this;
return function (message) {
var parsedMessage;
try {
parsedMessage = parse_legacy_protocol_1.parseLegacyProtocolMessage(connectionContext, JSON.parse(message));
}
catch (e) {
_this.sendError(connectionContext, null, { message: e.message }, message_types_1.default.GQL_CONNECTION_ERROR);
return;
}
var opId = parsedMessage.id;
switch (parsedMessage.type) {
case message_types_1.default.GQL_CONNECTION_INIT:
if (_this.onConnect) {
connectionContext.initPromise = new Promise(function (resolve, reject) {
try {
resolve(_this.onConnect(parsedMessage.payload, connectionContext.socket, connectionContext));
}
catch (e) {
reject(e);
}
});
}
connectionContext.initPromise.then(function (result) {
if (result === false) {
throw new Error('Prohibited connection!');
}
_this.sendMessage(connectionContext, undefined, message_types_1.default.GQL_CONNECTION_ACK, undefined);
if (_this.keepAlive) {
_this.sendKeepAlive(connectionContext);
var keepAliveTimer_1 = setInterval(function () {
if (connectionContext.socket.readyState === WebSocket.OPEN) {
_this.sendKeepAlive(connectionContext);
}
else {
clearInterval(keepAliveTimer_1);
}
}, _this.keepAlive);
}
}).catch(function (error) {
_this.sendError(connectionContext, opId, { message: error.message }, message_types_1.default.GQL_CONNECTION_ERROR);
setTimeout(function () {
connectionContext.socket.close(1011);
}, 10);
});
break;
case message_types_1.default.GQL_CONNECTION_TERMINATE:
connectionContext.socket.close();
break;
case message_types_1.default.GQL_START:
connectionContext.initPromise.then(function (initResult) {
if (connectionContext.operations && connectionContext.operations[opId]) {
_this.unsubscribe(connectionContext, opId);
}
var baseParams = {
query: parsedMessage.payload.query,
variables: parsedMessage.payload.variables,
operationName: parsedMessage.payload.operationName,
context: is_object_1.default(initResult) ? Object.assign(Object.create(Object.getPrototypeOf(initResult)), initResult) : {},
formatResponse: undefined,
formatError: undefined,
callback: undefined,
schema: _this.schema,
};
var promisedParams = Promise.resolve(baseParams);
connectionContext.operations[opId] = empty_iterable_1.createEmptyIterable();
if (_this.onOperation) {
var messageForCallback = parsedMessage;
promisedParams = Promise.resolve(_this.onOperation(messageForCallback, baseParams, connectionContext.socket));
}
return promisedParams.then(function (params) {
if (typeof params !== 'object') {
var error = "Invalid params returned from onOperation! return values must be an object!";
_this.sendError(connectionContext, opId, { message: error });
throw new Error(error);
}
if (!params.schema) {
var error = 'Missing schema information. The GraphQL schema should be provided either statically in' +
' the `SubscriptionServer` constructor or as a property on the object returned from onOperation!';
_this.sendError(connectionContext, opId, { message: error });
throw new Error(error);
}
var document = typeof baseParams.query !== 'string' ? baseParams.query : graphql_1.parse(baseParams.query);
var executionPromise;
var validationErrors = graphql_1.validate(params.schema, document, _this.specifiedRules);
if (validationErrors.length > 0) {
executionPromise = Promise.resolve({ errors: validationErrors });
}
else {
var executor = _this.execute;
if (_this.subscribe && is_subscriptions_1.isASubscriptionOperation(document, params.operationName)) {
executor = _this.subscribe;
}
executionPromise = Promise.resolve(executor(params.schema, document, _this.rootValue, params.context, params.variables, params.operationName));
}
return executionPromise.then(function (executionResult) { return ({
executionIterable: iterall_1.isAsyncIterable(executionResult) ?
executionResult : iterall_1.createAsyncIterator([executionResult]),
params: params,
}); });
}).then(function (_a) {
var executionIterable = _a.executionIterable, params = _a.params;
iterall_1.forAwaitEach(executionIterable, function (value) {
var result = value;
if (params.formatResponse) {
try {
result = params.formatResponse(value, params);
}
catch (err) {
console.error('Error in formatResponse function:', err);
}
}
_this.sendMessage(connectionContext, opId, message_types_1.default.GQL_DATA, result);
})
.then(function () {
_this.sendMessage(connectionContext, opId, message_types_1.default.GQL_COMPLETE, null);
})
.catch(function (e) {
var error = e;
if (params.formatError) {
try {
error = params.formatError(e, params);
}
catch (err) {
console.error('Error in formatError function: ', err);
}
}
if (Object.keys(error).length === 0) {
error = { name: error.name, message: error.message };
}
_this.sendError(connectionContext, opId, error);
});
return executionIterable;
}).then(function (subscription) {
connectionContext.operations[opId] = subscription;
}).then(function () {
_this.sendMessage(connectionContext, opId, message_types_1.default.SUBSCRIPTION_SUCCESS, undefined);
}).catch(function (e) {
if (e.errors) {
_this.sendMessage(connectionContext, opId, message_types_1.default.GQL_DATA, { errors: e.errors });
}
else {
_this.sendError(connectionContext, opId, { message: e.message });
}
_this.unsubscribe(connectionContext, opId);
return;
});
}).catch(function (error) {
_this.sendError(connectionContext, opId, { message: error.message });
_this.unsubscribe(connectionContext, opId);
});
break;
case message_types_1.default.GQL_STOP:
_this.unsubscribe(connectionContext, opId);
break;
default:
_this.sendError(connectionContext, opId, { message: 'Invalid message type!' });
}
};
};
SubscriptionServer.prototype.sendKeepAlive = function (connectionContext) {
if (connectionContext.isLegacy) {
this.sendMessage(connectionContext, undefined, message_types_1.default.KEEP_ALIVE, undefined);
}
else {
this.sendMessage(connectionContext, undefined, message_types_1.default.GQL_CONNECTION_KEEP_ALIVE, undefined);
}
};
SubscriptionServer.prototype.sendMessage = function (connectionContext, opId, type, payload) {
var parsedMessage = parse_legacy_protocol_1.parseLegacyProtocolMessage(connectionContext, {
type: type,
id: opId,
payload: payload,
});
if (parsedMessage && connectionContext.socket.readyState === WebSocket.OPEN) {
connectionContext.socket.send(JSON.stringify(parsedMessage));
}
};
SubscriptionServer.prototype.sendError = function (connectionContext, opId, errorPayload, overrideDefaultErrorType) {
var sanitizedOverrideDefaultErrorType = overrideDefaultErrorType || message_types_1.default.GQL_ERROR;
if ([
message_types_1.default.GQL_CONNECTION_ERROR,
message_types_1.default.GQL_ERROR,
].indexOf(sanitizedOverrideDefaultErrorType) === -1) {
throw new Error('overrideDefaultErrorType should be one of the allowed error messages' +
' GQL_CONNECTION_ERROR or GQL_ERROR');
}
this.sendMessage(connectionContext, opId, sanitizedOverrideDefaultErrorType, errorPayload);
};
return SubscriptionServer;
}());
exports.SubscriptionServer = SubscriptionServer;
//# sourceMappingURL=server.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { $$asyncIterator } from 'iterall';
declare type EmptyIterable = AsyncIterator<any> & {
[$$asyncIterator]: any;
};
export declare const createEmptyIterable: () => EmptyIterable;
export {};

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createEmptyIterable = void 0;
var iterall_1 = require("iterall");
exports.createEmptyIterable = function () {
var _a;
return _a = {
next: function () {
return Promise.resolve({ value: undefined, done: true });
},
return: function () {
return Promise.resolve({ value: undefined, done: true });
},
throw: function (e) {
return Promise.reject(e);
}
},
_a[iterall_1.$$asyncIterator] = function () {
return this;
},
_a;
};
//# sourceMappingURL=empty-iterable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"empty-iterable.js","sourceRoot":"","sources":["../../src/utils/empty-iterable.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAI7B,QAAA,mBAAmB,GAAG;;IACjC,OAAO;YACL,IAAI;gBACF,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM;gBACJ,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,KAAK,EAAL,UAAM,CAAQ;gBACZ,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;;QACD,GAAC,yBAAe,IAAhB;YACE,OAAO,IAAI,CAAC;QACd,CAAC;UACK,CAAC;AACX,CAAC,CAAC","sourcesContent":["import { $$asyncIterator } from 'iterall';\n\ntype EmptyIterable = AsyncIterator<any> & { [$$asyncIterator]: any };\n\nexport const createEmptyIterable = (): EmptyIterable => {\n return {\n next() {\n return Promise.resolve({ value: undefined, done: true });\n },\n return() {\n return Promise.resolve({ value: undefined, done: true });\n },\n throw(e: Error) {\n return Promise.reject(e);\n },\n [$$asyncIterator]() {\n return this;\n },\n } as any;\n};\n"]}

View File

@@ -0,0 +1 @@
export default function isObject(value?: any): boolean;

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isObject(value) {
return ((value !== null) && (typeof value === 'object'));
}
exports.default = isObject;
//# sourceMappingURL=is-object.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-object.js","sourceRoot":"","sources":["../../src/utils/is-object.ts"],"names":[],"mappings":";;AAAA,SAAwB,QAAQ,CAAC,KAAW;IAC1C,OAAO,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;AAC3D,CAAC;AAFD,2BAEC","sourcesContent":["export default function isObject(value?: any): boolean {\n return ((value !== null) && (typeof value === 'object'));\n}\n"]}

View File

@@ -0,0 +1 @@
export default function isString(value?: any): value is string;

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isString(value) {
return typeof value === 'string';
}
exports.default = isString;
//# sourceMappingURL=is-string.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-string.js","sourceRoot":"","sources":["../../src/utils/is-string.ts"],"names":[],"mappings":";;AAAA,SAAwB,QAAQ,CAAC,KAAW;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACnC,CAAC;AAFD,2BAEC","sourcesContent":["export default function isString(value?: any): value is string {\n return typeof value === 'string';\n}\n"]}

View File

@@ -0,0 +1,2 @@
import { DocumentNode } from 'graphql';
export declare const isASubscriptionOperation: (document: DocumentNode, operationName: string) => boolean;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isASubscriptionOperation = void 0;
var graphql_1 = require("graphql");
exports.isASubscriptionOperation = function (document, operationName) {
var operationAST = graphql_1.getOperationAST(document, operationName);
return !!operationAST && operationAST.operation === 'subscription';
};
//# sourceMappingURL=is-subscriptions.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-subscriptions.js","sourceRoot":"","sources":["../../src/utils/is-subscriptions.ts"],"names":[],"mappings":";;;AAAA,mCAAwD;AAE3C,QAAA,wBAAwB,GAAG,UAAC,QAAsB,EAAE,aAAqB;IACpF,IAAM,YAAY,GAAG,yBAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAE9D,OAAO,CAAC,CAAC,YAAY,IAAI,YAAY,CAAC,SAAS,KAAK,cAAc,CAAC;AACrE,CAAC,CAAC","sourcesContent":["import { DocumentNode, getOperationAST } from 'graphql';\n\nexport const isASubscriptionOperation = (document: DocumentNode, operationName: string): boolean => {\n const operationAST = getOperationAST(document, operationName);\n\n return !!operationAST && operationAST.operation === 'subscription';\n};\n"]}

6
node_modules/subscriptions-transport-ws/netlify.toml generated vendored Normal file
View File

@@ -0,0 +1,6 @@
[build]
base = "docs/"
publish = "docs/public/"
command = "gatsby build --prefix-paths && mkdir -p docs/graphql-subscriptions && mv public/* docs/graphql-subscriptions && mv docs public/ && mv public/docs/graphql-subscriptions/_redirects public"
[build.environment]
NPM_VERSION = "6"

63
node_modules/subscriptions-transport-ws/package.json generated vendored Normal file
View File

@@ -0,0 +1,63 @@
{
"name": "subscriptions-transport-ws",
"version": "0.9.19",
"description": "A websocket transport for GraphQL subscriptions",
"main": "dist/index.js",
"browser": "dist/client.js",
"repository": {
"type": "git",
"url": "git+https://github.com/apollostack/subscriptions-transport-ws.git"
},
"dependencies": {
"backo2": "^1.0.2",
"eventemitter3": "^3.1.0",
"iterall": "^1.2.1",
"symbol-observable": "^1.0.4",
"ws": "^5.2.0 || ^6.0.0 || ^7.0.0"
},
"scripts": {
"clean": "rimraf browser dist coverage",
"compile": "tsc",
"pretest": "npm run compile",
"test": "npm run testonly --",
"posttest": "npm run lint",
"lint": "tslint --format stylish --project ./tsconfig.json",
"watch": "tsc -w",
"testonly": "mocha --exit --reporter spec --full-trace ./dist/test/**/*.js",
"coverage": "node ./node_modules/istanbul/lib/cli.js cover _mocha -- --exit --full-trace ./dist/test/tests.js",
"postcoverage": "remap-istanbul --input coverage/coverage.raw.json --type lcovonly --output coverage/lcov.info",
"browser-compile": "webpack --config \"./unpkg-webpack.config.js\"",
"prepublishOnly": "npm run clean && npm run compile && npm run browser-compile"
},
"peerDependencies": {
"graphql": ">=0.10.0"
},
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/graphql": "^14.0.0",
"@types/is-promise": "^2.1.0",
"@types/lodash": "^4.14.109",
"@types/mocha": "^5.2.5",
"@types/node": "^8.0.8",
"@types/sinon": "^5.0.1",
"@types/ws": "^5.1.2",
"chai": "^4.0.2",
"graphql": "^15.3.0",
"graphql-subscriptions": "^1.0.0",
"istanbul": "^1.0.0-alpha.2",
"lodash": "^4.17.1",
"mocha": "^5.2.0",
"mock-socket-with-protocol": "^7.1.0",
"remap-istanbul": "^0.11.1",
"rimraf": "^2.6.1",
"sinon": "^6.1.4",
"tslint": "^5.10.0",
"typescript": "^3.9.6",
"webpack": "^3.1.0"
},
"typings": "dist/index.d.ts",
"typescript": {
"definition": "dist/index.d.ts"
},
"license": "MIT"
}

View File

@@ -0,0 +1,6 @@
{
"packageFiles": ["docs/package.json"],
"extends": [
"apollo-docs"
]
}

27
node_modules/subscriptions-transport-ws/tsconfig.json generated vendored Normal file
View File

@@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"inlineSources": true,
"noImplicitAny": true,
"rootDir": "./src",
"outDir": "./dist",
"allowSyntheticDefaultImports": true,
"removeComments": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"pretty": true,
"declaration": true,
"skipLibCheck": true,
"lib": ["es6", "esnext.asynciterable"],
"types": [
"node"
]
},
"exclude": [
"node_modules",
"dist"
]
}

134
node_modules/subscriptions-transport-ws/tslint.json generated vendored Normal file
View File

@@ -0,0 +1,134 @@
{
"rules": {
"align": [
false,
"parameters",
"arguments",
"statements"
],
"ban": false,
"class-name": true,
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"max-line-length": [
true,
140
],
"member-access": true,
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": false,
"no-console": [
true,
"log",
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-null-keyword": false,
"no-require-imports": false,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-var-keyword": true,
"no-var-requires": false,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-finally",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": [
true,
"always"
],
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "always",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": [
false,
"call-signature",
"parameter",
"arrow-parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "space",
"index-signature": "space",
"parameter": "space",
"property-declaration": "space",
"variable-declaration": "space"
}
],
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords",
"allow-pascal-case"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}

20
node_modules/subscriptions-transport-ws/typings.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
interface Array<T> {
indexOfField : (propertyName: string, value: any) => number;
}
declare module 'lodash.assign' {
import {assign} from 'lodash';
export = assign;
}
declare module 'lodash.isobject' {
import {isObject} from 'lodash';
export = isObject;
}
declare module 'lodash.isstring' {
import {isString} from 'lodash';
export = isString;
}
declare module 'backo2';

View File

@@ -0,0 +1,11 @@
var path = require('path');
module.exports = {
context: path.join(__dirname, '/dist'),
entry: './client.js',
output: {
path: path.join(__dirname, '/browser'),
filename: 'client.js',
library: 'SubscriptionsTransportWs'
}
};