Code Monkey home page Code Monkey logo

typed-rest-client's Introduction

Build Status

Typed REST and HTTP Client with TypeScript Typings

A lightweight REST and HTTP client optimized for use with TypeScript with generics and async await.

Features

  • REST and HTTP client with TypeScript generics and async/await/Promises
  • Typings included so no need to acquire separately (great for intellisense and no versioning drift)
  • Basic, Bearer and NTLM Support out of the box. Extensible handlers for others.
  • Proxy support
  • Certificate support (Self-signed server and client cert)
  • Redirects supported

Intellisense and compile support:

intellisense

Install

npm install typed-rest-client --save

Or to install the latest preview:

npm install typed-rest-client@preview --save

Samples

See the samples for complete coding examples. Also see the REST and HTTP tests for detailed examples.

Errors

HTTP

The HTTP client does not throw unless truly exceptional.

  • A request that successfully executes resulting in a 404, 500 etc... will return a response object with a status code and a body.
  • Redirects (3xx) will be followed by default.

See HTTP tests for detailed examples.

REST

The REST client is a high-level client which uses the HTTP client. Its responsibility is to turn a body into a typed resource object.

  • A 200 will be success.
  • Redirects (3xx) will be followed.
  • A 404 will not throw but the result object will be null and the result statusCode will be set.
  • Other 4xx and 5xx errors will throw. The status code will be attached to the error object. If a RESTful error object is returned ({ message: xxx}), then the error message will be that. Otherwise, it will be a generic, Failed Request: (xxx).

See REST tests for detailed examples.

Debugging

To enable detailed console logging of all HTTP requests and responses, set the NODE_DEBUG environment varible:

export NODE_DEBUG=http

or

set NODE_DEBUG=http

Node support

The typed-rest-client is built using the latest LTS version of Node 8. We also support the latest LTS for Node 6 and newer.

Contributing

To contribute to this repository, see the contribution guide

To build:

$ npm run build

To run all tests:

$ npm test

To just run unit tests:

$ npm run units

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Security Issues

Do you think there might be a security issue? Have you been phished or identified a security vulnerability? Please don't report it here - let us know by sending an email to [email protected].

typed-rest-client's People

Contributors

andrew8er avatar annich-ms avatar bobsilent avatar bryanmacfarlane avatar dependabot[bot] avatar devonsabbatical avatar dmitriibobreshev avatar ezzhevnikita avatar hamzahejja avatar issacnitinmsft avatar jtpetty avatar kirill-ivlev avatar konstantintyukalov avatar kuleshovilya avatar max-zaytsev avatar microsoft-github-policy-service[bot] avatar mmajcica avatar olevett avatar omeshp avatar roman-shchukin avatar sergeykochanov avatar stephenmichaelf avatar tasadar2 avatar thomaschampagne avatar tingluohuang avatar tuwrraphael avatar vtbassmatt avatar williambernardet avatar willsmythe avatar yahavi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typed-rest-client's Issues

RestClient additionalHeaders check

In the rest client there is a check if additional headers are specified.

https://github.com/Microsoft/typed-rest-client/blob/7186708f6f5ed96c6c5ca204405915595d5b2149/lib/RestClient.ts#L171

In case user specifies a custom Content-Type header (necessary at example in case we are using uploadStream to upload a file via mutipart/formdata standard (RFC 2388) the default one will not be added.
The problem is that the check over Content-Type header is case sensitive, so if you added a content-type header, this will not be detected and used correctly.

I would suggest to use a non case sensitive check for this.
If you guys do agree with me, I have a code ready and I'll request a PR.

Thanks

Set PR CI validation

One yaml file
3 defs (linux, osx and windows). Use hosted linux, OSX and VS2017 pools

Dates in return types are deserialized as strings

Environment

Node version: 8.10
Npm version: 5.8.0
OS and version: MacOS 10.13.3
typed-rest-client version: stable

Issue Description

When using a type for the response which has Date as type for a field, that field ends up being a string, thus violating the type.

Expected behaviour

If I have a field which is a Date, I expect the deserialization to fail whenever the returned type isn't a date, or if the type does represent a parseable Date, that the field gets correctly transformed into a Date.

Actual behaviour

Instead of a Date, we get string. This means that any code that I write expecting there to be a Date, becomes type-unsafe as all the Date methods are not available in string objects.

Steps to reproduce

  1. Create type class with Date field.
  2. Make request to endpoint which returns a string-encoded standard JSON Date for that field.
  3. Verify that none of the Date methods are available in the deserialized object.

As I understand, this may be tricky to solve as JSON.parse will see a string and leave it as a string. However, we could possibly introspect the type of the response and handle the Date manually.

Error in running samples

Hello.
While following on contributing guide, I had an error in npm run samples.

> [email protected] samples /Users/kwangin/workspace/github_source/typed-rest-client
> node make.js samples

> /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/.bin/tsc --outDir /Users/kwangin/workspace/github_source/typed-rest-client/_build
/Users/kwangin/workspace/github_source/typed-rest-client/samples /Users/kwangin/workspace/github_source/typed-rest-client
> node samples.js
module.js:491
    throw err;
    ^

Error: Cannot find module '/Users/kwangin/workspace/github_source/typed-rest-client/samples/samples.js'
    at Function.Module._resolveFilename (module.js:489:15)
    at Function.Module._load (module.js:439:25)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:578:3
/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:381
      if (config.fatal) throw e;
                        ^

Error: exec: internal error
    at Object.error (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:112:27)
    at _exec (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/exec.js:292:12)
    at /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:316:23
    at run (/Users/kwangin/workspace/github_source/typed-rest-client/make.js:14:14)
    at Function.target.samples (/Users/kwangin/workspace/github_source/typed-rest-client/make.js:51:5)
    at Object.global.target.(anonymous function) [as samples] (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:36:40)
    at /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:48:27
    at Array.forEach (<anonymous>)
    at Timeout._onTimeout (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:46:10)
    at ontimeout (timers.js:469:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] samples: `node make.js samples`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] samples script.

