-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Expand file tree
/
Copy pathindex.ts
More file actions
78 lines (67 loc) · 2.43 KB
/
Copy pathindex.ts
File metadata and controls
78 lines (67 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import type { GraphQLResponse, RequestParameters } from "relay-runtime";
import { Observable } from "relay-runtime";
import type { OperationVariables } from "@apollo/client";
import type { HttpLink } from "@apollo/client/link/http";
import { maybe } from "@apollo/client/utilities/internal/globals";
// eslint-disable-next-line local-rules/import-from-inside-other-export
import { readMultipartBody } from "../../../link/http/parseAndCheckHttpResponse.js";
// eslint-disable-next-line local-rules/import-from-inside-other-export
import { fallbackHttpConfig } from "../../../link/http/selectHttpOptionsAndBody.js";
const backupFetch = maybe(() => fetch);
type CreateMultipartSubscriptionOptions = {
fetch?: WindowOrWorkerGlobalScope["fetch"];
headers?: Record<string, string>;
};
export function createFetchMultipartSubscription(
uri: string,
{ fetch: preferredFetch, headers }: CreateMultipartSubscriptionOptions = {}
) {
return function fetchMultipartSubscription(
operation: RequestParameters,
variables: OperationVariables
): Observable<GraphQLResponse> {
const body: HttpLink.Body = {
operationName: operation.name,
variables,
query: operation.text || "",
};
const options = generateOptionsForMultipartSubscription(headers || {});
return Observable.create((sink) => {
try {
options.body = JSON.stringify(body);
} catch (parseError) {
sink.error(parseError as Error);
}
const currentFetch = preferredFetch || maybe(() => fetch) || backupFetch;
const observerNext = sink.next.bind(sink);
currentFetch!(uri, options)
.then((response) => {
const ctype = response.headers?.get("content-type");
if (ctype !== null && /^multipart\/mixed/i.test(ctype)) {
return readMultipartBody(response, observerNext);
}
sink.error(new Error("Expected multipart response"));
})
.then(() => {
sink.complete();
})
.catch((err: any) => {
sink.error(err);
});
});
};
}
function generateOptionsForMultipartSubscription(
headers: Record<string, string>
) {
const options: { headers: Record<string, any>; body?: string } = {
...fallbackHttpConfig.options,
headers: {
...(headers || {}),
...fallbackHttpConfig.headers,
accept:
"multipart/mixed;boundary=graphql;subscriptionSpec=1.0,application/json",
},
};
return options;
}