mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 09:46:16 +01:00
added subscription api to apiClient
This commit is contained in:
@@ -49,6 +49,7 @@
|
||||
"@scm-manager/ui-types": "^2.0.0-SNAPSHOT",
|
||||
"classnames": "^2.2.6",
|
||||
"date-fns": "^2.4.1",
|
||||
"event-source-polyfill": "^1.0.9",
|
||||
"query-string": "5",
|
||||
"react": "^16.8.6",
|
||||
"react-diff-view": "^1.8.1",
|
||||
|
||||
@@ -1,6 +1,36 @@
|
||||
import { contextPath } from "./urls";
|
||||
import { createBackendError, ForbiddenError, isBackendError, UnauthorizedError } from "./errors";
|
||||
import { BackendErrorContent } from "./errors";
|
||||
// @ts-ignore we have not types for event-source-polyfill
|
||||
import { EventSourcePolyfill } from "event-source-polyfill";
|
||||
import { createBackendError, ForbiddenError, isBackendError, UnauthorizedError, BackendErrorContent } from "./errors";
|
||||
|
||||
type SubscriptionEvent = {
|
||||
type: string;
|
||||
};
|
||||
|
||||
type OpenEvent = SubscriptionEvent;
|
||||
|
||||
type ErrorEvent = SubscriptionEvent & {
|
||||
error: Error;
|
||||
};
|
||||
|
||||
type MessageEvent = SubscriptionEvent & {
|
||||
data: string;
|
||||
lastEventId?: string;
|
||||
};
|
||||
|
||||
type MessageListeners = {
|
||||
[eventType: string]: (event: MessageEvent) => void;
|
||||
};
|
||||
|
||||
type SubscriptionContext = {
|
||||
onOpen?: OpenEvent;
|
||||
onMessage: MessageListeners;
|
||||
onError?: ErrorEvent;
|
||||
};
|
||||
|
||||
type SubscriptionArgument = MessageListeners | SubscriptionContext;
|
||||
|
||||
type Cancel = () => void;
|
||||
|
||||
const sessionId = (
|
||||
Date.now().toString(36) +
|
||||
@@ -33,28 +63,34 @@ const extractXsrfToken = () => {
|
||||
return extractXsrfTokenFromCookie(document.cookie);
|
||||
};
|
||||
|
||||
const applyFetchOptions: (p: RequestInit) => RequestInit = o => {
|
||||
if (!o.headers) {
|
||||
o.headers = {};
|
||||
}
|
||||
|
||||
// @ts-ignore We are sure that here we only get headers of type Record<string, string>
|
||||
const headers: Record<string, string> = o.headers;
|
||||
headers["Cache"] = "no-cache";
|
||||
// identify the request as ajax request
|
||||
headers["X-Requested-With"] = "XMLHttpRequest";
|
||||
// identify the web interface
|
||||
headers["X-SCM-Client"] = "WUI";
|
||||
// identify the window session
|
||||
headers["X-SCM-Session-ID"] = sessionId
|
||||
const createRequestHeaders = () => {
|
||||
const headers: { [key: string]: string } = {
|
||||
// disable caching for now
|
||||
Cache: "no-cache",
|
||||
// identify the request as ajax request
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
// identify the web interface
|
||||
"X-SCM-Client": "WUI",
|
||||
// identify the window session
|
||||
"X-SCM-Session-ID": sessionId
|
||||
};
|
||||
|
||||
const xsrf = extractXsrfToken();
|
||||
if (xsrf) {
|
||||
headers["X-XSRF-Token"] = xsrf;
|
||||
}
|
||||
return headers;
|
||||
};
|
||||
|
||||
const applyFetchOptions: (p: RequestInit) => RequestInit = o => {
|
||||
if (o.headers) {
|
||||
o.headers = {
|
||||
...createRequestHeaders()
|
||||
};
|
||||
} else {
|
||||
o.headers = createRequestHeaders();
|
||||
}
|
||||
o.credentials = "same-origin";
|
||||
o.headers = headers;
|
||||
return o;
|
||||
};
|
||||
|
||||
@@ -174,12 +210,39 @@ class ApiClient {
|
||||
if (!options.headers) {
|
||||
options.headers = {};
|
||||
}
|
||||
// @ts-ignore We are sure that here we only get headers of type Record<string, string>
|
||||
// @ts-ignore We are sure that here we only get headers of type {[name:string]: string}
|
||||
options.headers["Content-Type"] = contentType;
|
||||
}
|
||||
|
||||
return fetch(createUrl(url), options).then(handleFailure);
|
||||
}
|
||||
|
||||
subscribe(url: string, argument: SubscriptionArgument): Cancel {
|
||||
const es = new EventSourcePolyfill(createUrl(url), {
|
||||
withCredentials: true,
|
||||
headers: createRequestHeaders()
|
||||
});
|
||||
|
||||
let listeners: MessageListeners;
|
||||
// type guard, to identify that argument is of type SubscriptionContext
|
||||
if ("onMessage" in argument) {
|
||||
listeners = (argument as SubscriptionContext).onMessage;
|
||||
if (argument.onError) {
|
||||
es.onerror = argument.onError;
|
||||
}
|
||||
if (argument.onOpen) {
|
||||
es.onopen = argument.onOpen;
|
||||
}
|
||||
} else {
|
||||
listeners = argument;
|
||||
}
|
||||
|
||||
for (const type in listeners) {
|
||||
es.addEventListener(type, listeners[type]);
|
||||
}
|
||||
|
||||
return es.close;
|
||||
}
|
||||
}
|
||||
|
||||
export const apiClient = new ApiClient();
|
||||
|
||||
@@ -6539,6 +6539,11 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
event-source-polyfill@^1.0.9:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/event-source-polyfill/-/event-source-polyfill-1.0.9.tgz#1fe3ebf8e3faddafd4fc237424f5e5ab2706b6d0"
|
||||
integrity sha512-+x0BMKTYwZcmGmlkHK0GsXkX1+otfEwqu3QitN0wmWuHaZniw3HeIx1k5OjWX3JUHQHlPS4yONol6eokS1ZAWg==
|
||||
|
||||
eventemitter3@^3.1.0:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
|
||||
|
||||
Reference in New Issue
Block a user