Am I doing something wrong?
My node version is v8.3.0, and npm is 5.5.1.
Thanks.

Please tag released versions

Once again, thanks for your had work on this library :)

Request

Could you please, prior to publication of this library on NPM, include in your build script (if any) a tagging of the current version in GIT ?

Purpose

When using a specify published version of your lib, it would be useful to have a tag on the version tree in order to

  • Reproduce the build
  • Explore the code at that time for debugging purpose
    etc.

How to

There are severall methods, here is one, for example
https://coderwall.com/p/mk18zq/automatic-git-version-tagging-for-npm-modules

Thanks :)

Headers set with IRequestOptions in HttpClient constructor not used in requests.

Environment

typed-rest-client version: 1.0.7

Issue Description

I can instantiate the HttpClient with default headers as follows:

this.httpClient = new HttpClient("myUserAgent", [basicHandler], {headers: {"Accept": "application/json"}});

But it doesn't send these headers to the endpoint. In fact, it doesn't seem to use them at all.

When I send the Accept header as additionalHeader on the get method, everything works as expected
response = await this.httpClient.get("https://example.com/clients", { "Accept": "application/json"});

Expected behaviour

The default headers, defined in the constructor, should be merged with the additional headers sent along with the get/post/... method.

Actual behaviour

No default headers are sent to the endpoint.

No example of how to setup client using proxy

  1. Please check our current Issues to see if someone already reported this https://github.com/Microsoft/typed-rest-client/issues
  2. Take a look at our Instructions for logging issues https://github.com/Microsoft/typed-rest-client/blob/master/CONTRIBUTING.md#instructions-for-logging-issues

Environment

Node version: 8.9.4
Npm version: 5.6.0
OS and version: MacOS High Sierra
typed-rest-client version: 1.0.9

Issue Description

I can't configure the proxy. Not sure if there is a bug or if I messed up sth.
Also, my script is run by protractor with a configured proxy

Expected behaviour

Add example how to use a proxy (and verify it)

Actual behaviour

I got the following error:
tunneling socket could not be established, cause=connect ETIMEDOUT ip address:port

Steps to reproduce

  1. setup proxy
  2. try to configure HTTPClient to work with this proxy

Logs

Cannot use the library on linux

I cannot use this library on linux, because of inconsistent casing of files. Take bearertoken.d.ts as an example, it is importing '../interfaces. A file interfaces.d.ts does not exist, it should have been including '../Interfaces'.

Results in this error:

src/client/HttpClient.ts(5,33): error TS2307: Cannot find module 'typed-rest-client/interfaces'.

Empty base URL results in strange behavior with non-default ports

Environment

Node version: 8.10
Npm version: 5.8.0
OS and version: MacOS 10.13.3
typed-rest-client version: stable

Issue Description

Using Typed Rest Client without specifying a base URL does not play well with non-default ports. I was using a node server on port 3000 and without specifying a URL, it tries to send requests as follows:

http://localhost:3000/:80/product/abca

Expected behaviour

I expect it to behave like the fetch polyfill, where as if a base URL is not specified, it takes the request URL as an absolute URL for the current host:port combination. In my specific case, when I do a request to /product/abca, I expect the request to go to http://localhost:3000/product/abca.

Actual behaviour

Currently it seems to be a weird hybrid as since I didn't specify a base URL and my requests are relative, it appends the port and probably has an empty hostname. Basically currently we have a strange behavior, which possibly should throw an error if we don't want to support empty base URL + relative requests.

Steps to reproduce

  1. let restClient: rc.RestClient = new rc.RestClient('frontend');
  2. let response: rc.IRestResponse<Array> = await restClient.get<Array>('/product/' + searchString);

Logs

Not relevant.

Make explicit reference to httpntlm module [discussion]

The diff below shows how to use httpntlm module as direct, explicit dependency in the project without worrying of correctly meeting MIT license requirements. The change seems to be opaque to implementation (including current tests). Do you think that this could make a project structure cleaner and easier to maintain?

commit 167bdf1a32366f1abc6c7a23d33b18ba1176c0a9
Author: Peter Blazejewicz <[email protected]>
Date:   Mon Nov 20 21:54:12 2017 +0100

    Use NPM distributed version of httpntlm package

diff --git a/lib/handlers/ntlm.ts b/lib/handlers/ntlm.ts
index 483aff6..bcdd8b2 100644
--- a/lib/handlers/ntlm.ts
+++ b/lib/handlers/ntlm.ts
@@ -5,8 +5,8 @@ import VsoBaseInterfaces = require('../interfaces');
 
 import http = require("http");
 import https = require("https");
