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: exclude operation name via a field in RequestConfig #645

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Minimal GraphQL client supporting Node and browsers for scripts or simple apps
- [None (default)](#none-default)
- [Ignore](#ignore)
- [All](#all)
- [IgnoreOperationName](#ignoreoperationname)
- [Knowledge Base](#knowledge-base)
- [Why was the file upload feature taken away? Will it return?](#why-was-the-file-upload-feature-taken-away-will-it-return)
- [Why do I have to install `graphql`?](#why-do-i-have-to-install-graphql)
Expand Down Expand Up @@ -152,6 +153,15 @@ Ignore incoming errors and resolve like no errors occurred

Return both the errors and data, only works with `rawRequest`.

### IgnoreOperationName

By default the GraphQLClient tries to extract the operationName from the document.
You can define `ignoreOperationName` in the constructor of GraphQLClient to avoid the extraction process if it is not needed.

```ts
const client = new GraphQLClient(endpoint, { ignoreOperationName: true })
```

Copy link
Member

Choose a reason for hiding this comment

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

Could you explain the following:

  • Example of document sent, ignored vs not ignored
  • Why this matters

Links to other information sources are fine.

Copy link
Contributor Author

@robertobadalamenti robertobadalamenti Jan 19, 2024

Choose a reason for hiding this comment

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

I have created a new commit with an updated readme that I hope answers your questions. Feel free to ask me anything, I will be happy to answer.

## Knowledge Base

#### Why was the file upload feature taken away? Will it return?
Expand Down
15 changes: 13 additions & 2 deletions src/graphql-ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ export type SocketHandler = {
onClose?: () => any
}

export type SocketClientConfig = {
ignoreOperationName?: boolean
}

export type UnsubscribeCallback = () => void

export interface GraphQLSubscriber<T, E = unknown> {
Expand All @@ -89,11 +93,18 @@ export class GraphQLWebSocketClient {
static PROTOCOL = `graphql-transport-ws`

private socket: WebSocket
private ignoreOperationName: boolean | undefined
private socketState: SocketState = { acknowledged: false, lastRequestId: 0, subscriptions: {} }

constructor(socket: WebSocket, { onInit, onAcknowledged, onPing, onPong }: SocketHandler) {
constructor(
socket: WebSocket,
{ onInit, onAcknowledged, onPing, onPong }: SocketHandler,
socketClientConfg?: SocketClientConfig,
) {
this.socket = socket

this.ignoreOperationName = socketClientConfg?.ignoreOperationName

socket.addEventListener(`open`, async (e) => {
this.socketState.acknowledged = false
this.socketState.subscriptions = {}
Expand Down Expand Up @@ -236,7 +247,7 @@ export class GraphQLWebSocketClient {
subscriber: GraphQLSubscriber<T, E>,
variables?: V,
): UnsubscribeCallback {
const { query, operationName } = resolveRequestDocument(document)
const { query, operationName } = resolveRequestDocument(document, this.ignoreOperationName)
return this.makeSubscribe(query, operationName, subscriber, variables)
}

Expand Down
10 changes: 6 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,15 @@ class GraphQLClient {
method = `POST`,
requestMiddleware,
responseMiddleware,
ignoreOperationName,
...fetchOptions
} = this.requestConfig
const { url } = this
if (rawRequestOptions.signal !== undefined) {
fetchOptions.signal = rawRequestOptions.signal
}

const { operationName } = resolveRequestDocument(rawRequestOptions.query)
const { operationName } = resolveRequestDocument(rawRequestOptions.query, ignoreOperationName)

return makeRequest<T, V>({
url,
Expand Down Expand Up @@ -261,14 +262,15 @@ class GraphQLClient {
method = `POST`,
requestMiddleware,
responseMiddleware,
ignoreOperationName,
...fetchOptions
} = this.requestConfig
const { url } = this
if (requestOptions.signal !== undefined) {
fetchOptions.signal = requestOptions.signal
}

const { query, operationName } = resolveRequestDocument(requestOptions.document)
const { query, operationName } = resolveRequestDocument(requestOptions.document, ignoreOperationName)

return makeRequest<T>({
url,
Expand Down Expand Up @@ -308,14 +310,14 @@ class GraphQLClient {
// prettier-ignore
batchRequests<T extends BatchResult, V extends Variables = Variables>(documentsOrOptions: BatchRequestDocument<V>[] | BatchRequestsOptions<V>, requestHeaders?: HeadersInit): Promise<T> {
const batchRequestOptions = parseBatchRequestArgs<V>(documentsOrOptions, requestHeaders)
const { headers, ...fetchOptions } = this.requestConfig
const { headers, ignoreOperationName, ...fetchOptions } = this.requestConfig

if (batchRequestOptions.signal !== undefined) {
fetchOptions.signal = batchRequestOptions.signal
}

const queries = batchRequestOptions.documents.map(
({ document }) => resolveRequestDocument(document).query
({ document }) => resolveRequestDocument(document, ignoreOperationName).query
)
const variables = batchRequestOptions.documents.map(({ variables }) => variables)

Expand Down
9 changes: 8 additions & 1 deletion src/resolveRequestDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,13 @@ const extractOperationName = (document: DocumentNode): string | undefined => {

export const resolveRequestDocument = (
document: RequestDocument,
ignoreOperationName?: boolean,
): { query: string; operationName?: string } => {
if (typeof document === `string`) {
if (ignoreOperationName) {
return { query: document }
}

let operationName = undefined

try {
Expand All @@ -42,7 +47,9 @@ export const resolveRequestDocument = (

return { query: document, operationName }
}

if (ignoreOperationName) {
return { query: print(document) }
}
const operationName = extractOperationName(document)

return { query: print(document), operationName }
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export interface RequestConfig extends Omit<RequestInit, 'headers' | 'method'>,
requestMiddleware?: RequestMiddleware
responseMiddleware?: ResponseMiddleware
jsonSerializer?: JsonSerializer
ignoreOperationName?: boolean
}

export type BatchRequestDocument<V extends Variables = Variables> = {
Expand Down