Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make GraphQL a peer dependency, support GraphQL v15.0 #1356

Merged
merged 2 commits into from Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Expand Up @@ -77,7 +77,6 @@
"chalk": "4.1.1",
"chokidar": "^3.4.2",
"cookie": "^0.4.2",
"graphql": "^16.3.0",
"headers-polyfill": "^3.0.4",
"inquirer": "^8.2.0",
"is-node-process": "^1.0.1",
Expand Down Expand Up @@ -116,6 +115,7 @@
"eslint-plugin-prettier": "^3.4.0",
"fs-extra": "^10.0.0",
"fs-teardown": "^0.3.0",
"graphql": "^16.3.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to migrate to v16 given the optional range is 15/16? Are there any features that are dropped in v16 that we may accidentally rely upon?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since v16 is the version that MSW has used in the latest release, I think it makes sense to keep it as the devDependency version.

There are two main changes in this PR that affect run-time compatibility:

  1. Changing usage of OperationTypeNode from enum to string
  2. The parse function

Changing OperationTypeNode should be safe to do, the enum in v16 maps to the same strings that were used in v15.

The parse function from graphql is the only piece of runtime code that is actually used by MSW. It's being used to get the OperationDefinitionNode for the GraphQL operation that is intercepted. From what I can tell, the fields that MSW is interested in on OperationDefinitionNode are unchanged between v15 and v16.

Based on this, I think it should be safe to list v15 as a dependency.

It's also worth noting that v15 is, at the time of writing, the most commonly downloaded version of graphql on NPM (3+ million downloads a week, compared to ~2 million for v16). It would be good to be backwards compatible with v15, because lots of MSW users probably have that version in their projects.

"jest": "26",
"json-bigint": "^1.0.0",
"lint-staged": "^11.0.1",
Expand All @@ -134,9 +134,13 @@
"webpack-dev-server": "^3.11.2"
},
"peerDependencies": {
"graphql": "^15.0.0 || ^16.0.0",
kettanaito marked this conversation as resolved.
Show resolved Hide resolved
kettanaito marked this conversation as resolved.
Show resolved Hide resolved
"typescript": ">= 4.2.x <= 4.7.x"
},
"peerDependenciesMeta": {
"graphql": {
"optional": true
},
"typescript": {
"optional": true
}
Expand Down
2 changes: 1 addition & 1 deletion src/context/errors.ts
@@ -1,4 +1,4 @@
import { GraphQLError } from 'graphql'
import type { GraphQLError } from 'graphql'
import { ResponseTransformer } from '../response'
import { jsonParse } from '../utils/internal/jsonParse'
import { mergeRight } from '../utils/internal/mergeRight'
Expand Down
10 changes: 5 additions & 5 deletions src/graphql.ts
@@ -1,4 +1,4 @@
import { DocumentNode, OperationTypeNode } from 'graphql'
import type { DocumentNode, OperationTypeNode } from 'graphql'
import { ResponseResolver } from './handlers/RequestHandler'
import {
GraphQLHandler,
Expand Down Expand Up @@ -83,7 +83,7 @@ const standardGraphQLHandlers = {
* })
* @see {@link https://mswjs.io/docs/api/graphql/query `graphql.query()`}
*/
query: createScopedGraphQLHandler(OperationTypeNode.QUERY, '*'),
query: createScopedGraphQLHandler('query' as OperationTypeNode, '*'),

/**
* Captures a GraphQL mutation by a given name.
Expand All @@ -93,14 +93,14 @@ const standardGraphQLHandlers = {
* })
* @see {@link https://mswjs.io/docs/api/graphql/mutation `graphql.mutation()`}
*/
mutation: createScopedGraphQLHandler(OperationTypeNode.MUTATION, '*'),
mutation: createScopedGraphQLHandler('mutation' as OperationTypeNode, '*'),
}

function createGraphQLLink(url: Path): typeof standardGraphQLHandlers {
return {
operation: createGraphQLOperationHandler(url),
query: createScopedGraphQLHandler(OperationTypeNode.QUERY, url),
mutation: createScopedGraphQLHandler(OperationTypeNode.MUTATION, url),
query: createScopedGraphQLHandler('query' as OperationTypeNode, url),
mutation: createScopedGraphQLHandler('mutation' as OperationTypeNode, url),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/handlers/GraphQLHandler.ts
@@ -1,4 +1,4 @@
import { DocumentNode, OperationTypeNode } from 'graphql'
import type { DocumentNode, OperationTypeNode } from 'graphql'
import { SerializedResponse } from '../setupWorker/glossary'
import { data } from '../context/data'
import { extensions } from '../context/extensions'
Expand Down
6 changes: 4 additions & 2 deletions src/utils/internal/parseGraphQLRequest.ts
@@ -1,8 +1,7 @@
import {
import type {
DocumentNode,
OperationDefinitionNode,
OperationTypeNode,
parse,
} from 'graphql'
import { GraphQLVariables } from '../../handlers/GraphQLHandler'
import { getPublicUrlFromRequest } from '../request/getPublicUrlFromRequest'
Expand Down Expand Up @@ -41,6 +40,9 @@ export function parseDocumentNode(node: DocumentNode): ParsedGraphQLQuery {

function parseQuery(query: string): ParsedGraphQLQuery | Error {
try {
// Since 'graphql' is an optional peer dependency,
// we'll attempt to import it dynamically
const { parse } = require('graphql')
const ast = parse(query)
return parseDocumentNode(ast)
} catch (error) {
Expand Down