@open-rpc/client-js
Advanced tools
Comparing version 1.7.1 to 1.8.0
@@ -0,1 +1,2 @@ | ||
import fetch from "isomorphic-fetch"; | ||
import { Transport } from "./Transport"; | ||
@@ -7,2 +8,3 @@ import { JSONRPCRequestData } from "../Request"; | ||
headers?: Record<string, string>; | ||
fetcher?: typeof fetch; | ||
} | ||
@@ -13,2 +15,3 @@ declare class HTTPTransport extends Transport { | ||
private readonly headers; | ||
private readonly injectedFetcher?; | ||
constructor(uri: string, options?: HTTPTransportOptions); | ||
@@ -15,0 +18,0 @@ connect(): Promise<any>; |
@@ -66,5 +66,8 @@ "use strict"; | ||
if (data instanceof Array) { | ||
return data.every(function (datum) { return datum.request.request.id === null || datum.request.request.id === undefined; }); | ||
return data.every(function (datum) { | ||
return datum.request.request.id === null || | ||
datum.request.request.id === undefined; | ||
}); | ||
} | ||
return (data.request.id === null || data.request.id === undefined); | ||
return data.request.id === null || data.request.id === undefined; | ||
}; | ||
@@ -74,2 +77,3 @@ _this.uri = uri; | ||
_this.headers = HTTPTransport.setupHeaders(options && options.headers); | ||
_this.injectedFetcher = options === null || options === void 0 ? void 0 : options.fetcher; | ||
return _this; | ||
@@ -83,3 +87,3 @@ } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var prom, notifications, batch, result, body, responseErr, e_1, responseErr; | ||
var prom, notifications, batch, fetcher, result, body, responseErr, e_1, responseErr; | ||
return __generator(this, function (_a) { | ||
@@ -91,6 +95,7 @@ switch (_a.label) { | ||
batch = Request_1.getBatchRequests(data); | ||
fetcher = this.injectedFetcher || isomorphic_fetch_1.default; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 4, , 5]); | ||
return [4 /*yield*/, isomorphic_fetch_1.default(this.uri, { | ||
return [4 /*yield*/, fetcher(this.uri, { | ||
method: "POST", | ||
@@ -97,0 +102,0 @@ headers: this.headers, |
@@ -81,3 +81,6 @@ "use strict"; | ||
data = reqMocks.generateMockRequest(1, "foo", ["bar"]); | ||
return [4 /*yield*/, httpTransport.sendData({ request: data, internalID: 1 })]; | ||
return [4 /*yield*/, httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
})]; | ||
case 1: | ||
@@ -98,3 +101,6 @@ result = _a.sent(); | ||
data = reqMocks.generateMockNotificationRequest("foo", ["bar"]); | ||
return [4 /*yield*/, httpTransport.sendData({ request: data, internalID: 1 })]; | ||
return [4 /*yield*/, httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
})]; | ||
case 1: | ||
@@ -127,3 +133,6 @@ result = _a.sent(); | ||
httpTransport = new HTTPTransport_1.HTTPTransport("http://localhost:8545/rpc-garbage"); | ||
data = { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }; | ||
data = { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}; | ||
return [4 /*yield*/, expect(httpTransport.sendData(data)).rejects.toThrowError("Bad response format")]; | ||
@@ -148,3 +157,6 @@ case 1: | ||
}, | ||
request: { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }, | ||
request: { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}, | ||
}; | ||
@@ -164,3 +176,6 @@ return [4 /*yield*/, expect(httpTransport.sendData([data])).rejects.toThrow("Bad response format")]; | ||
httpTransport = new HTTPTransport_1.HTTPTransport("http://localhost:8545/crash"); | ||
data = { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }; | ||
data = { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}; | ||
return [4 /*yield*/, expect(httpTransport.sendData(data)).rejects.toThrowError("Random Segfault that crashes fetch")]; | ||
@@ -233,2 +248,24 @@ case 1: | ||
}); }); | ||
it("accepts an injected fetcher", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var injectedFetchMock, httpTransport, data, result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
injectedFetchMock = isomorphic_fetch_1.default; | ||
httpTransport = new HTTPTransport_1.HTTPTransport("http://localhost:8545/rpc-notification", { | ||
fetcher: injectedFetchMock, | ||
}); | ||
data = reqMocks.generateMockNotificationRequest("foo", ["bar"]); | ||
return [4 /*yield*/, httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
})]; | ||
case 1: | ||
result = _a.sent(); | ||
expect(injectedFetchMock.mock.calls.length).toEqual(1); | ||
expect(result).toEqual(undefined); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
}); |
@@ -0,1 +1,13 @@ | ||
# [1.8.0](https://github.com/open-rpc/client-js/compare/1.7.1...1.8.0) (2023-01-04) | ||
### Bug Fixes | ||
* general updates ([1395a54](https://github.com/open-rpc/client-js/commit/1395a545912d64b2516d8f53d1ad564612379653)) | ||
### Features | ||
* **httptransport:** injected fetcher ([cd68627](https://github.com/open-rpc/client-js/commit/cd686279a98df680e0ac293532c71486235f71cb)) | ||
## [1.7.1](https://github.com/open-rpc/client-js/compare/1.7.0...1.7.1) (2021-08-20) | ||
@@ -2,0 +14,0 @@ |
{ | ||
"name": "@open-rpc/client-js", | ||
"version": "1.7.1", | ||
"version": "1.8.0", | ||
"description": " A browser-compatible JSON-RPC client with multiple transports.", | ||
@@ -22,6 +22,6 @@ "main": "build/index.js", | ||
"devDependencies": { | ||
"@types/isomorphic-fetch": "0.0.35", | ||
"@types/isomorphic-fetch": "0.0.36", | ||
"@types/jest": "^26.0.3", | ||
"@types/serve-handler": "^6.1.0", | ||
"@types/websocket": "1.0.1", | ||
"@types/websocket": "1.0.5", | ||
"@types/ws": "^7.2.0", | ||
@@ -38,3 +38,3 @@ "jest": "^25.1.0", | ||
"isomorphic-fetch": "^3.0.0", | ||
"isomorphic-ws": "^4.0.1", | ||
"isomorphic-ws": "^5.0.0", | ||
"strict-event-emitter-types": "^2.0.0", | ||
@@ -41,0 +41,0 @@ "ws": "^7.0.0" |
@@ -1,4 +0,4 @@ | ||
import {HTTPTransport, HTTPTransportOptions} from "./HTTPTransport"; | ||
import { HTTPTransport, HTTPTransportOptions } from "./HTTPTransport"; | ||
import * as reqMocks from "../__mocks__/requestData"; | ||
import _fetchMock from "isomorphic-fetch" | ||
import _fetchMock from "isomorphic-fetch"; | ||
const fetchMock = _fetchMock as jest.Mock<Promise<any>>; | ||
@@ -18,5 +18,10 @@ | ||
it("can send and retrieve request data", async () => { | ||
const httpTransport = new HTTPTransport("http://localhost:8545/rpc-request"); | ||
const httpTransport = new HTTPTransport( | ||
"http://localhost:8545/rpc-request" | ||
); | ||
const data = reqMocks.generateMockRequest(1, "foo", ["bar"]); | ||
const result = await httpTransport.sendData({ request: data, internalID: 1 }); | ||
const result = await httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
}); | ||
expect(result.method).toEqual("foo"); | ||
@@ -27,5 +32,10 @@ expect(result.params).toEqual(["bar"]); | ||
it("can send notification data", async () => { | ||
const httpTransport = new HTTPTransport("http://localhost:8545/rpc-notification"); | ||
const httpTransport = new HTTPTransport( | ||
"http://localhost:8545/rpc-notification" | ||
); | ||
const data = reqMocks.generateMockNotificationRequest("foo", ["bar"]); | ||
const result = await httpTransport.sendData({ request: data, internalID: 1 }); | ||
const result = await httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
}); | ||
expect(result).toEqual(undefined); | ||
@@ -37,13 +47,24 @@ }); | ||
const data = reqMocks.generateMockRequest(9, "foo", ["bar"]); | ||
await expect(httpTransport.sendData({ request: data, internalID: 9 })).rejects.toThrowError("Error message"); | ||
await expect( | ||
httpTransport.sendData({ request: data, internalID: 9 }) | ||
).rejects.toThrowError("Error message"); | ||
}); | ||
it("should throw error on bad data response", async () => { | ||
const httpTransport = new HTTPTransport("http://localhost:8545/rpc-garbage"); | ||
const data = { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }; | ||
await expect(httpTransport.sendData(data)).rejects.toThrowError("Bad response format"); | ||
const httpTransport = new HTTPTransport( | ||
"http://localhost:8545/rpc-garbage" | ||
); | ||
const data = { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}; | ||
await expect(httpTransport.sendData(data)).rejects.toThrowError( | ||
"Bad response format" | ||
); | ||
}); | ||
it("should throw error on bad data response from a batch", async (done) => { | ||
const httpTransport = new HTTPTransport("http://localhost:8545/rpc-garbage"); | ||
const httpTransport = new HTTPTransport( | ||
"http://localhost:8545/rpc-garbage" | ||
); | ||
const data = { | ||
@@ -55,5 +76,10 @@ resolve: (d: any) => ({}), | ||
}, | ||
request: { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }, | ||
request: { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}, | ||
}; | ||
await expect(httpTransport.sendData([data])).rejects.toThrow("Bad response format"); | ||
await expect(httpTransport.sendData([data])).rejects.toThrow( | ||
"Bad response format" | ||
); | ||
}); | ||
@@ -63,4 +89,9 @@ | ||
const httpTransport = new HTTPTransport("http://localhost:8545/crash"); | ||
const data = { request: reqMocks.generateMockRequest(9, "foo", ["bar"]), internalID: 9 }; | ||
await expect(httpTransport.sendData(data)).rejects.toThrowError("Random Segfault that crashes fetch"); | ||
const data = { | ||
request: reqMocks.generateMockRequest(9, "foo", ["bar"]), | ||
internalID: 9, | ||
}; | ||
await expect(httpTransport.sendData(data)).rejects.toThrowError( | ||
"Random Segfault that crashes fetch" | ||
); | ||
}); | ||
@@ -71,25 +102,42 @@ | ||
const data = reqMocks.generateMockRequest(1, "foo", ["bar"]); | ||
await httpTransport.sendData({request: data, internalID: 1}); | ||
await httpTransport.sendData({ request: data, internalID: 1 }); | ||
} | ||
it("sets content type to application/json", async () => { | ||
await callFetch({headers: {"Content-Type": "image/png"}}) | ||
const headers = fetchMock.mock.calls[0][1].headers | ||
expect(headers.get("Content-Type")).toEqual("application/json") | ||
await callFetch({ headers: { "Content-Type": "image/png" } }); | ||
const headers = fetchMock.mock.calls[0][1].headers; | ||
expect(headers.get("Content-Type")).toEqual("application/json"); | ||
}); | ||
it("sets header passed from options", async () => { | ||
const headerName = "Authorization" | ||
const headerValue = "Basic credentials" | ||
await callFetch({headers: {[headerName]: headerValue}}) | ||
const headers = fetchMock.mock.calls[0][1].headers | ||
expect(headers.get(headerName)).toEqual(headerValue) | ||
const headerName = "Authorization"; | ||
const headerValue = "Basic credentials"; | ||
await callFetch({ headers: { [headerName]: headerValue } }); | ||
const headers = fetchMock.mock.calls[0][1].headers; | ||
expect(headers.get(headerName)).toEqual(headerValue); | ||
}); | ||
it("sets credentials argument passed from options", async () => { | ||
const credentials = "include" | ||
await callFetch({credentials}) | ||
expect(fetchMock.mock.calls[0][1].credentials).toEqual(credentials) | ||
const credentials = "include"; | ||
await callFetch({ credentials }); | ||
expect(fetchMock.mock.calls[0][1].credentials).toEqual(credentials); | ||
}); | ||
it("accepts an injected fetcher", async () => { | ||
const injectedFetchMock = _fetchMock as jest.Mock<Promise<any>>; | ||
const httpTransport = new HTTPTransport( | ||
"http://localhost:8545/rpc-notification", | ||
{ | ||
fetcher: injectedFetchMock, | ||
} | ||
); | ||
const data = reqMocks.generateMockNotificationRequest("foo", ["bar"]); | ||
const result = await httpTransport.sendData({ | ||
request: data, | ||
internalID: 1, | ||
}); | ||
expect(injectedFetchMock.mock.calls.length).toEqual(1); | ||
expect(result).toEqual(undefined); | ||
}); | ||
}); | ||
import fetch from "isomorphic-fetch"; | ||
import { Transport } from "./Transport"; | ||
import { JSONRPCRequestData, getNotifications, getBatchRequests } from "../Request"; | ||
import { | ||
JSONRPCRequestData, | ||
getNotifications, | ||
getBatchRequests, | ||
} from "../Request"; | ||
import { ERR_UNKNOWN, JSONRPCError } from "../Error"; | ||
type CredentialsOption = "omit" | "same-origin" | "include" | ||
type CredentialsOption = "omit" | "same-origin" | "include"; | ||
interface HTTPTransportOptions { | ||
credentials?: CredentialsOption | ||
headers?: Record<string, string> | ||
credentials?: CredentialsOption; | ||
headers?: Record<string, string>; | ||
fetcher?: typeof fetch; | ||
} | ||
@@ -16,3 +21,4 @@ | ||
private readonly credentials?: CredentialsOption; | ||
private readonly headers: Headers | ||
private readonly headers: Headers; | ||
private readonly injectedFetcher?: typeof fetch; | ||
constructor(uri: string, options?: HTTPTransportOptions) { | ||
@@ -22,3 +28,4 @@ super(); | ||
this.credentials = options && options.credentials; | ||
this.headers = HTTPTransport.setupHeaders(options && options.headers) | ||
this.headers = HTTPTransport.setupHeaders(options && options.headers); | ||
this.injectedFetcher = options?.fetcher; | ||
} | ||
@@ -29,8 +36,12 @@ public connect(): Promise<any> { | ||
public async sendData(data: JSONRPCRequestData, timeout: number | null = null): Promise<any> { | ||
public async sendData( | ||
data: JSONRPCRequestData, | ||
timeout: number | null = null | ||
): Promise<any> { | ||
const prom = this.transportRequestManager.addRequest(data, timeout); | ||
const notifications = getNotifications(data); | ||
const batch = getBatchRequests(data); | ||
const fetcher = this.injectedFetcher || fetch; | ||
try { | ||
const result = await fetch(this.uri, { | ||
const result = await fetcher(this.uri, { | ||
method: "POST", | ||
@@ -56,4 +67,10 @@ headers: this.headers, | ||
const responseErr = new JSONRPCError(e.message, ERR_UNKNOWN, e); | ||
this.transportRequestManager.settlePendingRequest(notifications, responseErr); | ||
this.transportRequestManager.settlePendingRequest(getBatchRequests(data), responseErr); | ||
this.transportRequestManager.settlePendingRequest( | ||
notifications, | ||
responseErr | ||
); | ||
this.transportRequestManager.settlePendingRequest( | ||
getBatchRequests(data), | ||
responseErr | ||
); | ||
return Promise.reject(responseErr); | ||
@@ -65,16 +82,20 @@ } | ||
// tslint:disable-next-line:no-empty | ||
public close(): void { } | ||
public close(): void {} | ||
private onlyNotifications = (data: JSONRPCRequestData) => { | ||
if (data instanceof Array) { | ||
return data.every((datum) => datum.request.request.id === null || datum.request.request.id === undefined); | ||
return data.every( | ||
(datum) => | ||
datum.request.request.id === null || | ||
datum.request.request.id === undefined | ||
); | ||
} | ||
return (data.request.id === null || data.request.id === undefined); | ||
} | ||
return data.request.id === null || data.request.id === undefined; | ||
}; | ||
private static setupHeaders(headerOptions?: Record<string, string>): Headers { | ||
const headers = new Headers(headerOptions) | ||
const headers = new Headers(headerOptions); | ||
// Overwrite header options to ensure correct content type. | ||
headers.set("Content-Type", "application/json") | ||
return headers | ||
headers.set("Content-Type", "application/json"); | ||
return headers; | ||
} | ||
@@ -84,2 +105,2 @@ } | ||
export default HTTPTransport; | ||
export {HTTPTransport, HTTPTransportOptions, CredentialsOption} | ||
export { HTTPTransport, HTTPTransportOptions, CredentialsOption }; |
Sorry, the diff of this file is not supported yet
282591
103
5056
+ Addedisomorphic-ws@5.0.0(transitive)
- Removedisomorphic-ws@4.0.1(transitive)
Updatedisomorphic-ws@^5.0.0