Enable cookie jar for Node client using request package (#3202)
This commit is contained in:
parent
36ca210a65
commit
865de16086
|
|
@ -103,6 +103,17 @@ namespace FunctionalTests
|
|||
routes.MapConnectionHandler<EchoConnectionHandler>("/echo");
|
||||
});
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.Value.Contains("/negotiate"))
|
||||
{
|
||||
context.Response.Cookies.Append("testCookie", "testValue");
|
||||
context.Response.Cookies.Append("testCookie2", "testValue2");
|
||||
context.Response.Cookies.Append("expiredCookie", "doesntmatter", new CookieOptions() { Expires = DateTimeOffset.Now.AddHours(-1) });
|
||||
}
|
||||
await next.Invoke();
|
||||
});
|
||||
|
||||
app.UseSignalR(routes =>
|
||||
{
|
||||
routes.MapHub<TestHub>("/testhub");
|
||||
|
|
|
|||
|
|
@ -88,5 +88,15 @@ namespace FunctionalTests
|
|||
{
|
||||
return Context.GetHttpContext().Request.Headers["Content-Type"];
|
||||
}
|
||||
|
||||
public string GetCookie(string cookieName)
|
||||
{
|
||||
var cookies = Context.GetHttpContext().Request.Cookies;
|
||||
if (cookies.TryGetValue(cookieName, out var cookieValue))
|
||||
{
|
||||
return cookieValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,123 @@
|
|||
"version": "file:../signalr",
|
||||
"requires": {
|
||||
"eventsource": "^1.0.7",
|
||||
"request": "^2.88.0",
|
||||
"ws": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/caseless": {
|
||||
"version": "0.12.1",
|
||||
"bundled": true
|
||||
},
|
||||
"@types/eventsource": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"@types/form-data": {
|
||||
"version": "2.2.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.9.4",
|
||||
"bundled": true
|
||||
},
|
||||
"@types/request": {
|
||||
"version": "2.47.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"@types/caseless": "*",
|
||||
"@types/form-data": "*",
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*"
|
||||
}
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.3",
|
||||
"bundled": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "5.5.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"co": "^4.6.0",
|
||||
"fast-deep-equal": "^1.0.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"bundled": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"bundled": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"bundled": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"bundled": true
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"bundled": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
|
|
@ -33,16 +138,110 @@
|
|||
"original": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"bundled": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"bundled": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ajv": "^5.3.0",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"bundled": true
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.11.0",
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"bundled": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.3.1",
|
||||
"bundled": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.37.0",
|
||||
"bundled": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.21",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"mime-db": "~1.37.0"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"bundled": true
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -52,25 +251,98 @@
|
|||
"url-parse": "^1.4.3"
|
||||
}
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"bundled": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.1.29",
|
||||
"bundled": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"bundled": true
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true
|
||||
},
|
||||
"typedarray-to-buffer": {
|
||||
"version": "3.1.5",
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"bundled": true
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.15.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"is-typedarray": "^1.0.0"
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"bundled": true
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.3",
|
||||
"bundled": true,
|
||||
|
|
@ -79,14 +351,17 @@
|
|||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"websocket": {
|
||||
"version": "1.0.26",
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"bundled": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"debug": "^2.2.0",
|
||||
"nan": "^2.3.3",
|
||||
"typedarray-to-buffer": "^3.1.2",
|
||||
"yaeti": "^0.0.6"
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
|
|
@ -95,10 +370,6 @@
|
|||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"yaeti": {
|
||||
"version": "0.0.6",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -200,10 +471,6 @@
|
|||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"bundled": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
|
|
@ -2819,9 +3086,9 @@
|
|||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
|
||||
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ChildProcess, execSync, spawn } from "child_process";
|
||||
import { ChildProcess, exec, spawn } from "child_process";
|
||||
import { EOL } from "os";
|
||||
import { Readable } from "stream";
|
||||
|
||||
|
|
@ -163,26 +163,23 @@ function runJest(url: string) {
|
|||
const configPath = path.resolve(__dirname, "..", "func.jest.config.js");
|
||||
|
||||
console.log("Starting Node tests using Jest.");
|
||||
try {
|
||||
execSync(`"${process.execPath}" "${jestPath}" --config "${configPath}"`, { env: { SERVER_URL: url }, timeout: 200000 });
|
||||
return 0;
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
console.log(error.stderr);
|
||||
console.log(error.stdout);
|
||||
return error.status || 1;
|
||||
}
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
const logStream = fs.createWriteStream(path.resolve(__dirname, "..", "..", "..", "..", "artifacts", "logs", "node.functionaltests.log"));
|
||||
const p = exec(`"${process.execPath}" "${jestPath}" --config "${configPath}"`, { env: { SERVER_URL: url }, timeout: 200000, maxBuffer: 10 * 1024 * 1024 },
|
||||
(error: any, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.log(error.message);
|
||||
return resolve(error.code);
|
||||
}
|
||||
return resolve(0);
|
||||
});
|
||||
p.stdout.pipe(logStream);
|
||||
p.stderr.pipe(logStream);
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
// Check if we got any browsers
|
||||
if (config.browsers.length === 0) {
|
||||
console.log("Unable to locate any suitable browsers. Skipping browser functional tests.");
|
||||
process.exit(0);
|
||||
return; // For good measure
|
||||
}
|
||||
|
||||
const serverPath = path.resolve(__dirname, "..", "bin", configuration, "netcoreapp2.2", "FunctionalTests.dll");
|
||||
|
||||
debug(`Launching Functional Test Server: ${serverPath}`);
|
||||
|
|
@ -243,14 +240,22 @@ function runJest(url: string) {
|
|||
// Pass server URL to tests
|
||||
conf.client.args = ["--server", url];
|
||||
|
||||
const results = await runKarma(conf);
|
||||
const jestExit = await runJest(url);
|
||||
|
||||
const jestExit = runJest(url);
|
||||
// Check if we got any browsers
|
||||
let karmaExit;
|
||||
if (config.browsers.length === 0) {
|
||||
console.log("Unable to locate any suitable browsers. Skipping browser functional tests.");
|
||||
} else {
|
||||
karmaExit = (await runKarma(conf)).exitCode;
|
||||
}
|
||||
|
||||
console.log(`karma exit code: ${results.exitCode}`);
|
||||
if (karmaExit) {
|
||||
console.log(`karma exit code: ${karmaExit}`);
|
||||
}
|
||||
console.log(`jest exit code: ${jestExit}`);
|
||||
|
||||
process.exit(results.exitCode !== 0 ? results.exitCode : jestExit);
|
||||
process.exit(jestExit !== 0 ? jestExit : karmaExit);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { TestLogger } from "./TestLogger";
|
|||
|
||||
// We want to continue testing HttpConnection, but we don't export it anymore. So just pull it in directly from the source file.
|
||||
import { HttpConnection } from "@aspnet/signalr/dist/esm/HttpConnection";
|
||||
import "./LogBannerReporter";
|
||||
|
||||
const commonOptions: IHttpConnectionOptions = {
|
||||
logMessageContent: true,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, H
|
|||
import { MessagePackHubProtocol } from "@aspnet/signalr-protocol-msgpack";
|
||||
|
||||
import { eachTransport, eachTransportAndProtocol, ENDPOINT_BASE_URL } from "./Common";
|
||||
import "./LogBannerReporter";
|
||||
import { TestLogger } from "./TestLogger";
|
||||
|
||||
const TESTHUBENDPOINT_URL = ENDPOINT_BASE_URL + "/testhub";
|
||||
|
|
@ -562,6 +563,26 @@ describe("hubConnection", () => {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
it("preserves cookies between requests", async (done) => {
|
||||
const hubConnection = getConnectionBuilder(transportType).build();
|
||||
await hubConnection.start();
|
||||
const cookieValue = await hubConnection.invoke<string>("GetCookie", "testCookie");
|
||||
const cookieValue2 = await hubConnection.invoke<string>("GetCookie", "testCookie2");
|
||||
expect(cookieValue).toEqual("testValue");
|
||||
expect(cookieValue2).toEqual("testValue2");
|
||||
await hubConnection.stop();
|
||||
done();
|
||||
});
|
||||
|
||||
it("expired cookies are not preserved", async (done) => {
|
||||
const hubConnection = getConnectionBuilder(transportType).build();
|
||||
await hubConnection.start();
|
||||
const cookieValue = await hubConnection.invoke<string>("GetCookie", "expiredCookie");
|
||||
expect(cookieValue).toBeNull();
|
||||
await hubConnection.stop();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -16,4 +16,9 @@ export class LogBannerReporter implements jasmine.CustomReporter {
|
|||
}
|
||||
}
|
||||
|
||||
jasmine.getEnv().addReporter(new LogBannerReporter());
|
||||
if (typeof window !== "undefined" && (window as any).customReporterRegistered !== true) {
|
||||
(window as any).customReporterRegistered = true;
|
||||
jasmine.getEnv().addReporter(new LogBannerReporter());
|
||||
} else if (typeof window === "undefined") {
|
||||
jasmine.getEnv().addReporter(new LogBannerReporter());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import { ECHOENDPOINT_URL } from "./Common";
|
||||
import "./LogBannerReporter";
|
||||
|
||||
// On slower CI machines, these tests sometimes take longer than 5s
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10 * 1000;
|
||||
|
|
|
|||
|
|
@ -37,5 +37,6 @@ module.exports = {
|
|||
externals: {
|
||||
"@aspnet/signalr": "signalR",
|
||||
"@aspnet/signalr-protocol-msgpack": "signalR.protocols.msgpack",
|
||||
"request": "request",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@aspnet/signalr-protocol-msgpack",
|
||||
"version": "1.1.0-preview3-t000",
|
||||
"version": "1.1.0-rtm-t000",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@aspnet/signalr-protocol-msgpack",
|
||||
"version": "1.1.0-preview1-t000",
|
||||
"version": "1.1.0-rtm-t000",
|
||||
"description": "MsgPack Protocol support for ASP.NET Core SignalR",
|
||||
"main": "./dist/cjs/index.js",
|
||||
"module": "./dist/esm/index.js",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,151 @@
|
|||
{
|
||||
"name": "@aspnet/signalr",
|
||||
"version": "1.1.0-preview3-t000",
|
||||
"version": "1.1.0-rtm-t000",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/caseless": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz",
|
||||
"integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/eventsource": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/eventsource/-/eventsource-1.0.2.tgz",
|
||||
"integrity": "sha512-CprOekOB/lzAiGDF1MPWHX053RVTCYyYU3M8HOQXpdD0QfXijM//Na/hZxHaQv4ydsiB1uOBQ3p8S5nXpP4nNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/form-data": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
|
||||
"integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.9.4.tgz",
|
||||
"integrity": "sha512-fCHV45gS+m3hH17zgkgADUSi2RR1Vht6wOZ0jyHP8rjiQra9f+mIcgwPQHllmDocYOstIEbKlxbFDYlgrTPYqw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/request": {
|
||||
"version": "2.47.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.1.tgz",
|
||||
"integrity": "sha512-TV3XLvDjQbIeVxJ1Z3oCTDk/KuYwwcNKVwz2YaT0F5u86Prgc4syDAp6P96rkTQQ4bIdh+VswQIC9zS6NjY7/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/caseless": "*",
|
||||
"@types/form-data": "*",
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*"
|
||||
}
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.3.tgz",
|
||||
"integrity": "sha512-MDQLxNFRLasqS4UlkWMSACMKeSm1x4Q3TxzUC7KQUsh6RK1ZrQ0VEyE3yzXcBu+K8ejVj4wuX32eUG02yNp+YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
||||
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
|
||||
"requires": {
|
||||
"co": "^4.6.0",
|
||||
"fast-deep-equal": "^1.0.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
|
||||
"integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz",
|
||||
|
|
@ -35,6 +160,132 @@
|
|||
"original": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
|
||||
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
|
||||
"integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
|
||||
"requires": {
|
||||
"ajv": "^5.3.0",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
|
||||
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
|
||||
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.21",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
|
||||
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
|
||||
"requires": {
|
||||
"mime-db": "~1.37.0"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"original": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
|
||||
|
|
@ -43,16 +294,111 @@
|
|||
"url-parse": "^1.4.3"
|
||||
}
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.1.29",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
|
||||
"integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz",
|
||||
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw=="
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz",
|
||||
"integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==",
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz",
|
||||
|
|
@ -62,6 +408,21 @@
|
|||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@aspnet/signalr",
|
||||
"version": "1.1.0-preview1-t000",
|
||||
"version": "1.1.0-rtm-t000",
|
||||
"description": "ASP.NET Core SignalR Client",
|
||||
"main": "./dist/cjs/index.js",
|
||||
"module": "./dist/esm/index.js",
|
||||
|
|
@ -38,10 +38,12 @@
|
|||
"devDependencies": {
|
||||
"es6-promise": "^4.2.2",
|
||||
"@types/node": "^10.9.4",
|
||||
"@types/eventsource": "^1.0.2"
|
||||
"@types/eventsource": "^1.0.2",
|
||||
"@types/request": "^2.47.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": "^6.0.0",
|
||||
"eventsource": "^1.0.7"
|
||||
"eventsource": "^1.0.7",
|
||||
"request": "^2.88.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,4 +45,8 @@ export class DefaultHttpClient extends HttpClient {
|
|||
|
||||
return this.httpClient.send(request);
|
||||
}
|
||||
|
||||
public getCookieString(url: string): string {
|
||||
return this.httpClient.getCookieString(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,4 +141,14 @@ export abstract class HttpClient {
|
|||
* @returns {Promise<HttpResponse>} A Promise that resolves with an HttpResponse describing the response, or rejects with an Error indicating a failure.
|
||||
*/
|
||||
public abstract send(request: HttpRequest): Promise<HttpResponse>;
|
||||
|
||||
/** Gets all cookies that apply to the specified URL.
|
||||
*
|
||||
* @param url The URL that the cookies are valid for.
|
||||
* @returns {string} A string containing all the key-value cookie pairs for the specified URL.
|
||||
*/
|
||||
// @ts-ignore
|
||||
public getCookieString(url: string): string {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ export class HttpConnection implements IConnection {
|
|||
if (!this.options.WebSocket) {
|
||||
throw new Error("'WebSocket' is not supported in your environment.");
|
||||
}
|
||||
return new WebSocketTransport(this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.WebSocket);
|
||||
return new WebSocketTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.WebSocket);
|
||||
case HttpTransportType.ServerSentEvents:
|
||||
if (!this.options.EventSource) {
|
||||
throw new Error("'EventSource' is not supported in your environment.");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import * as http from "http";
|
||||
import * as https from "https";
|
||||
import { URL } from "url";
|
||||
import * as Request from "request";
|
||||
|
||||
import { AbortError, HttpError, TimeoutError } from "./Errors";
|
||||
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
|
||||
|
|
@ -12,87 +10,70 @@ import { isArrayBuffer } from "./Utils";
|
|||
|
||||
export class NodeHttpClient extends HttpClient {
|
||||
private readonly logger: ILogger;
|
||||
private readonly request: Request.RequestAPI<Request.Request, Request.CoreOptions, Request.RequiredUriUrl>;
|
||||
private readonly cookieJar: Request.CookieJar;
|
||||
|
||||
public constructor(logger: ILogger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.cookieJar = Request.jar();
|
||||
this.request = Request.defaults({ jar: this.cookieJar });
|
||||
}
|
||||
|
||||
public send(request: HttpRequest): Promise<HttpResponse> {
|
||||
public send(httpRequest: HttpRequest): Promise<HttpResponse> {
|
||||
return new Promise<HttpResponse>((resolve, reject) => {
|
||||
const url = new URL(request.url!);
|
||||
const options: http.RequestOptions = {
|
||||
|
||||
let requestBody: Buffer | string;
|
||||
if (isArrayBuffer(httpRequest.content)) {
|
||||
requestBody = Buffer.from(httpRequest.content);
|
||||
} else {
|
||||
requestBody = httpRequest.content || "";
|
||||
}
|
||||
|
||||
const currentRequest = this.request(httpRequest.url!, {
|
||||
body: requestBody,
|
||||
// If binary is expected 'null' should be used, otherwise for text 'utf8'
|
||||
encoding: httpRequest.responseType === "arraybuffer" ? null : "utf8",
|
||||
headers: {
|
||||
// Tell auth middleware to 401 instead of redirecting
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
...request.headers,
|
||||
...httpRequest.headers,
|
||||
},
|
||||
hostname: url.hostname,
|
||||
method: request.method,
|
||||
// /abc/xyz + ?id=12ssa_30
|
||||
path: url.pathname + url.search,
|
||||
port: url.port,
|
||||
};
|
||||
method: httpRequest.method,
|
||||
timeout: httpRequest.timeout,
|
||||
},
|
||||
(error, response, body) => {
|
||||
if (httpRequest.abortSignal) {
|
||||
httpRequest.abortSignal.onabort = null;
|
||||
}
|
||||
|
||||
// "any" is used here because require() can't be correctly resolved by the compiler
|
||||
// when httpOrHttps is typeof http | typeof https. Change to http when editing to get
|
||||
// intellisense.
|
||||
const httpOrHttps: any = url.protocol === "https" ? https : http;
|
||||
|
||||
const req = httpOrHttps.request(options, (res: http.IncomingMessage) => {
|
||||
const data: Buffer[] = [];
|
||||
let dataLength = 0;
|
||||
res.on("data", (chunk: any) => {
|
||||
data.push(chunk);
|
||||
// Buffer.concat will be slightly faster if we keep track of the length
|
||||
dataLength += chunk.length;
|
||||
});
|
||||
|
||||
res.on("end", () => {
|
||||
if (request.abortSignal) {
|
||||
request.abortSignal.onabort = null;
|
||||
if (error) {
|
||||
if (error.code === "ETIMEDOUT") {
|
||||
this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
|
||||
reject(new TimeoutError());
|
||||
}
|
||||
this.logger.log(LogLevel.Warning, `Error from HTTP request. ${error}`);
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||||
let resp: string | ArrayBuffer;
|
||||
if (request.responseType === "arraybuffer") {
|
||||
resp = Buffer.concat(data, dataLength);
|
||||
resolve(new HttpResponse(res.statusCode, res.statusMessage || "", resp));
|
||||
} else {
|
||||
resp = Buffer.concat(data, dataLength).toString();
|
||||
resolve(new HttpResponse(res.statusCode, res.statusMessage || "", resp));
|
||||
}
|
||||
} else {
|
||||
reject(new HttpError(res.statusMessage || "", res.statusCode || 0));
|
||||
}
|
||||
});
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
resolve(new HttpResponse(response.statusCode, response.statusMessage || "", body));
|
||||
} else {
|
||||
reject(new HttpError(response.statusMessage || "", response.statusCode || 0));
|
||||
}
|
||||
});
|
||||
|
||||
if (request.abortSignal) {
|
||||
request.abortSignal.onabort = () => {
|
||||
req.abort();
|
||||
if (httpRequest.abortSignal) {
|
||||
httpRequest.abortSignal.onabort = () => {
|
||||
currentRequest.abort();
|
||||
reject(new AbortError());
|
||||
};
|
||||
}
|
||||
|
||||
if (request.timeout) {
|
||||
req.setTimeout(request.timeout, () => {
|
||||
this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
|
||||
reject(new TimeoutError());
|
||||
});
|
||||
}
|
||||
|
||||
req.on("error", (e: Error) => {
|
||||
this.logger.log(LogLevel.Warning, `Error from HTTP request. ${e}`);
|
||||
reject(e);
|
||||
});
|
||||
|
||||
if (isArrayBuffer(request.content)) {
|
||||
req.write(Buffer.from(request.content));
|
||||
} else {
|
||||
req.write(request.content || "");
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
public getCookieString(url: string): string {
|
||||
return this.cookieJar.getCookieString(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export interface EventSourceConstructor {
|
|||
}
|
||||
|
||||
export interface WebSocketConstructor {
|
||||
new(url: string, protocols?: string | string[]): WebSocket;
|
||||
new(url: string, protocols?: string | string[], options?: any): WebSocket;
|
||||
readonly CLOSED: number;
|
||||
readonly CLOSING: number;
|
||||
readonly CONNECTING: number;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,14 @@ export class ServerSentEventsTransport implements ITransport {
|
|||
return;
|
||||
}
|
||||
|
||||
const eventSource = new this.eventSourceConstructor(url, { withCredentials: true });
|
||||
let eventSource: EventSource;
|
||||
if (typeof window !== "undefined") {
|
||||
eventSource = new this.eventSourceConstructor(url, { withCredentials: true });
|
||||
} else {
|
||||
// Non-browser passes cookies via the dictionary
|
||||
const cookies = this.httpClient.getCookieString(url);
|
||||
eventSource = new this.eventSourceConstructor(url, { withCredentials: true, headers: { Cookie: cookies } } as EventSourceInit);
|
||||
}
|
||||
|
||||
try {
|
||||
eventSource.onmessage = (e: MessageEvent) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import { HttpClient } from "./HttpClient";
|
||||
import { ILogger, LogLevel } from "./ILogger";
|
||||
import { ITransport, TransferFormat } from "./ITransport";
|
||||
import { WebSocketConstructor } from "./Polyfills";
|
||||
|
|
@ -12,17 +13,19 @@ export class WebSocketTransport implements ITransport {
|
|||
private readonly accessTokenFactory: (() => string | Promise<string>) | undefined;
|
||||
private readonly logMessageContent: boolean;
|
||||
private readonly webSocketConstructor: WebSocketConstructor;
|
||||
private readonly httpClient: HttpClient;
|
||||
private webSocket?: WebSocket;
|
||||
|
||||
public onreceive: ((data: string | ArrayBuffer) => void) | null;
|
||||
public onclose: ((error?: Error) => void) | null;
|
||||
|
||||
constructor(accessTokenFactory: (() => string | Promise<string>) | undefined, logger: ILogger,
|
||||
constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise<string>) | undefined, logger: ILogger,
|
||||
logMessageContent: boolean, webSocketConstructor: WebSocketConstructor) {
|
||||
this.logger = logger;
|
||||
this.accessTokenFactory = accessTokenFactory;
|
||||
this.logMessageContent = logMessageContent;
|
||||
this.webSocketConstructor = webSocketConstructor;
|
||||
this.httpClient = httpClient;
|
||||
|
||||
this.onreceive = null;
|
||||
this.onclose = null;
|
||||
|
|
@ -44,7 +47,23 @@ export class WebSocketTransport implements ITransport {
|
|||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
url = url.replace(/^http/, "ws");
|
||||
const webSocket = new this.webSocketConstructor(url);
|
||||
let webSocket: WebSocket | undefined;
|
||||
const cookies = this.httpClient.getCookieString(url);
|
||||
|
||||
if (typeof window === "undefined" && cookies) {
|
||||
// Only pass cookies when in non-browser environments
|
||||
webSocket = new this.webSocketConstructor(url, undefined, {
|
||||
headers: {
|
||||
Cookie: `${cookies}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!webSocket) {
|
||||
// Chrome is not happy with passing 'undefined' as protocol
|
||||
webSocket = new this.webSocketConstructor(url);
|
||||
}
|
||||
|
||||
if (transferFormat === TransferFormat.Binary) {
|
||||
webSocket.binaryType = "arraybuffer";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { TransferFormat } from "../src/ITransport";
|
|||
import { WebSocketTransport } from "../src/WebSocketTransport";
|
||||
import { VerifyLogger } from "./Common";
|
||||
import { TestMessageEvent } from "./TestEventSource";
|
||||
import { TestHttpClient } from "./TestHttpClient";
|
||||
import { TestCloseEvent, TestErrorEvent, TestEvent, TestWebSocket } from "./TestWebSocket";
|
||||
import { registerUnhandledRejectionHandler } from "./Utils";
|
||||
|
||||
|
|
@ -22,7 +23,7 @@ describe("WebSocketTransport", () => {
|
|||
|
||||
it("connect waits for WebSocket to be connected", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const webSocket = new WebSocketTransport(undefined, logger, true, TestWebSocket);
|
||||
const webSocket = new WebSocketTransport(new TestHttpClient(), undefined, logger, true, TestWebSocket);
|
||||
|
||||
let connectComplete: boolean = false;
|
||||
const connectPromise = (async () => {
|
||||
|
|
@ -44,7 +45,7 @@ describe("WebSocketTransport", () => {
|
|||
it("connect fails if there is error during connect", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
(global as any).ErrorEvent = TestErrorEvent;
|
||||
const webSocket = new WebSocketTransport(undefined, logger, true, TestWebSocket);
|
||||
const webSocket = new WebSocketTransport(new TestHttpClient(), undefined, logger, true, TestWebSocket);
|
||||
|
||||
let connectComplete: boolean = false;
|
||||
const connectPromise = (async () => {
|
||||
|
|
@ -204,7 +205,7 @@ describe("WebSocketTransport", () => {
|
|||
});
|
||||
|
||||
async function createAndStartWebSocket(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), format?: TransferFormat): Promise<WebSocketTransport> {
|
||||
const webSocket = new WebSocketTransport(accessTokenFactory, logger, true, TestWebSocket);
|
||||
const webSocket = new WebSocketTransport(new TestHttpClient(), accessTokenFactory, logger, true, TestWebSocket);
|
||||
|
||||
const connectPromise = webSocket.connect(url || "http://example.com", format || TransferFormat.Text);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ module.exports = baseConfig(__dirname, "signalr", {
|
|||
externals: [
|
||||
"websocket",
|
||||
"eventsource",
|
||||
"http",
|
||||
"url",
|
||||
"request"
|
||||
]
|
||||
});
|
||||
Loading…
Reference in New Issue