-var _ = require("underscore");
-var ntlm = require("../opensource/node-http-ntlm/ntlm");
+const _ = require("underscore");
+const ntlm = require("httpntlm");
 
 export class NtlmCredentialHandler implements VsoBaseInterfaces.IRequestHandler {
     username: string;
diff --git a/lib/opensource/node-http-ntlm/ntlm.js b/lib/opensource/node-http-ntlm/ntlm.js
deleted file mode 100644
index 5a776c3..0000000
--- a/lib/opensource/node-http-ntlm/ntlm.js
+++ /dev/null
@@ -1,390 +0,0 @@
-var crypto = require('crypto');
-
-var flags = {
-	NTLM_NegotiateUnicode                :  0x00000001,
-	NTLM_NegotiateOEM                    :  0x00000002,
-	NTLM_RequestTarget                   :  0x00000004,
-	NTLM_Unknown9                        :  0x00000008,
-	NTLM_NegotiateSign                   :  0x00000010,
-	NTLM_NegotiateSeal                   :  0x00000020,
-	NTLM_NegotiateDatagram               :  0x00000040,
-	NTLM_NegotiateLanManagerKey          :  0x00000080,
-	NTLM_Unknown8                        :  0x00000100,
-	NTLM_NegotiateNTLM                   :  0x00000200,
-	NTLM_NegotiateNTOnly                 :  0x00000400,
-	NTLM_Anonymous                       :  0x00000800,
-	NTLM_NegotiateOemDomainSupplied      :  0x00001000,
-	NTLM_NegotiateOemWorkstationSupplied :  0x00002000,
-	NTLM_Unknown6                        :  0x00004000,
-	NTLM_NegotiateAlwaysSign             :  0x00008000,
-	NTLM_TargetTypeDomain                :  0x00010000,
-	NTLM_TargetTypeServer                :  0x00020000,
-	NTLM_TargetTypeShare                 :  0x00040000,
-	NTLM_NegotiateExtendedSecurity       :  0x00080000,
-	NTLM_NegotiateIdentify               :  0x00100000,
-	NTLM_Unknown5                        :  0x00200000,
-	NTLM_RequestNonNTSessionKey          :  0x00400000,
-	NTLM_NegotiateTargetInfo             :  0x00800000,
-	NTLM_Unknown4                        :  0x01000000,
-	NTLM_NegotiateVersion                :  0x02000000,
-	NTLM_Unknown3                        :  0x04000000,
-	NTLM_Unknown2                        :  0x08000000,
-	NTLM_Unknown1                        :  0x10000000,
-	NTLM_Negotiate128                    :  0x20000000,
-	NTLM_NegotiateKeyExchange            :  0x40000000,
-	NTLM_Negotiate56                     :  0x80000000
-};
-var typeflags = {
-	NTLM_TYPE1_FLAGS : 	  flags.NTLM_NegotiateUnicode
-						+ flags.NTLM_NegotiateOEM
-						+ flags.NTLM_RequestTarget
-						+ flags.NTLM_NegotiateNTLM
-						+ flags.NTLM_NegotiateOemDomainSupplied
-						+ flags.NTLM_NegotiateOemWorkstationSupplied
-						+ flags.NTLM_NegotiateAlwaysSign
-						+ flags.NTLM_NegotiateExtendedSecurity
-						+ flags.NTLM_NegotiateVersion
-						+ flags.NTLM_Negotiate128
-						+ flags.NTLM_Negotiate56,
-
-	NTLM_TYPE2_FLAGS :    flags.NTLM_NegotiateUnicode
-						+ flags.NTLM_RequestTarget
-						+ flags.NTLM_NegotiateNTLM
-						+ flags.NTLM_NegotiateAlwaysSign
-						+ flags.NTLM_NegotiateExtendedSecurity
-						+ flags.NTLM_NegotiateTargetInfo
-						+ flags.NTLM_NegotiateVersion
-						+ flags.NTLM_Negotiate128
-						+ flags.NTLM_Negotiate56
-};
-
-function createType1Message(options){
-	var domain = escape(options.domain.toUpperCase());
-	var workstation = escape(options.workstation.toUpperCase());
-	var protocol = 'NTLMSSP\0';
-
-	var BODY_LENGTH = 40;
-
-	var type1flags = typeflags.NTLM_TYPE1_FLAGS;
-	if(!domain || domain === '')
-		type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
-
-	var pos = 0;
-	var buf = new Buffer(BODY_LENGTH + domain.length + workstation.length);
-
-
-	buf.write(protocol, pos, protocol.length); pos += protocol.length; // protocol
-	buf.writeUInt32LE(1, pos); pos += 4;          // type 1
-	buf.writeUInt32LE(type1flags, pos); pos += 4; // TYPE1 flag
-
-	buf.writeUInt16LE(domain.length, pos); pos += 2; // domain length
-	buf.writeUInt16LE(domain.length, pos); pos += 2; // domain max length
-	buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos); pos += 4; // domain buffer offset
-
-	buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation length
-	buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation max length
-	buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // workstation buffer offset
-
-	buf.writeUInt8(5, pos); pos += 1;      //ProductMajorVersion
-	buf.writeUInt8(1, pos); pos += 1;      //ProductMinorVersion
-	buf.writeUInt16LE(2600, pos); pos += 2; //ProductBuild
-
-	buf.writeUInt8(0 , pos); pos += 1; //VersionReserved1
-	buf.writeUInt8(0 , pos); pos += 1; //VersionReserved2
-	buf.writeUInt8(0 , pos); pos += 1; //VersionReserved3
-	buf.writeUInt8(15, pos); pos += 1; //NTLMRevisionCurrent
-
-	buf.write(workstation, pos, workstation.length, 'ascii'); pos += workstation.length; // workstation string
-	buf.write(domain     , pos, domain.length     , 'ascii'); pos += domain.length;
-
-	return 'NTLM ' + buf.toString('base64');
-}
-
-function parseType2Message(rawmsg, callback){
-	var match = rawmsg.match(/NTLM (.+)?/);
-	if(!match || !match[1])
-		return callback(new Error("Couldn't find NTLM in the message type2 comming from the server"));
-
-	var buf = new Buffer(match[1], 'base64');
-
-	var msg = {};
-
-	msg.signature = buf.slice(0, 8);
-	msg.type = buf.readInt16LE(8);
-
-	if(msg.type != 2)
-		return callback(new Error("Server didn't return a type 2 message"));
-
-	msg.targetNameLen = buf.readInt16LE(12);
-	msg.targetNameMaxLen = buf.readInt16LE(14);
-	msg.targetNameOffset = buf.readInt32LE(16);
-	msg.targetName  = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
-
-    msg.negotiateFlags = buf.readInt32LE(20);
-    msg.serverChallenge = buf.slice(24, 32);
-    msg.reserved = buf.slice(32, 40);
-
-    if(msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo){
-    	msg.targetInfoLen = buf.readInt16LE(40);
-    	msg.targetInfoMaxLen = buf.readInt16LE(42);
-    	msg.targetInfoOffset = buf.readInt32LE(44);
-    	msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
-    }
-	return msg;
-}
-
-function createType3Message(msg2, options){
-	var nonce = msg2.serverChallenge;
-	var username = options.username;
-	var password = options.password;
-	var negotiateFlags = msg2.negotiateFlags;
-
-	var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
-	var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
-
-	var BODY_LENGTH = 72;
-
-	var domainName = escape(options.domain.toUpperCase());
-	var workstation = escape(options.workstation.toUpperCase());
-
-	var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
-
-	var encryptedRandomSessionKey = "";
-	if(isUnicode){
-		workstationBytes = new Buffer(workstation, 'utf16le');
-		domainNameBytes = new Buffer(domainName, 'utf16le');
-		usernameBytes = new Buffer(username, 'utf16le');
-		encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'utf16le');
-	}else{
-		workstationBytes = new Buffer(workstation, 'ascii');
-		domainNameBytes = new Buffer(domainName, 'ascii');
-		usernameBytes = new Buffer(username, 'ascii');
-		encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'ascii');
-	}
-
-	var lmChallengeResponse = calc_resp(create_LM_hashed_password_v1(password), nonce);
-	var ntChallengeResponse = calc_resp(create_NT_hashed_password_v1(password), nonce);
-
-	if(isNegotiateExtendedSecurity){
-		var pwhash = create_NT_hashed_password_v1(password);
-	 	var clientChallenge = "";
-	 	for(var i=0; i < 8; i++){
-	 		clientChallenge += String.fromCharCode( Math.floor(Math.random()*256) );
-	   	}
-	   	var clientChallengeBytes = new Buffer(clientChallenge, 'ascii');
-	    var challenges = ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
-	    lmChallengeResponse = challenges.lmChallengeResponse;
-	    ntChallengeResponse = challenges.ntChallengeResponse;
-	}
-
-	var signature = 'NTLMSSP\0';
-
-	var pos = 0;
-	var buf = new Buffer(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
-
-	buf.write(signature, pos, signature.length); pos += signature.length;
-	buf.writeUInt32LE(3, pos); pos += 4;          // type 1
-
-	buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseLen
-	buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseMaxLen
-	buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos); pos += 4; // LmChallengeResponseOffset
-
-	buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseLen
-	buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseMaxLen
-	buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos); pos += 4; // NtChallengeResponseOffset
-
-	buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameLen
-	buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameMaxLen
-	buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; 			  // DomainNameOffset
-
-	buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameLen
-	buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameMaxLen
-	buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos); pos += 4; // UserNameOffset
-
-	buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationLen
-	buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationMaxLen
-	buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos); pos += 4; // WorkstationOffset
-
-	buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyLen
-	buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyMaxLen
-	buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos); pos += 4; // EncryptedRandomSessionKeyOffset
-
-	buf.writeUInt32LE(typeflags.NTLM_TYPE2_FLAGS, pos); pos += 4; // NegotiateFlags
-
-	buf.writeUInt8(5, pos); pos++; // ProductMajorVersion
-	buf.writeUInt8(1, pos); pos++; // ProductMinorVersion
-	buf.writeUInt16LE(2600, pos); pos += 2; // ProductBuild
-	buf.writeUInt8(0, pos); pos++; // VersionReserved1
-	buf.writeUInt8(0, pos); pos++; // VersionReserved2
-	buf.writeUInt8(0, pos); pos++; // VersionReserved3
-	buf.writeUInt8(15, pos); pos++; // NTLMRevisionCurrent
-
-	domainNameBytes.copy(buf, pos); pos += domainNameBytes.length;
-	usernameBytes.copy(buf, pos); pos += usernameBytes.length;
-	workstationBytes.copy(buf, pos); pos += workstationBytes.length;
-	lmChallengeResponse.copy(buf, pos); pos += lmChallengeResponse.length;
-	ntChallengeResponse.copy(buf, pos); pos += ntChallengeResponse.length;
-	encryptedRandomSessionKeyBytes.copy(buf, pos); pos += encryptedRandomSessionKeyBytes.length;
-
-	return 'NTLM ' + buf.toString('base64');
-}
-
-function create_LM_hashed_password_v1(password){
-	// fix the password length to 14 bytes
-	password = password.toUpperCase();
-	var passwordBytes = new Buffer(password, 'ascii');
-
-	var passwordBytesPadded = new Buffer(14);
-	passwordBytesPadded.fill("\0");
-	var sourceEnd = 14;
-	if(passwordBytes.length < 14) sourceEnd = passwordBytes.length;
-	passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
-
-	// split into 2 parts of 7 bytes:
-	var firstPart = passwordBytesPadded.slice(0,7);
-	var secondPart = passwordBytesPadded.slice(7);
-
-	function encrypt(buf){
-		var key = insertZerosEvery7Bits(buf);
-		var des = crypto.createCipheriv('DES-ECB', key, '');
-		return des.update("KGS!@#$%"); // page 57 in [MS-NLMP]);
-	}
-
-	var firstPartEncrypted = encrypt(firstPart);
-	var secondPartEncrypted = encrypt(secondPart);
-
-	return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
-}
-
-function insertZerosEvery7Bits(buf){
-	var binaryArray = bytes2binaryArray(buf);
-	var newBinaryArray = [];
-	for(var i=0; i<binaryArray.length; i++){
-		newBinaryArray.push(binaryArray[i]);
-
-		if((i+1)%7 === 0){
-			newBinaryArray.push(0);
-		}
-	}
-	return binaryArray2bytes(newBinaryArray);
-}
-
-function bytes2binaryArray(buf){
-	var hex2binary = {
-		0: [0,0,0,0],
-		1: [0,0,0,1],
-		2: [0,0,1,0],
-		3: [0,0,1,1],
-		4: [0,1,0,0],
-		5: [0,1,0,1],
-		6: [0,1,1,0],
-		7: [0,1,1,1],
-		8: [1,0,0,0],
-		9: [1,0,0,1],
-		A: [1,0,1,0],
-		B: [1,0,1,1],
-		C: [1,1,0,0],
-		D: [1,1,0,1],
-		E: [1,1,1,0],
-		F: [1,1,1,1]
-	};
-
-	var hexString = buf.toString('hex').toUpperCase();
-	var array = [];
-	for(var i=0; i<hexString.length; i++){
-   		var hexchar = hexString.charAt(i);
-   		array = array.concat(hex2binary[hexchar]);
-   	}
-   	return array;
-}
-
-function binaryArray2bytes(array){
-	var binary2hex = {
-		'0000': 0,
-		'0001': 1,
-		'0010': 2,
-		'0011': 3,
-		'0100': 4,
-		'0101': 5,
-		'0110': 6,
-		'0111': 7,
-		'1000': 8,
-		'1001': 9,
-		'1010': 'A',
-		'1011': 'B',
-		'1100': 'C',
-		'1101': 'D',
-		'1110': 'E',
-		'1111': 'F'
-	};
-
- 	var bufArray = [];
-
-	for(var i=0; i<array.length; i +=8 ){
-		if((i+7) > array.length)
-			break;
-
-		var binString1 = '' + array[i] + '' + array[i+1] + '' + array[i+2] + '' + array[i+3];
-		var binString2 = '' + array[i+4] + '' + array[i+5] + '' + array[i+6] + '' + array[i+7];
-   		var hexchar1 = binary2hex[binString1];
-   		var hexchar2 = binary2hex[binString2];
-
-   		var buf = new Buffer(hexchar1 + '' + hexchar2, 'hex');
-   		bufArray.push(buf);
-   	}
-
-   	return Buffer.concat(bufArray);
-}
-
-function create_NT_hashed_password_v1(password){
-	var buf = new Buffer(password, 'utf16le');
-	var md4 = crypto.createHash('md4');
-	md4.update(buf);
-	return new Buffer(md4.digest());
-}
-
-function calc_resp(password_hash, server_challenge){
-    // padding with zeros to make the hash 21 bytes long
-    var passHashPadded = new Buffer(21);
-    passHashPadded.fill("\0");
-    password_hash.copy(passHashPadded, 0, 0, password_hash.length);
-
-    var resArray = [];
-
-    var des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(0,7)), '');
-    resArray.push( des.update(server_challenge.slice(0,8)) );
-
-    des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(7,14)), '');
-    resArray.push( des.update(server_challenge.slice(0,8)) );
-
-    des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(14,21)), '');
-    resArray.push( des.update(server_challenge.slice(0,8)) );
-
-   	return Buffer.concat(resArray);
-}
-
-function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge){
-	// padding with zeros to make the hash 16 bytes longer
-    var lmChallengeResponse = new Buffer(clientChallenge.length + 16);
-    lmChallengeResponse.fill("\0");
-    clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
-
-    var buf = Buffer.concat([serverChallenge, clientChallenge]);
-    var md5 = crypto.createHash('md5');
-    md5.update(buf);
-    var sess = md5.digest();
-    var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0,8));
-
-    return {
-    	lmChallengeResponse: lmChallengeResponse,
-    	ntChallengeResponse: ntChallengeResponse
-    };
-}
-
-exports.createType1Message = createType1Message;
-exports.parseType2Message = parseType2Message;
-exports.createType3Message = createType3Message;
-
-
-
-
diff --git a/lib/opensource/node-http-ntlm/readme.txt b/lib/opensource/node-http-ntlm/readme.txt
deleted file mode 100644
index b341600..0000000
--- a/lib/opensource/node-http-ntlm/readme.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// This software (ntlm.js) was copied from a file of the same name at https://github.com/SamDecrock/node-http-ntlm/blob/master/ntlm.js.
-//
-// As of this writing, it is a part of the node-http-ntlm module produced by SamDecrock.
-//
-// It is used as a part of the NTLM support provided by the vso-node-api library.
-//
diff --git a/make.js b/make.js
index db067fe..dee7eeb 100644
--- a/make.js
+++ b/make.js
@@ -28,7 +28,6 @@ target.build = function () {
 
     run(path.join(__dirname, 'node_modules/.bin/tsc') + ' --outDir ' + buildPath);
     // cp(rp('dependencies/typings.json'), buildPath);
-    cp('-Rf', rp('lib/opensource'), buildPath);
     cp(rp('package.json'), buildPath);
     cp(rp('README.md'), buildPath);
     cp(rp('LICENSE'), buildPath);
diff --git a/package.json b/package.json
index d42420c..6fe0095 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "@types/mocha": "^2.2.41"
   },
   "dependencies": {
+    "httpntlm": "1.7.5",
     "tunnel": "0.0.4",
     "underscore": "1.8.3"
   }

