parent
723249d36c
commit
9ae6b70efb
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"author": "Richard Moore <me@ricmoo.com>",
|
"author": "Richard Moore <me@ricmoo.com>",
|
||||||
"browser": {
|
"browser": {
|
||||||
"./ipc-provider": "./lib/browser-ipc-provider.js",
|
"./lib/ipc-provider": "./lib/browser-ipc-provider.js",
|
||||||
"net": "./lib/browser-net.js",
|
"net": "./lib/browser-net.js",
|
||||||
"ws": "./lib/browser-ws.js"
|
"ws": "./lib/browser-ws.js"
|
||||||
},
|
},
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
import { Logger } from "@ethersproject/logger";
|
import { Logger } from "@ethersproject/logger";
|
||||||
import { version } from "./_version";
|
import { version } from "./_version";
|
||||||
|
|
||||||
let WS = (WebSocket as any);
|
let WS: any = null;
|
||||||
|
|
||||||
if (WS == null) {
|
try {
|
||||||
|
WS = (WebSocket as any);
|
||||||
|
if (WS == null) { throw new Error("inject please"); }
|
||||||
|
} catch (error) {
|
||||||
const logger = new Logger(version);
|
const logger = new Logger(version);
|
||||||
WS = function() {
|
WS = function() {
|
||||||
logger.throwError("WebSockets not supported in this environment", Logger.errors.UNSUPPORTED_OPERATION, {
|
logger.throwError("WebSockets not supported in this environment", Logger.errors.UNSUPPORTED_OPERATION, {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
{
|
{
|
||||||
"author": "Richard Moore <me@ricmoo.com>",
|
"author": "Richard Moore <me@ricmoo.com>",
|
||||||
|
"browser": {
|
||||||
|
"./lib/geturl": "./lib/browser-geturl.js"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersproject/base64": ">=5.0.0-beta.126",
|
"@ethersproject/base64": ">=5.0.0-beta.126",
|
||||||
"@ethersproject/logger": ">=5.0.0-beta.129",
|
"@ethersproject/logger": ">=5.0.0-beta.129",
|
||||||
"@ethersproject/properties": ">=5.0.0-beta.131",
|
"@ethersproject/properties": ">=5.0.0-beta.131",
|
||||||
"@ethersproject/strings": ">=5.0.0-beta.130",
|
"@ethersproject/strings": ">=5.0.0-beta.130"
|
||||||
"cross-fetch": "3.0.4"
|
|
||||||
},
|
},
|
||||||
"description": "Utility fucntions for managing web requests for ethers.",
|
"description": "Utility fucntions for managing web requests for ethers.",
|
||||||
"ethereum": "donations.ethers.eth",
|
"ethereum": "donations.ethers.eth",
|
||||||
|
51
packages/web/src.ts/browser-geturl.ts
Normal file
51
packages/web/src.ts/browser-geturl.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
export type GetUrlResponse = {
|
||||||
|
statusCode: number,
|
||||||
|
statusMessage: string;
|
||||||
|
headers: { [ key: string] : string };
|
||||||
|
body: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Options = {
|
||||||
|
method?: string,
|
||||||
|
body?: string
|
||||||
|
headers?: { [ key: string] : string },
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getUrl(href: string, options?: Options): Promise<GetUrlResponse> {
|
||||||
|
if (options == null) { options = { }; }
|
||||||
|
|
||||||
|
const request = {
|
||||||
|
method: (options.method || "GET"),
|
||||||
|
headers: (options.headers || { }),
|
||||||
|
body: (options.body || undefined),
|
||||||
|
|
||||||
|
mode: <RequestMode>"cors", // no-cors, cors, *same-origin
|
||||||
|
cache: <RequestCache>"no-cache", // *default, no-cache, reload, force-cache, only-if-cached
|
||||||
|
credentials: <RequestCredentials>"same-origin", // include, *same-origin, omit
|
||||||
|
redirect: <RequestRedirect>"follow", // manual, *follow, error
|
||||||
|
referrer: "client", // no-referrer, *client
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch(href, request);
|
||||||
|
const body = await response.text();
|
||||||
|
|
||||||
|
const headers: { [ name: string ]: string } = { };
|
||||||
|
if (response.headers.forEach) {
|
||||||
|
response.headers.forEach((value, key) => {
|
||||||
|
headers[key.toLowerCase()] = value;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
(<() => Array<string>>((<any>(response.headers)).keys))().forEach((key) => {
|
||||||
|
headers[key.toLowerCase()] = response.headers.get(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
headers: headers,
|
||||||
|
statusCode: response.status,
|
||||||
|
statusMessage: response.statusText,
|
||||||
|
body: body,
|
||||||
|
}
|
||||||
|
}
|
95
packages/web/src.ts/geturl.ts
Normal file
95
packages/web/src.ts/geturl.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import http from "http";
|
||||||
|
import https from "https";
|
||||||
|
import { URL } from "url"
|
||||||
|
|
||||||
|
import { Logger } from "@ethersproject/logger";
|
||||||
|
import { version } from "./_version";
|
||||||
|
const logger = new Logger(version);
|
||||||
|
|
||||||
|
export type GetUrlResponse = {
|
||||||
|
statusCode: number,
|
||||||
|
statusMessage: string;
|
||||||
|
headers: { [ key: string] : string };
|
||||||
|
body: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Options = {
|
||||||
|
method?: string,
|
||||||
|
body?: string
|
||||||
|
headers?: { [ key: string] : string },
|
||||||
|
};
|
||||||
|
|
||||||
|
function getResponse(request: http.ClientRequest): Promise<GetUrlResponse> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
request.once("response", (resp: http.IncomingMessage) => {
|
||||||
|
const response: GetUrlResponse = {
|
||||||
|
statusCode: resp.statusCode,
|
||||||
|
statusMessage: resp.statusMessage,
|
||||||
|
headers: Object.keys(resp.headers).reduce((accum, name) => {
|
||||||
|
let value = resp.headers[name];
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value = value.join(", ");
|
||||||
|
}
|
||||||
|
accum[name] = value;
|
||||||
|
return accum;
|
||||||
|
}, <{ [ name: string ]: string }>{ }),
|
||||||
|
body: null
|
||||||
|
};
|
||||||
|
resp.setEncoding("utf8");
|
||||||
|
|
||||||
|
resp.on("data", (chunk: string) => {
|
||||||
|
if (response.body == null) { response.body = ""; }
|
||||||
|
response.body += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
resp.on("end", () => {
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
resp.on("error", (error) => {
|
||||||
|
(<any>error).response = response;
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("error", (error) => { reject(error); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getUrl(href: string, options?: Options): Promise<GetUrlResponse> {
|
||||||
|
if (options == null) { options = { }; }
|
||||||
|
|
||||||
|
const url = new URL(href);
|
||||||
|
|
||||||
|
const request = {
|
||||||
|
method: (options.method || "GET"),
|
||||||
|
headers: (options.headers || { }),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req: http.ClientRequest = null;
|
||||||
|
switch (url.protocol) {
|
||||||
|
case "http:": {
|
||||||
|
req = http.request(url, request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "https:":
|
||||||
|
req = https.request(url, request);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.throwError(`unsupported protocol ${ url.protocol }`, Logger.errors.UNSUPPORTED_OPERATION, {
|
||||||
|
protocol: url.protocol,
|
||||||
|
operation: "request"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.body) {
|
||||||
|
req.write(options.body);
|
||||||
|
}
|
||||||
|
req.end();
|
||||||
|
|
||||||
|
const response = await getResponse(req);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import fetch from "cross-fetch";
|
|
||||||
|
|
||||||
import { encode as base64Encode } from "@ethersproject/base64";
|
import { encode as base64Encode } from "@ethersproject/base64";
|
||||||
import { shallowCopy } from "@ethersproject/properties";
|
import { shallowCopy } from "@ethersproject/properties";
|
||||||
import { toUtf8Bytes } from "@ethersproject/strings";
|
import { toUtf8Bytes } from "@ethersproject/strings";
|
||||||
@ -10,6 +8,8 @@ import { Logger } from "@ethersproject/logger";
|
|||||||
import { version } from "./_version";
|
import { version } from "./_version";
|
||||||
const logger = new Logger(version);
|
const logger = new Logger(version);
|
||||||
|
|
||||||
|
import { getUrl, GetUrlResponse } from "./geturl";
|
||||||
|
|
||||||
// Exported Types
|
// Exported Types
|
||||||
export type ConnectionInfo = {
|
export type ConnectionInfo = {
|
||||||
url: string,
|
url: string,
|
||||||
@ -36,31 +36,12 @@ export type PollOptions = {
|
|||||||
|
|
||||||
export type FetchJsonResponse = {
|
export type FetchJsonResponse = {
|
||||||
statusCode: number;
|
statusCode: number;
|
||||||
status: string;
|
|
||||||
headers: { [ header: string ]: string };
|
headers: { [ header: string ]: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
type Header = { key: string, value: string };
|
type Header = { key: string, value: string };
|
||||||
|
|
||||||
function getResponse(response: Response): FetchJsonResponse {
|
|
||||||
const headers: { [ header: string ]: string } = { };
|
|
||||||
if (response.headers.forEach) {
|
|
||||||
response.headers.forEach((value, key) => {
|
|
||||||
headers[key.toLowerCase()] = value;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
(<() => Array<string>>((<any>(response.headers)).keys))().forEach((key) => {
|
|
||||||
headers[key.toLowerCase()] = response.headers.get(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: response.status,
|
|
||||||
status: response.statusText,
|
|
||||||
headers: headers
|
|
||||||
};
|
|
||||||
}
|
|
||||||
export function fetchJson(connection: string | ConnectionInfo, json?: string, processFunc?: (value: any, response: FetchJsonResponse) => any): Promise<any> {
|
export function fetchJson(connection: string | ConnectionInfo, json?: string, processFunc?: (value: any, response: FetchJsonResponse) => any): Promise<any> {
|
||||||
const headers: { [key: string]: Header } = { };
|
const headers: { [key: string]: Header } = { };
|
||||||
|
|
||||||
@ -69,11 +50,6 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||||||
// @TODO: Allow ConnectionInfo to override some of these values
|
// @TODO: Allow ConnectionInfo to override some of these values
|
||||||
const options: any = {
|
const options: any = {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
mode: "cors", // no-cors, cors, *same-origin
|
|
||||||
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
|
|
||||||
credentials: "same-origin", // include, *same-origin, omit
|
|
||||||
redirect: "follow", // manual, *follow, error
|
|
||||||
referrer: "client", // no-referrer, *client
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let allow304 = false;
|
let allow304 = false;
|
||||||
@ -157,33 +133,27 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||||||
|
|
||||||
const runningFetch = (async function() {
|
const runningFetch = (async function() {
|
||||||
|
|
||||||
let response: Response = null;
|
let response: GetUrlResponse = null;
|
||||||
let body: string = null;
|
try {
|
||||||
|
response = await getUrl(url, options);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
response = (<any>error).response;
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
let body = response.body;
|
||||||
try {
|
|
||||||
response = await fetch(url, options);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
body = await response.text();
|
|
||||||
|
|
||||||
if (allow304 && response.status === 304) {
|
if (allow304 && response.statusCode === 304) {
|
||||||
body = null;
|
body = null;
|
||||||
break;
|
|
||||||
|
|
||||||
} else if (!response.ok) {
|
} else if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||||
runningTimeout.cancel();
|
runningTimeout.cancel();
|
||||||
logger.throwError("bad response", Logger.errors.SERVER_ERROR, {
|
logger.throwError("bad response", Logger.errors.SERVER_ERROR, {
|
||||||
status: response.status,
|
status: response.statusCode,
|
||||||
body: body,
|
headers: response.headers,
|
||||||
type: response.type,
|
body: body,
|
||||||
url: response.url
|
url: url
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runningTimeout.cancel();
|
runningTimeout.cancel();
|
||||||
@ -203,7 +173,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||||||
|
|
||||||
if (processFunc) {
|
if (processFunc) {
|
||||||
try {
|
try {
|
||||||
json = await processFunc(json, getResponse(response));
|
json = await processFunc(json, response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.throwError("processing response error", Logger.errors.SERVER_ERROR, {
|
logger.throwError("processing response error", Logger.errors.SERVER_ERROR, {
|
||||||
body: json,
|
body: json,
|
||||||
|
19
packages/web/thirdparty.d.ts
vendored
19
packages/web/thirdparty.d.ts
vendored
@ -1,17 +1,4 @@
|
|||||||
declare module "xmlhttprequest" {
|
declare module "node-fetch" {
|
||||||
export class XMLHttpRequest {
|
function fetch(url: string, options: any): Promise<Response>;
|
||||||
readyState: number;
|
export default fetch;
|
||||||
status: number;
|
|
||||||
responseText: string;
|
|
||||||
|
|
||||||
constructor();
|
|
||||||
open(method: string, url: string, async?: boolean): void;
|
|
||||||
setRequestHeader(key: string, value: string): void;
|
|
||||||
send(body?: string): void;
|
|
||||||
abort(): void;
|
|
||||||
|
|
||||||
onreadystatechange: () => void;
|
|
||||||
onerror: (error: Error) => void;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
import resolve from 'rollup-plugin-node-resolve';
|
import resolve from 'rollup-plugin-node-resolve';
|
||||||
import commonjs from 'rollup-plugin-commonjs';
|
import commonjs from 'rollup-plugin-commonjs';
|
||||||
import json from 'rollup-plugin-json';
|
import json from 'rollup-plugin-json';
|
||||||
@ -8,9 +10,10 @@ import { terser } from "rollup-plugin-terser";
|
|||||||
|
|
||||||
import { createFilter } from 'rollup-pluginutils';
|
import { createFilter } from 'rollup-pluginutils';
|
||||||
|
|
||||||
function Replacer(options = {}) {
|
function Replacer(basePath, options = {}) {
|
||||||
const filter = createFilter(options.include, options.exclude);
|
const filter = createFilter(options.include, options.exclude);
|
||||||
let suffixes = Object.keys(options.replace);
|
const suffixes = Object.keys(options.replace);
|
||||||
|
const pathUp = path.resolve(basePath, "..");
|
||||||
return {
|
return {
|
||||||
name: "file-replacer",
|
name: "file-replacer",
|
||||||
transform(code, id) {
|
transform(code, id) {
|
||||||
@ -26,14 +29,20 @@ function Replacer(options = {}) {
|
|||||||
for (let i = 0; i < suffixes.length; i++) {
|
for (let i = 0; i < suffixes.length; i++) {
|
||||||
const suffix = suffixes[i];
|
const suffix = suffixes[i];
|
||||||
if (id.match(new RegExp(suffix))) {
|
if (id.match(new RegExp(suffix))) {
|
||||||
let newCode = options.replace[suffix];
|
const newCode = options.replace[suffix];
|
||||||
console.log(`Replace: ${ id } (${ code.length } => ${ newCode.length })`);
|
console.log(`Replace: ${ id.substring(pathUp.length + 1) } (${ code.length } => ${ newCode.length })`);
|
||||||
return {
|
return {
|
||||||
code: newCode,
|
code: newCode,
|
||||||
map: { mappings: '' }
|
map: { mappings: '' }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id.substring(0, basePath.length) !== basePath) {
|
||||||
|
console.log(`Keep: ${ id.substring(pathUp.length + 1) }`);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -48,11 +57,7 @@ const ellipticPackage = (function() {
|
|||||||
return JSON.stringify({ version: ellipticPackage.version });
|
return JSON.stringify({ version: ellipticPackage.version });
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export default commandLineArgs => {
|
function getConfig(minify, buildModule, testing) {
|
||||||
let minify = commandLineArgs.configMinify;
|
|
||||||
let buildModule = commandLineArgs.configModule;
|
|
||||||
let testing = commandLineArgs.configTest;
|
|
||||||
|
|
||||||
let input = "packages/ethers/lib/index.js"
|
let input = "packages/ethers/lib/index.js"
|
||||||
let output = [ "umd" ];
|
let output = [ "umd" ];
|
||||||
let format = "umd";
|
let format = "umd";
|
||||||
@ -65,7 +70,7 @@ export default commandLineArgs => {
|
|||||||
mainFields = [ "browser", "module", "main" ];
|
mainFields = [ "browser", "module", "main" ];
|
||||||
}
|
}
|
||||||
|
|
||||||
const replacer = Replacer({
|
const replacer = Replacer(path.resolve("packages"), {
|
||||||
replace: {
|
replace: {
|
||||||
// Remove the precomputed secp256k1 points
|
// Remove the precomputed secp256k1 points
|
||||||
"elliptic/lib/elliptic/precomputed/secp256k1.js$": undef,
|
"elliptic/lib/elliptic/precomputed/secp256k1.js$": undef,
|
||||||
@ -108,9 +113,11 @@ export default commandLineArgs => {
|
|||||||
plugins.push(terser());
|
plugins.push(terser());
|
||||||
}
|
}
|
||||||
|
|
||||||
let outputFile = (("packages/") +
|
const outputFile = [
|
||||||
(testing ? "tests": "ethers") +
|
"packages",
|
||||||
("/dist/ethers." + output.join(".") + ".js"));
|
(testing ? "tests": "ethers"),
|
||||||
|
("/dist/ethers." + output.join(".") + ".js")
|
||||||
|
].join("/");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
input: input,
|
input: input,
|
||||||
@ -125,3 +132,18 @@ export default commandLineArgs => {
|
|||||||
plugins: plugins
|
plugins: plugins
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default commandLineArgs => {
|
||||||
|
const testing = commandLineArgs.configTest;
|
||||||
|
|
||||||
|
if (commandLineArgs.configAll) {
|
||||||
|
return [
|
||||||
|
getConfig(false, false, testing),
|
||||||
|
getConfig(false, true, testing),
|
||||||
|
getConfig(true, false, testing),
|
||||||
|
getConfig(true, true, testing)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return getConfig(commandLineArgs.configMinify, commandLineArgs.configModule, testing);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user