263 lines
9.1 KiB
JavaScript
263 lines
9.1 KiB
JavaScript
"use strict";
|
|
// Licensed to the .NET Foundation under one or more agreements.
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getGlobalThis = exports.getErrorString = exports.constructUserAgent = exports.getUserAgentHeader = exports.ConsoleLogger = exports.SubjectSubscription = exports.createLogger = exports.sendMessage = exports.isArrayBuffer = exports.formatArrayBuffer = exports.getDataDetail = exports.Platform = exports.Arg = exports.VERSION = void 0;
|
|
const ILogger_1 = require("./ILogger");
|
|
const Loggers_1 = require("./Loggers");
|
|
const pkg_version_1 = require("./pkg-version");
|
|
Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return pkg_version_1.VERSION; } });
|
|
/** @private */
|
|
class Arg {
|
|
static isRequired(val, name) {
|
|
if (val === null || val === undefined) {
|
|
throw new Error(`The '${name}' argument is required.`);
|
|
}
|
|
}
|
|
static isNotEmpty(val, name) {
|
|
if (!val || val.match(/^\s*$/)) {
|
|
throw new Error(`The '${name}' argument should not be empty.`);
|
|
}
|
|
}
|
|
static isIn(val, values, name) {
|
|
// TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.
|
|
if (!(val in values)) {
|
|
throw new Error(`Unknown ${name} value: ${val}.`);
|
|
}
|
|
}
|
|
}
|
|
exports.Arg = Arg;
|
|
/** @private */
|
|
class Platform {
|
|
// react-native has a window but no document so we should check both
|
|
static get isBrowser() {
|
|
return !Platform.isNode && typeof window === "object" && typeof window.document === "object";
|
|
}
|
|
// WebWorkers don't have a window object so the isBrowser check would fail
|
|
static get isWebWorker() {
|
|
return !Platform.isNode && typeof self === "object" && "importScripts" in self;
|
|
}
|
|
// react-native has a window but no document
|
|
static get isReactNative() {
|
|
return !Platform.isNode && typeof window === "object" && typeof window.document === "undefined";
|
|
}
|
|
// Node apps shouldn't have a window object, but WebWorkers don't either
|
|
// so we need to check for both WebWorker and window
|
|
static get isNode() {
|
|
return typeof process !== "undefined" && process.release && process.release.name === "node";
|
|
}
|
|
}
|
|
exports.Platform = Platform;
|
|
/** @private */
|
|
function getDataDetail(data, includeContent) {
|
|
let detail = "";
|
|
if (isArrayBuffer(data)) {
|
|
detail = `Binary data of length ${data.byteLength}`;
|
|
if (includeContent) {
|
|
detail += `. Content: '${formatArrayBuffer(data)}'`;
|
|
}
|
|
}
|
|
else if (typeof data === "string") {
|
|
detail = `String data of length ${data.length}`;
|
|
if (includeContent) {
|
|
detail += `. Content: '${data}'`;
|
|
}
|
|
}
|
|
return detail;
|
|
}
|
|
exports.getDataDetail = getDataDetail;
|
|
/** @private */
|
|
function formatArrayBuffer(data) {
|
|
const view = new Uint8Array(data);
|
|
// Uint8Array.map only supports returning another Uint8Array?
|
|
let str = "";
|
|
view.forEach((num) => {
|
|
const pad = num < 16 ? "0" : "";
|
|
str += `0x${pad}${num.toString(16)} `;
|
|
});
|
|
// Trim of trailing space.
|
|
return str.substr(0, str.length - 1);
|
|
}
|
|
exports.formatArrayBuffer = formatArrayBuffer;
|
|
// Also in signalr-protocol-msgpack/Utils.ts
|
|
/** @private */
|
|
function isArrayBuffer(val) {
|
|
return val && typeof ArrayBuffer !== "undefined" &&
|
|
(val instanceof ArrayBuffer ||
|
|
// Sometimes we get an ArrayBuffer that doesn't satisfy instanceof
|
|
(val.constructor && val.constructor.name === "ArrayBuffer"));
|
|
}
|
|
exports.isArrayBuffer = isArrayBuffer;
|
|
/** @private */
|
|
async function sendMessage(logger, transportName, httpClient, url, content, options) {
|
|
const headers = {};
|
|
const [name, value] = getUserAgentHeader();
|
|
headers[name] = value;
|
|
logger.log(ILogger_1.LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, options.logMessageContent)}.`);
|
|
const responseType = isArrayBuffer(content) ? "arraybuffer" : "text";
|
|
const response = await httpClient.post(url, {
|
|
content,
|
|
headers: { ...headers, ...options.headers },
|
|
responseType,
|
|
timeout: options.timeout,
|
|
withCredentials: options.withCredentials,
|
|
});
|
|
logger.log(ILogger_1.LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`);
|
|
}
|
|
exports.sendMessage = sendMessage;
|
|
/** @private */
|
|
function createLogger(logger) {
|
|
if (logger === undefined) {
|
|
return new ConsoleLogger(ILogger_1.LogLevel.Information);
|
|
}
|
|
if (logger === null) {
|
|
return Loggers_1.NullLogger.instance;
|
|
}
|
|
if (logger.log !== undefined) {
|
|
return logger;
|
|
}
|
|
return new ConsoleLogger(logger);
|
|
}
|
|
exports.createLogger = createLogger;
|
|
/** @private */
|
|
class SubjectSubscription {
|
|
constructor(subject, observer) {
|
|
this._subject = subject;
|
|
this._observer = observer;
|
|
}
|
|
dispose() {
|
|
const index = this._subject.observers.indexOf(this._observer);
|
|
if (index > -1) {
|
|
this._subject.observers.splice(index, 1);
|
|
}
|
|
if (this._subject.observers.length === 0 && this._subject.cancelCallback) {
|
|
this._subject.cancelCallback().catch((_) => { });
|
|
}
|
|
}
|
|
}
|
|
exports.SubjectSubscription = SubjectSubscription;
|
|
/** @private */
|
|
class ConsoleLogger {
|
|
constructor(minimumLogLevel) {
|
|
this._minLevel = minimumLogLevel;
|
|
this.out = console;
|
|
}
|
|
log(logLevel, message) {
|
|
if (logLevel >= this._minLevel) {
|
|
const msg = `[${new Date().toISOString()}] ${ILogger_1.LogLevel[logLevel]}: ${message}`;
|
|
switch (logLevel) {
|
|
case ILogger_1.LogLevel.Critical:
|
|
case ILogger_1.LogLevel.Error:
|
|
this.out.error(msg);
|
|
break;
|
|
case ILogger_1.LogLevel.Warning:
|
|
this.out.warn(msg);
|
|
break;
|
|
case ILogger_1.LogLevel.Information:
|
|
this.out.info(msg);
|
|
break;
|
|
default:
|
|
// console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug
|
|
this.out.log(msg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
exports.ConsoleLogger = ConsoleLogger;
|
|
/** @private */
|
|
function getUserAgentHeader() {
|
|
let userAgentHeaderName = "X-SignalR-User-Agent";
|
|
if (Platform.isNode) {
|
|
userAgentHeaderName = "User-Agent";
|
|
}
|
|
return [userAgentHeaderName, constructUserAgent(pkg_version_1.VERSION, getOsName(), getRuntime(), getRuntimeVersion())];
|
|
}
|
|
exports.getUserAgentHeader = getUserAgentHeader;
|
|
/** @private */
|
|
function constructUserAgent(version, os, runtime, runtimeVersion) {
|
|
// Microsoft SignalR/[Version] ([Detailed Version]; [Operating System]; [Runtime]; [Runtime Version])
|
|
let userAgent = "Microsoft SignalR/";
|
|
const majorAndMinor = version.split(".");
|
|
userAgent += `${majorAndMinor[0]}.${majorAndMinor[1]}`;
|
|
userAgent += ` (${version}; `;
|
|
if (os && os !== "") {
|
|
userAgent += `${os}; `;
|
|
}
|
|
else {
|
|
userAgent += "Unknown OS; ";
|
|
}
|
|
userAgent += `${runtime}`;
|
|
if (runtimeVersion) {
|
|
userAgent += `; ${runtimeVersion}`;
|
|
}
|
|
else {
|
|
userAgent += "; Unknown Runtime Version";
|
|
}
|
|
userAgent += ")";
|
|
return userAgent;
|
|
}
|
|
exports.constructUserAgent = constructUserAgent;
|
|
// eslint-disable-next-line spaced-comment
|
|
/*#__PURE__*/ function getOsName() {
|
|
if (Platform.isNode) {
|
|
switch (process.platform) {
|
|
case "win32":
|
|
return "Windows NT";
|
|
case "darwin":
|
|
return "macOS";
|
|
case "linux":
|
|
return "Linux";
|
|
default:
|
|
return process.platform;
|
|
}
|
|
}
|
|
else {
|
|
return "";
|
|
}
|
|
}
|
|
// eslint-disable-next-line spaced-comment
|
|
/*#__PURE__*/ function getRuntimeVersion() {
|
|
if (Platform.isNode) {
|
|
return process.versions.node;
|
|
}
|
|
return undefined;
|
|
}
|
|
function getRuntime() {
|
|
if (Platform.isNode) {
|
|
return "NodeJS";
|
|
}
|
|
else {
|
|
return "Browser";
|
|
}
|
|
}
|
|
/** @private */
|
|
function getErrorString(e) {
|
|
if (e.stack) {
|
|
return e.stack;
|
|
}
|
|
else if (e.message) {
|
|
return e.message;
|
|
}
|
|
return `${e}`;
|
|
}
|
|
exports.getErrorString = getErrorString;
|
|
/** @private */
|
|
function getGlobalThis() {
|
|
// globalThis is semi-new and not available in Node until v12
|
|
if (typeof globalThis !== "undefined") {
|
|
return globalThis;
|
|
}
|
|
if (typeof self !== "undefined") {
|
|
return self;
|
|
}
|
|
if (typeof window !== "undefined") {
|
|
return window;
|
|
}
|
|
if (typeof global !== "undefined") {
|
|
return global;
|
|
}
|
|
throw new Error("could not find global");
|
|
}
|
|
exports.getGlobalThis = getGlobalThis;
|
|
//# sourceMappingURL=Utils.js.map
|