Thanks!

CI Broken

CI failed on the last commit (before my stream of ugly commits trying to diagnose). Looks like it fails on previous commits as well, so I think this is actually an issue with the CI, not the commit.

Remove typings and Index.d.ts

In the distributed npm package, Index.d.ts has /// <reference path="../typings/index.d.ts" /> which prevents it from compiling. It works fine after I delete the file. Can we remove this?

Also, the documentation encourages installation of typings which was deprecated long time back. Can we update it to follow the best practices?

Large file download

Would you be so kind to provide us an example on how to efficiently download a large file with the http client?

It may sound trivial as a question, however for someone starting with Node and TS, aiming to build an efficient build task, this could be very useful.

Thanks

NTLM options need to all be specified

Right now if ntlmHandler's workstation and domain aren't specified, calls to ntlm.createType1Message (and maybe other methods) fail. They work if workstation and domain are specified, even if they're set to empty strings.

Discovered this while investigating microsoft/azure-devops-node-api#172

FYI - this is where it fails because it tries to call toUppercase on an undefined object

Failing to read error message

At the following line, in case of, let's say a 400 response that returns a body that is not JSON content

https://github.com/Microsoft/typed-rest-client/blob/17af59a9fdd8fcc1ed8e60064c46df20bcce6f52/lib/RestClient.ts#L221

