"use strict"; | |
// Copyright (c) Microsoft. All rights reserved. | |
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
const httpm = require("./HttpClient"); | |
const util = require("./Util"); | |
class RestClient { | |
/** | |
* Creates an instance of the RestClient | |
* @constructor | |
* @param {string} userAgent - userAgent for requests | |
* @param {string} baseUrl - (Optional) If not specified, use full urls per request. If supplied and a function passes a relative url, it will be appended to this | |
* @param {ifm.IRequestHandler[]} handlers - handlers are typically auth handlers (basic, bearer, ntlm supplied) | |
* @param {ifm.IRequestOptions} requestOptions - options for each http requests (http proxy setting, socket timeout) | |
*/ | |
constructor(userAgent, baseUrl, handlers, requestOptions) { | |
this.client = new httpm.HttpClient(userAgent, handlers, requestOptions); | |
if (baseUrl) { | |
this._baseUrl = baseUrl; | |
} | |
} | |
/** | |
* Gets a resource from an endpoint | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} requestUrl - fully qualified or relative url | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
options(requestUrl, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(requestUrl, this._baseUrl); | |
let res = yield this.client.options(url, this._headersFromOptions(options)); | |
return this.processResponse(res, options); | |
}); | |
} | |
/** | |
* Gets a resource from an endpoint | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} resource - fully qualified url or relative path | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
get(resource, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(resource, this._baseUrl, (options || {}).queryParameters); | |
let res = yield this.client.get(url, this._headersFromOptions(options)); | |
return this.processResponse(res, options); | |
}); | |
} | |
/** | |
* Deletes a resource from an endpoint | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} resource - fully qualified or relative url | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
del(resource, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(resource, this._baseUrl, (options || {}).queryParameters); | |
let res = yield this.client.del(url, this._headersFromOptions(options)); | |
return this.processResponse(res, options); | |
}); | |
} | |
/** | |
* Creates resource(s) from an endpoint | |
* T type of object returned. | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} resource - fully qualified or relative url | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
create(resource, resources, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(resource, this._baseUrl); | |
let headers = this._headersFromOptions(options, true); | |
let data = JSON.stringify(resources, null, 2); | |
let res = yield this.client.post(url, data, headers); | |
return this.processResponse(res, options); | |
}); | |
} | |
/** | |
* Updates resource(s) from an endpoint | |
* T type of object returned. | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} resource - fully qualified or relative url | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
update(resource, resources, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(resource, this._baseUrl); | |
let headers = this._headersFromOptions(options, true); | |
let data = JSON.stringify(resources, null, 2); | |
let res = yield this.client.patch(url, data, headers); | |
return this.processResponse(res, options); | |
}); | |
} | |
/** | |
* Replaces resource(s) from an endpoint | |
* T type of object returned. | |
* Be aware that not found returns a null. Other error conditions reject the promise | |
* @param {string} resource - fully qualified or relative url | |
* @param {IRequestOptions} requestOptions - (optional) requestOptions object | |
*/ | |
replace(resource, resources, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(resource, this._baseUrl); | |
let headers = this._headersFromOptions(options, true); | |
let data = JSON.stringify(resources, null, 2); | |
let res = yield this.client.put(url, data, headers); | |
return this.processResponse(res, options); | |
}); | |
} | |
uploadStream(verb, requestUrl, stream, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
let url = util.getUrl(requestUrl, this._baseUrl); | |
let headers = this._headersFromOptions(options, true); | |
let res = yield this.client.sendStream(verb, url, stream, headers); | |
return this.processResponse(res, options); | |
}); | |
} | |
_headersFromOptions(options, contentType) { | |
options = options || {}; | |
let headers = options.additionalHeaders || {}; | |
headers["Accept"] = options.acceptHeader || "application/json"; | |
if (contentType) { | |
let found = false; | |
for (let header in headers) { | |
if (header.toLowerCase() == "content-type") { | |
found = true; | |
} | |
} | |
if (!found) { | |
headers["Content-Type"] = 'application/json; charset=utf-8'; | |
} | |
} | |
return headers; | |
} | |
static dateTimeDeserializer(key, value) { | |
if (typeof value === 'string') { | |
let a = new Date(value); | |
if (!isNaN(a.valueOf())) { | |
return a; | |
} | |
} | |
return value; | |
} | |
processResponse(res, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { | |
const statusCode = res.message.statusCode; | |
const response = { | |
statusCode: statusCode, | |
result: null, | |
headers: {} | |
}; | |
// not found leads to null obj returned | |
if (statusCode == httpm.HttpCodes.NotFound) { | |
resolve(response); | |
} | |
let obj; | |
let contents; | |
// get the result from the body | |
try { | |
contents = yield res.readBody(); | |
if (contents && contents.length > 0) { | |
if (options && options.deserializeDates) { | |
obj = JSON.parse(contents, RestClient.dateTimeDeserializer); | |
} | |
else { | |
obj = JSON.parse(contents); | |
} | |
if (options && options.responseProcessor) { | |
response.result = options.responseProcessor(obj); | |
} | |
else { | |
response.result = obj; | |
} | |
} | |
response.headers = res.message.headers; | |
} | |
catch (err) { | |
// Invalid resource (contents not json); leaving result obj null | |
} | |
// note that 3xx redirects are handled by the http layer. | |
if (statusCode > 299) { | |
let msg; | |
// if exception/error in body, attempt to get better error | |
if (obj && obj.message) { | |
msg = obj.message; | |
} | |
else if (contents && contents.length > 0) { | |
// it may be the case that the exception is in the body message as string | |
msg = contents; | |
} | |
else { | |
msg = "Failed request: (" + statusCode + ")"; | |
} | |
let err = new Error(msg); | |
// attach statusCode and body obj (if available) to the error object | |
err['statusCode'] = statusCode; | |
if (response.result) { | |
err['result'] = response.result; | |
} | |
reject(err); | |
} | |
else { | |
resolve(response); | |
} | |
})); | |
}); | |
} | |
} | |
exports.RestClient = RestClient; |