From e07d923cfdddc1393bd22efc3b41c7c3a7593bbf Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 6 Apr 2026 12:45:16 +0200 Subject: [PATCH 01/11] feat!: `msw/graphql`, `graphql` as an optional peer dependency --- config/plugins/esbuild/graphQLImportPlugin.ts | 34 -------------- package.json | 26 ++++++----- pnpm-lock.yaml | 18 ++++---- src/core/handlers/RequestHandler.ts | 2 +- src/core/index.ts | 21 +-------- src/core/utils/internal/isHandlerKind.test.ts | 2 +- .../internal/parseGraphQLRequest.test.ts | 2 +- .../graphql-handler.test.ts} | 6 +-- .../graphql-handler.ts} | 30 ++++++------ src/{core => graphql}/graphql.test.ts | 0 src/{core => graphql}/graphql.ts | 6 +-- src/graphql/index.ts | 20 ++++++++ .../parse-graphql-request.ts} | 18 ++++---- .../graphql-api/anonymous-operation.mocks.ts | 3 +- .../graphql-api/anonymous-operation.test.ts | 2 +- test/browser/graphql-api/cookies.mocks.ts | 3 +- .../graphql-api/custom-predicate.mocks.ts | 2 +- .../graphql-api/custom-predicate.test.ts | 2 +- .../graphql-api/document-node.mocks.ts | 3 +- test/browser/graphql-api/errors.mocks.ts | 3 +- test/browser/graphql-api/extensions.mocks.ts | 3 +- test/browser/graphql-api/link.mocks.ts | 3 +- test/browser/graphql-api/logging.mocks.ts | 3 +- .../graphql-api/multipart-data.mocks.ts | 3 +- test/browser/graphql-api/mutation.mocks.ts | 3 +- .../graphql-api/operation-reference.mocks.ts | 3 +- test/browser/graphql-api/operation.mocks.ts | 3 +- test/browser/graphql-api/query.mocks.ts | 3 +- .../graphql-api/response-patching.mocks.ts | 3 +- test/browser/graphql-api/variables.mocks.ts | 3 +- .../graphql-api/anonymous-operations.test.ts | 3 +- .../batched-queries.apollo.test.ts | 10 +--- .../batched-queries.batched-execute.test.ts | 3 +- .../graphql-api/compatibility.node.test.ts | 3 +- test/node/graphql-api/content-type.test.ts | 3 +- test/node/graphql-api/cookies.test.ts | 3 +- .../graphql-api/custom-predicate.node.test.ts | 3 +- test/node/graphql-api/extensions.node.test.ts | 3 +- .../response-patching.node.test.ts | 3 +- .../graphql-api/typed-document-node.test.ts | 3 +- .../graphql-api/typed-document-string.test.ts | 3 +- test/typings/custom-handler.test-d.ts | 3 +- test/typings/custom-resolver.test-d.ts | 4 +- .../graphql-custom-predicate.test-d.ts | 2 +- .../graphql-typed-document-node.test-d.ts | 3 +- .../graphql-typed-document-string.test-d.ts | 3 +- test/typings/graphql.test-d.ts | 3 +- test/typings/setup-server.test-d.ts | 3 +- test/typings/setup-worker.test-d.ts | 3 +- tsup.config.ts | 46 ++++++++++++------- 50 files changed, 179 insertions(+), 164 deletions(-) delete mode 100644 config/plugins/esbuild/graphQLImportPlugin.ts rename src/{core/handlers/GraphQLHandler.test.ts => graphql/graphql-handler.test.ts} (99%) rename src/{core/handlers/GraphQLHandler.ts => graphql/graphql-handler.ts} (93%) rename src/{core => graphql}/graphql.test.ts (100%) rename src/{core => graphql}/graphql.ts (96%) create mode 100644 src/graphql/index.ts rename src/{core/utils/internal/parseGraphQLRequest.ts => graphql/parse-graphql-request.ts} (92%) diff --git a/config/plugins/esbuild/graphQLImportPlugin.ts b/config/plugins/esbuild/graphQLImportPlugin.ts deleted file mode 100644 index f5f592454..000000000 --- a/config/plugins/esbuild/graphQLImportPlugin.ts +++ /dev/null @@ -1,34 +0,0 @@ -import fs from 'node:fs' -import type { Plugin } from 'esbuild' - -/** - * A plugin to replace `require('graphql')` statements with `await import('graphql')` - * only for ESM bundles. This makes the GraphQL module to be imported lazily - * while maintaining the CommonJS compatibility. - * @see https://github.com/mswjs/msw/issues/2254 - */ -export function graphqlImportPlugin(): Plugin { - return { - name: 'graphql-import-plugin', - setup(build) { - if (build.initialOptions.format !== 'esm') { - return - } - - build.onLoad({ filter: /\.ts$/ }, async (args) => { - const contents = await fs.promises.readFile(args.path, 'utf-8') - const match = /require\(['"]graphql['"]\)/g.exec(contents) - - if (match) { - return { - loader: 'ts', - contents: - contents.slice(0, match.index - 1) + - `await import('graphql').catch((error) => {console.error('[MSW] Failed to parse a GraphQL query: cannot import the "graphql" module. Please make sure you install it if you wish to intercept GraphQL requests. See the original import error below.'); throw error})` + - contents.slice(match.index + match[0].length), - } - } - }) - }, - } -} diff --git a/package.json b/package.json index 317952693..e3103d153 100644 --- a/package.json +++ b/package.json @@ -123,22 +123,22 @@ "default": "./lib/core/http.js" } }, - "./core/graphql": { + "./graphql": { "module-sync": { - "types": "./lib/core/graphql.d.mts", - "default": "./lib/core/graphql.mjs" + "types": "./lib/graphql/index.d.mts", + "default": "./lib/graphql/index.mjs" }, "module": { - "types": "./lib/core/graphql.d.mts", - "default": "./lib/core/graphql.mjs" + "types": "./lib/graphql/index.d.mts", + "default": "./lib/graphql/index.mjs" }, "import": { - "types": "./lib/core/graphql.d.mts", - "default": "./lib/core/graphql.mjs" + "types": "./lib/graphql/index.d.mts", + "default": "./lib/graphql/index.mjs" }, "default": { - "types": "./lib/core/graphql.d.ts", - "default": "./lib/core/graphql.js" + "types": "./lib/graphql/index.d.ts", + "default": "./lib/graphql/index.js" } }, "./core/ws": { @@ -242,7 +242,6 @@ "@open-draft/deferred-promise": "^2.2.0", "@types/statuses": "^2.0.6", "cookie": "^1.0.2", - "graphql": "^16.12.0", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", @@ -289,6 +288,7 @@ "fastify": "^5.6.2", "fs-teardown": "^0.3.0", "glob": "^13.0.0", + "graphql": "^16.13.2", "jsdom": "^25.0.1", "json-bigint": "^1.0.0", "knip": "^5.70.1", @@ -311,9 +311,13 @@ "webpack-http-server": "^0.5.0" }, "peerDependencies": { - "typescript": ">= 4.8.x" + "graphql": ">=16", + "typescript": ">=4.8.x" }, "peerDependenciesMeta": { + "graphql": { + "optional": true + }, "typescript": { "optional": true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 764f3d71a..01319f634 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,9 +23,6 @@ importers: cookie: specifier: ^1.0.2 version: 1.0.2 - graphql: - specifier: ^16.12.0 - version: 16.12.0 headers-polyfill: specifier: ^4.0.2 version: 4.0.3 @@ -83,7 +80,7 @@ importers: version: 11.2.0 '@graphql-typed-document-node/core': specifier: ^3.2.0 - version: 3.2.0(graphql@16.12.0) + version: 3.2.0(graphql@16.13.2) '@open-draft/test-server': specifier: ^0.4.2 version: 0.4.2 @@ -159,6 +156,9 @@ importers: glob: specifier: ^13.0.0 version: 13.0.0 + graphql: + specifier: ^16.13.2 + version: 16.13.2 jsdom: specifier: ^25.0.1 version: 25.0.1 @@ -3074,8 +3074,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphql@16.12.0: - resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} + graphql@16.13.2: + resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} has-bigints@1.0.2: @@ -5848,9 +5848,9 @@ snapshots: - bufferutil - utf-8-validate - '@graphql-typed-document-node/core@3.2.0(graphql@16.12.0)': + '@graphql-typed-document-node/core@3.2.0(graphql@16.13.2)': dependencies: - graphql: 16.12.0 + graphql: 16.13.2 '@hono/node-server@1.19.6(hono@4.10.4)': dependencies: @@ -8457,7 +8457,7 @@ snapshots: graphemer@1.4.0: {} - graphql@16.12.0: {} + graphql@16.13.2: {} has-bigints@1.0.2: {} diff --git a/src/core/handlers/RequestHandler.ts b/src/core/handlers/RequestHandler.ts index 520b100d1..62fa8ec0c 100644 --- a/src/core/handlers/RequestHandler.ts +++ b/src/core/handlers/RequestHandler.ts @@ -12,7 +12,7 @@ import { DefaultUnsafeFetchResponse, } from '../HttpResponse' import type { HandlerKind } from './common' -import type { GraphQLRequestBody } from './GraphQLHandler' +import type { GraphQLRequestBody } from '../../graphql/graphql-handler' export type DefaultRequestMultipartBody = Record< string, diff --git a/src/core/index.ts b/src/core/index.ts index 87ab122e4..890b0bd30 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -6,8 +6,6 @@ export { SetupApi } from './SetupApi' export { RequestHandler } from './handlers/RequestHandler' export { http } from './http' export { HttpHandler, HttpMethods } from './handlers/HttpHandler' -export { graphql } from './graphql' -export { GraphQLHandler } from './handlers/GraphQLHandler' /* WebSocket handler */ export { ws, type WebSocketLink } from './ws' @@ -27,7 +25,7 @@ export { } from './sse' import type { HttpHandler } from './handlers/HttpHandler' -import type { GraphQLHandler } from './handlers/GraphQLHandler' +import type { GraphQLHandler } from '../graphql/graphql-handler' import type { WebSocketHandler } from './handlers/WebSocketHandler' export type AnyHandler = HttpHandler | GraphQLHandler | WebSocketHandler @@ -70,26 +68,9 @@ export type { } from './handlers/HttpHandler' export type { HttpRequestHandler, HttpResponseResolver } from './http' -export type { - GraphQLQuery, - GraphQLVariables, - GraphQLRequestBody, - GraphQLResponseBody, - GraphQLJsonRequestBody, - GraphQLOperationType, - GraphQLCustomPredicate, -} from './handlers/GraphQLHandler' -export type { - GraphQLRequestHandler, - GraphQLOperationHandler, - GraphQLResponseResolver, - GraphQLLinkHandlers, -} from './graphql' - export type { WebSocketData, WebSocketEventListener } from './ws' export type { Path, PathParams, Match } from './utils/matching/matchRequestUrl' -export type { ParsedGraphQLRequest } from './utils/internal/parseGraphQLRequest' export type { ResponseResolutionContext } from './utils/executeHandlers' export { diff --git a/src/core/utils/internal/isHandlerKind.test.ts b/src/core/utils/internal/isHandlerKind.test.ts index 84486fbe9..87ba687fe 100644 --- a/src/core/utils/internal/isHandlerKind.test.ts +++ b/src/core/utils/internal/isHandlerKind.test.ts @@ -1,4 +1,4 @@ -import { GraphQLHandler } from '../../handlers/GraphQLHandler' +import { GraphQLHandler } from '../../../graphql/graphql-handler' import { HttpHandler } from '../../handlers/HttpHandler' import { RequestHandler } from '../../handlers/RequestHandler' import { WebSocketHandler } from '../../handlers/WebSocketHandler' diff --git a/src/core/utils/internal/parseGraphQLRequest.test.ts b/src/core/utils/internal/parseGraphQLRequest.test.ts index 3067ca889..7635450f0 100644 --- a/src/core/utils/internal/parseGraphQLRequest.test.ts +++ b/src/core/utils/internal/parseGraphQLRequest.test.ts @@ -6,7 +6,7 @@ import { OperationTypeNode } from 'graphql' import { ParsedGraphQLRequest, parseGraphQLRequest, -} from './parseGraphQLRequest' +} from '../../../graphql/parse-graphql-request' test('returns true given a GraphQL-compatible request', async () => { const getRequest = new Request( diff --git a/src/core/handlers/GraphQLHandler.test.ts b/src/graphql/graphql-handler.test.ts similarity index 99% rename from src/core/handlers/GraphQLHandler.test.ts rename to src/graphql/graphql-handler.test.ts index 6a9c9435d..e3ee879bf 100644 --- a/src/core/handlers/GraphQLHandler.test.ts +++ b/src/graphql/graphql-handler.test.ts @@ -6,9 +6,9 @@ import { GraphQLRequestBody, GraphQLResolverExtras, isDocumentNode, -} from './GraphQLHandler' -import { HttpResponse } from '../HttpResponse' -import { ResponseResolver } from './RequestHandler' +} from './graphql-handler' +import { HttpResponse } from '../core/HttpResponse' +import { ResponseResolver } from '../core/handlers/RequestHandler' const resolver: ResponseResolver> = ({ variables, diff --git a/src/core/handlers/GraphQLHandler.ts b/src/graphql/graphql-handler.ts similarity index 93% rename from src/core/handlers/GraphQLHandler.ts rename to src/graphql/graphql-handler.ts index 9199addc0..24a45a0a3 100644 --- a/src/core/handlers/GraphQLHandler.ts +++ b/src/graphql/graphql-handler.ts @@ -12,25 +12,29 @@ import { RequestHandlerExecutionResult, RequestHandlerOptions, ResponseResolver, -} from './RequestHandler' -import { getTimestamp } from '../utils/logging/getTimestamp' -import { getStatusCodeColor } from '../utils/logging/getStatusCodeColor' -import { serializeRequest } from '../utils/logging/serializeRequest' -import { serializeResponse } from '../utils/logging/serializeResponse' -import { Match, matchRequestUrl, Path } from '../utils/matching/matchRequestUrl' +} from '~/core/handlers/RequestHandler' +import { getTimestamp } from '~/core/utils/logging/getTimestamp' +import { getStatusCodeColor } from '~/core/utils/logging/getStatusCodeColor' +import { serializeRequest } from '~/core/utils/logging/serializeRequest' +import { serializeResponse } from '~/core/utils/logging/serializeResponse' +import { + Match, + matchRequestUrl, + Path, +} from '~/core/utils/matching/matchRequestUrl' import { ParsedGraphQLRequest, GraphQLMultipartRequestBody, parseGraphQLRequest, parseDocumentNode, ParsedGraphQLQuery, -} from '../utils/internal/parseGraphQLRequest' -import { toPublicUrl } from '../utils/request/toPublicUrl' -import { devUtils } from '../utils/internal/devUtils' -import { getAllRequestCookies } from '../utils/request/getRequestCookies' -import { ResponseResolutionContext } from 'src/iife' -import { kDefaultContentType, StrictRequest } from '../HttpResponse' -import { getAllAcceptedMimeTypes } from '../utils/request/getAllAcceptedMimeTypes' +} from './parse-graphql-request' +import { toPublicUrl } from '~/core/utils/request/toPublicUrl' +import { devUtils } from '~/core/utils/internal/devUtils' +import { getAllRequestCookies } from '~/core/utils/request/getRequestCookies' +import { kDefaultContentType, StrictRequest } from '~/core/HttpResponse' +import { getAllAcceptedMimeTypes } from '~/core/utils/request/getAllAcceptedMimeTypes' +import { type ResponseResolutionContext } from '~/core/utils/executeHandlers' export interface DocumentTypeDecoration< Result = { [key: string]: any }, diff --git a/src/core/graphql.test.ts b/src/graphql/graphql.test.ts similarity index 100% rename from src/core/graphql.test.ts rename to src/graphql/graphql.test.ts diff --git a/src/core/graphql.ts b/src/graphql/graphql.ts similarity index 96% rename from src/core/graphql.ts rename to src/graphql/graphql.ts index aa61d5c71..8ed98566c 100644 --- a/src/core/graphql.ts +++ b/src/graphql/graphql.ts @@ -2,7 +2,7 @@ import type { OperationTypeNode } from 'graphql' import { ResponseResolver, RequestHandlerOptions, -} from './handlers/RequestHandler' +} from '~/core/handlers/RequestHandler' import { GraphQLHandler, GraphQLVariables, @@ -11,8 +11,8 @@ import { GraphQLResponseBody, GraphQLQuery, GraphQLPredicate, -} from './handlers/GraphQLHandler' -import type { Path } from './utils/matching/matchRequestUrl' +} from 'src/graphql/graphql-handler' +import type { Path } from '~/core/utils/matching/matchRequestUrl' export type GraphQLRequestHandler = < Query extends GraphQLQuery = GraphQLQuery, diff --git a/src/graphql/index.ts b/src/graphql/index.ts new file mode 100644 index 000000000..4d376617e --- /dev/null +++ b/src/graphql/index.ts @@ -0,0 +1,20 @@ +export { + graphql, + type GraphQLRequestHandler, + type GraphQLOperationHandler, + type GraphQLResponseResolver, + type GraphQLLinkHandlers, +} from './graphql' + +export { + GraphQLHandler, + type GraphQLQuery, + type GraphQLVariables, + type GraphQLRequestBody, + type GraphQLResponseBody, + type GraphQLJsonRequestBody, + type GraphQLOperationType, + type GraphQLCustomPredicate, +} from './graphql-handler' + +export { type ParsedGraphQLRequest } from './parse-graphql-request' diff --git a/src/core/utils/internal/parseGraphQLRequest.ts b/src/graphql/parse-graphql-request.ts similarity index 92% rename from src/core/utils/internal/parseGraphQLRequest.ts rename to src/graphql/parse-graphql-request.ts index 5c81409c6..61f775b40 100644 --- a/src/core/utils/internal/parseGraphQLRequest.ts +++ b/src/graphql/parse-graphql-request.ts @@ -1,13 +1,13 @@ -import type { - DocumentNode, - OperationDefinitionNode, - OperationTypeNode, +import { + type DocumentNode, + type OperationDefinitionNode, + type OperationTypeNode, } from 'graphql' -import type { GraphQLVariables } from '../../handlers/GraphQLHandler' -import { toPublicUrl } from '../request/toPublicUrl' -import { devUtils } from './devUtils' -import { jsonParse } from './jsonParse' -import { parseMultipartData } from './parseMultipartData' +import type { GraphQLVariables } from './graphql-handler' +import { toPublicUrl } from '~/core/utils/request/toPublicUrl' +import { devUtils } from '~/core/utils/internal/devUtils' +import { jsonParse } from '~/core/utils/internal/jsonParse' +import { parseMultipartData } from '~/core/utils/internal/parseMultipartData' interface GraphQLInput { query: string | null diff --git a/test/browser/graphql-api/anonymous-operation.mocks.ts b/test/browser/graphql-api/anonymous-operation.mocks.ts index 48796fe35..8a3db03dd 100644 --- a/test/browser/graphql-api/anonymous-operation.mocks.ts +++ b/test/browser/graphql-api/anonymous-operation.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker() diff --git a/test/browser/graphql-api/anonymous-operation.test.ts b/test/browser/graphql-api/anonymous-operation.test.ts index a28d84e46..854562fdd 100644 --- a/test/browser/graphql-api/anonymous-operation.test.ts +++ b/test/browser/graphql-api/anonymous-operation.test.ts @@ -6,7 +6,7 @@ import { waitFor } from '../../support/waitFor' declare namespace window { export const msw: { worker: import('msw/browser').SetupWorkerApi - graphql: typeof import('msw').graphql + graphql: typeof import('msw/graphql').graphql HttpResponse: typeof import('msw').HttpResponse } } diff --git a/test/browser/graphql-api/cookies.mocks.ts b/test/browser/graphql-api/cookies.mocks.ts index 7cd387da2..54df7a7a8 100644 --- a/test/browser/graphql-api/cookies.mocks.ts +++ b/test/browser/graphql-api/cookies.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker( diff --git a/test/browser/graphql-api/custom-predicate.mocks.ts b/test/browser/graphql-api/custom-predicate.mocks.ts index 66779bcf8..c67732cc8 100644 --- a/test/browser/graphql-api/custom-predicate.mocks.ts +++ b/test/browser/graphql-api/custom-predicate.mocks.ts @@ -1,4 +1,4 @@ -import { graphql } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker() diff --git a/test/browser/graphql-api/custom-predicate.test.ts b/test/browser/graphql-api/custom-predicate.test.ts index 3a0e4d3f2..988327769 100644 --- a/test/browser/graphql-api/custom-predicate.test.ts +++ b/test/browser/graphql-api/custom-predicate.test.ts @@ -1,4 +1,4 @@ -import { graphql } from 'msw' +import { graphql } from 'msw/graphql' import { SetupWorkerApi } from 'msw/browser' import { gql } from '../../support/graphql' import { test, expect } from '../playwright.extend' diff --git a/test/browser/graphql-api/document-node.mocks.ts b/test/browser/graphql-api/document-node.mocks.ts index 38d66056e..92dce3cc2 100644 --- a/test/browser/graphql-api/document-node.mocks.ts +++ b/test/browser/graphql-api/document-node.mocks.ts @@ -1,5 +1,6 @@ import { parse } from 'graphql' -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const GetUser = parse(` diff --git a/test/browser/graphql-api/errors.mocks.ts b/test/browser/graphql-api/errors.mocks.ts index 18b98088a..e0f0c80df 100644 --- a/test/browser/graphql-api/errors.mocks.ts +++ b/test/browser/graphql-api/errors.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker( diff --git a/test/browser/graphql-api/extensions.mocks.ts b/test/browser/graphql-api/extensions.mocks.ts index 8981bf8cb..e78e6a097 100644 --- a/test/browser/graphql-api/extensions.mocks.ts +++ b/test/browser/graphql-api/extensions.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' interface LoginQuery { diff --git a/test/browser/graphql-api/link.mocks.ts b/test/browser/graphql-api/link.mocks.ts index 9e25b356e..be26f0c41 100644 --- a/test/browser/graphql-api/link.mocks.ts +++ b/test/browser/graphql-api/link.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const github = graphql.link('https://api.github.com/graphql') diff --git a/test/browser/graphql-api/logging.mocks.ts b/test/browser/graphql-api/logging.mocks.ts index b24f7a270..2d54b5599 100644 --- a/test/browser/graphql-api/logging.mocks.ts +++ b/test/browser/graphql-api/logging.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' interface GetUserDetailQuery { diff --git a/test/browser/graphql-api/multipart-data.mocks.ts b/test/browser/graphql-api/multipart-data.mocks.ts index 4732768e5..50e45bca5 100644 --- a/test/browser/graphql-api/multipart-data.mocks.ts +++ b/test/browser/graphql-api/multipart-data.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker( diff --git a/test/browser/graphql-api/mutation.mocks.ts b/test/browser/graphql-api/mutation.mocks.ts index 1a6253433..cdde3df0f 100644 --- a/test/browser/graphql-api/mutation.mocks.ts +++ b/test/browser/graphql-api/mutation.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' interface LogoutQuery { diff --git a/test/browser/graphql-api/operation-reference.mocks.ts b/test/browser/graphql-api/operation-reference.mocks.ts index a0137d52c..c4bee1f8a 100644 --- a/test/browser/graphql-api/operation-reference.mocks.ts +++ b/test/browser/graphql-api/operation-reference.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker( diff --git a/test/browser/graphql-api/operation.mocks.ts b/test/browser/graphql-api/operation.mocks.ts index f5ecc0fc4..94db1b815 100644 --- a/test/browser/graphql-api/operation.mocks.ts +++ b/test/browser/graphql-api/operation.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const worker = setupWorker( diff --git a/test/browser/graphql-api/query.mocks.ts b/test/browser/graphql-api/query.mocks.ts index 740a4d8f9..976570f4a 100644 --- a/test/browser/graphql-api/query.mocks.ts +++ b/test/browser/graphql-api/query.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' interface GetUserDetailQuery { diff --git a/test/browser/graphql-api/response-patching.mocks.ts b/test/browser/graphql-api/response-patching.mocks.ts index 09ce40573..84f0d2010 100644 --- a/test/browser/graphql-api/response-patching.mocks.ts +++ b/test/browser/graphql-api/response-patching.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, bypass, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' import { createGraphQLClient, gql } from '../../support/graphql' diff --git a/test/browser/graphql-api/variables.mocks.ts b/test/browser/graphql-api/variables.mocks.ts index cdb2176f7..379142fb6 100644 --- a/test/browser/graphql-api/variables.mocks.ts +++ b/test/browser/graphql-api/variables.mocks.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' interface GetGitHubUserQuery { diff --git a/test/node/graphql-api/anonymous-operations.test.ts b/test/node/graphql-api/anonymous-operations.test.ts index 08c8161fc..55219acd0 100644 --- a/test/node/graphql-api/anonymous-operations.test.ts +++ b/test/node/graphql-api/anonymous-operations.test.ts @@ -1,6 +1,7 @@ // @vitest-environment node import { HttpServer } from '@open-draft/test-server/http' -import { HttpResponse, graphql } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient } from '../../support/graphql' diff --git a/test/node/graphql-api/batched-queries.apollo.test.ts b/test/node/graphql-api/batched-queries.apollo.test.ts index d8599d919..ecc10790a 100644 --- a/test/node/graphql-api/batched-queries.apollo.test.ts +++ b/test/node/graphql-api/batched-queries.apollo.test.ts @@ -4,14 +4,8 @@ * @see https://github.com/mswjs/msw/issues/510 * @see https://www.apollographql.com/docs/router/executing-operations/query-batching */ -import { - http, - graphql, - bypass, - HttpResponse, - getResponse, - RequestHandler, -} from 'msw' +import { http, bypass, HttpResponse, getResponse, RequestHandler } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { HttpServer } from '@open-draft/test-server/http' diff --git a/test/node/graphql-api/batched-queries.batched-execute.test.ts b/test/node/graphql-api/batched-queries.batched-execute.test.ts index 88ba33382..6e5aa1121 100644 --- a/test/node/graphql-api/batched-queries.batched-execute.test.ts +++ b/test/node/graphql-api/batched-queries.batched-execute.test.ts @@ -10,7 +10,8 @@ import { print, defaultFieldResolver, } from 'graphql' -import { http, HttpResponse, GraphQLVariables, bypass } from 'msw' +import { http, HttpResponse, bypass } from 'msw' +import { type GraphQLVariables } from 'msw/graphql' import { setupServer } from 'msw/node' import { HttpServer } from '@open-draft/test-server/http' import { createGraphQLClient } from '../../support/graphql' diff --git a/test/node/graphql-api/compatibility.node.test.ts b/test/node/graphql-api/compatibility.node.test.ts index b3aad7675..07d64b112 100644 --- a/test/node/graphql-api/compatibility.node.test.ts +++ b/test/node/graphql-api/compatibility.node.test.ts @@ -1,6 +1,7 @@ // @vitest-environment node import { graphql as executeGraphql, buildSchema } from 'graphql' -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient, gql } from '../../support/graphql' diff --git a/test/node/graphql-api/content-type.test.ts b/test/node/graphql-api/content-type.test.ts index ade9e60a9..d3b04c305 100644 --- a/test/node/graphql-api/content-type.test.ts +++ b/test/node/graphql-api/content-type.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient } from '../../support/graphql' diff --git a/test/node/graphql-api/cookies.test.ts b/test/node/graphql-api/cookies.test.ts index 5b059f808..d7560c5d4 100644 --- a/test/node/graphql-api/cookies.test.ts +++ b/test/node/graphql-api/cookies.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient, gql } from '../../support/graphql' diff --git a/test/node/graphql-api/custom-predicate.node.test.ts b/test/node/graphql-api/custom-predicate.node.test.ts index 5422c213e..d6b47e863 100644 --- a/test/node/graphql-api/custom-predicate.node.test.ts +++ b/test/node/graphql-api/custom-predicate.node.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient, gql } from '../../support/graphql' diff --git a/test/node/graphql-api/extensions.node.test.ts b/test/node/graphql-api/extensions.node.test.ts index 245ae45e5..6cb65690b 100644 --- a/test/node/graphql-api/extensions.node.test.ts +++ b/test/node/graphql-api/extensions.node.test.ts @@ -1,6 +1,7 @@ // @vitest-environment node import { buildSchema, graphql as executeGraphql } from 'graphql' -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { createGraphQLClient, gql } from '../../support/graphql' diff --git a/test/node/graphql-api/response-patching.node.test.ts b/test/node/graphql-api/response-patching.node.test.ts index ed686f23e..8a2dfe287 100644 --- a/test/node/graphql-api/response-patching.node.test.ts +++ b/test/node/graphql-api/response-patching.node.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { bypass, graphql, HttpResponse } from 'msw' +import { bypass, HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { graphql as executeGraphql, buildSchema } from 'graphql' import { HttpServer } from '@open-draft/test-server/http' diff --git a/test/node/graphql-api/typed-document-node.test.ts b/test/node/graphql-api/typed-document-node.test.ts index b71297430..6c731ad12 100644 --- a/test/node/graphql-api/typed-document-node.test.ts +++ b/test/node/graphql-api/typed-document-node.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { gql, diff --git a/test/node/graphql-api/typed-document-string.test.ts b/test/node/graphql-api/typed-document-string.test.ts index 93cb6100a..5c136438a 100644 --- a/test/node/graphql-api/typed-document-string.test.ts +++ b/test/node/graphql-api/typed-document-string.test.ts @@ -1,5 +1,6 @@ // @vitest-environment node -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' import { gql, diff --git a/test/typings/custom-handler.test-d.ts b/test/typings/custom-handler.test-d.ts index c2cddfa4d..31c88ab16 100644 --- a/test/typings/custom-handler.test-d.ts +++ b/test/typings/custom-handler.test-d.ts @@ -1,5 +1,6 @@ import { it } from 'vitest' -import { http, HttpRequestHandler, GraphQLRequestHandler, graphql } from 'msw' +import { http, HttpRequestHandler } from 'msw' +import { GraphQLRequestHandler, graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' import { setupServer } from 'msw/node' diff --git a/test/typings/custom-resolver.test-d.ts b/test/typings/custom-resolver.test-d.ts index 18d30a6e4..2d10bf709 100644 --- a/test/typings/custom-resolver.test-d.ts +++ b/test/typings/custom-resolver.test-d.ts @@ -6,11 +6,13 @@ import { PathParams, DefaultBodyType, HttpResponse, +} from 'msw' +import { graphql, GraphQLQuery, GraphQLVariables, GraphQLResponseResolver, -} from 'msw' +} from 'msw/graphql' it('custom http resolver has correct parameters type', () => { /** diff --git a/test/typings/graphql-custom-predicate.test-d.ts b/test/typings/graphql-custom-predicate.test-d.ts index 13e5f802d..58bffdce5 100644 --- a/test/typings/graphql-custom-predicate.test-d.ts +++ b/test/typings/graphql-custom-predicate.test-d.ts @@ -3,7 +3,7 @@ import { type GraphQLOperationType, type GraphQLVariables, type GraphQLResponseResolver, -} from 'msw' +} from 'msw/graphql' const resolver: GraphQLResponseResolver = () => void 0 diff --git a/test/typings/graphql-typed-document-node.test-d.ts b/test/typings/graphql-typed-document-node.test-d.ts index 81139ba1c..bc81d57f1 100644 --- a/test/typings/graphql-typed-document-node.test-d.ts +++ b/test/typings/graphql-typed-document-node.test-d.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { TypedDocumentNode } from '@graphql-typed-document-node/core' const GetUserQuery = {} as TypedDocumentNode< diff --git a/test/typings/graphql-typed-document-string.test-d.ts b/test/typings/graphql-typed-document-string.test-d.ts index f5b996c9f..c46ac67aa 100644 --- a/test/typings/graphql-typed-document-string.test-d.ts +++ b/test/typings/graphql-typed-document-string.test-d.ts @@ -1,4 +1,5 @@ -import { graphql, HttpResponse } from 'msw' +import { HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { DocumentTypeDecoration } from '@graphql-typed-document-node/core' declare function createTypedDocumentString( diff --git a/test/typings/graphql.test-d.ts b/test/typings/graphql.test-d.ts index 6e90fdc87..3ddb7531a 100644 --- a/test/typings/graphql.test-d.ts +++ b/test/typings/graphql.test-d.ts @@ -1,6 +1,7 @@ import { it, expectTypeOf } from 'vitest' import { parse } from 'graphql' -import { graphql, HttpResponse, passthrough } from 'msw' +import { HttpResponse, passthrough } from 'msw' +import { graphql } from 'msw/graphql' it('graphql mutation can be used without variables generic type', () => { graphql.mutation('GetUser', () => { diff --git a/test/typings/setup-server.test-d.ts b/test/typings/setup-server.test-d.ts index 7e6f58f69..71495fe5c 100644 --- a/test/typings/setup-server.test-d.ts +++ b/test/typings/setup-server.test-d.ts @@ -1,4 +1,5 @@ -import { http, HttpResponse, graphql } from 'msw' +import { http, HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupServer } from 'msw/node' it('does not produce a type error when called without arguments', () => { diff --git a/test/typings/setup-worker.test-d.ts b/test/typings/setup-worker.test-d.ts index 8313f966a..0bd6ea259 100644 --- a/test/typings/setup-worker.test-d.ts +++ b/test/typings/setup-worker.test-d.ts @@ -1,4 +1,5 @@ -import { http, HttpResponse, graphql } from 'msw' +import { http, HttpResponse } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' it('does not produce a type error when called without arguments', () => { diff --git a/tsup.config.ts b/tsup.config.ts index 0bd9b72b9..8b590b7fa 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -7,7 +7,6 @@ import { } from './config/plugins/esbuild/copyWorkerPlugin' import { resolveCoreImportsPlugin } from './config/plugins/esbuild/resolveCoreImportsPlugin' import { forceEsmExtensionsPlugin } from './config/plugins/esbuild/forceEsmExtensionsPlugin' -import { graphqlImportPlugin } from './config/plugins/esbuild/graphQLImportPlugin' import packageJson from './package.json' // Externalize the in-house dependencies so that the user @@ -25,7 +24,7 @@ const SERVICE_WORKER_CHECKSUM = getWorkerChecksum() * This bundles the shims so CJS modules could be used * in the browser. */ -const shimConfig: Options = { +const shimConfig = defineConfig({ name: 'shims', platform: 'neutral', entry: glob.sync('./src/shims/**/*.ts', { @@ -39,9 +38,9 @@ const shimConfig: Options = { splitting: false, sourcemap: false, dts: true, -} +}) -const coreConfig: Options = { +const coreConfig = defineConfig({ name: 'core', platform: 'neutral', entry: glob.sync('./src/core/**/*.ts', { @@ -58,10 +57,24 @@ const coreConfig: Options = { sourcemap: true, dts: true, tsconfig: path.resolve(__dirname, 'src/tsconfig.core.build.json'), - esbuildPlugins: [graphqlImportPlugin(), forceEsmExtensionsPlugin()], -} + esbuildPlugins: [forceEsmExtensionsPlugin()], +}) -const nodeConfig: Options = { +const graphqlConfig = defineConfig({ + name: 'graphql', + platform: 'neutral', + entry: ['./src/graphql/index.ts'], + external: [ecosystemDependencies], + format: ['esm', 'cjs'], + outDir: './lib/graphql', + bundle: false, + sourcemap: true, + dts: true, + tsconfig: path.resolve(__dirname, 'src/tsconfig.core.build.json'), + esbuildPlugins: [forceEsmExtensionsPlugin()], +}) + +const nodeConfig = defineConfig({ name: 'node', platform: 'node', entry: ['./src/node/index.ts'], @@ -75,9 +88,9 @@ const nodeConfig: Options = { dts: true, tsconfig: path.resolve(__dirname, 'src/tsconfig.node.build.json'), esbuildPlugins: [resolveCoreImportsPlugin(), forceEsmExtensionsPlugin()], -} +}) -const browserConfig: Options = { +const browserConfig = defineConfig({ name: 'browser', platform: 'browser', entry: ['./src/browser/index.ts'], @@ -113,9 +126,9 @@ const browserConfig: Options = { forceEsmExtensionsPlugin(), copyWorkerPlugin(SERVICE_WORKER_CHECKSUM), ], -} +}) -const reactNativeConfig: Options = { +const reactNativeConfig = defineConfig({ name: 'react-native', platform: 'node', entry: ['./src/native/index.ts'], @@ -128,9 +141,9 @@ const reactNativeConfig: Options = { dts: true, tsconfig: path.resolve(__dirname, 'src/tsconfig.node.build.json'), esbuildPlugins: [resolveCoreImportsPlugin(), forceEsmExtensionsPlugin()], -} +}) -const iifeConfig: Options = { +const iifeConfig = defineConfig({ name: 'iife', platform: 'browser', globalName: 'MockServiceWorker', @@ -152,13 +165,14 @@ const iifeConfig: Options = { // the worker API must have the the integrity checksum defined. SERVICE_WORKER_CHECKSUM: JSON.stringify(SERVICE_WORKER_CHECKSUM), }, -} +}) -export default defineConfig([ +export default [ shimConfig, coreConfig, nodeConfig, reactNativeConfig, browserConfig, iifeConfig, -]) + graphqlConfig, +] From ab24ec5d9ef4e9ae3ef0e6959716d99881640b19 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 6 Apr 2026 14:42:56 +0200 Subject: [PATCH 02/11] chore: bundle `/graphql`, add `msw/graphql` test alias --- test/support/alias.ts | 1 + tsup.config.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/support/alias.ts b/test/support/alias.ts index f94103356..95ba13760 100644 --- a/test/support/alias.ts +++ b/test/support/alias.ts @@ -11,6 +11,7 @@ export const mswExports = { 'msw/node': fromRoot('./lib/node/index.mjs'), 'msw/native': fromRoot('./lib/native/index.mjs'), 'msw/browser': fromRoot('./lib/browser/index.mjs'), + 'msw/graphql': fromRoot('./lib/graphql/index.mjs'), msw: fromRoot('./lib/core/index.mjs'), } diff --git a/tsup.config.ts b/tsup.config.ts index 66649b0da..a0371a02b 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -67,7 +67,6 @@ const graphqlConfig = defineConfig({ external: [ecosystemDependencies], format: ['esm', 'cjs'], outDir: './lib/graphql', - bundle: false, sourcemap: true, dts: true, tsconfig: path.resolve(__dirname, 'src/tsconfig.core.build.json'), From 7b92af7166471afa707a1922210b4a4f1d12bd41 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 6 Apr 2026 14:46:10 +0200 Subject: [PATCH 03/11] test: use `node-websocket` for `websocket-frame` test --- src/core/experimental/frames/websocket-frame.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/experimental/frames/websocket-frame.test.ts b/src/core/experimental/frames/websocket-frame.test.ts index 26780cbe8..02a5519c5 100644 --- a/src/core/experimental/frames/websocket-frame.test.ts +++ b/src/core/experimental/frames/websocket-frame.test.ts @@ -1,3 +1,4 @@ +// @vitest-environment node-websocket import { http } from '../../http' import { graphql } from '../../../graphql' import { ws } from '../../ws' From 1ba4f4dbbffbb118ad6d1bc52c6a2461d88d36dd Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 12:39:00 +0200 Subject: [PATCH 04/11] chore(webpackHttpServer): drop manual export path aliasing --- test/browser/setup/webpackHttpServer.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/browser/setup/webpackHttpServer.ts b/test/browser/setup/webpackHttpServer.ts index 233259103..1c225f6e4 100644 --- a/test/browser/setup/webpackHttpServer.ts +++ b/test/browser/setup/webpackHttpServer.ts @@ -56,13 +56,6 @@ async function startWebpackServer(): Promise { ], }, resolve: { - alias: { - 'msw/browser': new URL( - '../../../lib/browser/index.mjs', - import.meta.url, - ).pathname, - msw: new URL('../../../lib/core/index.mjs', import.meta.url).pathname, - }, extensions: ['.ts', '.js', '.mjs', '.cjs'], }, }, From 51a6da25a7c95bd20961b20956f98ce9861a763a Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 12:40:18 +0200 Subject: [PATCH 05/11] fix(parseQuery): drop dynamic `graphql` require --- src/graphql/parse-graphql-request.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/graphql/parse-graphql-request.ts b/src/graphql/parse-graphql-request.ts index 42711e247..958abfb38 100644 --- a/src/graphql/parse-graphql-request.ts +++ b/src/graphql/parse-graphql-request.ts @@ -1,4 +1,5 @@ import { + parse, type DocumentNode, type OperationDefinitionNode, type OperationTypeNode, @@ -40,15 +41,6 @@ export function parseDocumentNode(node: DocumentNode): ParsedGraphQLQuery { } async function parseQuery(query: string): Promise { - /** - * @note Use `require` to get the "graphql" module here. - * It has to be scoped to this function because this module leaks to the - * root export. It has to be `require` because tools like Jest have trouble - * handling dynamic imports. It gets replaced with a dynamic import on build time. - */ - // eslint-disable-next-line @typescript-eslint/no-require-imports - const { parse } = require('graphql') - try { const ast = parse(query) return parseDocumentNode(ast) From c5d2e01d73c81c8a8771057a4fd6e4ec82567d39 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 12:48:20 +0200 Subject: [PATCH 06/11] fix: prevent empty import to core after build --- src/graphql/graphql.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphql/graphql.ts b/src/graphql/graphql.ts index bd7ad2526..16df704f9 100644 --- a/src/graphql/graphql.ts +++ b/src/graphql/graphql.ts @@ -1,7 +1,7 @@ import type { OperationTypeNode } from 'graphql' -import { - type ResponseResolver, - type RequestHandlerOptions, +import type { + ResponseResolver, + RequestHandlerOptions, } from '#core/handlers/RequestHandler' import { GraphQLHandler, From 3a4f1744d88dbc5b8b7d4fa498d12495d408852f Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 12:48:28 +0200 Subject: [PATCH 07/11] fix: revert `bundle: false` for graphql builds --- tsup.config.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tsup.config.ts b/tsup.config.ts index a0371a02b..2c4ce5a27 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -63,14 +63,19 @@ const coreConfig = defineConfig({ const graphqlConfig = defineConfig({ name: 'graphql', platform: 'neutral', - entry: ['./src/graphql/index.ts'], + entry: glob.sync('./src/graphql/**/*.ts', { + ignore: '**/*.test.ts', + posix: true, + dotRelative: true, + }), external: [ecosystemDependencies], format: ['esm', 'cjs'], outDir: './lib/graphql', + bundle: false, sourcemap: true, dts: true, tsconfig: path.resolve(__dirname, 'src/tsconfig.core.build.json'), - esbuildPlugins: [forceEsmExtensionsPlugin()], + esbuildPlugins: [resolveCoreImportsPlugin(), forceEsmExtensionsPlugin()], }) const nodeConfig = defineConfig({ From 5f6ce2d694698073f6deaa46fb120201627a5592 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 12:50:21 +0200 Subject: [PATCH 08/11] test: fix missing `bypass` in response patching test --- test/browser/graphql-api/response-patching.mocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/browser/graphql-api/response-patching.mocks.ts b/test/browser/graphql-api/response-patching.mocks.ts index 84f0d2010..edbedddf6 100644 --- a/test/browser/graphql-api/response-patching.mocks.ts +++ b/test/browser/graphql-api/response-patching.mocks.ts @@ -1,4 +1,4 @@ -import { HttpResponse } from 'msw' +import { bypass, HttpResponse } from 'msw' import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' import { createGraphQLClient, gql } from '../../support/graphql' From 25f1f016544ead9bcc1b572d8eadc841b82a42a9 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 13:40:23 +0200 Subject: [PATCH 09/11] test: fix `graphql` import in a type test --- test/typings/regressions/request-handler-type.test-d.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/typings/regressions/request-handler-type.test-d.ts b/test/typings/regressions/request-handler-type.test-d.ts index 8fd74f5b5..171457f73 100644 --- a/test/typings/regressions/request-handler-type.test-d.ts +++ b/test/typings/regressions/request-handler-type.test-d.ts @@ -3,14 +3,13 @@ */ import { http, - graphql, ws, type HttpHandler, type RequestHandler, type AnyHandler, type WebSocketHandler, - type GraphQLHandler, } from 'msw' +import { graphql, type GraphQLHandler } from 'msw/graphql' import { setupServer } from 'msw/node' import { setupWorker } from 'msw/browser' From 708707f3dc45f5fd26b046e7f3d5ab849bdf9fc3 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 14:03:11 +0200 Subject: [PATCH 10/11] fix: externalize `mswCore` and fix `replaceCoreImports` --- config/replaceCoreImports.js | 34 +++++++++++++++++++---------- src/core/handlers/RequestHandler.ts | 5 +---- src/core/utils/executeHandlers.ts | 2 +- src/graphql/graphql-handler.test.ts | 2 +- src/graphql/graphql-handler.ts | 2 +- src/graphql/index.ts | 2 +- tsup.config.ts | 2 +- 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/config/replaceCoreImports.js b/config/replaceCoreImports.js index c4dff75d4..9f1570ca1 100644 --- a/config/replaceCoreImports.js +++ b/config/replaceCoreImports.js @@ -1,29 +1,39 @@ -const CORE_ESM_IMPORT_PATTERN = /from ["'](#core(.*))["'](;)?/gm -const CORE_CJS_IMPORT_PATTERN = /require\(["'](#core(.*))["']\)(;)?/gm +const CORE_ESM_IMPORT_PATTERN = /(from|import)\s+["'](#core(.*?))["'](;)?/gm +const CORE_CJS_IMPORT_PATTERN = /require\(["'](#core(.*?))["']\)(;)?/gm function getCoreImportPattern(isEsm) { return isEsm ? CORE_ESM_IMPORT_PATTERN : CORE_CJS_IMPORT_PATTERN } export function hasCoreImports(fileContents, isEsm) { - return getCoreImportPattern(isEsm).test(fileContents) + return fileContents.search(getCoreImportPattern(isEsm)) !== -1 } export function replaceCoreImports(moduleFilePath, fileContents, isEsm) { + if (isEsm) { + return fileContents.replace( + CORE_ESM_IMPORT_PATTERN, + (_, keyword, __, maybeSubmodulePath, maybeSemicolon) => { + const submodulePath = maybeSubmodulePath || '/index' + /** + * @note Although all .d.ts are considered ESM, append different + * file extension for d.mts files. + */ + const extension = moduleFilePath.endsWith('.d.mts') ? '.mjs' : '' + const semicolon = maybeSemicolon || '' + + return `${keyword} "../core${submodulePath}${extension}"${semicolon}` + }, + ) + } + return fileContents.replace( - getCoreImportPattern(isEsm), + CORE_CJS_IMPORT_PATTERN, (_, __, maybeSubmodulePath, maybeSemicolon) => { const submodulePath = maybeSubmodulePath || '/index' - /** - * @note Although all .d.ts are considered ESM, append different - * file extension for d.mts files. - */ - const extension = moduleFilePath.endsWith('.d.mts') ? '.mjs' : '' const semicolon = maybeSemicolon || '' - return isEsm - ? `from "../core${submodulePath}${extension}"${semicolon}` - : `require("../core${submodulePath}")${semicolon}` + return `require("../core${submodulePath}")${semicolon}` }, ) } diff --git a/src/core/handlers/RequestHandler.ts b/src/core/handlers/RequestHandler.ts index 7705a3aa4..bff1736fa 100644 --- a/src/core/handlers/RequestHandler.ts +++ b/src/core/handlers/RequestHandler.ts @@ -7,10 +7,7 @@ import { import type { ResponseResolutionContext } from '../utils/executeHandlers' import type { MaybePromise } from '../typeUtils' import type { HttpResponse } from '../HttpResponse' -import { - type StrictRequest, - type DefaultUnsafeFetchResponse, -} from '../HttpResponse' +import type { StrictRequest, DefaultUnsafeFetchResponse } from '../HttpResponse' import type { GraphQLRequestBody } from '../../graphql/graphql-handler' import { devUtils } from '../utils/internal/devUtils' import { getRawSetCookie } from '../utils/HttpResponse/decorators' diff --git a/src/core/utils/executeHandlers.ts b/src/core/utils/executeHandlers.ts index c740961c2..35ad85160 100644 --- a/src/core/utils/executeHandlers.ts +++ b/src/core/utils/executeHandlers.ts @@ -1,5 +1,5 @@ import type { RequestHandler } from '../handlers/RequestHandler' -import { type RequestHandlerExecutionResult } from '../handlers/RequestHandler' +import type { RequestHandlerExecutionResult } from '../handlers/RequestHandler' export interface HandlersExecutionResult { handler: RequestHandler diff --git a/src/graphql/graphql-handler.test.ts b/src/graphql/graphql-handler.test.ts index 6a930de45..6054285c6 100644 --- a/src/graphql/graphql-handler.test.ts +++ b/src/graphql/graphql-handler.test.ts @@ -8,7 +8,7 @@ import { type GraphQLResolverExtras, } from './graphql-handler' import { HttpResponse } from '../core/HttpResponse' -import { type ResponseResolver } from '../core/handlers/RequestHandler' +import type { ResponseResolver } from '../core/handlers/RequestHandler' const resolver: ResponseResolver> = ({ variables, diff --git a/src/graphql/graphql-handler.ts b/src/graphql/graphql-handler.ts index 6c5fcb93e..a8c192a3e 100644 --- a/src/graphql/graphql-handler.ts +++ b/src/graphql/graphql-handler.ts @@ -34,7 +34,7 @@ import { devUtils } from '#core/utils/internal/devUtils' import { getAllRequestCookies } from '#core/utils/request/getRequestCookies' import { kDefaultContentType, type StrictRequest } from '#core/HttpResponse' import { getAllAcceptedMimeTypes } from '#core/utils/request/getAllAcceptedMimeTypes' -import { type ResponseResolutionContext } from '#core/utils/executeHandlers' +import type { ResponseResolutionContext } from '#core/utils/executeHandlers' export interface DocumentTypeDecoration< Result = { [key: string]: any }, diff --git a/src/graphql/index.ts b/src/graphql/index.ts index 4d376617e..36e71c34b 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -17,4 +17,4 @@ export { type GraphQLCustomPredicate, } from './graphql-handler' -export { type ParsedGraphQLRequest } from './parse-graphql-request' +export type { ParsedGraphQLRequest } from './parse-graphql-request' diff --git a/tsup.config.ts b/tsup.config.ts index 2c4ce5a27..e0e756444 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -68,7 +68,7 @@ const graphqlConfig = defineConfig({ posix: true, dotRelative: true, }), - external: [ecosystemDependencies], + external: [mswCore, ecosystemDependencies], format: ['esm', 'cjs'], outDir: './lib/graphql', bundle: false, From 16a3cc193e8cf107d16819d8306680b742233930 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 12 May 2026 14:11:59 +0200 Subject: [PATCH 11/11] test: fix improper `graphql` import in tests --- test/browser/msw-api/setup-worker/listHandlers.mocks.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/browser/msw-api/setup-worker/listHandlers.mocks.ts b/test/browser/msw-api/setup-worker/listHandlers.mocks.ts index 9e135d161..624d4c61f 100644 --- a/test/browser/msw-api/setup-worker/listHandlers.mocks.ts +++ b/test/browser/msw-api/setup-worker/listHandlers.mocks.ts @@ -1,4 +1,5 @@ -import { http, graphql } from 'msw' +import { http } from 'msw' +import { graphql } from 'msw/graphql' import { setupWorker } from 'msw/browser' const resolver = () => void 0