the code will fail. This means that no matter which responseProcessor function we specify, it will never be reached.
A better approach would be to just wrap that line in something like this:

try {
 obj = JSON.parse(contents);
 } catch (e) {
 }   

This will allow us to specify a custom responseProcessor function which then will bring the simple error string in the exception.

If you agree, I'll submit a PR.

"TypeError: Cannot read property 'resolve' of undefined" when using React

The simplest example failed this error. After debugging I found that lib/Utils.js has the failing call: path.posix.resolve(base.pathname, resultantUrl.pathname); but path.posix is undefined with my setup. This setup is basically a React web app (meaning that the code is executed on the browser VM rather than by Node), on a Windows 10 box, if that makes a difference. I've simply replaced the call with path.resolve(base.pathname, resultantUrl.pathname), and it works, but I'm not sure if this is altering the outcome for some case.

Stack trace:

TypeError: Cannot read property 'resolve' of undefined
at Object.getUrl (http://localhost:3000/static/js/bundle.js:66588:40)
at RestClient.<anonymous> (http://localhost:3000/static/js/bundle.js:66412:28
at Generator.next (<anonymous>)    at http://localhost:3000/static/js/bundle.js:66370:71
at new Promise (<anonymous>)
at ./node_modules/typed-rest-client/RestClient.js.__awaiter (http://localhost:3000/static/js/bundle.js:66366:12)
at RestClient.get (http://localhost:3000/static/js/bundle.js:66411:16)
at TodoStore../src/model/TodoStore.ts.TodoStore.loadTodos (http://localhost:3000/static/js/bundle.js:69754:29)
at Object../src/App.tsx (http://localhost:3000/static/js/bundle.js:69321:11)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at fn (http://localhost:3000/static/js/bundle.js:89:20)
at Object../src/index.tsx (http://localhost:3000/static/js/bundle.js:69614:63)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at fn (http://localhost:3000/static/js/bundle.js:89:20)
at Object.0 (http://localhost:3000/static/js/bundle.js:70021:18)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at ./node_modules/ansi-regex/index.js.module.exports (http://localhost:3000/static/js/bundle.js:725:37)
at http://localhost:3000/static/js/bundle.js:728:10

Support using in a web page

https://github.com/Microsoft/typed-rest-client/blob/7ce1f4fe3407900f98a23568c7001c9c8fb23468/lib/HttpClient.ts#L11

Sorry if this is the wrong place to add this but when I am trying to use the library in a project I am getting an error saying that the http.globalAgent is undefined.
At that point http.Agent is available but for some reason not the globalAgent.
Commenting this out or setting the maxSockets in the Agent seems to work properly
http.Agent.maxSockets = 100;

Sorry but I was not able to get more info out of the documentation and ensured that I have the latest node and everything.

Even though npm run build and npm run test seems to work without any issues.

Here is a small sample of how I tried to use the library

import * as rm from 'typed-rest-client/RestClient';

interface Student {
    message: string
};

async function runSample() {
    let restc: rm.RestClient = new rm.RestClient('rest-samples', 'https://sample-api.dev');

    let res: rm.IRestResponse<Student> = await restc.get<Student>('/ping');

    console.log(res.statusCode);
    console.log(res.result);

    console.log('aha');
}

runSample();

The final file is complied with webpack

and I just include the final .js file into the html sample page where I get the error about the http.globalAgent.

Is there a specific reason why you setup the maxSocket at that point and not further down the code like you do for the httpProxy?

Hope the above makes sense.
For any clarifications plz let me know

If this does not make sense or you believe it is irrelevant then plz close it

Thank you

How to set a cookie for a request

Hello I'm using you client but I'm having some issues to set the auth cookie in the request

this.client = new rm.HttpClient('prevent-client');
var headers = {
    "Content-Type": "application/json",
    "Set-Cookie": this.cookieJar
};
var payload = {'cpid': 200};
 var responseStream = await this.client.post(this.host, JSON.stringify(payload), headers);

But the cookies are not sent to the server. Any ideas how to solve this? Thanks.

Propogate headers in RestClient's IRestResponse

Environment

Node version:
Npm version: 8.11.4
OS and version: Windows 10
typed-rest-client version: 1.0.9

Issue Description

Currently, in RestClient, calls to the public functions all receive a httpm.HttpClientResponse object which contains headers but return a promise of an IRestResponse object which does not contain headers.

Expected behaviour

IRestResponse should contain headers

Actual behaviour

IRestResponse only contains information pulled from the result and the status code.

Steps to reproduce

let restc: RestClient = new RestClient('rest-samples', 'httpbin.org/');
let restRes: IRestResponse<Object> = await restc.get<Object>('get');

Try to get headers from restRes

http client with binary data response

Environment

Node version: 8.12
Npm version: 6.4.1
OS and version: windows 10
typed-rest-client version: 1.0.11

Issue Description

I want to receive a file from server. server reponse binary file in body, but http client in this module override all non ascii byte to 65533. I figure out that reponse data is converted to string. Any method to deal with binary data?

I cannot launch the sample provided

0 info it worked if it ends with ok
1 verbose cli [ 'C:\Program Files (x86)\nodejs\node.exe',
1 verbose cli 'C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js',
1 verbose cli 'run',
1 verbose cli 'build' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle [email protected]prebuild: [email protected]
6 silly lifecycle [email protected]
prebuild: no script for prebuild, continuing
7 info lifecycle [email protected]build: [email protected]
8 verbose lifecycle [email protected]
build: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]build: PATH: C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\node-gyp-bin;C:\andrei\typed-rest-client\node_modules.bin;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Broadcom\Broadcom 802.11;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files\Hewlett-Packard\SimplePass;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit;C:\Program Files\Microsoft SQL Server\110\Tools\Binn;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0;C:\Program Files\Microsoft SQL Server\120\Tools\Binn;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit;C:\Users\Massimo.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm;C:\Program Files\Microsoft\Web Platform Installer;C:\Program Files (x86)\Microsoft SDKs\Azure\CLI\wbin;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Windows Phone TShell;C:\Program Files\Microsoft SQL Server\130\Tools\Binn;C:\Program Files (x86)\nodejs;C:\Program Files (x86)\Skype\Phone;C:\Program Files\dotnet;C:\Program Files\Git\cmd;C:\Users\Massimo.dnx\bin;C:\Users\Massimo\AppData\Local\Code\bin;C:\Program Files (x86)\Microsoft VS Code\bin;c:\Users\Massimo\AppData\Local\Android\sdk\platform-tools;C:\Users\Massimo\Downloads\watchman;C:\Users\Massimo\AppData\Local\Microsoft\WindowsApps;C:\Users\Massimo\AppData\Roaming\npm;C:\maven\bin;C:\OpenSSL-Win64\bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;
10 verbose lifecycle [email protected]
build: CWD: C:\andrei\typed-rest-client
11 silly lifecycle [email protected]build: Args: [ '/d /s /c', 'node make.js build' ]
12 silly lifecycle [email protected]
build: Returned: code: 1 signal: null
13 info lifecycle [email protected]~build: Failed to exec build script
14 verbose stack Error: [email protected] build: node make.js build
14 verbose stack Exit status 1
14 verbose stack at EventEmitter. (C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\lib\utils\lifecycle.js:279:16)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess. (C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\lib\utils\spawn.js:40:14)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:886:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid [email protected]
16 verbose cwd C:\andrei\typed-rest-client
17 verbose Windows_NT 10.0.15063
18 verbose argv "C:\Program Files (x86)\nodejs\node.exe" "C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js" "run" "build"
19 verbose node v6.10.2
20 verbose npm v4.5.0
21 error code ELIFECYCLE
22 error errno 1
23 error [email protected] build: node make.js build
23 error Exit status 1
24 error Failed at the [email protected] build script 'node make.js build'.
24 error Make sure you have the latest version of node.js and npm installed.
24 error If you do, this is most likely a problem with the typed-rest-client package,
24 error not with npm itself.
24 error Tell the author that this fails on your system:
24 error node make.js build
24 error You can get information on how to open an issue for this project with:
24 error npm bugs typed-rest-client
24 error Or if that isn't available, you can get their info via:
24 error npm owner ls typed-rest-client
24 error There is likely additional logging output above.
25 verbose exit [ 1, true ]

Here is my GIT SHA:
C:\andrei\typed-rest-client>git log
commit f486197
Author: Bryan MacFarlane [email protected]
Date: Tue Mar 28 16:30:56 2017 -0400

added options request

Support IE11 - target es5

Hi again,
this is mainly a question/request.

Issue Description

We currently use the library for browser usage and as we would like to be able and support IE11 the current npm package is not compatible as the compilation is targeted for es2015.
(The issue is that after compilation the files keep the class references which are not supported by IE11).

Solution

We have tried to work a solution with that and we have forked and updated the required files to target es5.

Our script works awesome with this change.

You can view the fork and branch here

https://github.com/baxevanis/typed-rest-client/tree/feature/support_es5

Please be aware that we also install the package through npm and github and that is why we had to add some additional configuration in the package.json (prepare and postinstall) to ensure npm can properly install the package.

Questions

So I have two questions:

  1. If we are to make a pull request with the target change to es5, would you consider accepting this change or your script relies on using es2015 explicitly?

  2. Can we publish a new npm package ex: typed-rest-client-es5 that will support es5? (by doing this we can clean up the additional changes that are required to install the package from github).

Thank you
Nikolaos

Support paths in base url

Just had a bug that turned out to be caused by the base "url" effectively being a "base domain."

For example, if you set the base url to http://example.com/common/base/path and then call a method with a relative path of /relative/path the client will end up calling http://example.com/relative/path.

From my experience, it's pretty common for REST API's to have a common base url that includes path elements and it is also common for client implementations to accept common path elements in the base url.

I think it would be a lot more user-friendly and conventional to support path elements in the base url.

Support using custom agent to manage requests.

Currently the request using global node agent for request in some cases and in other cases agent option isn't passed while making the rest api call.

We make a lot of calls to the same host in our tasks, currently these call are leading to create of new sockets, we want to be able to reuse sockets by setting keepAlive. We also want to throttle these calls by limiting maxSockets on the agent. Also, using an custom agent will not affect the calls made using global node agent.

Build errors, modules not found

Environment

Node version: 10.0.0
Npm version: 5.6.0
OS and version: Windows 10
typed-rest-client version: 1.0.7

Issue Description

Created a new Angular 6 project, added typed-rest-client.
Created a component which uses NtlmCredentialHandler and HttpClient and compiled. I get the errors below.

Expected behaviour

No errors should occur on build.

Actual behaviour

The following errors occur on build:

ERROR in ./node_modules/typed-rest-client/opensource/node-http-ntlm/ntlm.js
Module not found: Error: Can't resolve 'crypto' in 'C:\myapp\node_modules\typed-rest-client\opensource\node-http-ntlm'

ERROR in ./node_modules/typed-rest-client/handlers/ntlm.js
Module not found: Error: Can't resolve 'http' in 'C:\myapp\node_modules\typed-rest-client\handlers'

ERROR in ./node_modules/typed-rest-client/handlers/ntlm.js
Module not found: Error: Can't resolve 'https' in 'C:\myapp\node_modules\typed-rest-client\handlers'

Proxy doesn't work when password has url sensitive characters

Environment

Node version: 6.x
Npm version:
OS and version:
typed-rest-client version: 0.15.1

Issue Description

If password has characters like ':' '' proxy doesn't work, since we are url encoding the password at
https://github.com/Microsoft/typed-rest-client/blob/93448b8ffdf5183cddb710d0fde99d7e697026f1/lib/HttpClient.ts#L408

Expected behaviour

Proxy should work when password has url sensitive characters.

Actual behaviour

Error: tunneling socket could not be established, statusCode=407

Add nock to devDependencies

I think it would be better to add a mocking library which nock is to the devDependencies, because this should not be deployed on production systems. Other opinions about this?

How to get status code from an error response?

hi -- I'm using the create method to post an object to an external REST api. The response returned can have various status codes (even 300+) that indicate various things -- most of which are not actually errors. However, anything that returns with code not 2xx gets handled in the promise's catch block where the promise is rejected -- and the object I get back has properties "message" and "stack", but no status code (or anything else). Since I do need the status code, not just the message -- how do I get it? Thanks in advance.

UPDATE: Looking at the code it seems that you're swallowing this: https://github.com/Microsoft/typed-rest-client/blob/3587b31fe5b77f2d57b3ac5fb0f722fb1485ea6e/lib/RestClient.ts#L210-L220

Is there really no way to get the exact status code of a non-2xx response??? I find that hard to fathom.

In addition, what if one needs other info from a non-2xx response, like its data?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.