@microsoft/microsoft-graph-client
Advanced tools
Comparing version 2.2.1 to 3.0.0-Preview.1
@@ -10,6 +10,10 @@ /** | ||
*/ | ||
import { MSALAuthenticationProviderOptions } from "../authentication/msal/MSALAuthenticationProviderOptions"; | ||
import { AuthenticationProvider } from "../IAuthenticationProvider"; | ||
import { AuthenticationProviderOptions } from "../IAuthenticationProviderOptions"; | ||
import { MSALAuthenticationProviderOptions } from "../MSALAuthenticationProviderOptions"; | ||
/** | ||
* @deprecated Use of ImplicitMSALAuthenticationProvider, that is, | ||
* using the implicit authorization flow is not recommended. | ||
* Use the TokenCredentialAuthenticationProvider with azure/identity library or | ||
* a CustomAuthenticationProvider with msal-browser library instead. | ||
* @class | ||
@@ -16,0 +20,0 @@ * Class representing ImplicitMSALAuthenticationProvider |
@@ -9,4 +9,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ImplicitMSALAuthenticationProvider = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
* @deprecated Use of ImplicitMSALAuthenticationProvider, that is, | ||
* using the implicit authorization flow is not recommended. | ||
* Use the TokenCredentialAuthenticationProvider with azure/identity library or | ||
* a CustomAuthenticationProvider with msal-browser library instead. | ||
* @class | ||
@@ -38,3 +43,3 @@ * Class representing ImplicitMSALAuthenticationProvider | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var options, scopes, error, tokenRequest, authResponse, error_1, authResponse, error_2, tokenRequest, authResponse, error_3; | ||
var options, scopes, error, tokenRequest, authResponse, error_1, authResponse, tokenRequest, authResponse; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -56,3 +61,3 @@ switch (_a.label) { | ||
} | ||
if (!this.msalApplication.getAccount()) return [3 /*break*/, 11]; | ||
if (!this.msalApplication.getAccount()) return [3 /*break*/, 8]; | ||
tokenRequest = { | ||
@@ -63,3 +68,3 @@ scopes: scopes, | ||
case 1: | ||
_a.trys.push([1, 3, , 10]); | ||
_a.trys.push([1, 3, , 7]); | ||
return [4 /*yield*/, this.msalApplication.acquireTokenSilent(tokenRequest)]; | ||
@@ -71,19 +76,11 @@ case 2: | ||
error_1 = _a.sent(); | ||
if (!(error_1.name === "InteractionRequiredAuthError")) return [3 /*break*/, 8]; | ||
_a.label = 4; | ||
if (!(error_1.name === "InteractionRequiredAuthError")) return [3 /*break*/, 5]; | ||
return [4 /*yield*/, this.msalApplication.acquireTokenPopup(tokenRequest)]; | ||
case 4: | ||
_a.trys.push([4, 6, , 7]); | ||
return [4 /*yield*/, this.msalApplication.acquireTokenPopup(tokenRequest)]; | ||
case 5: | ||
authResponse = _a.sent(); | ||
return [2 /*return*/, authResponse.accessToken]; | ||
case 6: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 7: return [3 /*break*/, 9]; | ||
case 8: throw error_1; | ||
case 9: return [3 /*break*/, 10]; | ||
case 10: return [3 /*break*/, 15]; | ||
case 11: | ||
_a.trys.push([11, 14, , 15]); | ||
case 5: throw error_1; | ||
case 6: return [3 /*break*/, 7]; | ||
case 7: return [3 /*break*/, 11]; | ||
case 8: | ||
tokenRequest = { | ||
@@ -93,12 +90,9 @@ scopes: scopes, | ||
return [4 /*yield*/, this.msalApplication.loginPopup(tokenRequest)]; | ||
case 12: | ||
case 9: | ||
_a.sent(); | ||
return [4 /*yield*/, this.msalApplication.acquireTokenSilent(tokenRequest)]; | ||
case 13: | ||
case 10: | ||
authResponse = _a.sent(); | ||
return [2 /*return*/, authResponse.accessToken]; | ||
case 14: | ||
error_3 = _a.sent(); | ||
throw error_3; | ||
case 15: return [2 /*return*/]; | ||
case 11: return [2 /*return*/]; | ||
} | ||
@@ -105,0 +99,0 @@ }); |
@@ -13,2 +13,3 @@ /** | ||
export * from "../middleware/RetryHandler"; | ||
export * from "../middleware/RedirectHandler"; | ||
export * from "../middleware/TelemetryHandler"; | ||
@@ -19,2 +20,3 @@ export * from "../middleware/MiddlewareFactory"; | ||
export * from "../middleware/options/RetryHandlerOptions"; | ||
export * from "../middleware/options/RedirectHandlerOptions"; | ||
export * from "../middleware/options/TelemetryHandlerOptions"; | ||
@@ -26,2 +28,9 @@ export * from "../middleware/options/ChaosHandlerOptions"; | ||
export * from "../tasks/OneDriveLargeFileUploadTask"; | ||
export * from "../tasks/OneDriveLargeFileUploadTaskUtil"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/FileUpload"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "../tasks/FileUploadTask/UploadResult"; | ||
export * from "../tasks/FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
export * from "../tasks/FileUploadTask/Range"; | ||
export * from "../tasks/PageIterator"; | ||
@@ -31,2 +40,3 @@ export * from "../Client"; | ||
export * from "../GraphError"; | ||
export * from "../GraphClientError"; | ||
export * from "../GraphRequest"; | ||
@@ -42,4 +52,2 @@ export * from "../IAuthProvider"; | ||
export * from "../IOptions"; | ||
export * from "./ImplicitMSALAuthenticationProvider"; | ||
export * from "../MSALAuthenticationProviderOptions"; | ||
export * from "../ResponseType"; |
@@ -14,7 +14,11 @@ "use strict"; | ||
tslib_1.__exportStar(require("../middleware/HTTPMessageHandler"), exports); | ||
tslib_1.__exportStar(require("../middleware/IMiddleware"), exports); | ||
tslib_1.__exportStar(require("../middleware/RetryHandler"), exports); | ||
tslib_1.__exportStar(require("../middleware/RedirectHandler"), exports); | ||
tslib_1.__exportStar(require("../middleware/TelemetryHandler"), exports); | ||
tslib_1.__exportStar(require("../middleware/MiddlewareFactory"), exports); | ||
tslib_1.__exportStar(require("../middleware/options/AuthenticationHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("../middleware/options/IMiddlewareOptions"), exports); | ||
tslib_1.__exportStar(require("../middleware/options/RetryHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("../middleware/options/RedirectHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("../middleware/options/TelemetryHandlerOptions"), exports); | ||
@@ -26,2 +30,9 @@ tslib_1.__exportStar(require("../middleware/options/ChaosHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("../tasks/OneDriveLargeFileUploadTask"), exports); | ||
tslib_1.__exportStar(require("../tasks/OneDriveLargeFileUploadTaskUtil"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/FileObjectClasses/StreamUpload"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/FileObjectClasses/FileUpload"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/FileObjectClasses/StreamUpload"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/UploadResult"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/Interfaces/IUploadEventHandlers"), exports); | ||
tslib_1.__exportStar(require("../tasks/FileUploadTask/Range"), exports); | ||
tslib_1.__exportStar(require("../tasks/PageIterator"), exports); | ||
@@ -31,6 +42,14 @@ tslib_1.__exportStar(require("../Client"), exports); | ||
tslib_1.__exportStar(require("../GraphError"), exports); | ||
tslib_1.__exportStar(require("../GraphClientError"), exports); | ||
tslib_1.__exportStar(require("../GraphRequest"), exports); | ||
tslib_1.__exportStar(require("./ImplicitMSALAuthenticationProvider"), exports); | ||
tslib_1.__exportStar(require("../MSALAuthenticationProviderOptions"), exports); | ||
tslib_1.__exportStar(require("../IAuthProvider"), exports); | ||
tslib_1.__exportStar(require("../IAuthenticationProvider"), exports); | ||
tslib_1.__exportStar(require("../IAuthenticationProviderOptions"), exports); | ||
tslib_1.__exportStar(require("../IAuthProviderCallback"), exports); | ||
tslib_1.__exportStar(require("../IClientOptions"), exports); | ||
tslib_1.__exportStar(require("../IContext"), exports); | ||
tslib_1.__exportStar(require("../IFetchOptions"), exports); | ||
tslib_1.__exportStar(require("../IGraphRequestCallback"), exports); | ||
tslib_1.__exportStar(require("../IOptions"), exports); | ||
tslib_1.__exportStar(require("../ResponseType"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -9,2 +9,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Client = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
@@ -36,10 +38,5 @@ * @module Client | ||
}; | ||
try { | ||
ValidatePolyFilling_1.validatePolyFilling(); | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
ValidatePolyFilling_1.validatePolyFilling(); | ||
for (var key in clientOptions) { | ||
if (clientOptions.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(clientOptions, key)) { | ||
this.config[key] = clientOptions[key]; | ||
@@ -59,3 +56,3 @@ } | ||
else if (clientOptions.middleware !== undefined) { | ||
httpClient = new (HTTPClient_1.HTTPClient.bind.apply(HTTPClient_1.HTTPClient, [void 0].concat([].concat(clientOptions.middleware))))(); | ||
httpClient = new (HTTPClient_1.HTTPClient.bind.apply(HTTPClient_1.HTTPClient, tslib_1.__spreadArray([void 0], [].concat(clientOptions.middleware))))(); | ||
} | ||
@@ -80,3 +77,3 @@ else { | ||
for (var i in options) { | ||
if (options.hasOwnProperty(i)) { | ||
if (Object.prototype.hasOwnProperty.call(options, i)) { | ||
clientOptions[i] = i === "authProvider" ? new CustomAuthenticationProvider_1.CustomAuthenticationProvider(options[i]) : options[i]; | ||
@@ -95,8 +92,3 @@ } | ||
Client.initWithMiddleware = function (clientOptions) { | ||
try { | ||
return new Client(clientOptions); | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
return new Client(clientOptions); | ||
}; | ||
@@ -103,0 +95,0 @@ /** |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GRAPH_URLS = exports.GRAPH_BASE_URL = exports.GRAPH_API_VERSION = void 0; | ||
/** | ||
@@ -27,3 +28,3 @@ * @module Constants | ||
*/ | ||
exports.GRAPH_URLS = new Set(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn"]); | ||
exports.GRAPH_URLS = new Set(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com"]); | ||
//# sourceMappingURL=Constants.js.map |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BatchRequestContent = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -346,2 +347,4 @@ /** | ||
/** | ||
* @see{@https://tools.ietf.org/html/rfc7578#section-4.4} | ||
* TODO- Setting/Defaulting of content-type header to the correct value | ||
* @see {@link https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching#request-format} | ||
@@ -348,0 +351,0 @@ */ |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BatchResponseContent = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -11,0 +12,0 @@ /** |
@@ -7,5 +7,2 @@ /** | ||
*/ | ||
/** | ||
* @module CustomAuthenticationProvider | ||
*/ | ||
import { AuthenticationProvider } from "./IAuthenticationProvider"; | ||
@@ -12,0 +9,0 @@ import { AuthProvider } from "./IAuthProvider"; |
@@ -9,4 +9,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CustomAuthenticationProvider = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
* @module CustomAuthenticationProvider | ||
*/ | ||
var GraphClientError_1 = require("./GraphClientError"); | ||
/** | ||
* @class | ||
@@ -38,10 +43,26 @@ * Class representing CustomAuthenticationProvider | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
_this.provider(function (error, accessToken) { | ||
if (accessToken) { | ||
resolve(accessToken); | ||
} | ||
else { | ||
reject(error); | ||
} | ||
}); | ||
_this.provider(function (error, accessToken) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var invalidTokenMessage, err; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!accessToken) return [3 /*break*/, 1]; | ||
resolve(accessToken); | ||
return [3 /*break*/, 3]; | ||
case 1: | ||
if (!error) { | ||
invalidTokenMessage = "Access token is undefined or empty.\ | ||
Please provide a valid token.\ | ||
For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md"; | ||
error = new GraphClientError_1.GraphClientError(invalidTokenMessage); | ||
} | ||
return [4 /*yield*/, GraphClientError_1.GraphClientError.setGraphClientError(error)]; | ||
case 2: | ||
err = _a.sent(); | ||
reject(err); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
})]; | ||
@@ -48,0 +69,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GraphError = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -11,0 +12,0 @@ /** |
@@ -31,3 +31,3 @@ /** | ||
* Populates the GraphError instance from the Error returned by graph service | ||
* @param {any} error - The error returned by graph service or some native error | ||
* @param {GraphAPIErrorResponse} graphError - The error possibly returned by graph service or some native error | ||
* @param {number} statusCode - The status code of the response | ||
@@ -54,2 +54,3 @@ * @returns A promise that resolves to GraphError instance | ||
* To get the GraphError object | ||
* Reference - https://docs.microsoft.com/en-us/graph/errors | ||
* @param {any} [error = null] - The error returned by graph service or some native error | ||
@@ -56,0 +57,0 @@ * @param {number} [statusCode = -1] - The status code of the response |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GraphErrorHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -44,3 +45,3 @@ /** | ||
* Populates the GraphError instance from the Error returned by graph service | ||
* @param {any} error - The error returned by graph service or some native error | ||
* @param {GraphAPIErrorResponse} graphError - The error possibly returned by graph service or some native error | ||
* @param {number} statusCode - The status code of the response | ||
@@ -61,4 +62,4 @@ * @returns A promise that resolves to GraphError instance | ||
*/ | ||
GraphErrorHandler.constructErrorFromResponse = function (error, statusCode) { | ||
error = error.error; | ||
GraphErrorHandler.constructErrorFromResponse = function (graphError, statusCode) { | ||
var error = graphError.error; | ||
var gError = new GraphError_1.GraphError(statusCode, error.message); | ||
@@ -70,8 +71,3 @@ gError.code = error.code; | ||
} | ||
try { | ||
gError.body = JSON.stringify(error); | ||
} | ||
catch (error) { | ||
// tslint:disable-line: no-empty | ||
} | ||
gError.body = JSON.stringify(error); | ||
return gError; | ||
@@ -84,2 +80,3 @@ }; | ||
* To get the GraphError object | ||
* Reference - https://docs.microsoft.com/en-us/graph/errors | ||
* @param {any} [error = null] - The error returned by graph service or some native error | ||
@@ -99,3 +96,3 @@ * @param {number} [statusCode = -1] - The status code of the response | ||
} | ||
else if (typeof Error !== "undefined" && error instanceof Error) { | ||
else if (error instanceof Error) { | ||
gError = GraphErrorHandler.constructError(error, statusCode); | ||
@@ -105,2 +102,3 @@ } | ||
gError = new GraphError_1.GraphError(statusCode); | ||
gError.body = error; // if a custom error is passed which is not instance of Error object or a graph API response | ||
} | ||
@@ -107,0 +105,0 @@ if (typeof callback === "function") { |
@@ -9,3 +9,8 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GraphRequest = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
* @module GraphRequest | ||
*/ | ||
var GraphClientError_1 = require("./GraphClientError"); | ||
var GraphErrorHandler_1 = require("./GraphErrorHandler"); | ||
@@ -22,3 +27,2 @@ var GraphRequestUtil_1 = require("./GraphRequestUtil"); | ||
var GraphRequest = /** @class */ (function () { | ||
/* tslint:enable: variable-name */ | ||
/** | ||
@@ -125,3 +129,3 @@ * @public | ||
if (this.config.debugLogging) { | ||
console.log(url); // tslint:disable-line: no-console | ||
console.log(url); | ||
} | ||
@@ -141,3 +145,3 @@ return url; | ||
for (var property in urlComponents.oDataQueryParams) { | ||
if (urlComponents.oDataQueryParams.hasOwnProperty(property)) { | ||
if (Object.prototype.hasOwnProperty.call(urlComponents.oDataQueryParams, property)) { | ||
query.push(property + "=" + urlComponents.oDataQueryParams[property]); | ||
@@ -149,3 +153,3 @@ } | ||
for (var property in urlComponents.otherURLQueryParams) { | ||
if (urlComponents.otherURLQueryParams.hasOwnProperty(property)) { | ||
if (Object.prototype.hasOwnProperty.call(urlComponents.otherURLQueryParams, property)) { | ||
query.push(property + "=" + urlComponents.otherURLQueryParams[property]); | ||
@@ -187,3 +191,3 @@ } | ||
for (var key in queryDictionaryOrString) { | ||
if (queryDictionaryOrString.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(queryDictionaryOrString, key)) { | ||
this.setURLComponentsQueryParamater(key, queryDictionaryOrString[key]); | ||
@@ -307,4 +311,7 @@ } | ||
error_1 = _a.sent(); | ||
if (error_1 instanceof GraphClientError_1.GraphClientError) { | ||
throw error_1; | ||
} | ||
statusCode = void 0; | ||
if (typeof rawResponse !== "undefined") { | ||
if (rawResponse) { | ||
statusCode = rawResponse.status; | ||
@@ -361,3 +368,3 @@ } | ||
for (var key in headers) { | ||
if (headers.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(headers, key)) { | ||
this._headers[key] = headers[key]; | ||
@@ -387,3 +394,3 @@ } | ||
for (var key in options) { | ||
if (options.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(options, key)) { | ||
this._options[key] = options[key]; | ||
@@ -517,3 +524,3 @@ } | ||
GraphRequest.prototype.count = function (isCount) { | ||
if (isCount === void 0) { isCount = false; } | ||
if (isCount === void 0) { isCount = true; } | ||
this.urlComponents.oDataQueryParams.$count = isCount.toString(); | ||
@@ -544,3 +551,3 @@ return this; | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, response, error_2; | ||
var url, options, response; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -553,13 +560,6 @@ switch (_a.label) { | ||
}; | ||
_a.label = 1; | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 4: return [2 /*return*/]; | ||
} | ||
@@ -579,3 +579,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, className, response, error_3; | ||
var url, options, className; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -598,13 +598,4 @@ switch (_a.label) { | ||
} | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_3 = _a.sent(); | ||
throw error_3; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -624,13 +615,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var error_4; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.post(content, callback)]; | ||
case 0: return [4 /*yield*/, this.post(content, callback)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_4 = _a.sent(); | ||
throw error_4; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -650,3 +634,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, response, error_5; | ||
var url, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -661,13 +645,4 @@ switch (_a.label) { | ||
}; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_5 = _a.sent(); | ||
throw error_5; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -687,3 +662,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, response, error_6; | ||
var url, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -698,13 +673,4 @@ switch (_a.label) { | ||
}; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_6 = _a.sent(); | ||
throw error_6; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -724,13 +690,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var error_7; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.patch(content, callback)]; | ||
case 0: return [4 /*yield*/, this.patch(content, callback)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_7 = _a.sent(); | ||
throw error_7; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -749,3 +708,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, response, error_8; | ||
var url, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -758,13 +717,4 @@ switch (_a.label) { | ||
}; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_8 = _a.sent(); | ||
throw error_8; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -783,13 +733,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var error_9; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.delete(callback)]; | ||
case 0: return [4 /*yield*/, this.delete(callback)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_9 = _a.sent(); | ||
throw error_9; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -808,3 +751,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, stream, error_10; | ||
var url, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -818,13 +761,4 @@ switch (_a.label) { | ||
this.responseType(ResponseType_1.ResponseType.STREAM); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
stream = _a.sent(); | ||
return [2 /*return*/, stream]; | ||
case 3: | ||
error_10 = _a.sent(); | ||
throw error_10; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -844,3 +778,3 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, options, response, error_11; | ||
var url, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -857,13 +791,4 @@ switch (_a.label) { | ||
}; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.send(url, options, callback)]; | ||
case 2: | ||
response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 3: | ||
error_11 = _a.sent(); | ||
throw error_11; | ||
case 4: return [2 /*return*/]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -870,0 +795,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isGraphURL = exports.serializeContent = exports.urlJoin = exports.oDataQueryNames = void 0; | ||
/** | ||
@@ -23,3 +24,3 @@ * @module GraphRequestUtil | ||
*/ | ||
exports.urlJoin = function (urlSegments) { | ||
var urlJoin = function (urlSegments) { | ||
var removePostSlash = function (s) { return s.replace(/\/+$/, ""); }; | ||
@@ -31,2 +32,3 @@ var removePreSlash = function (s) { return s.replace(/^\/+/, ""); }; | ||
}; | ||
exports.urlJoin = urlJoin; | ||
/** | ||
@@ -44,3 +46,3 @@ * Serializes the content | ||
*/ | ||
exports.serializeContent = function (content) { | ||
var serializeContent = function (content) { | ||
var className = content && content.constructor && content.constructor.name; | ||
@@ -66,2 +68,3 @@ if (className === "Buffer" || className === "Blob" || className === "File" || className === "FormData" || typeof content === "string") { | ||
}; | ||
exports.serializeContent = serializeContent; | ||
/** | ||
@@ -72,3 +75,3 @@ * Checks if the url is one of the service root endpoints for Microsoft Graph and Graph Explorer. | ||
*/ | ||
exports.isGraphURL = function (url) { | ||
var isGraphURL = function (url) { | ||
// Valid Graph URL pattern - https://graph.microsoft.com/{version}/{resource}?{query-parameters} | ||
@@ -95,2 +98,3 @@ // Valid Graph URL example - https://graph.microsoft.com/v1.0/ | ||
}; | ||
exports.isGraphURL = isGraphURL; | ||
//# sourceMappingURL=GraphRequestUtil.js.map |
@@ -9,2 +9,3 @@ /** | ||
* @module GraphResponseHandler | ||
* References - https://fetch.spec.whatwg.org/#responses | ||
*/ | ||
@@ -11,0 +12,0 @@ import { GraphRequestCallback } from "./IGraphRequestCallback"; |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GraphResponseHandler = exports.DocumentType = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -65,23 +66,18 @@ var ResponseType_1 = require("./ResponseType"); | ||
GraphResponseHandler.parseDocumentResponse = function (rawResponse, type) { | ||
try { | ||
if (typeof DOMParser !== "undefined") { | ||
return new Promise(function (resolve, reject) { | ||
rawResponse.text().then(function (xmlString) { | ||
try { | ||
var parser = new DOMParser(); | ||
var xmlDoc = parser.parseFromString(xmlString, type); | ||
resolve(xmlDoc); | ||
} | ||
catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
if (typeof DOMParser !== "undefined") { | ||
return new Promise(function (resolve, reject) { | ||
rawResponse.text().then(function (xmlString) { | ||
try { | ||
var parser = new DOMParser(); | ||
var xmlDoc = parser.parseFromString(xmlString, type); | ||
resolve(xmlDoc); | ||
} | ||
catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
} | ||
else { | ||
return Promise.resolve(rawResponse.body); | ||
} | ||
}); | ||
} | ||
catch (error) { | ||
throw error; | ||
else { | ||
return Promise.resolve(rawResponse.body); | ||
} | ||
@@ -100,3 +96,3 @@ }; | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var responseValue, _a, contentType, mimeType, error_1; | ||
var responseValue, contentType, _a, mimeType; | ||
return tslib_1.__generator(this, function (_b) { | ||
@@ -109,69 +105,66 @@ switch (_b.label) { | ||
} | ||
_b.label = 1; | ||
case 1: | ||
_b.trys.push([1, 26, , 27]); | ||
contentType = rawResponse.headers.get("Content-type"); | ||
_a = responseType; | ||
switch (_a) { | ||
case ResponseType_1.ResponseType.ARRAYBUFFER: return [3 /*break*/, 2]; | ||
case ResponseType_1.ResponseType.BLOB: return [3 /*break*/, 4]; | ||
case ResponseType_1.ResponseType.DOCUMENT: return [3 /*break*/, 6]; | ||
case ResponseType_1.ResponseType.JSON: return [3 /*break*/, 8]; | ||
case ResponseType_1.ResponseType.STREAM: return [3 /*break*/, 10]; | ||
case ResponseType_1.ResponseType.TEXT: return [3 /*break*/, 12]; | ||
case ResponseType_1.ResponseType.ARRAYBUFFER: return [3 /*break*/, 1]; | ||
case ResponseType_1.ResponseType.BLOB: return [3 /*break*/, 3]; | ||
case ResponseType_1.ResponseType.DOCUMENT: return [3 /*break*/, 5]; | ||
case ResponseType_1.ResponseType.JSON: return [3 /*break*/, 7]; | ||
case ResponseType_1.ResponseType.STREAM: return [3 /*break*/, 9]; | ||
case ResponseType_1.ResponseType.TEXT: return [3 /*break*/, 11]; | ||
} | ||
return [3 /*break*/, 14]; | ||
case 2: return [4 /*yield*/, rawResponse.arrayBuffer()]; | ||
case 3: | ||
return [3 /*break*/, 13]; | ||
case 1: return [4 /*yield*/, rawResponse.arrayBuffer()]; | ||
case 2: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 4: return [4 /*yield*/, rawResponse.blob()]; | ||
case 5: | ||
return [3 /*break*/, 24]; | ||
case 3: return [4 /*yield*/, rawResponse.blob()]; | ||
case 4: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 6: return [4 /*yield*/, GraphResponseHandler.parseDocumentResponse(rawResponse, DocumentType.TEXT_XML)]; | ||
case 7: | ||
return [3 /*break*/, 24]; | ||
case 5: return [4 /*yield*/, GraphResponseHandler.parseDocumentResponse(rawResponse, DocumentType.TEXT_XML)]; | ||
case 6: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 8: return [4 /*yield*/, rawResponse.json()]; | ||
case 9: | ||
return [3 /*break*/, 24]; | ||
case 7: return [4 /*yield*/, rawResponse.json()]; | ||
case 8: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 10: return [4 /*yield*/, Promise.resolve(rawResponse.body)]; | ||
case 11: | ||
return [3 /*break*/, 24]; | ||
case 9: return [4 /*yield*/, Promise.resolve(rawResponse.body)]; | ||
case 10: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 12: return [4 /*yield*/, rawResponse.text()]; | ||
return [3 /*break*/, 24]; | ||
case 11: return [4 /*yield*/, rawResponse.text()]; | ||
case 12: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 24]; | ||
case 13: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 25]; | ||
case 14: | ||
contentType = rawResponse.headers.get("Content-type"); | ||
if (!(contentType !== null)) return [3 /*break*/, 23]; | ||
if (!(contentType !== null)) return [3 /*break*/, 22]; | ||
mimeType = contentType.split(";")[0]; | ||
if (!new RegExp(ContentTypeRegexStr.DOCUMENT).test(mimeType)) return [3 /*break*/, 16]; | ||
if (!new RegExp(ContentTypeRegexStr.DOCUMENT).test(mimeType)) return [3 /*break*/, 15]; | ||
return [4 /*yield*/, GraphResponseHandler.parseDocumentResponse(rawResponse, mimeType)]; | ||
case 14: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 21]; | ||
case 15: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 22]; | ||
if (!new RegExp(ContentTypeRegexStr.IMAGE).test(mimeType)) return [3 /*break*/, 16]; | ||
responseValue = rawResponse.blob(); | ||
return [3 /*break*/, 21]; | ||
case 16: | ||
if (!new RegExp(ContentTypeRegexStr.IMAGE).test(mimeType)) return [3 /*break*/, 17]; | ||
responseValue = rawResponse.blob(); | ||
return [3 /*break*/, 22]; | ||
if (!(mimeType === ContentType.TEXT_PLAIN)) return [3 /*break*/, 18]; | ||
return [4 /*yield*/, rawResponse.text()]; | ||
case 17: | ||
if (!(mimeType === ContentType.TEXT_PLAIN)) return [3 /*break*/, 19]; | ||
return [4 /*yield*/, rawResponse.text()]; | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 21]; | ||
case 18: | ||
if (!(mimeType === ContentType.APPLICATION_JSON)) return [3 /*break*/, 20]; | ||
return [4 /*yield*/, rawResponse.json()]; | ||
case 19: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 22]; | ||
case 19: | ||
if (!(mimeType === ContentType.APPLICATION_JSON)) return [3 /*break*/, 21]; | ||
return [4 /*yield*/, rawResponse.json()]; | ||
return [3 /*break*/, 21]; | ||
case 20: | ||
responseValue = _b.sent(); | ||
return [3 /*break*/, 22]; | ||
case 21: | ||
responseValue = Promise.resolve(rawResponse.body); | ||
_b.label = 22; | ||
case 22: return [3 /*break*/, 24]; | ||
case 23: | ||
_b.label = 21; | ||
case 21: return [3 /*break*/, 23]; | ||
case 22: | ||
/** | ||
@@ -189,9 +182,5 @@ * RFC specification {@link https://tools.ietf.org/html/rfc7231#section-3.1.1.5} says: | ||
responseValue = Promise.resolve(rawResponse.body); | ||
_b.label = 24; | ||
case 24: return [3 /*break*/, 25]; | ||
case 25: return [3 /*break*/, 27]; | ||
case 26: | ||
error_1 = _b.sent(); | ||
throw error_1; | ||
case 27: return [2 /*return*/, responseValue]; | ||
_b.label = 23; | ||
case 23: return [3 /*break*/, 24]; | ||
case 24: return [2 /*return*/, responseValue]; | ||
} | ||
@@ -213,7 +202,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var response, error_2; | ||
var response; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 4, , 5]); | ||
if (!(responseType === ResponseType_1.ResponseType.RAW)) return [3 /*break*/, 1]; | ||
@@ -238,7 +226,3 @@ return [2 /*return*/, Promise.resolve(rawResponse)]; | ||
_a.label = 3; | ||
case 3: return [3 /*break*/, 5]; | ||
case 4: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 5: return [2 /*return*/]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -245,0 +229,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HTTPClient = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -79,7 +80,6 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var error, error_1; | ||
var error; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
if (typeof context.request === "string" && context.options === undefined) { | ||
@@ -95,6 +95,2 @@ error = new Error(); | ||
return [2 /*return*/, context]; | ||
case 2: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -101,0 +97,0 @@ }); |
@@ -9,2 +9,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HTTPClientFactory = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
@@ -79,3 +81,3 @@ * @module HTTPClientFactory | ||
// Middleware should not empty or undefined. This is check is present in the HTTPClient constructor. | ||
return new (HTTPClient_1.HTTPClient.bind.apply(HTTPClient_1.HTTPClient, [void 0].concat(middleware)))(); | ||
return new (HTTPClient_1.HTTPClient.bind.apply(HTTPClient_1.HTTPClient, tslib_1.__spreadArray([void 0], middleware)))(); | ||
}; | ||
@@ -82,0 +84,0 @@ return HTTPClientFactory; |
@@ -10,14 +10,16 @@ /** | ||
* Signature to define the fetch request options for node environment | ||
* @property {number} [follow] - Maximum redirect count. 0 to not follow redirect | ||
* @property {number} [timeout] - Request/Response timeout in milliseconds, it resets on redirect. 0 to disable (OS limit applies) | ||
* @property {number} [compress] - Support gzip/deflate content encoding. false to disable | ||
* @property {number} [size] - Maximum response body size in bytes. 0 to disable | ||
* @property {any} [agent] - HTTP(S).Agent instance, allows custom proxy, certificate, lookup, family etc. | ||
* @property {number} [follow] - node-fetch option: maximum redirect count. 0 to not follow redirect | ||
* @property {number} [compress] - node-fetch option: support gzip/deflate content encoding. false to disable | ||
* @property {number} [size] - node-fetch option: maximum response body size in bytes. 0 to disable | ||
* @property {any} [agent] - node-fetch option: HTTP(S).Agent instance, allows custom proxy, certificate, lookup, family etc. | ||
* @property {number} [highWaterMark] - node-fetch option: maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. | ||
* @property {boolean} [insecureHTTPParser] - node-fetch option: use an insecure HTTP parser that accepts invalid HTTP headers when `true`. | ||
*/ | ||
export interface NodeFetchInit { | ||
follow?: number; | ||
timeout?: number; | ||
compress?: boolean; | ||
size?: number; | ||
agent?: any; | ||
highWaterMark?: number; | ||
insecureHTTPParser?: boolean; | ||
} | ||
@@ -24,0 +26,0 @@ /** |
@@ -26,2 +26,9 @@ /** | ||
export * from "./tasks/OneDriveLargeFileUploadTask"; | ||
export * from "./tasks/OneDriveLargeFileUploadTaskUtil"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/FileUpload"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "./tasks/FileUploadTask/UploadResult"; | ||
export * from "./tasks/FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
export * from "./tasks/FileUploadTask/Range"; | ||
export * from "./tasks/PageIterator"; | ||
@@ -31,2 +38,3 @@ export * from "./Client"; | ||
export * from "./GraphError"; | ||
export * from "./GraphClientError"; | ||
export * from "./GraphRequest"; | ||
@@ -41,5 +49,3 @@ export * from "./IAuthProvider"; | ||
export * from "./IGraphRequestCallback"; | ||
export * from "./ImplicitMSALAuthenticationProvider"; | ||
export * from "./IOptions"; | ||
export * from "./MSALAuthenticationProviderOptions"; | ||
export * from "./ResponseType"; |
@@ -14,2 +14,3 @@ "use strict"; | ||
tslib_1.__exportStar(require("./middleware/HTTPMessageHandler"), exports); | ||
tslib_1.__exportStar(require("./middleware/IMiddleware"), exports); | ||
tslib_1.__exportStar(require("./middleware/RetryHandler"), exports); | ||
@@ -20,2 +21,3 @@ tslib_1.__exportStar(require("./middleware/RedirectHandler"), exports); | ||
tslib_1.__exportStar(require("./middleware/options/AuthenticationHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("./middleware/options/IMiddlewareOptions"), exports); | ||
tslib_1.__exportStar(require("./middleware/options/RetryHandlerOptions"), exports); | ||
@@ -29,2 +31,9 @@ tslib_1.__exportStar(require("./middleware/options/RedirectHandlerOptions"), exports); | ||
tslib_1.__exportStar(require("./tasks/OneDriveLargeFileUploadTask"), exports); | ||
tslib_1.__exportStar(require("./tasks/OneDriveLargeFileUploadTaskUtil"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/FileObjectClasses/StreamUpload"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/FileObjectClasses/FileUpload"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/FileObjectClasses/StreamUpload"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/UploadResult"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/Interfaces/IUploadEventHandlers"), exports); | ||
tslib_1.__exportStar(require("./tasks/FileUploadTask/Range"), exports); | ||
tslib_1.__exportStar(require("./tasks/PageIterator"), exports); | ||
@@ -34,6 +43,14 @@ tslib_1.__exportStar(require("./Client"), exports); | ||
tslib_1.__exportStar(require("./GraphError"), exports); | ||
tslib_1.__exportStar(require("./GraphClientError"), exports); | ||
tslib_1.__exportStar(require("./GraphRequest"), exports); | ||
tslib_1.__exportStar(require("./ImplicitMSALAuthenticationProvider"), exports); | ||
tslib_1.__exportStar(require("./MSALAuthenticationProviderOptions"), exports); | ||
tslib_1.__exportStar(require("./IAuthProvider"), exports); | ||
tslib_1.__exportStar(require("./IAuthenticationProvider"), exports); | ||
tslib_1.__exportStar(require("./IAuthenticationProviderOptions"), exports); | ||
tslib_1.__exportStar(require("./IAuthProviderCallback"), exports); | ||
tslib_1.__exportStar(require("./IClientOptions"), exports); | ||
tslib_1.__exportStar(require("./IContext"), exports); | ||
tslib_1.__exportStar(require("./IFetchOptions"), exports); | ||
tslib_1.__exportStar(require("./IGraphRequestCallback"), exports); | ||
tslib_1.__exportStar(require("./IOptions"), exports); | ||
tslib_1.__exportStar(require("./ResponseType"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -7,5 +7,2 @@ /** | ||
*/ | ||
/** | ||
* @module AuthenticationHandler | ||
*/ | ||
import { AuthenticationProvider } from "../IAuthenticationProvider"; | ||
@@ -12,0 +9,0 @@ import { Context } from "../IContext"; |
@@ -9,3 +9,8 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AuthenticationHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
* @module AuthenticationHandler | ||
*/ | ||
var GraphRequestUtil_1 = require("../GraphRequestUtil"); | ||
var MiddlewareControl_1 = require("./MiddlewareControl"); | ||
@@ -39,7 +44,8 @@ var MiddlewareUtil_1 = require("./MiddlewareUtil"); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var options, authenticationProvider, authenticationProviderOptions, token, bearerKey, error_1; | ||
var url, options, authenticationProvider, authenticationProviderOptions, token, bearerKey; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 3, , 4]); | ||
url = typeof context.request === "string" ? context.request : context.request.url; | ||
if (!GraphRequestUtil_1.isGraphURL(url)) return [3 /*break*/, 2]; | ||
options = void 0; | ||
@@ -51,7 +57,7 @@ if (context.middlewareControl instanceof MiddlewareControl_1.MiddlewareControl) { | ||
authenticationProviderOptions = void 0; | ||
if (typeof options !== "undefined") { | ||
if (options) { | ||
authenticationProvider = options.authenticationProvider; | ||
authenticationProviderOptions = options.authenticationProviderOptions; | ||
} | ||
if (typeof authenticationProvider === "undefined") { | ||
if (!authenticationProvider) { | ||
authenticationProvider = this.authenticationProvider; | ||
@@ -65,8 +71,10 @@ } | ||
TelemetryHandlerOptions_1.TelemetryHandlerOptions.updateFeatureUsageFlag(context, TelemetryHandlerOptions_1.FeatureUsageFlag.AUTHENTICATION_HANDLER_ENABLED); | ||
return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 2: return [2 /*return*/, _a.sent()]; | ||
case 3: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 4: return [2 /*return*/]; | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
if (context.options.headers) { | ||
delete context.options.headers[AuthenticationHandler.AUTHORIZATION_HEADER]; | ||
} | ||
_a.label = 3; | ||
case 3: return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 4: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -73,0 +81,0 @@ }); |
@@ -49,3 +49,3 @@ /** | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
@@ -59,8 +59,6 @@ * @param {string} requestDate - date of the request | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {string} statusMessage - the status message to be returned for the request | ||
* @param {ChaosHandlerOptions} options - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
* @param {string} requestDate - date of the request | ||
* @param {any?} requestBody - the request body to be returned for the request | ||
* @returns response body | ||
* * @returns response body | ||
*/ | ||
@@ -67,0 +65,0 @@ private createResponseBody; |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ChaosHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -39,3 +40,3 @@ var MiddlewareControl_1 = require("./MiddlewareControl"); | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
@@ -45,4 +46,4 @@ * @param {string} requestDate - date of the request | ||
*/ | ||
ChaosHandler.prototype.createResponseHeaders = function (statusCode, requestID, requestDate) { | ||
var responseHeader = new Headers(); | ||
ChaosHandler.prototype.createResponseHeaders = function (chaosHandlerOptions, requestID, requestDate) { | ||
var responseHeader = chaosHandlerOptions.headers ? new Headers(chaosHandlerOptions.headers) : new Headers(); | ||
responseHeader.append("Cache-Control", "no-store"); | ||
@@ -54,5 +55,5 @@ responseHeader.append("request-id", requestID); | ||
responseHeader.append("Strict-Transport-Security", ""); | ||
if (statusCode === 429) { | ||
if (chaosHandlerOptions.statusCode === 429) { | ||
// throttling case has to have a timeout scenario | ||
responseHeader.append("retry-after", "300"); | ||
responseHeader.append("retry-after", "3"); | ||
} | ||
@@ -64,17 +65,15 @@ return responseHeader; | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {string} statusMessage - the status message to be returned for the request | ||
* @param {ChaosHandlerOptions} options - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
* @param {string} requestDate - date of the request | ||
* @param {any?} requestBody - the request body to be returned for the request | ||
* @returns response body | ||
* * @returns response body | ||
*/ | ||
ChaosHandler.prototype.createResponseBody = function (statusCode, statusMessage, requestID, requestDate, responseBody) { | ||
if (responseBody) { | ||
return responseBody; | ||
ChaosHandler.prototype.createResponseBody = function (chaosHandlerOptions, requestID, requestDate) { | ||
if (chaosHandlerOptions.responseBody) { | ||
return chaosHandlerOptions.responseBody; | ||
} | ||
var body; | ||
if (statusCode >= 400) { | ||
var codeMessage = ChaosHandlerData_1.httpStatusCode[statusCode]; | ||
var errMessage = statusMessage; | ||
if (chaosHandlerOptions.statusCode >= 400) { | ||
var codeMessage = ChaosHandlerData_1.httpStatusCode[chaosHandlerOptions.statusCode]; | ||
var errMessage = chaosHandlerOptions.statusMessage; | ||
body = { | ||
@@ -103,18 +102,9 @@ error: { | ||
ChaosHandler.prototype.createResponse = function (chaosHandlerOptions, context) { | ||
try { | ||
var responseBody = void 0; | ||
var responseHeader = void 0; | ||
var requestID = void 0; | ||
var requestDate = void 0; | ||
var requestURL = context.request; | ||
requestID = MiddlewareUtil_1.generateUUID(); | ||
requestDate = new Date(); | ||
responseHeader = this.createResponseHeaders(chaosHandlerOptions.statusCode, requestID, requestDate.toString()); | ||
responseBody = this.createResponseBody(chaosHandlerOptions.statusCode, chaosHandlerOptions.statusMessage, requestID, requestDate.toString(), chaosHandlerOptions.responseBody); | ||
var init = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; | ||
context.response = new Response(responseBody, init); | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
var requestURL = context.request; | ||
var requestID = MiddlewareUtil_1.generateUUID(); | ||
var requestDate = new Date(); | ||
var responseHeader = this.createResponseHeaders(chaosHandlerOptions, requestID, requestDate.toString()); | ||
var responseBody = this.createResponseBody(chaosHandlerOptions, requestID, requestDate.toString()); | ||
var init = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; | ||
context.response = new Response(typeof responseBody === "string" ? responseBody : JSON.stringify(responseBody), init); | ||
}; | ||
@@ -130,21 +120,16 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var error_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 4, , 5]); | ||
this.setStatusCode(chaosHandlerOptions, context.request, context.options.method); | ||
if (!!chaosHandlerOptions.statusCode) return [3 /*break*/, 2]; | ||
if (!((chaosHandlerOptions.chaosStrategy === ChaosStrategy_1.ChaosStrategy.MANUAL && !this.nextMiddleware) || Math.floor(Math.random() * 100) < chaosHandlerOptions.chaosPercentage)) return [3 /*break*/, 1]; | ||
this.createResponse(chaosHandlerOptions, context); | ||
return [3 /*break*/, 3]; | ||
case 1: | ||
if (!this.nextMiddleware) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 1: | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
this.createResponse(chaosHandlerOptions, context); | ||
_a.label = 3; | ||
case 3: return [3 /*break*/, 5]; | ||
case 4: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 5: return [2 /*return*/]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -161,9 +146,4 @@ }); | ||
ChaosHandler.prototype.getRandomStatusCode = function (requestMethod) { | ||
try { | ||
var statusCodeArray = ChaosHandlerData_1.methodStatusCode[requestMethod]; | ||
return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
var statusCodeArray = ChaosHandlerData_1.methodStatusCode[requestMethod]; | ||
return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; | ||
}; | ||
@@ -193,39 +173,32 @@ /** | ||
var _this = this; | ||
try { | ||
if (chaosHandlerOptions.chaosStrategy === ChaosStrategy_1.ChaosStrategy.MANUAL) { | ||
if (chaosHandlerOptions.statusCode === undefined) { | ||
// manual mode with no status code, can be a global level or request level without statusCode | ||
var relativeURL_1 = this.getRelativeURL(requestURL); | ||
if (this.manualMap.get(relativeURL_1) !== undefined) { | ||
// checking Manual Map for exact match | ||
if (this.manualMap.get(relativeURL_1).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(relativeURL_1).get(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
if (chaosHandlerOptions.chaosStrategy === ChaosStrategy_1.ChaosStrategy.MANUAL) { | ||
if (chaosHandlerOptions.statusCode === undefined) { | ||
// manual mode with no status code, can be a global level or request level without statusCode | ||
var relativeURL_1 = this.getRelativeURL(requestURL); | ||
if (this.manualMap.get(relativeURL_1) !== undefined) { | ||
// checking Manual Map for exact match | ||
if (this.manualMap.get(relativeURL_1).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(relativeURL_1).get(requestMethod); | ||
} | ||
else { | ||
// checking for regex match if exact match doesn't work | ||
this.manualMap.forEach(function (value, key) { | ||
var regexURL = new RegExp(key + "$"); | ||
if (regexURL.test(relativeURL_1)) { | ||
if (_this.manualMap.get(key).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = _this.manualMap.get(key).get(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
// else statusCode would be undefined | ||
} | ||
else { | ||
// checking for regex match if exact match doesn't work | ||
this.manualMap.forEach(function (value, key) { | ||
var regexURL = new RegExp(key + "$"); | ||
if (regexURL.test(relativeURL_1)) { | ||
if (_this.manualMap.get(key).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = _this.manualMap.get(key).get(requestMethod); | ||
} | ||
}); | ||
} | ||
// Case of redirection or request url not in map ---> statusCode would be undefined | ||
// else statusCode would be undefined | ||
} | ||
}); | ||
} | ||
// Case of redirection or request url not in map ---> statusCode would be undefined | ||
} | ||
else { | ||
// Handling the case of Random here | ||
if (Math.floor(Math.random() * 100) < chaosHandlerOptions.chaosPercentage) { | ||
chaosHandlerOptions.statusCode = this.getRandomStatusCode(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
} | ||
} | ||
catch (error) { | ||
throw error; | ||
else { | ||
// Handling the case of Random here | ||
chaosHandlerOptions.statusCode = this.getRandomStatusCode(requestMethod); | ||
// else statusCode would be undefined | ||
} | ||
@@ -258,14 +231,9 @@ }; | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var chaosHandlerOptions, error_2; | ||
var chaosHandlerOptions; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
chaosHandlerOptions = this.getOptions(context); | ||
return [4 /*yield*/, this.sendRequest(chaosHandlerOptions, context)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -272,0 +240,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HTTPMessageHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -28,7 +29,6 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var _a, error_1; | ||
var _a; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_b.trys.push([0, 2, , 3]); | ||
_a = context; | ||
@@ -39,6 +39,2 @@ return [4 /*yield*/, fetch(context.request, context.options)]; | ||
return [2 /*return*/]; | ||
case 2: | ||
error_1 = _b.sent(); | ||
throw error_1; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -45,0 +41,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MiddlewareControl = void 0; | ||
/** | ||
@@ -24,3 +25,2 @@ * @class | ||
if (middlewareOptions === void 0) { middlewareOptions = []; } | ||
// tslint:disable-next-line:ban-types | ||
this.middlewareOptions = new Map(); | ||
@@ -43,3 +43,2 @@ for (var _i = 0, middlewareOptions_1 = middlewareOptions; _i < middlewareOptions_1.length; _i++) { | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
MiddlewareControl.prototype.getMiddlewareOptions = function (fn) { | ||
@@ -55,3 +54,2 @@ return this.middlewareOptions.get(fn); | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
MiddlewareControl.prototype.setMiddlewareOptions = function (fn, option) { | ||
@@ -58,0 +56,0 @@ this.middlewareOptions.set(fn, option); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MiddlewareFactory = void 0; | ||
var AuthenticationHandler_1 = require("./AuthenticationHandler"); | ||
@@ -11,0 +12,0 @@ var HTTPMessageHandler_1 = require("./HTTPMessageHandler"); |
@@ -25,3 +25,3 @@ /** | ||
*/ | ||
export declare const getRequestHeader: (request: RequestInfo, options: FetchOptions, key: string) => string; | ||
export declare const getRequestHeader: (request: RequestInfo, options: FetchOptions | undefined, key: string) => string | null; | ||
/** | ||
@@ -36,3 +36,3 @@ * @constant | ||
*/ | ||
export declare const setRequestHeader: (request: RequestInfo, options: FetchOptions, key: string, value: string) => void; | ||
export declare const setRequestHeader: (request: RequestInfo, options: FetchOptions | undefined, key: string, value: string) => void; | ||
/** | ||
@@ -47,3 +47,3 @@ * @constant | ||
*/ | ||
export declare const appendRequestHeader: (request: RequestInfo, options: FetchOptions, key: string, value: string) => void; | ||
export declare const appendRequestHeader: (request: RequestInfo, options: FetchOptions | undefined, key: string, value: string) => void; | ||
/** | ||
@@ -50,0 +50,0 @@ * @constant |
@@ -8,4 +8,4 @@ "use strict"; | ||
*/ | ||
var _this = this; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.cloneRequestWithNewUrl = exports.appendRequestHeader = exports.setRequestHeader = exports.getRequestHeader = exports.generateUUID = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -17,3 +17,3 @@ /** | ||
*/ | ||
exports.generateUUID = function () { | ||
var generateUUID = function () { | ||
var uuid = ""; | ||
@@ -28,2 +28,3 @@ for (var j = 0; j < 32; j++) { | ||
}; | ||
exports.generateUUID = generateUUID; | ||
/** | ||
@@ -37,3 +38,3 @@ * @constant | ||
*/ | ||
exports.getRequestHeader = function (request, options, key) { | ||
var getRequestHeader = function (request, options, key) { | ||
var value = null; | ||
@@ -62,2 +63,3 @@ if (typeof Request !== "undefined" && request instanceof Request) { | ||
}; | ||
exports.getRequestHeader = getRequestHeader; | ||
/** | ||
@@ -72,3 +74,3 @@ * @constant | ||
*/ | ||
exports.setRequestHeader = function (request, options, key, value) { | ||
var setRequestHeader = function (request, options, key, value) { | ||
var _a, _b; | ||
@@ -108,2 +110,3 @@ if (typeof Request !== "undefined" && request instanceof Request) { | ||
}; | ||
exports.setRequestHeader = setRequestHeader; | ||
/** | ||
@@ -118,3 +121,3 @@ * @constant | ||
*/ | ||
exports.appendRequestHeader = function (request, options, key, value) { | ||
var appendRequestHeader = function (request, options, key, value) { | ||
var _a, _b; | ||
@@ -149,2 +152,3 @@ if (typeof Request !== "undefined" && request instanceof Request) { | ||
}; | ||
exports.appendRequestHeader = appendRequestHeader; | ||
/** | ||
@@ -157,3 +161,3 @@ * @constant | ||
*/ | ||
exports.cloneRequestWithNewUrl = function (newUrl, request) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var cloneRequestWithNewUrl = function (newUrl, request) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { | ||
var body, _a, method, headers, referrer, referrerPolicy, mode, credentials, cache, redirect, integrity, keepalive, signal; | ||
@@ -179,2 +183,3 @@ return tslib_1.__generator(this, function (_b) { | ||
}); }; | ||
exports.cloneRequestWithNewUrl = cloneRequestWithNewUrl; | ||
//# sourceMappingURL=MiddlewareUtil.js.map |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AuthenticationHandlerOptions = void 0; | ||
/** | ||
@@ -11,0 +12,0 @@ * @class |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.httpStatusCode = exports.methodStatusCode = void 0; | ||
/** | ||
@@ -11,0 +12,0 @@ * @module ChaosHandlerData |
@@ -51,3 +51,9 @@ /** | ||
/** | ||
* The response headers to be returned in the response | ||
* | ||
* @public | ||
*/ | ||
headers: Headers; | ||
/** | ||
* @public | ||
* @constructor | ||
@@ -62,3 +68,3 @@ * To create an instance of Testing Handler Options | ||
*/ | ||
constructor(chaosStrategy?: ChaosStrategy, statusMessage?: string, statusCode?: number, chaosPercentage?: number, responseBody?: any); | ||
constructor(chaosStrategy?: ChaosStrategy, statusMessage?: string, statusCode?: number, chaosPercentage?: number, responseBody?: any, headers?: Headers); | ||
} |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ChaosHandlerOptions = void 0; | ||
/** | ||
@@ -32,3 +33,3 @@ * @module ChaosHandlerOptions | ||
*/ | ||
function ChaosHandlerOptions(chaosStrategy, statusMessage, statusCode, chaosPercentage, responseBody) { | ||
function ChaosHandlerOptions(chaosStrategy, statusMessage, statusCode, chaosPercentage, responseBody, headers) { | ||
if (chaosStrategy === void 0) { chaosStrategy = ChaosStrategy_1.ChaosStrategy.RANDOM; } | ||
@@ -41,2 +42,3 @@ if (statusMessage === void 0) { statusMessage = "Some error Happened"; } | ||
this.responseBody = responseBody; | ||
this.headers = headers; | ||
if (this.chaosPercentage > 100) { | ||
@@ -43,0 +45,0 @@ throw new Error("Error Pecentage can not be more than 100"); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ChaosStrategy = void 0; | ||
/** | ||
@@ -11,0 +12,0 @@ * @module ChaosStrategy |
@@ -48,3 +48,3 @@ /** | ||
*/ | ||
private static DEFAULT_SHOULD_RETRY; | ||
private static defaultShouldRetry; | ||
/** | ||
@@ -51,0 +51,0 @@ * @public |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RedirectHandlerOptions = void 0; | ||
/** | ||
@@ -26,3 +27,3 @@ * @class | ||
if (maxRedirects === void 0) { maxRedirects = RedirectHandlerOptions.DEFAULT_MAX_REDIRECTS; } | ||
if (shouldRedirect === void 0) { shouldRedirect = RedirectHandlerOptions.DEFAULT_SHOULD_RETRY; } | ||
if (shouldRedirect === void 0) { shouldRedirect = RedirectHandlerOptions.defaultShouldRetry; } | ||
if (maxRedirects > RedirectHandlerOptions.MAX_MAX_REDIRECTS) { | ||
@@ -57,3 +58,3 @@ var error = new Error("MaxRedirects should not be more than " + RedirectHandlerOptions.MAX_MAX_REDIRECTS); | ||
*/ | ||
RedirectHandlerOptions.DEFAULT_SHOULD_RETRY = function () { return true; }; | ||
RedirectHandlerOptions.defaultShouldRetry = function () { return true; }; | ||
return RedirectHandlerOptions; | ||
@@ -60,0 +61,0 @@ }()); |
@@ -66,3 +66,3 @@ /** | ||
*/ | ||
private static DEFAULT_SHOULD_RETRY; | ||
private static defaultShouldRetry; | ||
/** | ||
@@ -69,0 +69,0 @@ * @public |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RetryHandlerOptions = void 0; | ||
/** | ||
@@ -28,3 +29,3 @@ * @class | ||
if (maxRetries === void 0) { maxRetries = RetryHandlerOptions.DEFAULT_MAX_RETRIES; } | ||
if (shouldRetry === void 0) { shouldRetry = RetryHandlerOptions.DEFAULT_SHOULD_RETRY; } | ||
if (shouldRetry === void 0) { shouldRetry = RetryHandlerOptions.defaultShouldRetry; } | ||
if (delay > RetryHandlerOptions.MAX_DELAY && maxRetries > RetryHandlerOptions.MAX_MAX_RETRIES) { | ||
@@ -100,3 +101,3 @@ var error = new Error("Delay and MaxRetries should not be more than " + RetryHandlerOptions.MAX_DELAY + " and " + RetryHandlerOptions.MAX_MAX_RETRIES); | ||
*/ | ||
RetryHandlerOptions.DEFAULT_SHOULD_RETRY = function () { return true; }; | ||
RetryHandlerOptions.defaultShouldRetry = function () { return true; }; | ||
return RetryHandlerOptions; | ||
@@ -103,0 +104,0 @@ }()); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TelemetryHandlerOptions = exports.FeatureUsageFlag = void 0; | ||
var MiddlewareControl_1 = require("../MiddlewareControl"); | ||
@@ -20,2 +21,3 @@ /** | ||
(function (FeatureUsageFlag) { | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
FeatureUsageFlag[FeatureUsageFlag["NONE"] = 0] = "NONE"; | ||
@@ -25,2 +27,3 @@ FeatureUsageFlag[FeatureUsageFlag["REDIRECT_HANDLER_ENABLED"] = 1] = "REDIRECT_HANDLER_ENABLED"; | ||
FeatureUsageFlag[FeatureUsageFlag["AUTHENTICATION_HANDLER_ENABLED"] = 4] = "AUTHENTICATION_HANDLER_ENABLED"; | ||
/* eslint-enable @typescript-eslint/naming-convention */ | ||
})(FeatureUsageFlag = exports.FeatureUsageFlag || (exports.FeatureUsageFlag = {})); | ||
@@ -69,5 +72,3 @@ /** | ||
TelemetryHandlerOptions.prototype.setFeatureUsage = function (flag) { | ||
/* tslint:disable: no-bitwise */ | ||
this.featureUsage = this.featureUsage | flag; | ||
/* tslint:enable: no-bitwise */ | ||
}; | ||
@@ -74,0 +75,0 @@ /** |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RedirectHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -147,8 +148,6 @@ var RequestMethod_1 = require("../RequestMethod"); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var response, redirectUrl, error_1; | ||
var response, redirectUrl; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 8, , 9]); | ||
return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 0: return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 1: | ||
@@ -177,7 +176,3 @@ _a.sent(); | ||
case 6: return [2 /*return*/]; | ||
case 7: return [3 /*break*/, 9]; | ||
case 8: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 9: return [2 /*return*/]; | ||
case 7: return [2 /*return*/]; | ||
} | ||
@@ -196,7 +191,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var redirectCount, options, error_2; | ||
var redirectCount, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
redirectCount = 0; | ||
@@ -208,6 +202,2 @@ options = this.getOptions(context); | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -236,3 +226,3 @@ }); | ||
307, | ||
308, | ||
308, // Moved Permanently | ||
]; | ||
@@ -239,0 +229,0 @@ /** |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RetryHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -74,3 +75,2 @@ var RequestMethod_1 = require("../RequestMethod"); | ||
if (retryAfter !== null) { | ||
// tslint:disable: prefer-conditional-expression | ||
if (Number.isNaN(Number(retryAfter))) { | ||
@@ -82,3 +82,2 @@ newDelay = Math.round((new Date(retryAfter).getTime() - Date.now()) / 1000); | ||
} | ||
// tslint:enable: prefer-conditional-expression | ||
} | ||
@@ -137,8 +136,6 @@ else { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var delay, error_1; | ||
var delay; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 6, , 7]); | ||
return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 0: return [4 /*yield*/, this.nextMiddleware.execute(context)]; | ||
case 1: | ||
@@ -156,7 +153,2 @@ _a.sent(); | ||
case 4: return [2 /*return*/]; | ||
case 5: return [3 /*break*/, 7]; | ||
case 6: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 7: return [2 /*return*/]; | ||
} | ||
@@ -175,7 +167,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var retryAttempts, options, error_2; | ||
var retryAttempts, options; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
retryAttempts = 0; | ||
@@ -186,6 +177,2 @@ options = this.getOptions(context); | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -212,3 +199,3 @@ }); | ||
503, | ||
504, | ||
504, // Gateway timeout | ||
]; | ||
@@ -215,0 +202,0 @@ /** |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TelemetryHandler = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -36,7 +37,6 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var url, clientRequestId, sdkVersionValue, options, featureUsage, error_1; | ||
var url, clientRequestId, sdkVersionValue, options, featureUsage; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
url = typeof context.request === "string" ? context.request : context.request.url; | ||
@@ -67,6 +67,2 @@ if (GraphRequestUtil_1.isGraphURL(url)) { | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -73,0 +69,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RequestMethod = void 0; | ||
/** | ||
@@ -11,0 +12,0 @@ * @enum |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResponseType = void 0; | ||
/** | ||
@@ -11,0 +12,0 @@ * @enum |
@@ -7,7 +7,7 @@ /** | ||
*/ | ||
/** | ||
* @module LargeFileUploadTask | ||
*/ | ||
/// <reference types="node" /> | ||
import { Client } from "../index"; | ||
import { Range } from "../Range"; | ||
import { UploadEventHandlers } from "./FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
import { Range } from "./FileUploadTask/Range"; | ||
import { UploadResult } from "./FileUploadTask/UploadResult"; | ||
/** | ||
@@ -28,2 +28,3 @@ * @interface | ||
rangeSize?: number; | ||
uploadEventHandlers?: UploadEventHandlers; | ||
} | ||
@@ -39,4 +40,10 @@ /** | ||
expiry: Date; | ||
isCancelled?: boolean; | ||
} | ||
/** | ||
* @type | ||
* Representing the return type of the sliceFile function that is type of the slice of a given range. | ||
*/ | ||
export declare type SliceType = ArrayBuffer | Blob | Buffer; | ||
/** | ||
* @interface | ||
@@ -48,6 +55,7 @@ * Signature to define the properties and content of the file in upload task | ||
*/ | ||
export interface FileObject { | ||
content: ArrayBuffer | File; | ||
export interface FileObject<T> { | ||
content: T; | ||
name: string; | ||
size: number; | ||
sliceFile(range: Range): SliceType | Promise<SliceType>; | ||
} | ||
@@ -58,3 +66,3 @@ /** | ||
*/ | ||
export declare class LargeFileUploadTask { | ||
export declare class LargeFileUploadTask<T> { | ||
/** | ||
@@ -74,3 +82,3 @@ * @private | ||
*/ | ||
protected file: FileObject; | ||
protected file: FileObject<T>; | ||
/** | ||
@@ -101,3 +109,3 @@ * @protected | ||
*/ | ||
static createUploadSession(client: Client, requestUrl: string, payload: any, headers?: KeyValuePairObjectStringNumber): Promise<any>; | ||
static createUploadSession(client: Client, requestUrl: string, payload: any, headers?: KeyValuePairObjectStringNumber): Promise<LargeFileUploadSession>; | ||
/** | ||
@@ -113,3 +121,3 @@ * @public | ||
*/ | ||
constructor(client: Client, file: FileObject, uploadSession: LargeFileUploadSession, options?: LargeFileUploadTaskOptions); | ||
constructor(client: Client, file: FileObject<T>, uploadSession: LargeFileUploadSession, options?: LargeFileUploadTaskOptions); | ||
/** | ||
@@ -136,2 +144,3 @@ * @private | ||
/** | ||
* @deprecated This function has been moved into FileObject interface. | ||
* @public | ||
@@ -149,3 +158,3 @@ * Slices the file content to the given range | ||
*/ | ||
upload(): Promise<any>; | ||
upload(): Promise<UploadResult>; | ||
/** | ||
@@ -158,11 +167,22 @@ * @public | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The response body of the upload slice result | ||
*/ | ||
uploadSlice(fileSlice: ArrayBuffer | Blob | File, range: Range, totalSize: number): Promise<any>; | ||
uploadSlice(fileSlice: ArrayBuffer | Blob | File, range: Range, totalSize: number): Promise<unknown>; | ||
/** | ||
* @public | ||
* @async | ||
* Uploads given slice to the server | ||
* @param {unknown} fileSlice - The file slice | ||
* @param {Range} range - The range value | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The raw response of the upload slice result | ||
*/ | ||
uploadSliceGetRawResponse(fileSlice: unknown, range: Range, totalSize: number): Promise<Response>; | ||
/** | ||
* @public | ||
* @async | ||
* Deletes upload session in the server | ||
* @returns The promise resolves to cancelled response | ||
*/ | ||
cancel(): Promise<any>; | ||
cancel(): Promise<unknown>; | ||
/** | ||
@@ -174,3 +194,3 @@ * @public | ||
*/ | ||
getStatus(): Promise<any>; | ||
getStatus(): Promise<unknown>; | ||
/** | ||
@@ -182,4 +202,11 @@ * @public | ||
*/ | ||
resume(): Promise<any>; | ||
resume(): Promise<unknown>; | ||
/** | ||
* @public | ||
* @async | ||
* Get the upload session information | ||
* @returns The large file upload session | ||
*/ | ||
getUploadSession(): LargeFileUploadSession; | ||
} | ||
export {}; |
@@ -9,5 +9,13 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LargeFileUploadTask = void 0; | ||
var tslib_1 = require("tslib"); | ||
var Range_1 = require("../Range"); | ||
/** | ||
* @module LargeFileUploadTask | ||
*/ | ||
var GraphClientError_1 = require("../GraphClientError"); | ||
var GraphResponseHandler_1 = require("../GraphResponseHandler"); | ||
var ResponseType_1 = require("../ResponseType"); | ||
var Range_1 = require("./FileUploadTask/Range"); | ||
var UploadResult_1 = require("./FileUploadTask/UploadResult"); | ||
/** | ||
* @class | ||
@@ -35,4 +43,10 @@ * Class representing LargeFileUploadTask | ||
this.client = client; | ||
if (!file.sliceFile) { | ||
throw new GraphClientError_1.GraphClientError("Please pass the FileUpload object, StreamUpload object or any custom implementation of the FileObject interface"); | ||
} | ||
else { | ||
this.file = file; | ||
} | ||
this.file = file; | ||
if (options.rangeSize === undefined) { | ||
if (!options.rangeSize) { | ||
options.rangeSize = this.DEFAULT_FILE_SIZE; | ||
@@ -57,11 +71,9 @@ } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var session, largeFileUploadSession, err_1; | ||
var session, largeFileUploadSession; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, client | ||
.api(requestUrl) | ||
.headers(headers) | ||
.post(payload)]; | ||
case 0: return [4 /*yield*/, client | ||
.api(requestUrl) | ||
.headers(headers) | ||
.post(payload)]; | ||
case 1: | ||
@@ -72,8 +84,5 @@ session = _a.sent(); | ||
expiry: new Date(session.expirationDateTime), | ||
isCancelled: false, | ||
}; | ||
return [2 /*return*/, largeFileUploadSession]; | ||
case 2: | ||
err_1 = _a.sent(); | ||
throw err_1; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -129,2 +138,3 @@ }); | ||
/** | ||
* @deprecated This function has been moved into FileObject interface. | ||
* @public | ||
@@ -136,4 +146,7 @@ * Slices the file content to the given range | ||
LargeFileUploadTask.prototype.sliceFile = function (range) { | ||
var blob = this.file.content.slice(range.minValue, range.maxValue + 1); | ||
return blob; | ||
console.warn("The LargeFileUploadTask.sliceFile() function has been deprecated and moved into the FileObject interface."); | ||
if (this.file.content instanceof ArrayBuffer || this.file.content instanceof Blob || this.file.content instanceof Buffer) { | ||
return this.file.content.slice(range.minValue, range.maxValue + 1); | ||
} | ||
throw new GraphClientError_1.GraphClientError("The LargeFileUploadTask.sliceFile() function expects only Blob, ArrayBuffer or Buffer file content. Please note that the sliceFile() function is deprecated."); | ||
}; | ||
@@ -148,10 +161,10 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var nextRange, err, fileSlice, response, err_2; | ||
var uploadEventHandlers, nextRange, err, fileSlice, rawResponse, responseBody, uploadResult, res; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 4, , 5]); | ||
uploadEventHandlers = this.options && this.options.uploadEventHandlers; | ||
_a.label = 1; | ||
case 1: | ||
if (!true) return [3 /*break*/, 3]; | ||
if (!!this.uploadSession.isCancelled) return [3 /*break*/, 5]; | ||
nextRange = this.getNextRange(); | ||
@@ -163,18 +176,31 @@ if (nextRange.maxValue === -1) { | ||
} | ||
fileSlice = this.sliceFile(nextRange); | ||
return [4 /*yield*/, this.uploadSlice(fileSlice, nextRange, this.file.size)]; | ||
return [4 /*yield*/, this.file.sliceFile(nextRange)]; | ||
case 2: | ||
response = _a.sent(); | ||
// Upon completion of upload process incase of onedrive, driveItem is returned, which contains id | ||
if (response.id !== undefined) { | ||
return [2 /*return*/, response]; | ||
fileSlice = _a.sent(); | ||
return [4 /*yield*/, this.uploadSliceGetRawResponse(fileSlice, nextRange, this.file.size)]; | ||
case 3: | ||
rawResponse = _a.sent(); | ||
if (!rawResponse) { | ||
throw new GraphClientError_1.GraphClientError("Something went wrong! Large file upload slice response is null."); | ||
} | ||
else { | ||
this.updateTaskStatus(response); | ||
return [4 /*yield*/, GraphResponseHandler_1.GraphResponseHandler.getResponse(rawResponse)]; | ||
case 4: | ||
responseBody = _a.sent(); | ||
/** | ||
* (rawResponse.status === 201) -> This condition is applicable for OneDrive, PrintDocument and Outlook APIs. | ||
* (rawResponse.status === 200 && responseBody.id) -> This additional condition is applicable only for OneDrive API. | ||
*/ | ||
if (rawResponse.status === 201 || (rawResponse.status === 200 && responseBody.id)) { | ||
uploadResult = UploadResult_1.UploadResult.CreateUploadResult(responseBody, rawResponse.headers); | ||
return [2 /*return*/, uploadResult]; | ||
} | ||
res = { | ||
expirationDateTime: responseBody.expirationDateTime || responseBody.ExpirationDateTime, | ||
nextExpectedRanges: responseBody.NextExpectedRanges || responseBody.nextExpectedRanges, | ||
}; | ||
this.updateTaskStatus(res); | ||
if (uploadEventHandlers && uploadEventHandlers.progress) { | ||
uploadEventHandlers.progress(nextRange, uploadEventHandlers.extraCallbackParam); | ||
} | ||
return [3 /*break*/, 1]; | ||
case 3: return [3 /*break*/, 5]; | ||
case 4: | ||
err_2 = _a.sent(); | ||
throw err_2; | ||
case 5: return [2 /*return*/]; | ||
@@ -192,22 +218,16 @@ } | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The response body of the upload slice result | ||
*/ | ||
LargeFileUploadTask.prototype.uploadSlice = function (fileSlice, range, totalSize) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_3; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": "" + (range.maxValue - range.minValue + 1), | ||
"Content-Range": "bytes " + range.minValue + "-" + range.maxValue + "/" + totalSize, | ||
}) | ||
.put(fileSlice)]; | ||
case 0: return [4 /*yield*/, this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": "" + (range.maxValue - range.minValue + 1), | ||
"Content-Range": "bytes " + range.minValue + "-" + range.maxValue + "/" + totalSize, | ||
}) | ||
.put(fileSlice)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
err_3 = _a.sent(); | ||
throw err_3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -220,2 +240,28 @@ }); | ||
* @async | ||
* Uploads given slice to the server | ||
* @param {unknown} fileSlice - The file slice | ||
* @param {Range} range - The range value | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The raw response of the upload slice result | ||
*/ | ||
LargeFileUploadTask.prototype.uploadSliceGetRawResponse = function (fileSlice, range, totalSize) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": "" + (range.maxValue - range.minValue + 1), | ||
"Content-Range": "bytes " + range.minValue + "-" + range.maxValue + "/" + totalSize, | ||
}) | ||
.responseType(ResponseType_1.ResponseType.RAW) | ||
.put(fileSlice)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
* @public | ||
* @async | ||
* Deletes upload session in the server | ||
@@ -226,13 +272,15 @@ * @returns The promise resolves to cancelled response | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_4; | ||
var cancelResponse; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.client.api(this.uploadSession.url).delete()]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
err_4 = _a.sent(); | ||
throw err_4; | ||
case 3: return [2 /*return*/]; | ||
case 0: return [4 /*yield*/, this.client | ||
.api(this.uploadSession.url) | ||
.responseType(ResponseType_1.ResponseType.RAW) | ||
.delete()]; | ||
case 1: | ||
cancelResponse = _a.sent(); | ||
if (cancelResponse.status === 204) { | ||
this.uploadSession.isCancelled = true; | ||
} | ||
return [2 /*return*/, cancelResponse]; | ||
} | ||
@@ -250,8 +298,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var response, err_5; | ||
var response; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.client.api(this.uploadSession.url).get()]; | ||
case 0: return [4 /*yield*/, this.client.api(this.uploadSession.url).get()]; | ||
case 1: | ||
@@ -261,6 +307,2 @@ response = _a.sent(); | ||
return [2 /*return*/, response]; | ||
case 2: | ||
err_5 = _a.sent(); | ||
throw err_5; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -278,8 +320,5 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_6; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 3, , 4]); | ||
return [4 /*yield*/, this.getStatus()]; | ||
case 0: return [4 /*yield*/, this.getStatus()]; | ||
case 1: | ||
@@ -289,6 +328,2 @@ _a.sent(); | ||
case 2: return [2 /*return*/, _a.sent()]; | ||
case 3: | ||
err_6 = _a.sent(); | ||
throw err_6; | ||
case 4: return [2 /*return*/]; | ||
} | ||
@@ -298,2 +333,11 @@ }); | ||
}; | ||
/** | ||
* @public | ||
* @async | ||
* Get the upload session information | ||
* @returns The large file upload session | ||
*/ | ||
LargeFileUploadTask.prototype.getUploadSession = function () { | ||
return this.uploadSession; | ||
}; | ||
return LargeFileUploadTask; | ||
@@ -300,0 +344,0 @@ }()); |
@@ -8,6 +8,4 @@ /** | ||
/// <reference types="node" /> | ||
/** | ||
* @module OneDriveLargeFileUploadTask | ||
*/ | ||
import { Client } from "../index"; | ||
import { UploadEventHandlers } from "./FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
import { FileObject, LargeFileUploadSession, LargeFileUploadTask, LargeFileUploadTaskOptions } from "./LargeFileUploadTask"; | ||
@@ -21,12 +19,25 @@ /** | ||
*/ | ||
interface OneDriveLargeFileUploadOptions { | ||
export interface OneDriveLargeFileUploadOptions { | ||
fileName: string; | ||
path?: string; | ||
rangeSize?: number; | ||
conflictBehavior?: string; | ||
uploadEventHandlers?: UploadEventHandlers; | ||
} | ||
/** | ||
* @interface | ||
* Signature to define options when creating an upload task | ||
* @property {string} fileName - Specifies the name of a file to be uploaded (with extension) | ||
* @property {string} [path] - The path to which the file needs to be uploaded | ||
* @property {number} [rangeSize] - Specifies the range chunk size | ||
*/ | ||
interface OneDriveFileUploadSessionPayLoad { | ||
fileName: string; | ||
conflictBehavior?: string; | ||
} | ||
/** | ||
* @class | ||
* Class representing OneDriveLargeFileUploadTask | ||
*/ | ||
export declare class OneDriveLargeFileUploadTask extends LargeFileUploadTask { | ||
export declare class OneDriveLargeFileUploadTask<T> extends LargeFileUploadTask<T> { | ||
/** | ||
@@ -57,3 +68,3 @@ * @private | ||
*/ | ||
static create(client: Client, file: Blob | Buffer | File, options: OneDriveLargeFileUploadOptions): Promise<any>; | ||
static create(client: Client, file: Blob | Buffer | File, options: OneDriveLargeFileUploadOptions): Promise<OneDriveLargeFileUploadTask<Blob | ArrayBuffer | Buffer>>; | ||
/** | ||
@@ -63,2 +74,13 @@ * @public | ||
* @async | ||
* Creates a OneDriveLargeFileUploadTask | ||
* @param {Client} client - The GraphClient instance | ||
* @param {FileObject} file - FileObject instance | ||
* @param {OneDriveLargeFileUploadOptions} options - The options for upload task | ||
* @returns The promise that will be resolves to OneDriveLargeFileUploadTask instance | ||
*/ | ||
static createTaskWithFileObject<T>(client: Client, fileObject: FileObject<T>, options: OneDriveLargeFileUploadOptions): Promise<OneDriveLargeFileUploadTask<T>>; | ||
/** | ||
* @public | ||
* @static | ||
* @async | ||
* Makes request to the server to create an upload session | ||
@@ -68,5 +90,6 @@ * @param {Client} client - The GraphClient instance | ||
* @param {string} fileName - The name of a file to upload, (with extension) | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise that resolves to LargeFileUploadSession | ||
*/ | ||
static createUploadSession(client: Client, requestUrl: string, fileName: string): Promise<any>; | ||
static createUploadSession(client: Client, requestUrl: string, payloadOptions: OneDriveFileUploadSessionPayLoad): Promise<LargeFileUploadSession>; | ||
/** | ||
@@ -82,3 +105,3 @@ * @public | ||
*/ | ||
constructor(client: Client, file: FileObject, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions); | ||
constructor(client: Client, file: FileObject<T>, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions); | ||
/** | ||
@@ -88,6 +111,7 @@ * @public | ||
* @param {string} requestUrl - The URL to commit the upload session | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise resolves to committed response | ||
*/ | ||
commit(requestUrl: string): Promise<any>; | ||
commit(requestUrl: string, conflictBehavior?: string): Promise<unknown>; | ||
} | ||
export {}; |
@@ -9,3 +9,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OneDriveLargeFileUploadTask = void 0; | ||
var tslib_1 = require("tslib"); | ||
/** | ||
* @module OneDriveLargeFileUploadTask | ||
*/ | ||
var GraphClientError_1 = require("../GraphClientError"); | ||
var FileUpload_1 = require("./FileUploadTask/FileObjectClasses/FileUpload"); | ||
var LargeFileUploadTask_1 = require("./LargeFileUploadTask"); | ||
@@ -72,40 +78,58 @@ var OneDriveLargeFileUploadTaskUtil_1 = require("./OneDriveLargeFileUploadTaskUtil"); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var name, content, size, b, requestUrl, session, rangeSize, fileObj, err_1; | ||
var name, content, size, b, fileObj; | ||
return tslib_1.__generator(this, function (_a) { | ||
if (!client || !file || !options) { | ||
throw new GraphClientError_1.GraphClientError("Please provide the Graph client instance, file object and OneDriveLargeFileUploadOptions value"); | ||
} | ||
name = options.fileName; | ||
if (typeof Blob !== "undefined" && file instanceof Blob) { | ||
content = new File([file], name); | ||
size = content.size; | ||
} | ||
else if (typeof File !== "undefined" && file instanceof File) { | ||
content = file; | ||
size = content.size; | ||
} | ||
else if (typeof Buffer !== "undefined" && file instanceof Buffer) { | ||
b = file; | ||
size = b.byteLength - b.byteOffset; | ||
content = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength); | ||
} | ||
fileObj = new FileUpload_1.FileUpload(content, name, size); | ||
return [2 /*return*/, this.createTaskWithFileObject(client, fileObj, options)]; | ||
}); | ||
}); | ||
}; | ||
/** | ||
* @public | ||
* @static | ||
* @async | ||
* Creates a OneDriveLargeFileUploadTask | ||
* @param {Client} client - The GraphClient instance | ||
* @param {FileObject} file - FileObject instance | ||
* @param {OneDriveLargeFileUploadOptions} options - The options for upload task | ||
* @returns The promise that will be resolves to OneDriveLargeFileUploadTask instance | ||
*/ | ||
OneDriveLargeFileUploadTask.createTaskWithFileObject = function (client, fileObject, options) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var requestUrl, uploadSessionPayload, session, rangeSize; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
name = options.fileName; | ||
if (typeof Blob !== "undefined" && file instanceof Blob) { | ||
content = new File([file], name); | ||
size = content.size; | ||
if (!client || !fileObject || !options) { | ||
throw new GraphClientError_1.GraphClientError("Please provide the Graph client instance, FileObject interface implementation and OneDriveLargeFileUploadOptions value"); | ||
} | ||
else if (typeof File !== "undefined" && file instanceof File) { | ||
content = file; | ||
size = content.size; | ||
} | ||
else if (typeof Buffer !== "undefined" && file instanceof Buffer) { | ||
b = file; | ||
size = b.byteLength - b.byteOffset; | ||
content = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength); | ||
} | ||
_a.label = 1; | ||
requestUrl = OneDriveLargeFileUploadTask.constructCreateSessionUrl(options.fileName, options.path); | ||
uploadSessionPayload = { | ||
fileName: options.fileName, | ||
conflictBehavior: options.conflictBehavior, | ||
}; | ||
return [4 /*yield*/, OneDriveLargeFileUploadTask.createUploadSession(client, requestUrl, uploadSessionPayload)]; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
requestUrl = OneDriveLargeFileUploadTask.constructCreateSessionUrl(options.fileName, options.path); | ||
return [4 /*yield*/, OneDriveLargeFileUploadTask.createUploadSession(client, requestUrl, options.fileName)]; | ||
case 2: | ||
session = _a.sent(); | ||
rangeSize = OneDriveLargeFileUploadTaskUtil_1.getValidRangeSize(options.rangeSize); | ||
fileObj = { | ||
name: name, | ||
content: content, | ||
size: size, | ||
}; | ||
return [2 /*return*/, new OneDriveLargeFileUploadTask(client, fileObj, session, { | ||
return [2 /*return*/, new OneDriveLargeFileUploadTask(client, fileObject, session, { | ||
rangeSize: rangeSize, | ||
uploadEventHandlers: options.uploadEventHandlers, | ||
})]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
throw err_1; | ||
case 4: return [2 /*return*/]; | ||
} | ||
@@ -123,5 +147,6 @@ }); | ||
* @param {string} fileName - The name of a file to upload, (with extension) | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise that resolves to LargeFileUploadSession | ||
*/ | ||
OneDriveLargeFileUploadTask.createUploadSession = function (client, requestUrl, fileName) { | ||
OneDriveLargeFileUploadTask.createUploadSession = function (client, requestUrl, payloadOptions) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
@@ -132,13 +157,7 @@ var payload; | ||
item: { | ||
"@microsoft.graph.conflictBehavior": "rename", | ||
name: fileName, | ||
"@microsoft.graph.conflictBehavior": (payloadOptions === null || payloadOptions === void 0 ? void 0 : payloadOptions.conflictBehavior) || "rename", | ||
name: payloadOptions === null || payloadOptions === void 0 ? void 0 : payloadOptions.fileName, | ||
}, | ||
}; | ||
try { | ||
return [2 /*return*/, _super.createUploadSession.call(this, client, requestUrl, payload)]; | ||
} | ||
catch (err) { | ||
throw err; | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, _super.createUploadSession.call(this, client, requestUrl, payload)]; | ||
}); | ||
@@ -151,14 +170,15 @@ }); | ||
* @param {string} requestUrl - The URL to commit the upload session | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise resolves to committed response | ||
*/ | ||
OneDriveLargeFileUploadTask.prototype.commit = function (requestUrl) { | ||
OneDriveLargeFileUploadTask.prototype.commit = function (requestUrl, conflictBehavior) { | ||
if (conflictBehavior === void 0) { conflictBehavior = "rename"; } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var payload, err_2; | ||
var payload; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
payload = { | ||
name: this.file.name, | ||
"@microsoft.graph.conflictBehavior": "rename", | ||
"@microsoft.graph.conflictBehavior": conflictBehavior, | ||
"@microsoft.graph.sourceUrl": this.uploadSession.url, | ||
@@ -168,6 +188,2 @@ }; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
err_2 = _a.sent(); | ||
throw err_2; | ||
case 3: return [2 /*return*/]; | ||
} | ||
@@ -174,0 +190,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getValidRangeSize = void 0; | ||
/** | ||
@@ -39,3 +40,3 @@ * @module OneDriveLargeFileUploadTaskUtil | ||
*/ | ||
exports.getValidRangeSize = function (rangeSize) { | ||
var getValidRangeSize = function (rangeSize) { | ||
if (rangeSize === void 0) { rangeSize = DEFAULT_FILE_SIZE; } | ||
@@ -48,2 +49,3 @@ var sixtyMB = 60 * 1024 * 1024; | ||
}; | ||
exports.getValidRangeSize = getValidRangeSize; | ||
//# sourceMappingURL=OneDriveLargeFileUploadTaskUtil.js.map |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PageIterator = void 0; | ||
var tslib_1 = require("tslib"); | ||
@@ -59,7 +60,6 @@ /** | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var graphRequest, response, error_1; | ||
var graphRequest, response; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
graphRequest = this.client.api(this.nextLink); | ||
@@ -83,7 +83,3 @@ if (this.requestOptions) { | ||
this.deltaLink = response["@odata.deltaLink"]; | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
error_1 = _a.sent(); | ||
throw error_1; | ||
case 3: return [2 /*return*/]; | ||
return [2 /*return*/]; | ||
} | ||
@@ -110,7 +106,6 @@ }); | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var advance, error_2; | ||
var advance; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 6, , 7]); | ||
advance = this.iterationHelper(); | ||
@@ -134,7 +129,3 @@ _a.label = 1; | ||
} | ||
return [3 /*break*/, 7]; | ||
case 6: | ||
error_2 = _a.sent(); | ||
throw error_2; | ||
case 7: return [2 /*return*/]; | ||
return [2 /*return*/]; | ||
} | ||
@@ -154,9 +145,3 @@ }); | ||
return tslib_1.__generator(this, function (_a) { | ||
try { | ||
return [2 /*return*/, this.iterate()]; | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, this.iterate()]; | ||
}); | ||
@@ -163,0 +148,0 @@ }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validatePolyFilling = void 0; | ||
/** | ||
@@ -16,3 +17,3 @@ * @constant | ||
*/ | ||
exports.validatePolyFilling = function () { | ||
var validatePolyFilling = function () { | ||
if (typeof Promise === "undefined" && typeof fetch === "undefined") { | ||
@@ -35,2 +36,3 @@ var error = new Error("Library cannot function without Promise and fetch. So, please provide polyfill for them."); | ||
}; | ||
exports.validatePolyFilling = validatePolyFilling; | ||
//# sourceMappingURL=ValidatePolyFilling.js.map |
@@ -10,2 +10,2 @@ /** | ||
*/ | ||
export declare const PACKAGE_VERSION = "2.2.1"; | ||
export declare const PACKAGE_VERSION = "3.0.0-Preview.1"; |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PACKAGE_VERSION = void 0; | ||
// THIS FILE IS AUTO GENERATED | ||
@@ -15,3 +16,3 @@ // ANY CHANGES WILL BE LOST DURING BUILD | ||
*/ | ||
exports.PACKAGE_VERSION = "2.2.1"; | ||
exports.PACKAGE_VERSION = "3.0.0-Preview.1"; | ||
//# sourceMappingURL=Version.js.map |
159
package.json
{ | ||
"name": "@microsoft/microsoft-graph-client", | ||
"version": "2.2.1", | ||
"version": "3.0.0-Preview.1", | ||
"description": "Microsoft Graph Client Library", | ||
"keywords": [ | ||
"Microsoft", | ||
"Graph", | ||
"SDK", | ||
"JavaScript", | ||
"Client" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/microsoftgraph/msgraph-sdk-javascript.git" | ||
}, | ||
"license": "MIT", | ||
"main": "lib/src/index.js", | ||
"module": "lib/es/index.js", | ||
"module": "lib/es/src/index.js", | ||
"browser": { | ||
"./lib/es/src/index.js": "./lib/es/src/browser/index.js", | ||
"stream": "stream-browserify" | ||
}, | ||
"types": "./lib/src/index.d.ts", | ||
"typings": "lib/src/index", | ||
"files": [ | ||
"lib/", | ||
"src/" | ||
"src/", | ||
"authProviders/" | ||
], | ||
"types": "./lib/src/index.d.ts", | ||
"scripts": { | ||
"build": "npm run pre-build && npm run build:sub_cjs && npm run build:sub_es && rollup -c", | ||
"build:cjs": "tsc --p tsconfig-cjs.json", | ||
"build:es": "tsc --p tsconfig-es.json", | ||
"build:sub_cjs": "tsc -b tsconfig-sub-cjs.json", | ||
"build:sub_es": "tsc -b tsconfig-sub-es.json", | ||
"format": "npm run format:css && npm run format:html && npm run format:js && npm run format:json && npm run format:md && npm run format:rc && npm run format:ts", | ||
"format:css": "prettier --write \"**/*.css\"", | ||
"format:html": "prettier --write \"**/*.html\"", | ||
"format:js": "prettier --write \"**/*.js\"", | ||
"format:json": "prettier --write \"**/*.json\"", | ||
"format:md": "prettier --write \"**/*.md\"", | ||
"format:rc": "prettier --write --parser json \"**/.*rc\"", | ||
"format:ts": "prettier --write \"**/*.ts\"", | ||
"karma": "karma start --single-run --browsers ChromeHeadless karma.conf.js", | ||
"lint": "eslint . --ext .ts", | ||
"lint:fix": "eslint . --ext .ts --fix", | ||
"prepack": "npm install && npm run build && npm run test", | ||
"pre-build": "npm run setVersion", | ||
"setVersion": "gulp setVersion", | ||
"test": "npm run test:cjs && npm run test:esm", | ||
"test:cjs": "npm run build:sub_cjs && mocha 'lib/test/common/**/*.js' --require isomorphic-fetch && mocha 'lib/test/node/**/*.js' --require isomorphic-fetch", | ||
"test:coverage": "TS_NODE_PROJECT='./tsconfig-cjs.json' nyc mocha --require isomorphic-fetch -r ts-node/register test/common/**/*.ts && mocha --require isomorphic-fetch -r ts-node/register test/common/**/*.ts", | ||
"test:development": "tsc --p test/tsconfig-test-development.json && mocha 'lib/test/development/**/*.js' --require isomorphic-fetch", | ||
"test:esm": "npm run build:sub_es && mocha 'lib/es/test/common/**/*.js' --require esm --require isomorphic-fetch && mocha 'lib/es/test/node/**/*.js' --require esm --require isomorphic-fetch" | ||
}, | ||
"nyc": { | ||
"all": true, | ||
"cache": false, | ||
"exclude": [ | ||
"samples/", | ||
"*.js", | ||
"lib/" | ||
], | ||
"include": [ | ||
"src/" | ||
] | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.4.4", | ||
"msal": "^1.4.4", | ||
"tslib": "^1.9.3" | ||
"@babel/runtime": "^7.12.5", | ||
"tslib": "^2.2.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.4.4", | ||
"@babel/plugin-transform-runtime": "^7.4.4", | ||
"@babel/preset-env": "^7.4.4", | ||
"@types/mocha": "^5.2.6", | ||
"@azure/identity": "^1.3.0", | ||
"@babel/core": "^7.12.10", | ||
"@babel/plugin-transform-runtime": "^7.12.10", | ||
"@babel/preset-env": "^7.12.11", | ||
"@istanbuljs/nyc-config-typescript": "^1.0.1", | ||
"@microsoft/microsoft-graph-types": "^1.28.0", | ||
"@rollup/plugin-babel": "^5.2.2", | ||
"@rollup/plugin-commonjs": "^17.0.0", | ||
"@rollup/plugin-node-resolve": "^11.1.0", | ||
"@types/chai": "^4.2.14", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^12.0.10", | ||
"@types/sinon": "^9.0.9", | ||
"@typescript-eslint/eslint-plugin": "^3.8.0", | ||
"@typescript-eslint/parser": "^3.8.0", | ||
"chai": "^4.2.0", | ||
"eslint": "^7.19.0", | ||
"eslint-config-prettier": "^7.2.0", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"eslint-plugin-simple-import-sort": "^7.0.0", | ||
"esm": "^3.2.25", | ||
"form-data": "^2.3.3", | ||
"gulp": "^4.0.2", | ||
"husky": "^2.2.0", | ||
"isomorphic-fetch": "^2.2.1", | ||
"isomorphic-fetch": "^3.0.0", | ||
"karma": "^5.2.3", | ||
"karma-chai": "^0.1.0", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma-firefox-launcher": "^2.1.0", | ||
"karma-mocha": "^2.0.1", | ||
"karma-typescript": "^5.2.0", | ||
"lint-staged": "^8.1.5", | ||
"mocha": "^6.1.4", | ||
"mocha": "^6.2.3", | ||
"msal": "^1.0.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^1.17.0", | ||
"rollup": "^1.10.1", | ||
"rollup-plugin-babel": "^4.3.2", | ||
"rollup-plugin-commonjs": "^10.0.1", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"rollup-plugin-terser": "^5.0.0", | ||
"tslint": "^5.16.0", | ||
"tslint-config-prettier": "^1.18.0", | ||
"typescript": "^3.4.5", | ||
"rollup": "^2.36.2", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"sinon": "^9.2.4", | ||
"source-map-support": "^0.5.19", | ||
"stream-browserify": "^3.0.0", | ||
"ts-node": "^9.0.0", | ||
"typescript": "^4.2.4", | ||
"uglify-es": "^3.3.9" | ||
}, | ||
"scripts": { | ||
"setVersion": "gulp setVersion", | ||
"build:es": "tsc --p tsconfig-es.json", | ||
"build:cjs": "tsc --p tsconfig-cjs.json", | ||
"pre-build": "npm run setVersion", | ||
"build": "npm run pre-build && npm run build:cjs && npm run build:es && rollup -c", | ||
"test": "npm run build:cjs && mocha lib/spec/content && mocha lib/spec/core && mocha lib/spec/middleware && mocha lib/spec/tasks", | ||
"test:content": "tsc --p spec/tsconfig.json && mocha spec/content", | ||
"test:core": "tsc --p spec/tsconfig.json && mocha spec/core", | ||
"test:middleware": "tsc --p spec/tsconfig.json && mocha spec/middleware", | ||
"test:tasks": "tsc --p spec/tsconfig.json && mocha spec/tasks", | ||
"test:development": "tsc --p spec/tsconfig.json && mocha spec/development/workload", | ||
"test:workload": "tsc --p spec/tsconfig.json && mocha spec/development/workload", | ||
"lint": "tslint --project ./tsconfig-cjs.json -c tslint.json", | ||
"format:css": "prettier --write \"**/*.css\"", | ||
"format:html": "prettier --write \"**/*.html\"", | ||
"format:js": "prettier --write \"**/*.js\"", | ||
"format:json": "prettier --write \"**/*.json\"", | ||
"format:md": "prettier --write \"**/*.md\"", | ||
"format:rc": "prettier --write --parser json \"**/.*rc\"", | ||
"format:ts": "prettier --write \"**/*.ts\"", | ||
"format": "npm run format:css && npm run format:html && npm run format:js && npm run format:json && npm run format:md && npm run format:rc && npm run format:ts", | ||
"prepack": "npm install && npm run build && npm run test" | ||
"peerDependenciesMeta": { | ||
"@azure/identity": { | ||
"optional": true | ||
}, | ||
"buffer": { | ||
"optional": true | ||
}, | ||
"msal": { | ||
"optional": true | ||
}, | ||
"stream-browserify": { | ||
"optional": true | ||
} | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/microsoftgraph/msgraph-sdk-javascript.git" | ||
"engines": { | ||
"node": ">=10.0.0" | ||
} | ||
} |
171
README.md
# Microsoft Graph JavaScript Client Library | ||
[![npm version badge](https://img.shields.io/npm/v/@microsoft/microsoft-graph-client.svg?maxAge=86400)](https://www.npmjs.com/package/@microsoft/microsoft-graph-client) [![Travis](https://travis-ci.org/microsoftgraph/msgraph-sdk-javascript.svg?maxAge=86400)](https://travis-ci.org/microsoftgraph/msgraph-sdk-javascript) [![Known Vulnerabilities](https://snyk.io/test/github/microsoftgraph/msgraph-sdk-javascript/badge.svg?maxAge=86400)](https://snyk.io/test/github/microsoftgraph/msgraph-sdk-javascript) [![Licence](https://img.shields.io/github/license/microsoftgraph/msgraph-sdk-javascript.svg)](https://github.com/microsoftgraph/msgraph-sdk-javascript) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/microsoftgraph/msgraph-sdk-javascript) [![Downloads](https://img.shields.io/npm/dm/@microsoft/microsoft-graph-client.svg?maxAge=86400)](https://www.npmjs.com/package/@microsoft/microsoft-graph-client) | ||
[![npm version badge](https://img.shields.io/npm/v/@microsoft/microsoft-graph-client.svg?maxAge=86400)](https://www.npmjs.com/package/@microsoft/microsoft-graph-client) [![Known Vulnerabilities](https://snyk.io/test/github/microsoftgraph/msgraph-sdk-javascript/badge.svg?maxAge=86400)](https://snyk.io/test/github/microsoftgraph/msgraph-sdk-javascript) [![Licence](https://img.shields.io/github/license/microsoftgraph/msgraph-sdk-javascript.svg)](https://github.com/microsoftgraph/msgraph-sdk-javascript) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/microsoftgraph/msgraph-sdk-javascript) [![Downloads](https://img.shields.io/npm/dm/@microsoft/microsoft-graph-client.svg?maxAge=86400)](https://www.npmjs.com/package/@microsoft/microsoft-graph-client) | ||
The Microsoft Graph JavaScript client library is a lightweight wrapper around the Microsoft Graph API that can be used server-side and in the browser. | ||
**Looking for IntelliSense on models (Users, Groups, etc.)? Check out the [Microsoft Graph Types](https://github.com/microsoftgraph/msgraph-typescript-typings) repository!** | ||
- [Microsoft Graph JavaScript Client Library](#microsoft-graph-javascript-client-library) | ||
- [Installation](#installation) | ||
- [Via npm](#via-npm) | ||
- [Via Script Tag](#via-script-tag) | ||
- [Getting started](#getting-started) | ||
- [1. Register your application](#1-register-your-application) | ||
- [2. Create a Client Instance](#2-create-a-client-instance) | ||
- [3. Make requests to the graph](#3-make-requests-to-the-graph) | ||
- Documentation | ||
- [HTTP Actions](docs/Actions.md) | ||
- [Chained APIs to call Microsoft Graph](docs/CallingPattern.md) | ||
- [OData system query options - Query Parameters](docs/QueryParameters.md) | ||
- [Batch multiple requests into single HTTP request](docs/content/Batching.md) | ||
- [Cancel a HTTP request](docs/CancellingAHTTPRequest.md) | ||
- [Configurations to your request](docs/OtherAPIs.md) | ||
- [Query](docs/OtherAPIs.md#QUERY) | ||
- [Version](docs/OtherAPIs.md#VERSION) | ||
- [Headers](docs/OtherAPIs.md#HEADER-AND-HEADERS) | ||
- [Options](docs/OtherAPIs.md#OPTION-AND-OPTIONS) | ||
- [MiddlewareOptions](docs/OtherAPIs.md#MIDDLEWAREOPTIONS) | ||
- [ResponseType](docs/OtherAPIs.md#RESPONSETYPE) | ||
- [Upload large files to OneDrive, Outlook, Print API](docs/tasks/LargeFileUploadTask.md) | ||
- [Page Iteration](docs/tasks/PageIterator.md) | ||
- [Getting Raw Response](docs/GettingRawResponse.md) | ||
- [Creating an instance of TokenCredentialAuthenticationProvider](docs/TokenCredentialAuthenticationProvider.md) | ||
- [Questions and comments](#questions-and-comments) | ||
- [Contributing](#contributing) | ||
- [Additional resources](#additional-resources) | ||
- [Third Party Notices](#third-party-notices) | ||
- [Security Reporting](#security-reporting) | ||
- [License](#license) | ||
- [We Value and Adhere to the Microsoft Open Source Code of Conduct](#we-value-and-adhere-to-the-microsoft-open-source-code-of-conduct) | ||
[![TypeScript demo](https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-javascript/master/types-demo.PNG)](https://github.com/microsoftgraph/msgraph-typescript-typings) | ||
## Node version requirement | ||
Node.js 10 LTS or higher. | ||
## Installation | ||
@@ -19,6 +54,12 @@ | ||
import `@microsoft/microsoft-graph-client` into your module and also you will need polyfills for fetch like [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch). | ||
import `@microsoft/microsoft-graph-client` into your module. | ||
Also, you will need to import any fetch polyfill which suits your requirements. Following are some fetch polyfills - | ||
- [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch). | ||
- [cross-fetch](https://www.npmjs.com/package/cross-fetch) | ||
- [whatwg-fetch](https://www.npmjs.com/package/whatwg-fetch) | ||
```typescript | ||
import "isomorphic-fetch"; | ||
import "isomorphic-fetch"; // or import the fetch polyfill you installed | ||
import { Client } from "@microsoft/microsoft-graph-client"; | ||
@@ -52,105 +93,20 @@ ``` | ||
Register your application to use Microsoft Graph API using one of the following supported authentication portals: | ||
To call Microsoft Graph, your app must acquire an access token from the Microsoft identity platform. Learn more about this - | ||
- [Microsoft Application Registration Portal](https://apps.dev.microsoft.com): Register a new application that works with Microsoft Accounts and/or organizational accounts using the unified V2 Authentication Endpoint. | ||
- [Microsoft Azure Active Directory](https://manage.windowsazure.com): Register a new application in your tenant's Active Directory to support work or school users for your tenant or multiple tenants. | ||
- [Authentication and authorization basics for Microsoft Graph](https://docs.microsoft.com/en-us/graph/auth/auth-concepts) | ||
- [Register your app with the Microsoft identity platform](https://docs.microsoft.com/en-us/graph/auth/auth-concepts) | ||
### 2. Authenticate for the Microsoft Graph service | ||
### 2. Create a Client Instance | ||
The Microsoft Graph JavaScript Client Library has an adapter implementation ([ImplicitMSALAuthenticationProvider](src/ImplicitMSALAuthenticationProvider.ts)) for [MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-core) (Microsoft Authentication Library) which takes care of getting the `accessToken`. MSAL library does not ship with this library, user has to include it externally (For including MSAL, refer [this](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-core#installation)). | ||
The Microsoft Graph client is designed to make it simple to make calls to Microsoft Graph. You can use a single client instance for the lifetime of the application. | ||
> **Important Note:** MSAL is supported only for frontend applications, for server-side authentication you have to implement your own AuthenticationProvider. Learn how you can create a [Custom Authentication Provider](./docs/CustomAuthenticationProvider.md). | ||
For information on how to create a client instance, see [Creating Client Instance](./docs/CreatingClientInstance.md) | ||
#### Creating an instance of ImplicitMSALAuthenticationProvider in browser environment | ||
### 3. Make requests to the graph | ||
Refer devDependencies in [package.json](./package.json) for the compatible msal version and update that version in below. | ||
Once you have authentication setup and an instance of Client, you can begin to make calls to the service. All requests should start with `client.api(path)` and end with an [action](./docs/Actions.md). | ||
```html | ||
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/<version>/js/msal.min.js"></script> | ||
``` | ||
Example of getting user details: | ||
```typescript | ||
// Configuration options for MSAL @see https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/MSAL.js-1.0.0-api-release#configuration-options | ||
const msalConfig = { | ||
auth: { | ||
clientId: "your_client_id", // Client Id of the registered application | ||
redirectUri: "your_redirect_uri", | ||
}, | ||
}; | ||
const graphScopes = ["user.read", "mail.send"]; // An array of graph scopes | ||
// Important Note: This library implements loginPopup and acquireTokenPopup flow, remember this while initializing the msal | ||
// Initialize the MSAL @see https://github.com/AzureAD/microsoft-authentication-library-for-js#1-instantiate-the-useragentapplication | ||
const msalApplication = new Msal.UserAgentApplication(msalConfig); | ||
const options = new MicrosoftGraph.MSALAuthenticationProviderOptions(graphScopes); | ||
const authProvider = new MicrosoftGraph.ImplicitMSALAuthenticationProvider(msalApplication, options); | ||
``` | ||
#### Creating an instance of ImplicitMSALAuthenticationProvider in node environment | ||
Refer devDependencies in [package.json](./package.json) for the compatible msal version and update that version in below. | ||
```cmd | ||
npm install msal@<version> | ||
``` | ||
```typescript | ||
import { UserAgentApplication } from "msal"; | ||
import { ImplicitMSALAuthenticationProvider } from "@microsoft/microsoft-graph-client/lib/src/ImplicitMSALAuthenticationProvider"; | ||
import { MSALAuthenticationProviderOptions } from '@microsoft/microsoft-graph-client/lib/src/MSALAuthenticationProviderOptions'; | ||
// An Optional options for initializing the MSAL @see https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/MSAL-basics#configuration-options | ||
const msalConfig = { | ||
auth: { | ||
clientId: "your_client_id", // Client Id of the registered application | ||
redirectUri: "your_redirect_uri", | ||
}, | ||
}; | ||
const graphScopes = ["user.read", "mail.send"]; // An array of graph scopes | ||
// Important Note: This library implements loginPopup and acquireTokenPopup flow, remember this while initializing the msal | ||
// Initialize the MSAL @see https://github.com/AzureAD/microsoft-authentication-library-for-js#1-instantiate-the-useragentapplication | ||
const msalApplication = new UserAgentApplication(msalConfig); | ||
const options = new MSALAuthenticationProviderOptions(graphScopes); | ||
const authProvider = new ImplicitMSALAuthenticationProvider(msalApplication, options); | ||
``` | ||
User can integrate own preferred authentication library by implementing `IAuthenticationProvider` interface. Refer implementing [Custom Authentication Provider](./docs/CustomAuthenticationProvider.md). | ||
### 3. Initialize a Microsoft Graph Client object with an authentication provider | ||
An instance of the **Client** class handles requests to Microsoft Graph API and processing the responses. To create a new instance of this class, you need to provide an instance of [`IAuthenticationProvider`](src/IAuthenticationProvider.ts) which needs to be passed as a value for `authProvider` key in [`ClientOptions`](src/IClientOptions.ts) to a static initializer method `Client.initWithMiddleware`. | ||
#### For browser environment | ||
```typescript | ||
const options = { | ||
authProvider, // An instance created from previous step | ||
}; | ||
const Client = MicrosoftGraph.Client; | ||
const client = Client.initWithMiddleware(options); | ||
``` | ||
#### For node environment | ||
```typescript | ||
import { Client } from "@microsoft/microsoft-graph-client"; | ||
const options = { | ||
authProvider, // An instance created from previous step | ||
}; | ||
const client = Client.initWithMiddleware(options); | ||
``` | ||
For more information on initializing client, refer [this document](./docs/CreatingClientInstance.md). | ||
### 4. Make requests to the graph | ||
Once you have authentication setup and an instance of Client, you can begin to make calls to the service. All requests should be start with `client.api(path)` and end with an [action](./docs/Actions.md). | ||
Getting user details | ||
```typescript | ||
try { | ||
@@ -164,3 +120,3 @@ let userDetails = await client.api("/me").get(); | ||
Sending an email to the recipients | ||
Example of sending an email to the recipients: | ||
@@ -193,12 +149,2 @@ ```typescript | ||
## Documentation | ||
- [Batching](docs/content/Batching.md) | ||
- [Large File Upload Task](docs/tasks/LargeFileUploadTask.md) | ||
- [Page Iterator](docs/tasks/PageIterator.md) | ||
- [Actions](docs/Actions.md) | ||
- [Query Parameters](docs/QueryParameters.md) | ||
- [Other APIs](docs/OtherAPIs.md) | ||
- [Getting Raw Response](docs/GettingRawResponse.md) | ||
## Questions and comments | ||
@@ -215,5 +161,10 @@ | ||
- [Microsoft Graph website](https://graph.microsoft.io) | ||
- [Microsoft Graph TypeScript types](https://github.com/microsoftgraph/msgraph-typescript-typings/) | ||
- The Microsoft Graph TypeScript definitions enable editors to provide intellisense on Microsoft Graph objects including users, messages, and groups. | ||
- [@microsoft/microsoft-graph-types](https://www.npmjs.com/package/@microsoft/microsoft-graph-types) or [@types/microsoft-graph](https://www.npmjs.com/package/@types/microsoft-graph) | ||
- [@microsoft/microsoft-graph-types-beta](https://www.npmjs.com/package/@microsoft/microsoft-graph-types-beta) | ||
- [Build React Native apps with Microsoft Graph](https://docs.microsoft.com/en-us/graph/tutorials/react-native) | ||
- [Build Angular single-page apps with Microsoft Graph](https://github.com/microsoftgraph/msgraph-training-angularspa) | ||
- [Build Node.js Express apps with Microsoft Graph](https://github.com/microsoftgraph/msgraph-training-nodeexpressapp) | ||
- [Microsoft Graph Toolkit: UI Components and Authentication Providers for Microsoft Graph](https://docs.microsoft.com/en-us/graph/toolkit/overview) | ||
- [Office Dev Center](http://dev.office.com/) | ||
@@ -220,0 +171,0 @@ |
@@ -11,6 +11,5 @@ /** | ||
*/ | ||
import { MSALAuthenticationProviderOptions } from "../authentication/msal/MSALAuthenticationProviderOptions"; | ||
import { AuthenticationProvider } from "../IAuthenticationProvider"; | ||
import { AuthenticationProviderOptions } from "../IAuthenticationProviderOptions"; | ||
import { MSALAuthenticationProviderOptions } from "../MSALAuthenticationProviderOptions"; | ||
@@ -24,2 +23,6 @@ /** | ||
/** | ||
* @deprecated Use of ImplicitMSALAuthenticationProvider, that is, | ||
* using the implicit authorization flow is not recommended. | ||
* Use the TokenCredentialAuthenticationProvider with azure/identity library or | ||
* a CustomAuthenticationProvider with msal-browser library instead. | ||
* @class | ||
@@ -87,8 +90,4 @@ * Class representing ImplicitMSALAuthenticationProvider | ||
if (error.name === "InteractionRequiredAuthError") { | ||
try { | ||
const authResponse = await this.msalApplication.acquireTokenPopup(tokenRequest); | ||
return authResponse.accessToken; | ||
} catch (error) { | ||
throw error; | ||
} | ||
const authResponse = await this.msalApplication.acquireTokenPopup(tokenRequest); | ||
return authResponse.accessToken; | ||
} else { | ||
@@ -99,14 +98,10 @@ throw error; | ||
} else { | ||
try { | ||
const tokenRequest = { | ||
scopes, | ||
}; | ||
await this.msalApplication.loginPopup(tokenRequest); | ||
const authResponse = await this.msalApplication.acquireTokenSilent(tokenRequest); | ||
return authResponse.accessToken; | ||
} catch (error) { | ||
throw error; | ||
} | ||
const tokenRequest = { | ||
scopes, | ||
}; | ||
await this.msalApplication.loginPopup(tokenRequest); | ||
const authResponse = await this.msalApplication.acquireTokenSilent(tokenRequest); | ||
return authResponse.accessToken; | ||
} | ||
} | ||
} |
@@ -15,2 +15,3 @@ /** | ||
export * from "../middleware/RetryHandler"; | ||
export * from "../middleware/RedirectHandler"; | ||
export * from "../middleware/TelemetryHandler"; | ||
@@ -21,2 +22,3 @@ export * from "../middleware/MiddlewareFactory"; | ||
export * from "../middleware/options/RetryHandlerOptions"; | ||
export * from "../middleware/options/RedirectHandlerOptions"; | ||
export * from "../middleware/options/TelemetryHandlerOptions"; | ||
@@ -29,2 +31,9 @@ export * from "../middleware/options/ChaosHandlerOptions"; | ||
export * from "../tasks/OneDriveLargeFileUploadTask"; | ||
export * from "../tasks/OneDriveLargeFileUploadTaskUtil"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/FileUpload"; | ||
export * from "../tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "../tasks/FileUploadTask/UploadResult"; | ||
export * from "../tasks/FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
export * from "../tasks/FileUploadTask/Range"; | ||
export * from "../tasks/PageIterator"; | ||
@@ -35,2 +44,3 @@ | ||
export * from "../GraphError"; | ||
export * from "../GraphClientError"; | ||
export * from "../GraphRequest"; | ||
@@ -46,4 +56,2 @@ export * from "../IAuthProvider"; | ||
export * from "../IOptions"; | ||
export * from "./ImplicitMSALAuthenticationProvider"; | ||
export * from "../MSALAuthenticationProviderOptions"; | ||
export * from "../ResponseType"; |
@@ -48,3 +48,3 @@ /** | ||
for (const i in options) { | ||
if (options.hasOwnProperty(i)) { | ||
if (Object.prototype.hasOwnProperty.call(options, i)) { | ||
clientOptions[i] = i === "authProvider" ? new CustomAuthenticationProvider(options[i]) : options[i]; | ||
@@ -64,7 +64,3 @@ } | ||
public static initWithMiddleware(clientOptions: ClientOptions): Client { | ||
try { | ||
return new Client(clientOptions); | ||
} catch (error) { | ||
throw error; | ||
} | ||
return new Client(clientOptions); | ||
} | ||
@@ -79,9 +75,5 @@ | ||
private constructor(clientOptions: ClientOptions) { | ||
try { | ||
validatePolyFilling(); | ||
} catch (error) { | ||
throw error; | ||
} | ||
validatePolyFilling(); | ||
for (const key in clientOptions) { | ||
if (clientOptions.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(clientOptions, key)) { | ||
this.config[key] = clientOptions[key]; | ||
@@ -88,0 +80,0 @@ } |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
export const GRAPH_URLS = new Set<string>(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn"]); | ||
export const GRAPH_URLS = new Set<string>(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com"]); |
@@ -87,3 +87,3 @@ /** | ||
*/ | ||
private static requestLimit: number = 20; | ||
private static requestLimit = 20; | ||
@@ -231,3 +231,3 @@ /** | ||
private static async getRequestBody(request: IsomorphicRequest): Promise<any> { | ||
let bodyParsed: boolean = false; | ||
let bodyParsed = false; | ||
let body; | ||
@@ -239,3 +239,3 @@ try { | ||
} catch (e) { | ||
// tslint:disable-line: no-empty | ||
//TODO- Handle empty catches | ||
} | ||
@@ -275,3 +275,3 @@ if (!bodyParsed) { | ||
} catch (e) { | ||
// tslint:disable-line: no-empty | ||
// TODO-Handle empty catches | ||
} | ||
@@ -390,2 +390,4 @@ } | ||
/** | ||
* @see{@https://tools.ietf.org/html/rfc7578#section-4.4} | ||
* TODO- Setting/Defaulting of content-type header to the correct value | ||
* @see {@link https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching#request-format} | ||
@@ -392,0 +394,0 @@ */ |
@@ -12,2 +12,3 @@ /** | ||
import { GraphClientError } from "./GraphClientError"; | ||
import { AuthenticationProvider } from "./IAuthenticationProvider"; | ||
@@ -47,7 +48,14 @@ import { AuthProvider } from "./IAuthProvider"; | ||
return new Promise((resolve: (accessToken: string) => void, reject: (error: any) => void) => { | ||
this.provider((error: any, accessToken: string | null) => { | ||
this.provider(async (error: any, accessToken: string | null) => { | ||
if (accessToken) { | ||
resolve(accessToken); | ||
} else { | ||
reject(error); | ||
if (!error) { | ||
const invalidTokenMessage = "Access token is undefined or empty.\ | ||
Please provide a valid token.\ | ||
For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md"; | ||
error = new GraphClientError(invalidTokenMessage); | ||
} | ||
const err = await GraphClientError.setGraphClientError(error); | ||
reject(err); | ||
} | ||
@@ -54,0 +62,0 @@ }); |
@@ -58,3 +58,3 @@ /** | ||
*/ | ||
public constructor(statusCode: number = -1, message?: string, baseError?: Error) { | ||
public constructor(statusCode = -1, message?: string, baseError?: Error) { | ||
super(message || (baseError && baseError.message)); | ||
@@ -61,0 +61,0 @@ // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work |
@@ -16,2 +16,16 @@ /** | ||
/** | ||
* @interface | ||
* Signature for the json represent of the error response from the Graph API | ||
* https://docs.microsoft.com/en-us/graph/errors | ||
* @property {[key: string] : string | number} - The Key value pair | ||
*/ | ||
interface GraphAPIErrorResponse { | ||
error: { | ||
code: string; | ||
message: string; | ||
innerError: any; | ||
}; | ||
} | ||
/** | ||
* @class | ||
@@ -45,3 +59,3 @@ * Class for GraphErrorHandler | ||
* Populates the GraphError instance from the Error returned by graph service | ||
* @param {any} error - The error returned by graph service or some native error | ||
* @param {GraphAPIErrorResponse} graphError - The error possibly returned by graph service or some native error | ||
* @param {number} statusCode - The status code of the response | ||
@@ -62,4 +76,4 @@ * @returns A promise that resolves to GraphError instance | ||
*/ | ||
private static constructErrorFromResponse(error: any, statusCode: number): GraphError { | ||
error = error.error; | ||
private static constructErrorFromResponse(graphError: GraphAPIErrorResponse, statusCode: number): GraphError { | ||
const error = graphError.error; | ||
const gError = new GraphError(statusCode, error.message); | ||
@@ -71,7 +85,5 @@ gError.code = error.code; | ||
} | ||
try { | ||
gError.body = JSON.stringify(error); | ||
} catch (error) { | ||
// tslint:disable-line: no-empty | ||
} | ||
gError.body = JSON.stringify(error); | ||
return gError; | ||
@@ -85,2 +97,3 @@ } | ||
* To get the GraphError object | ||
* Reference - https://docs.microsoft.com/en-us/graph/errors | ||
* @param {any} [error = null] - The error returned by graph service or some native error | ||
@@ -91,10 +104,11 @@ * @param {number} [statusCode = -1] - The status code of the response | ||
*/ | ||
public static async getError(error: any = null, statusCode: number = -1, callback?: GraphRequestCallback): Promise<GraphError> { | ||
public static async getError(error: any = null, statusCode = -1, callback?: GraphRequestCallback): Promise<GraphError> { | ||
let gError: GraphError; | ||
if (error && error.error) { | ||
gError = GraphErrorHandler.constructErrorFromResponse(error, statusCode); | ||
} else if (typeof Error !== "undefined" && error instanceof Error) { | ||
} else if (error instanceof Error) { | ||
gError = GraphErrorHandler.constructError(error, statusCode); | ||
} else { | ||
gError = new GraphError(statusCode); | ||
gError.body = error; // if a custom error is passed which is not instance of Error object or a graph API response | ||
} | ||
@@ -101,0 +115,0 @@ if (typeof callback === "function") { |
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
import { GraphClientError } from "./GraphClientError"; | ||
import { GraphError } from "./GraphError"; | ||
@@ -79,3 +79,2 @@ import { GraphErrorHandler } from "./GraphErrorHandler"; | ||
/* tslint:disable: variable-name */ | ||
/** | ||
@@ -104,3 +103,2 @@ * @private | ||
private _responseType: ResponseType; | ||
/* tslint:enable: variable-name */ | ||
@@ -215,3 +213,3 @@ /** | ||
if (this.config.debugLogging) { | ||
console.log(url); // tslint:disable-line: no-console | ||
console.log(url); | ||
} | ||
@@ -232,3 +230,3 @@ return url; | ||
for (const property in urlComponents.oDataQueryParams) { | ||
if (urlComponents.oDataQueryParams.hasOwnProperty(property)) { | ||
if (Object.prototype.hasOwnProperty.call(urlComponents.oDataQueryParams, property)) { | ||
query.push(property + "=" + urlComponents.oDataQueryParams[property]); | ||
@@ -240,3 +238,3 @@ } | ||
for (const property in urlComponents.otherURLQueryParams) { | ||
if (urlComponents.otherURLQueryParams.hasOwnProperty(property)) { | ||
if (Object.prototype.hasOwnProperty.call(urlComponents.otherURLQueryParams, property)) { | ||
query.push(property + "=" + urlComponents.otherURLQueryParams[property]); | ||
@@ -277,3 +275,3 @@ } | ||
for (const key in queryDictionaryOrString) { | ||
if (queryDictionaryOrString.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(queryDictionaryOrString, key)) { | ||
this.setURLComponentsQueryParamater(key, queryDictionaryOrString[key]); | ||
@@ -389,4 +387,8 @@ } | ||
} catch (error) { | ||
if (error instanceof GraphClientError) { | ||
throw error; | ||
} | ||
let statusCode: number; | ||
if (typeof rawResponse !== "undefined") { | ||
if (rawResponse) { | ||
statusCode = rawResponse.status; | ||
@@ -440,3 +442,3 @@ } | ||
for (const key in headers) { | ||
if (headers.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(headers, key)) { | ||
this._headers[key] = headers[key] as string; | ||
@@ -468,3 +470,3 @@ } | ||
for (const key in options) { | ||
if (options.hasOwnProperty(key)) { | ||
if (Object.prototype.hasOwnProperty.call(options, key)) { | ||
this._options[key] = options[key]; | ||
@@ -609,3 +611,3 @@ } | ||
*/ | ||
public count(isCount: boolean = false): GraphRequest { | ||
public count(isCount = true): GraphRequest { | ||
this.urlComponents.oDataQueryParams.$count = isCount.toString(); | ||
@@ -641,8 +643,4 @@ return this; | ||
}; | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} | ||
@@ -672,8 +670,3 @@ | ||
} | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
@@ -690,7 +683,3 @@ | ||
public async create(content: any, callback?: GraphRequestCallback): Promise<any> { | ||
try { | ||
return await this.post(content, callback); | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.post(content, callback); | ||
} | ||
@@ -713,8 +702,3 @@ | ||
}; | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
@@ -737,8 +721,3 @@ | ||
}; | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
@@ -755,7 +734,3 @@ | ||
public async update(content: any, callback?: GraphRequestCallback): Promise<any> { | ||
try { | ||
return await this.patch(content, callback); | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.patch(content, callback); | ||
} | ||
@@ -775,8 +750,3 @@ | ||
}; | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
@@ -792,7 +762,3 @@ | ||
public async del(callback?: GraphRequestCallback): Promise<any> { | ||
try { | ||
return await this.delete(callback); | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.delete(callback); | ||
} | ||
@@ -813,8 +779,3 @@ | ||
this.responseType(ResponseType.STREAM); | ||
try { | ||
const stream = await this.send(url, options, callback); | ||
return stream; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
@@ -839,9 +800,4 @@ | ||
}; | ||
try { | ||
const response = await this.send(url, options, callback); | ||
return response; | ||
} catch (error) { | ||
throw error; | ||
} | ||
return await this.send(url, options, callback); | ||
} | ||
} |
@@ -10,2 +10,3 @@ /** | ||
* @module GraphResponseHandler | ||
* References - https://fetch.spec.whatwg.org/#responses | ||
*/ | ||
@@ -69,20 +70,16 @@ | ||
private static parseDocumentResponse(rawResponse: Response, type: DocumentType): Promise<any> { | ||
try { | ||
if (typeof DOMParser !== "undefined") { | ||
return new Promise((resolve, reject) => { | ||
rawResponse.text().then((xmlString) => { | ||
try { | ||
const parser = new DOMParser(); | ||
const xmlDoc = parser.parseFromString(xmlString, type); | ||
resolve(xmlDoc); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
if (typeof DOMParser !== "undefined") { | ||
return new Promise((resolve, reject) => { | ||
rawResponse.text().then((xmlString) => { | ||
try { | ||
const parser = new DOMParser(); | ||
const xmlDoc = parser.parseFromString(xmlString, type); | ||
resolve(xmlDoc); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
} else { | ||
return Promise.resolve(rawResponse.body); | ||
} | ||
} catch (error) { | ||
throw error; | ||
}); | ||
} else { | ||
return Promise.resolve(rawResponse.body); | ||
} | ||
@@ -106,55 +103,51 @@ } | ||
let responseValue: any; | ||
try { | ||
switch (responseType) { | ||
case ResponseType.ARRAYBUFFER: | ||
responseValue = await rawResponse.arrayBuffer(); | ||
break; | ||
case ResponseType.BLOB: | ||
responseValue = await rawResponse.blob(); | ||
break; | ||
case ResponseType.DOCUMENT: | ||
responseValue = await GraphResponseHandler.parseDocumentResponse(rawResponse, DocumentType.TEXT_XML); | ||
break; | ||
case ResponseType.JSON: | ||
responseValue = await rawResponse.json(); | ||
break; | ||
case ResponseType.STREAM: | ||
responseValue = await Promise.resolve(rawResponse.body); | ||
break; | ||
case ResponseType.TEXT: | ||
responseValue = await rawResponse.text(); | ||
break; | ||
default: | ||
const contentType = rawResponse.headers.get("Content-type"); | ||
if (contentType !== null) { | ||
const mimeType = contentType.split(";")[0]; | ||
if (new RegExp(ContentTypeRegexStr.DOCUMENT).test(mimeType)) { | ||
responseValue = await GraphResponseHandler.parseDocumentResponse(rawResponse, mimeType as DocumentType); | ||
} else if (new RegExp(ContentTypeRegexStr.IMAGE).test(mimeType)) { | ||
responseValue = rawResponse.blob(); | ||
} else if (mimeType === ContentType.TEXT_PLAIN) { | ||
responseValue = await rawResponse.text(); | ||
} else if (mimeType === ContentType.APPLICATION_JSON) { | ||
responseValue = await rawResponse.json(); | ||
} else { | ||
responseValue = Promise.resolve(rawResponse.body); | ||
} | ||
const contentType = rawResponse.headers.get("Content-type"); | ||
switch (responseType) { | ||
case ResponseType.ARRAYBUFFER: | ||
responseValue = await rawResponse.arrayBuffer(); | ||
break; | ||
case ResponseType.BLOB: | ||
responseValue = await rawResponse.blob(); | ||
break; | ||
case ResponseType.DOCUMENT: | ||
responseValue = await GraphResponseHandler.parseDocumentResponse(rawResponse, DocumentType.TEXT_XML); | ||
break; | ||
case ResponseType.JSON: | ||
responseValue = await rawResponse.json(); | ||
break; | ||
case ResponseType.STREAM: | ||
responseValue = await Promise.resolve(rawResponse.body); | ||
break; | ||
case ResponseType.TEXT: | ||
responseValue = await rawResponse.text(); | ||
break; | ||
default: | ||
if (contentType !== null) { | ||
const mimeType = contentType.split(";")[0]; | ||
if (new RegExp(ContentTypeRegexStr.DOCUMENT).test(mimeType)) { | ||
responseValue = await GraphResponseHandler.parseDocumentResponse(rawResponse, mimeType as DocumentType); | ||
} else if (new RegExp(ContentTypeRegexStr.IMAGE).test(mimeType)) { | ||
responseValue = rawResponse.blob(); | ||
} else if (mimeType === ContentType.TEXT_PLAIN) { | ||
responseValue = await rawResponse.text(); | ||
} else if (mimeType === ContentType.APPLICATION_JSON) { | ||
responseValue = await rawResponse.json(); | ||
} else { | ||
/** | ||
* RFC specification {@link https://tools.ietf.org/html/rfc7231#section-3.1.1.5} says: | ||
* A sender that generates a message containing a payload body SHOULD | ||
* generate a Content-Type header field in that message unless the | ||
* intended media type of the enclosed representation is unknown to the | ||
* sender. If a Content-Type header field is not present, the recipient | ||
* MAY either assume a media type of "application/octet-stream" | ||
* ([RFC2046], Section 4.5.1) or examine the data to determine its type. | ||
* | ||
* So assuming it as a stream type so returning the body. | ||
*/ | ||
responseValue = Promise.resolve(rawResponse.body); | ||
} | ||
break; | ||
} | ||
} catch (error) { | ||
throw error; | ||
} else { | ||
/** | ||
* RFC specification {@link https://tools.ietf.org/html/rfc7231#section-3.1.1.5} says: | ||
* A sender that generates a message containing a payload body SHOULD | ||
* generate a Content-Type header field in that message unless the | ||
* intended media type of the enclosed representation is unknown to the | ||
* sender. If a Content-Type header field is not present, the recipient | ||
* MAY either assume a media type of "application/octet-stream" | ||
* ([RFC2046], Section 4.5.1) or examine the data to determine its type. | ||
* | ||
* So assuming it as a stream type so returning the body. | ||
*/ | ||
responseValue = Promise.resolve(rawResponse.body); | ||
} | ||
break; | ||
} | ||
@@ -175,23 +168,19 @@ return responseValue; | ||
public static async getResponse(rawResponse: Response, responseType?: ResponseType, callback?: GraphRequestCallback): Promise<any> { | ||
try { | ||
if (responseType === ResponseType.RAW) { | ||
return Promise.resolve(rawResponse); | ||
} else { | ||
const response = await GraphResponseHandler.convertResponse(rawResponse, responseType); | ||
if (rawResponse.ok) { | ||
// Status Code 2XX | ||
if (typeof callback === "function") { | ||
callback(null, response); | ||
} else { | ||
return response; | ||
} | ||
if (responseType === ResponseType.RAW) { | ||
return Promise.resolve(rawResponse); | ||
} else { | ||
const response = await GraphResponseHandler.convertResponse(rawResponse, responseType); | ||
if (rawResponse.ok) { | ||
// Status Code 2XX | ||
if (typeof callback === "function") { | ||
callback(null, response); | ||
} else { | ||
// NOT OK Response | ||
throw response; | ||
return response; | ||
} | ||
} else { | ||
// NOT OK Response | ||
throw response; | ||
} | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
} |
@@ -82,15 +82,11 @@ /** | ||
public async sendRequest(context: Context): Promise<Context> { | ||
try { | ||
if (typeof context.request === "string" && context.options === undefined) { | ||
const error = new Error(); | ||
error.name = "InvalidRequestOptions"; | ||
error.message = "Unable to execute the middleware, Please provide valid options for a request"; | ||
throw error; | ||
} | ||
await this.middleware.execute(context); | ||
return context; | ||
} catch (error) { | ||
if (typeof context.request === "string" && context.options === undefined) { | ||
const error = new Error(); | ||
error.name = "InvalidRequestOptions"; | ||
error.message = "Unable to execute the middleware, Please provide valid options for a request"; | ||
throw error; | ||
} | ||
await this.middleware.execute(context); | ||
return context; | ||
} | ||
} |
@@ -11,14 +11,16 @@ /** | ||
* Signature to define the fetch request options for node environment | ||
* @property {number} [follow] - Maximum redirect count. 0 to not follow redirect | ||
* @property {number} [timeout] - Request/Response timeout in milliseconds, it resets on redirect. 0 to disable (OS limit applies) | ||
* @property {number} [compress] - Support gzip/deflate content encoding. false to disable | ||
* @property {number} [size] - Maximum response body size in bytes. 0 to disable | ||
* @property {any} [agent] - HTTP(S).Agent instance, allows custom proxy, certificate, lookup, family etc. | ||
* @property {number} [follow] - node-fetch option: maximum redirect count. 0 to not follow redirect | ||
* @property {number} [compress] - node-fetch option: support gzip/deflate content encoding. false to disable | ||
* @property {number} [size] - node-fetch option: maximum response body size in bytes. 0 to disable | ||
* @property {any} [agent] - node-fetch option: HTTP(S).Agent instance, allows custom proxy, certificate, lookup, family etc. | ||
* @property {number} [highWaterMark] - node-fetch option: maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. | ||
* @property {boolean} [insecureHTTPParser] - node-fetch option: use an insecure HTTP parser that accepts invalid HTTP headers when `true`. | ||
*/ | ||
export interface NodeFetchInit { | ||
follow?: number; | ||
timeout?: number; | ||
compress?: boolean; | ||
size?: number; | ||
agent?: any; | ||
highWaterMark?: number; | ||
insecureHTTPParser?: boolean; | ||
} | ||
@@ -25,0 +27,0 @@ |
@@ -29,2 +29,9 @@ /** | ||
export * from "./tasks/OneDriveLargeFileUploadTask"; | ||
export * from "./tasks/OneDriveLargeFileUploadTaskUtil"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/FileUpload"; | ||
export * from "./tasks/FileUploadTask/FileObjectClasses/StreamUpload"; | ||
export * from "./tasks/FileUploadTask/UploadResult"; | ||
export * from "./tasks/FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
export * from "./tasks/FileUploadTask/Range"; | ||
export * from "./tasks/PageIterator"; | ||
@@ -35,2 +42,3 @@ | ||
export * from "./GraphError"; | ||
export * from "./GraphClientError"; | ||
export * from "./GraphRequest"; | ||
@@ -45,5 +53,3 @@ export * from "./IAuthProvider"; | ||
export * from "./IGraphRequestCallback"; | ||
export * from "./ImplicitMSALAuthenticationProvider"; | ||
export * from "./IOptions"; | ||
export * from "./MSALAuthenticationProviderOptions"; | ||
export * from "./ResponseType"; |
@@ -12,6 +12,6 @@ /** | ||
import { isGraphURL } from "../GraphRequestUtil"; | ||
import { AuthenticationProvider } from "../IAuthenticationProvider"; | ||
import { AuthenticationProviderOptions } from "../IAuthenticationProviderOptions"; | ||
import { Context } from "../IContext"; | ||
import { Middleware } from "./IMiddleware"; | ||
@@ -33,3 +33,3 @@ import { MiddlewareControl } from "./MiddlewareControl"; | ||
*/ | ||
private static AUTHORIZATION_HEADER: string = "Authorization"; | ||
private static AUTHORIZATION_HEADER = "Authorization"; | ||
@@ -66,3 +66,4 @@ /** | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
const url = typeof context.request === "string" ? context.request : context.request.url; | ||
if (isGraphURL(url)) { | ||
let options: AuthenticationHandlerOptions; | ||
@@ -74,17 +75,19 @@ if (context.middlewareControl instanceof MiddlewareControl) { | ||
let authenticationProviderOptions: AuthenticationProviderOptions; | ||
if (typeof options !== "undefined") { | ||
if (options) { | ||
authenticationProvider = options.authenticationProvider; | ||
authenticationProviderOptions = options.authenticationProviderOptions; | ||
} | ||
if (typeof authenticationProvider === "undefined") { | ||
if (!authenticationProvider) { | ||
authenticationProvider = this.authenticationProvider; | ||
} | ||
const token: string = await authenticationProvider.getAccessToken(authenticationProviderOptions); | ||
const bearerKey: string = `Bearer ${token}`; | ||
const bearerKey = `Bearer ${token}`; | ||
appendRequestHeader(context.request, context.options, AuthenticationHandler.AUTHORIZATION_HEADER, bearerKey); | ||
TelemetryHandlerOptions.updateFeatureUsageFlag(context, FeatureUsageFlag.AUTHENTICATION_HANDLER_ENABLED); | ||
return await this.nextMiddleware.execute(context); | ||
} catch (error) { | ||
throw error; | ||
} else { | ||
if (context.options.headers) { | ||
delete context.options.headers[AuthenticationHandler.AUTHORIZATION_HEADER]; | ||
} | ||
} | ||
return await this.nextMiddleware.execute(context); | ||
} | ||
@@ -91,0 +94,0 @@ |
@@ -14,3 +14,2 @@ /** | ||
import { RequestMethod } from "../RequestMethod"; | ||
import { Middleware } from "./IMiddleware"; | ||
@@ -66,3 +65,3 @@ import { MiddlewareControl } from "./MiddlewareControl"; | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
@@ -72,5 +71,4 @@ * @param {string} requestDate - date of the request | ||
*/ | ||
private createResponseHeaders(statusCode: number, requestID: string, requestDate: string) { | ||
const responseHeader: Headers = new Headers(); | ||
private createResponseHeaders(chaosHandlerOptions: ChaosHandlerOptions, requestID: string, requestDate: string) { | ||
const responseHeader: Headers = chaosHandlerOptions.headers ? new Headers(chaosHandlerOptions.headers) : new Headers(); | ||
responseHeader.append("Cache-Control", "no-store"); | ||
@@ -83,6 +81,7 @@ responseHeader.append("request-id", requestID); | ||
if (statusCode === 429) { | ||
if (chaosHandlerOptions.statusCode === 429) { | ||
// throttling case has to have a timeout scenario | ||
responseHeader.append("retry-after", "300"); | ||
responseHeader.append("retry-after", "3"); | ||
} | ||
return responseHeader; | ||
@@ -94,17 +93,15 @@ } | ||
* @private | ||
* @param {number} statusCode - the status code to be returned for the request | ||
* @param {string} statusMessage - the status message to be returned for the request | ||
* @param {ChaosHandlerOptions} options - The ChaosHandlerOptions object | ||
* @param {string} requestID - request id | ||
* @param {string} requestDate - date of the request | ||
* @param {any?} requestBody - the request body to be returned for the request | ||
* @returns response body | ||
* * @returns response body | ||
*/ | ||
private createResponseBody(statusCode: number, statusMessage: string, requestID: string, requestDate: string, responseBody?: any) { | ||
if (responseBody) { | ||
return responseBody; | ||
private createResponseBody(chaosHandlerOptions: ChaosHandlerOptions, requestID: string, requestDate: string) { | ||
if (chaosHandlerOptions.responseBody) { | ||
return chaosHandlerOptions.responseBody; | ||
} | ||
let body: any; | ||
if (statusCode >= 400) { | ||
const codeMessage: string = httpStatusCode[statusCode]; | ||
const errMessage: string = statusMessage; | ||
if (chaosHandlerOptions.statusCode >= 400) { | ||
const codeMessage: string = httpStatusCode[chaosHandlerOptions.statusCode]; | ||
const errMessage: string = chaosHandlerOptions.statusMessage; | ||
@@ -134,18 +131,9 @@ body = { | ||
private createResponse(chaosHandlerOptions: ChaosHandlerOptions, context: Context) { | ||
try { | ||
let responseBody: any; | ||
let responseHeader: Headers; | ||
let requestID: string; | ||
let requestDate: Date; | ||
const requestURL = context.request as string; | ||
requestID = generateUUID(); | ||
requestDate = new Date(); | ||
responseHeader = this.createResponseHeaders(chaosHandlerOptions.statusCode, requestID, requestDate.toString()); | ||
responseBody = this.createResponseBody(chaosHandlerOptions.statusCode, chaosHandlerOptions.statusMessage, requestID, requestDate.toString(), chaosHandlerOptions.responseBody); | ||
const init: any = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; | ||
context.response = new Response(responseBody, init); | ||
} catch (error) { | ||
throw error; | ||
} | ||
const requestURL = context.request as string; | ||
const requestID = generateUUID(); | ||
const requestDate = new Date(); | ||
const responseHeader = this.createResponseHeaders(chaosHandlerOptions, requestID, requestDate.toString()); | ||
const responseBody = this.createResponseBody(chaosHandlerOptions, requestID, requestDate.toString()); | ||
const init: any = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; | ||
context.response = new Response(typeof responseBody === "string" ? responseBody : JSON.stringify(responseBody), init); | ||
} | ||
@@ -161,11 +149,7 @@ | ||
private async sendRequest(chaosHandlerOptions: ChaosHandlerOptions, context: Context): Promise<void> { | ||
try { | ||
this.setStatusCode(chaosHandlerOptions, context.request as string, context.options.method as RequestMethod); | ||
if (!chaosHandlerOptions.statusCode) { | ||
await this.nextMiddleware.execute(context); | ||
} else { | ||
this.createResponse(chaosHandlerOptions, context); | ||
} | ||
} catch (error) { | ||
throw error; | ||
this.setStatusCode(chaosHandlerOptions, context.request as string, context.options.method as RequestMethod); | ||
if ((chaosHandlerOptions.chaosStrategy === ChaosStrategy.MANUAL && !this.nextMiddleware) || Math.floor(Math.random() * 100) < chaosHandlerOptions.chaosPercentage) { | ||
this.createResponse(chaosHandlerOptions, context); | ||
} else if (this.nextMiddleware) { | ||
await this.nextMiddleware.execute(context); | ||
} | ||
@@ -181,8 +165,4 @@ } | ||
private getRandomStatusCode(requestMethod: RequestMethod): number { | ||
try { | ||
const statusCodeArray: number[] = methodStatusCode[requestMethod] as number[]; | ||
return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; | ||
} catch (error) { | ||
throw error; | ||
} | ||
const statusCodeArray: number[] = methodStatusCode[requestMethod] as number[]; | ||
return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; | ||
} | ||
@@ -197,3 +177,3 @@ | ||
private getRelativeURL(urlMethod: string): string { | ||
const pattern: RegExp = /https?:\/\/graph\.microsoft\.com\/[^/]+(.+?)(\?|$)/; | ||
const pattern = /https?:\/\/graph\.microsoft\.com\/[^/]+(.+?)(\?|$)/; | ||
let relativeURL: string; | ||
@@ -214,37 +194,31 @@ if (pattern.exec(urlMethod) !== null) { | ||
private setStatusCode(chaosHandlerOptions: ChaosHandlerOptions, requestURL: string, requestMethod: RequestMethod) { | ||
try { | ||
if (chaosHandlerOptions.chaosStrategy === ChaosStrategy.MANUAL) { | ||
if (chaosHandlerOptions.statusCode === undefined) { | ||
// manual mode with no status code, can be a global level or request level without statusCode | ||
const relativeURL: string = this.getRelativeURL(requestURL); | ||
if (this.manualMap.get(relativeURL) !== undefined) { | ||
// checking Manual Map for exact match | ||
if (this.manualMap.get(relativeURL).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(relativeURL).get(requestMethod); | ||
if (chaosHandlerOptions.chaosStrategy === ChaosStrategy.MANUAL) { | ||
if (chaosHandlerOptions.statusCode === undefined) { | ||
// manual mode with no status code, can be a global level or request level without statusCode | ||
const relativeURL: string = this.getRelativeURL(requestURL); | ||
if (this.manualMap.get(relativeURL) !== undefined) { | ||
// checking Manual Map for exact match | ||
if (this.manualMap.get(relativeURL).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(relativeURL).get(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
} else { | ||
// checking for regex match if exact match doesn't work | ||
this.manualMap.forEach((value: Map<string, number>, key: string) => { | ||
const regexURL = new RegExp(key + "$"); | ||
if (regexURL.test(relativeURL)) { | ||
if (this.manualMap.get(key).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(key).get(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
} | ||
// else statusCode would be undefined | ||
} else { | ||
// checking for regex match if exact match doesn't work | ||
this.manualMap.forEach((value: Map<string, number>, key: string) => { | ||
const regexURL: RegExp = new RegExp(key + "$"); | ||
if (regexURL.test(relativeURL)) { | ||
if (this.manualMap.get(key).get(requestMethod) !== undefined) { | ||
chaosHandlerOptions.statusCode = this.manualMap.get(key).get(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
// Case of redirection or request url not in map ---> statusCode would be undefined | ||
} | ||
} else { | ||
// Handling the case of Random here | ||
if (Math.floor(Math.random() * 100) < chaosHandlerOptions.chaosPercentage) { | ||
chaosHandlerOptions.statusCode = this.getRandomStatusCode(requestMethod); | ||
} | ||
// else statusCode would be undefined | ||
// Case of redirection or request url not in map ---> statusCode would be undefined | ||
} | ||
} catch (error) { | ||
throw error; | ||
} else { | ||
// Handling the case of Random here | ||
chaosHandlerOptions.statusCode = this.getRandomStatusCode(requestMethod); | ||
// else statusCode would be undefined | ||
} | ||
@@ -279,8 +253,4 @@ } | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
const chaosHandlerOptions: ChaosHandlerOptions = this.getOptions(context); | ||
return await this.sendRequest(chaosHandlerOptions, context); | ||
} catch (error) { | ||
throw error; | ||
} | ||
const chaosHandlerOptions: ChaosHandlerOptions = this.getOptions(context); | ||
return await this.sendRequest(chaosHandlerOptions, context); | ||
} | ||
@@ -287,0 +257,0 @@ |
@@ -13,3 +13,2 @@ /** | ||
import { Context } from "../IContext"; | ||
import { Middleware } from "./IMiddleware"; | ||
@@ -31,9 +30,4 @@ | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
context.response = await fetch(context.request, context.options); | ||
return; | ||
} catch (error) { | ||
throw error; | ||
} | ||
context.response = await fetch(context.request, context.options); | ||
} | ||
} |
@@ -23,3 +23,2 @@ /** | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
private middlewareOptions: Map<Function, MiddlewareOptions>; | ||
@@ -35,3 +34,2 @@ | ||
public constructor(middlewareOptions: MiddlewareOptions[] = []) { | ||
// tslint:disable-next-line:ban-types | ||
this.middlewareOptions = new Map<Function, MiddlewareOptions>(); | ||
@@ -54,3 +52,2 @@ for (const option of middlewareOptions) { | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
public getMiddlewareOptions(fn: Function): MiddlewareOptions { | ||
@@ -67,3 +64,2 @@ return this.middlewareOptions.get(fn); | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
public setMiddlewareOptions(fn: Function, option: MiddlewareOptions): void { | ||
@@ -70,0 +66,0 @@ this.middlewareOptions.set(fn, option); |
@@ -13,3 +13,2 @@ /** | ||
import { AuthenticationProvider } from "../IAuthenticationProvider"; | ||
import { AuthenticationHandler } from "./AuthenticationHandler"; | ||
@@ -16,0 +15,0 @@ import { HTTPMessageHandler } from "./HTTPMessageHandler"; |
@@ -20,3 +20,3 @@ /** | ||
export const generateUUID = (): string => { | ||
let uuid: string = ""; | ||
let uuid = ""; | ||
for (let j = 0; j < 32; j++) { | ||
@@ -23,0 +23,0 @@ if (j === 8 || j === 12 || j === 16 || j === 20) { |
@@ -14,3 +14,2 @@ /** | ||
import { AuthenticationProviderOptions } from "../../IAuthenticationProviderOptions"; | ||
import { MiddlewareOptions } from "./IMiddlewareOptions"; | ||
@@ -17,0 +16,0 @@ |
@@ -59,3 +59,10 @@ /** | ||
/** | ||
* The response headers to be returned in the response | ||
* | ||
* @public | ||
*/ | ||
public headers: Headers; | ||
/** | ||
* @public | ||
* @constructor | ||
@@ -70,3 +77,3 @@ * To create an instance of Testing Handler Options | ||
*/ | ||
public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusMessage: string = "Some error Happened", statusCode?: number, chaosPercentage?: number, responseBody?: any) { | ||
public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusMessage = "Some error Happened", statusCode?: number, chaosPercentage?: number, responseBody?: any, headers?: Headers) { | ||
this.chaosStrategy = chaosStrategy; | ||
@@ -77,2 +84,3 @@ this.statusCode = statusCode; | ||
this.responseBody = responseBody; | ||
this.headers = headers; | ||
if (this.chaosPercentage > 100) { | ||
@@ -79,0 +87,0 @@ throw new Error("Error Pecentage can not be more than 100"); |
@@ -13,3 +13,3 @@ /** | ||
/* tslint:disable: no-empty-interface */ | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface MiddlewareOptions {} |
@@ -31,3 +31,3 @@ /** | ||
*/ | ||
private static DEFAULT_MAX_REDIRECTS: number = 5; | ||
private static DEFAULT_MAX_REDIRECTS = 5; | ||
@@ -39,3 +39,3 @@ /** | ||
*/ | ||
private static MAX_MAX_REDIRECTS: number = 20; | ||
private static MAX_MAX_REDIRECTS = 20; | ||
@@ -58,3 +58,3 @@ /** | ||
*/ | ||
private static DEFAULT_SHOULD_RETRY: ShouldRedirect = () => true; | ||
private static defaultShouldRetry: ShouldRedirect = () => true; | ||
@@ -69,3 +69,3 @@ /** | ||
*/ | ||
public constructor(maxRedirects: number = RedirectHandlerOptions.DEFAULT_MAX_REDIRECTS, shouldRedirect: ShouldRedirect = RedirectHandlerOptions.DEFAULT_SHOULD_RETRY) { | ||
public constructor(maxRedirects: number = RedirectHandlerOptions.DEFAULT_MAX_REDIRECTS, shouldRedirect: ShouldRedirect = RedirectHandlerOptions.defaultShouldRetry) { | ||
if (maxRedirects > RedirectHandlerOptions.MAX_MAX_REDIRECTS) { | ||
@@ -72,0 +72,0 @@ const error = new Error(`MaxRedirects should not be more than ${RedirectHandlerOptions.MAX_MAX_REDIRECTS}`); |
@@ -13,3 +13,2 @@ /** | ||
import { FetchOptions } from "../../IFetchOptions"; | ||
import { MiddlewareOptions } from "./IMiddlewareOptions"; | ||
@@ -35,3 +34,3 @@ | ||
*/ | ||
private static DEFAULT_DELAY: number = 3; | ||
private static DEFAULT_DELAY = 3; | ||
@@ -43,3 +42,3 @@ /** | ||
*/ | ||
private static DEFAULT_MAX_RETRIES: number = 3; | ||
private static DEFAULT_MAX_RETRIES = 3; | ||
@@ -51,3 +50,3 @@ /** | ||
*/ | ||
private static MAX_DELAY: number = 180; | ||
private static MAX_DELAY = 180; | ||
@@ -59,3 +58,3 @@ /** | ||
*/ | ||
private static MAX_MAX_RETRIES: number = 10; | ||
private static MAX_MAX_RETRIES = 10; | ||
@@ -84,3 +83,3 @@ /** | ||
*/ | ||
private static DEFAULT_SHOULD_RETRY: ShouldRetry = () => true; | ||
private static defaultShouldRetry: ShouldRetry = () => true; | ||
@@ -96,3 +95,3 @@ /** | ||
*/ | ||
public constructor(delay: number = RetryHandlerOptions.DEFAULT_DELAY, maxRetries: number = RetryHandlerOptions.DEFAULT_MAX_RETRIES, shouldRetry: ShouldRetry = RetryHandlerOptions.DEFAULT_SHOULD_RETRY) { | ||
public constructor(delay: number = RetryHandlerOptions.DEFAULT_DELAY, maxRetries: number = RetryHandlerOptions.DEFAULT_MAX_RETRIES, shouldRetry: ShouldRetry = RetryHandlerOptions.defaultShouldRetry) { | ||
if (delay > RetryHandlerOptions.MAX_DELAY && maxRetries > RetryHandlerOptions.MAX_MAX_RETRIES) { | ||
@@ -99,0 +98,0 @@ const error = new Error(`Delay and MaxRetries should not be more than ${RetryHandlerOptions.MAX_DELAY} and ${RetryHandlerOptions.MAX_MAX_RETRIES}`); |
@@ -14,3 +14,2 @@ /** | ||
import { MiddlewareControl } from "../MiddlewareControl"; | ||
import { MiddlewareOptions } from "./IMiddlewareOptions"; | ||
@@ -25,3 +24,5 @@ | ||
*/ | ||
export enum FeatureUsageFlag { | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
NONE = 0x0, | ||
@@ -31,2 +32,3 @@ REDIRECT_HANDLER_ENABLED = 0x1, | ||
AUTHENTICATION_HANDLER_ENABLED = 0x4, | ||
/* eslint-enable @typescript-eslint/naming-convention */ | ||
} | ||
@@ -76,5 +78,3 @@ | ||
private setFeatureUsage(flag: FeatureUsageFlag): void { | ||
/* tslint:disable: no-bitwise */ | ||
this.featureUsage = this.featureUsage | flag; | ||
/* tslint:enable: no-bitwise */ | ||
} | ||
@@ -81,0 +81,0 @@ |
@@ -14,6 +14,5 @@ /** | ||
import { RequestMethod } from "../RequestMethod"; | ||
import { Middleware } from "./IMiddleware"; | ||
import { MiddlewareControl } from "./MiddlewareControl"; | ||
import { cloneRequestWithNewUrl, setRequestHeader } from "./MiddlewareUtil"; | ||
import { cloneRequestWithNewUrl } from "./MiddlewareUtil"; | ||
import { RedirectHandlerOptions } from "./options/RedirectHandlerOptions"; | ||
@@ -47,3 +46,3 @@ import { FeatureUsageFlag, TelemetryHandlerOptions } from "./options/TelemetryHandlerOptions"; | ||
*/ | ||
private static STATUS_CODE_SEE_OTHER: number = 303; | ||
private static STATUS_CODE_SEE_OTHER = 303; | ||
@@ -55,3 +54,3 @@ /** | ||
*/ | ||
private static LOCATION_HEADER: string = "Location"; | ||
private static LOCATION_HEADER = "Location"; | ||
@@ -63,3 +62,3 @@ /** | ||
*/ | ||
private static AUTHORIZATION_HEADER: string = "Authorization"; | ||
private static AUTHORIZATION_HEADER = "Authorization"; | ||
@@ -145,3 +144,3 @@ /** | ||
private shouldDropAuthorizationHeader(requestUrl: string, redirectUrl: string): boolean { | ||
const schemeHostRegex: RegExp = /^[A-Za-z].+?:\/\/.+?(?=\/|$)/; | ||
const schemeHostRegex = /^[A-Za-z].+?:\/\/.+?(?=\/|$)/; | ||
const requestMatches: string[] = schemeHostRegex.exec(requestUrl); | ||
@@ -199,23 +198,19 @@ let requestAuthority: string; | ||
private async executeWithRedirect(context: Context, redirectCount: number, options: RedirectHandlerOptions): Promise<void> { | ||
try { | ||
await this.nextMiddleware.execute(context); | ||
const response = context.response; | ||
if (redirectCount < options.maxRedirects && this.isRedirect(response) && this.hasLocationHeader(response) && options.shouldRedirect(response)) { | ||
++redirectCount; | ||
if (response.status === RedirectHandler.STATUS_CODE_SEE_OTHER) { | ||
context.options.method = RequestMethod.GET; | ||
delete context.options.body; | ||
} else { | ||
const redirectUrl: string = this.getLocationHeader(response); | ||
if (!this.isRelativeURL(redirectUrl) && this.shouldDropAuthorizationHeader(response.url, redirectUrl)) { | ||
delete context.options.headers[RedirectHandler.AUTHORIZATION_HEADER]; | ||
} | ||
await this.updateRequestUrl(redirectUrl, context); | ||
await this.nextMiddleware.execute(context); | ||
const response = context.response; | ||
if (redirectCount < options.maxRedirects && this.isRedirect(response) && this.hasLocationHeader(response) && options.shouldRedirect(response)) { | ||
++redirectCount; | ||
if (response.status === RedirectHandler.STATUS_CODE_SEE_OTHER) { | ||
context.options.method = RequestMethod.GET; | ||
delete context.options.body; | ||
} else { | ||
const redirectUrl: string = this.getLocationHeader(response); | ||
if (!this.isRelativeURL(redirectUrl) && this.shouldDropAuthorizationHeader(response.url, redirectUrl)) { | ||
delete context.options.headers[RedirectHandler.AUTHORIZATION_HEADER]; | ||
} | ||
await this.executeWithRedirect(context, redirectCount, options); | ||
} else { | ||
return; | ||
await this.updateRequestUrl(redirectUrl, context); | ||
} | ||
} catch (error) { | ||
throw error; | ||
await this.executeWithRedirect(context, redirectCount, options); | ||
} else { | ||
return; | ||
} | ||
@@ -232,11 +227,7 @@ } | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
const redirectCount: number = 0; | ||
const options = this.getOptions(context); | ||
context.options.redirect = RedirectHandler.MANUAL_REDIRECT; | ||
TelemetryHandlerOptions.updateFeatureUsageFlag(context, FeatureUsageFlag.REDIRECT_HANDLER_ENABLED); | ||
return await this.executeWithRedirect(context, redirectCount, options); | ||
} catch (error) { | ||
throw error; | ||
} | ||
const redirectCount = 0; | ||
const options = this.getOptions(context); | ||
context.options.redirect = RedirectHandler.MANUAL_REDIRECT; | ||
TelemetryHandlerOptions.updateFeatureUsageFlag(context, FeatureUsageFlag.REDIRECT_HANDLER_ENABLED); | ||
return await this.executeWithRedirect(context, redirectCount, options); | ||
} | ||
@@ -243,0 +234,0 @@ |
@@ -15,3 +15,2 @@ /** | ||
import { RequestMethod } from "../RequestMethod"; | ||
import { Middleware } from "./IMiddleware"; | ||
@@ -45,3 +44,3 @@ import { MiddlewareControl } from "./MiddlewareControl"; | ||
*/ | ||
private static RETRY_ATTEMPT_HEADER: string = "Retry-Attempt"; | ||
private static RETRY_ATTEMPT_HEADER = "Retry-Attempt"; | ||
@@ -53,3 +52,3 @@ /** | ||
*/ | ||
private static RETRY_AFTER_HEADER: string = "Retry-After"; | ||
private static RETRY_AFTER_HEADER = "Retry-After"; | ||
@@ -122,3 +121,2 @@ /** | ||
if (retryAfter !== null) { | ||
// tslint:disable: prefer-conditional-expression | ||
if (Number.isNaN(Number(retryAfter))) { | ||
@@ -129,3 +127,2 @@ newDelay = Math.round((new Date(retryAfter).getTime() - Date.now()) / 1000); | ||
} | ||
// tslint:enable: prefer-conditional-expression | ||
} else { | ||
@@ -181,15 +178,11 @@ // Adding randomness to avoid retrying at a same | ||
private async executeWithRetry(context: Context, retryAttempts: number, options: RetryHandlerOptions): Promise<void> { | ||
try { | ||
await this.nextMiddleware.execute(context); | ||
if (retryAttempts < options.maxRetries && this.isRetry(context.response) && this.isBuffered(context.request, context.options) && options.shouldRetry(options.delay, retryAttempts, context.request, context.options, context.response)) { | ||
++retryAttempts; | ||
setRequestHeader(context.request, context.options, RetryHandler.RETRY_ATTEMPT_HEADER, retryAttempts.toString()); | ||
const delay = this.getDelay(context.response, retryAttempts, options.delay); | ||
await this.sleep(delay); | ||
return await this.executeWithRetry(context, retryAttempts, options); | ||
} else { | ||
return; | ||
} | ||
} catch (error) { | ||
throw error; | ||
await this.nextMiddleware.execute(context); | ||
if (retryAttempts < options.maxRetries && this.isRetry(context.response) && this.isBuffered(context.request, context.options) && options.shouldRetry(options.delay, retryAttempts, context.request, context.options, context.response)) { | ||
++retryAttempts; | ||
setRequestHeader(context.request, context.options, RetryHandler.RETRY_ATTEMPT_HEADER, retryAttempts.toString()); | ||
const delay = this.getDelay(context.response, retryAttempts, options.delay); | ||
await this.sleep(delay); | ||
return await this.executeWithRetry(context, retryAttempts, options); | ||
} else { | ||
return; | ||
} | ||
@@ -206,10 +199,6 @@ } | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
const retryAttempts: number = 0; | ||
const options: RetryHandlerOptions = this.getOptions(context); | ||
TelemetryHandlerOptions.updateFeatureUsageFlag(context, FeatureUsageFlag.RETRY_HANDLER_ENABLED); | ||
return await this.executeWithRetry(context, retryAttempts, options); | ||
} catch (error) { | ||
throw error; | ||
} | ||
const retryAttempts = 0; | ||
const options: RetryHandlerOptions = this.getOptions(context); | ||
TelemetryHandlerOptions.updateFeatureUsageFlag(context, FeatureUsageFlag.RETRY_HANDLER_ENABLED); | ||
return await this.executeWithRetry(context, retryAttempts, options); | ||
} | ||
@@ -216,0 +205,0 @@ |
@@ -14,3 +14,2 @@ /** | ||
import { PACKAGE_VERSION } from "../Version"; | ||
import { Middleware } from "./IMiddleware"; | ||
@@ -69,31 +68,27 @@ import { MiddlewareControl } from "./MiddlewareControl"; | ||
public async execute(context: Context): Promise<void> { | ||
try { | ||
const url = typeof context.request === "string" ? context.request : context.request.url; | ||
if (isGraphURL(url)) { | ||
// Add telemetry only if the request url is a Graph URL. | ||
// Errors are reported as in issue #265 if headers are present when redirecting to a non Graph URL | ||
let clientRequestId: string = getRequestHeader(context.request, context.options, TelemetryHandler.CLIENT_REQUEST_ID_HEADER); | ||
if (!clientRequestId) { | ||
clientRequestId = generateUUID(); | ||
setRequestHeader(context.request, context.options, TelemetryHandler.CLIENT_REQUEST_ID_HEADER, clientRequestId); | ||
} | ||
let sdkVersionValue: string = `${TelemetryHandler.PRODUCT_NAME}/${PACKAGE_VERSION}`; | ||
let options: TelemetryHandlerOptions; | ||
if (context.middlewareControl instanceof MiddlewareControl) { | ||
options = context.middlewareControl.getMiddlewareOptions(TelemetryHandlerOptions) as TelemetryHandlerOptions; | ||
} | ||
if (options) { | ||
const featureUsage: string = options.getFeatureUsage(); | ||
sdkVersionValue += ` (${TelemetryHandler.FEATURE_USAGE_STRING}=${featureUsage})`; | ||
} | ||
appendRequestHeader(context.request, context.options, TelemetryHandler.SDK_VERSION_HEADER, sdkVersionValue); | ||
} else { | ||
// Remove telemetry headers if present during redirection. | ||
delete context.options.headers[TelemetryHandler.CLIENT_REQUEST_ID_HEADER]; | ||
delete context.options.headers[TelemetryHandler.SDK_VERSION_HEADER]; | ||
const url = typeof context.request === "string" ? context.request : context.request.url; | ||
if (isGraphURL(url)) { | ||
// Add telemetry only if the request url is a Graph URL. | ||
// Errors are reported as in issue #265 if headers are present when redirecting to a non Graph URL | ||
let clientRequestId: string = getRequestHeader(context.request, context.options, TelemetryHandler.CLIENT_REQUEST_ID_HEADER); | ||
if (!clientRequestId) { | ||
clientRequestId = generateUUID(); | ||
setRequestHeader(context.request, context.options, TelemetryHandler.CLIENT_REQUEST_ID_HEADER, clientRequestId); | ||
} | ||
return await this.nextMiddleware.execute(context); | ||
} catch (error) { | ||
throw error; | ||
let sdkVersionValue = `${TelemetryHandler.PRODUCT_NAME}/${PACKAGE_VERSION}`; | ||
let options: TelemetryHandlerOptions; | ||
if (context.middlewareControl instanceof MiddlewareControl) { | ||
options = context.middlewareControl.getMiddlewareOptions(TelemetryHandlerOptions) as TelemetryHandlerOptions; | ||
} | ||
if (options) { | ||
const featureUsage: string = options.getFeatureUsage(); | ||
sdkVersionValue += ` (${TelemetryHandler.FEATURE_USAGE_STRING}=${featureUsage})`; | ||
} | ||
appendRequestHeader(context.request, context.options, TelemetryHandler.SDK_VERSION_HEADER, sdkVersionValue); | ||
} else { | ||
// Remove telemetry headers if present during redirection. | ||
delete context.options.headers[TelemetryHandler.CLIENT_REQUEST_ID_HEADER]; | ||
delete context.options.headers[TelemetryHandler.SDK_VERSION_HEADER]; | ||
} | ||
return await this.nextMiddleware.execute(context); | ||
} | ||
@@ -100,0 +95,0 @@ |
@@ -12,4 +12,9 @@ /** | ||
import { GraphClientError } from "../GraphClientError"; | ||
import { GraphResponseHandler } from "../GraphResponseHandler"; | ||
import { Client } from "../index"; | ||
import { Range } from "../Range"; | ||
import { ResponseType } from "../ResponseType"; | ||
import { UploadEventHandlers } from "./FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
import { Range } from "./FileUploadTask/Range"; | ||
import { UploadResult } from "./FileUploadTask/UploadResult"; | ||
@@ -43,2 +48,3 @@ /** | ||
rangeSize?: number; | ||
uploadEventHandlers?: UploadEventHandlers; | ||
} | ||
@@ -55,5 +61,12 @@ | ||
expiry: Date; | ||
isCancelled?: boolean; | ||
} | ||
/** | ||
* @type | ||
* Representing the return type of the sliceFile function that is type of the slice of a given range. | ||
*/ | ||
export type SliceType = ArrayBuffer | Blob | Buffer; | ||
/** | ||
* @interface | ||
@@ -65,6 +78,7 @@ * Signature to define the properties and content of the file in upload task | ||
*/ | ||
export interface FileObject { | ||
content: ArrayBuffer | File; | ||
export interface FileObject<T> { | ||
content: T; | ||
name: string; | ||
size: number; | ||
sliceFile(range: Range): SliceType | Promise<SliceType>; | ||
} | ||
@@ -76,3 +90,3 @@ | ||
*/ | ||
export class LargeFileUploadTask { | ||
export class LargeFileUploadTask<T> { | ||
/** | ||
@@ -94,3 +108,3 @@ * @private | ||
*/ | ||
protected file: FileObject; | ||
protected file: FileObject<T>; | ||
@@ -125,16 +139,13 @@ /** | ||
*/ | ||
public static async createUploadSession(client: Client, requestUrl: string, payload: any, headers: KeyValuePairObjectStringNumber = {}): Promise<any> { | ||
try { | ||
const session = await client | ||
.api(requestUrl) | ||
.headers(headers) | ||
.post(payload); | ||
const largeFileUploadSession: LargeFileUploadSession = { | ||
url: session.uploadUrl, | ||
expiry: new Date(session.expirationDateTime), | ||
}; | ||
return largeFileUploadSession; | ||
} catch (err) { | ||
throw err; | ||
} | ||
public static async createUploadSession(client: Client, requestUrl: string, payload: any, headers: KeyValuePairObjectStringNumber = {}): Promise<LargeFileUploadSession> { | ||
const session = await client | ||
.api(requestUrl) | ||
.headers(headers) | ||
.post(payload); | ||
const largeFileUploadSession: LargeFileUploadSession = { | ||
url: session.uploadUrl, | ||
expiry: new Date(session.expirationDateTime), | ||
isCancelled: false, | ||
}; | ||
return largeFileUploadSession; | ||
} | ||
@@ -152,8 +163,15 @@ | ||
*/ | ||
public constructor(client: Client, file: FileObject, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions = {}) { | ||
public constructor(client: Client, file: FileObject<T>, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions = {}) { | ||
this.client = client; | ||
if (!file.sliceFile) { | ||
throw new GraphClientError("Please pass the FileUpload object, StreamUpload object or any custom implementation of the FileObject interface"); | ||
} else { | ||
this.file = file; | ||
} | ||
this.file = file; | ||
if (options.rangeSize === undefined) { | ||
if (!options.rangeSize) { | ||
options.rangeSize = this.DEFAULT_FILE_SIZE; | ||
} | ||
this.options = options; | ||
@@ -213,2 +231,3 @@ this.uploadSession = uploadSession; | ||
/** | ||
* @deprecated This function has been moved into FileObject interface. | ||
* @public | ||
@@ -220,4 +239,7 @@ * Slices the file content to the given range | ||
public sliceFile(range: Range): ArrayBuffer | Blob { | ||
const blob = this.file.content.slice(range.minValue, range.maxValue + 1); | ||
return blob; | ||
console.warn("The LargeFileUploadTask.sliceFile() function has been deprecated and moved into the FileObject interface."); | ||
if (this.file.content instanceof ArrayBuffer || this.file.content instanceof Blob || this.file.content instanceof Buffer) { | ||
return this.file.content.slice(range.minValue, range.maxValue + 1); | ||
} | ||
throw new GraphClientError("The LargeFileUploadTask.sliceFile() function expects only Blob, ArrayBuffer or Buffer file content. Please note that the sliceFile() function is deprecated."); | ||
} | ||
@@ -231,22 +253,38 @@ | ||
*/ | ||
public async upload(): Promise<any> { | ||
try { | ||
while (true) { | ||
const nextRange = this.getNextRange(); | ||
if (nextRange.maxValue === -1) { | ||
const err = new Error("Task with which you are trying to upload is already completed, Please check for your uploaded file"); | ||
err.name = "Invalid Session"; | ||
throw err; | ||
} | ||
const fileSlice = this.sliceFile(nextRange); | ||
const response = await this.uploadSlice(fileSlice, nextRange, this.file.size); | ||
// Upon completion of upload process incase of onedrive, driveItem is returned, which contains id | ||
if (response.id !== undefined) { | ||
return response; | ||
} else { | ||
this.updateTaskStatus(response); | ||
} | ||
public async upload(): Promise<UploadResult> { | ||
const uploadEventHandlers = this.options && this.options.uploadEventHandlers; | ||
while (!this.uploadSession.isCancelled) { | ||
const nextRange = this.getNextRange(); | ||
if (nextRange.maxValue === -1) { | ||
const err = new Error("Task with which you are trying to upload is already completed, Please check for your uploaded file"); | ||
err.name = "Invalid Session"; | ||
throw err; | ||
} | ||
} catch (err) { | ||
throw err; | ||
const fileSlice = await this.file.sliceFile(nextRange); | ||
const rawResponse = await this.uploadSliceGetRawResponse(fileSlice, nextRange, this.file.size); | ||
if (!rawResponse) { | ||
throw new GraphClientError("Something went wrong! Large file upload slice response is null."); | ||
} | ||
const responseBody = await GraphResponseHandler.getResponse(rawResponse); | ||
/** | ||
* (rawResponse.status === 201) -> This condition is applicable for OneDrive, PrintDocument and Outlook APIs. | ||
* (rawResponse.status === 200 && responseBody.id) -> This additional condition is applicable only for OneDrive API. | ||
*/ | ||
if (rawResponse.status === 201 || (rawResponse.status === 200 && responseBody.id)) { | ||
const uploadResult = UploadResult.CreateUploadResult(responseBody, rawResponse.headers); | ||
return uploadResult; | ||
} | ||
/* Handling the API issue where the case of Outlook upload response property -'nextExpectedRanges' is not uniform. | ||
* https://github.com/microsoftgraph/msgraph-sdk-serviceissues/issues/39 | ||
*/ | ||
const res: UploadStatusResponse = { | ||
expirationDateTime: responseBody.expirationDateTime || responseBody.ExpirationDateTime, | ||
nextExpectedRanges: responseBody.NextExpectedRanges || responseBody.nextExpectedRanges, | ||
}; | ||
this.updateTaskStatus(res); | ||
if (uploadEventHandlers && uploadEventHandlers.progress) { | ||
uploadEventHandlers.progress(nextRange, uploadEventHandlers.extraCallbackParam); | ||
} | ||
} | ||
@@ -262,15 +300,12 @@ } | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The response body of the upload slice result | ||
*/ | ||
public async uploadSlice(fileSlice: ArrayBuffer | Blob | File, range: Range, totalSize: number): Promise<any> { | ||
try { | ||
return await this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": `${range.maxValue - range.minValue + 1}`, | ||
"Content-Range": `bytes ${range.minValue}-${range.maxValue}/${totalSize}`, | ||
}) | ||
.put(fileSlice); | ||
} catch (err) { | ||
throw err; | ||
} | ||
public async uploadSlice(fileSlice: ArrayBuffer | Blob | File, range: Range, totalSize: number): Promise<unknown> { | ||
return await this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": `${range.maxValue - range.minValue + 1}`, | ||
"Content-Range": `bytes ${range.minValue}-${range.maxValue}/${totalSize}`, | ||
}) | ||
.put(fileSlice); | ||
} | ||
@@ -281,11 +316,34 @@ | ||
* @async | ||
* Uploads given slice to the server | ||
* @param {unknown} fileSlice - The file slice | ||
* @param {Range} range - The range value | ||
* @param {number} totalSize - The total size of a complete file | ||
* @returns The raw response of the upload slice result | ||
*/ | ||
public async uploadSliceGetRawResponse(fileSlice: unknown, range: Range, totalSize: number): Promise<Response> { | ||
return await this.client | ||
.api(this.uploadSession.url) | ||
.headers({ | ||
"Content-Length": `${range.maxValue - range.minValue + 1}`, | ||
"Content-Range": `bytes ${range.minValue}-${range.maxValue}/${totalSize}`, | ||
}) | ||
.responseType(ResponseType.RAW) | ||
.put(fileSlice); | ||
} | ||
/** | ||
* @public | ||
* @async | ||
* Deletes upload session in the server | ||
* @returns The promise resolves to cancelled response | ||
*/ | ||
public async cancel(): Promise<any> { | ||
try { | ||
return await this.client.api(this.uploadSession.url).delete(); | ||
} catch (err) { | ||
throw err; | ||
public async cancel(): Promise<unknown> { | ||
const cancelResponse = await this.client | ||
.api(this.uploadSession.url) | ||
.responseType(ResponseType.RAW) | ||
.delete(); | ||
if (cancelResponse.status === 204) { | ||
this.uploadSession.isCancelled = true; | ||
} | ||
return cancelResponse; | ||
} | ||
@@ -299,10 +357,6 @@ | ||
*/ | ||
public async getStatus(): Promise<any> { | ||
try { | ||
const response = await this.client.api(this.uploadSession.url).get(); | ||
this.updateTaskStatus(response); | ||
return response; | ||
} catch (err) { | ||
throw err; | ||
} | ||
public async getStatus(): Promise<unknown> { | ||
const response = await this.client.api(this.uploadSession.url).get(); | ||
this.updateTaskStatus(response); | ||
return response; | ||
} | ||
@@ -316,10 +370,16 @@ | ||
*/ | ||
public async resume(): Promise<any> { | ||
try { | ||
await this.getStatus(); | ||
return await this.upload(); | ||
} catch (err) { | ||
throw err; | ||
} | ||
public async resume(): Promise<unknown> { | ||
await this.getStatus(); | ||
return await this.upload(); | ||
} | ||
/** | ||
* @public | ||
* @async | ||
* Get the upload session information | ||
* @returns The large file upload session | ||
*/ | ||
public getUploadSession(): LargeFileUploadSession { | ||
return this.uploadSession; | ||
} | ||
} |
@@ -12,4 +12,6 @@ /** | ||
import { GraphClientError } from "../GraphClientError"; | ||
import { Client } from "../index"; | ||
import { FileUpload } from "./FileUploadTask/FileObjectClasses/FileUpload"; | ||
import { UploadEventHandlers } from "./FileUploadTask/Interfaces/IUploadEventHandlers"; | ||
import { FileObject, LargeFileUploadSession, LargeFileUploadTask, LargeFileUploadTaskOptions } from "./LargeFileUploadTask"; | ||
@@ -25,13 +27,27 @@ import { getValidRangeSize } from "./OneDriveLargeFileUploadTaskUtil"; | ||
*/ | ||
interface OneDriveLargeFileUploadOptions { | ||
export interface OneDriveLargeFileUploadOptions { | ||
fileName: string; | ||
path?: string; | ||
rangeSize?: number; | ||
conflictBehavior?: string; | ||
uploadEventHandlers?: UploadEventHandlers; | ||
} | ||
/** | ||
* @interface | ||
* Signature to define options when creating an upload task | ||
* @property {string} fileName - Specifies the name of a file to be uploaded (with extension) | ||
* @property {string} [path] - The path to which the file needs to be uploaded | ||
* @property {number} [rangeSize] - Specifies the range chunk size | ||
*/ | ||
interface OneDriveFileUploadSessionPayLoad { | ||
fileName: string; | ||
conflictBehavior?: string; | ||
} | ||
/** | ||
* @class | ||
* Class representing OneDriveLargeFileUploadTask | ||
*/ | ||
export class OneDriveLargeFileUploadTask extends LargeFileUploadTask { | ||
export class OneDriveLargeFileUploadTask<T> extends LargeFileUploadTask<T> { | ||
/** | ||
@@ -42,3 +58,3 @@ * @private | ||
*/ | ||
private static DEFAULT_UPLOAD_PATH: string = "/"; | ||
private static DEFAULT_UPLOAD_PATH = "/"; | ||
@@ -83,3 +99,6 @@ /** | ||
*/ | ||
public static async create(client: Client, file: Blob | Buffer | File, options: OneDriveLargeFileUploadOptions): Promise<any> { | ||
public static async create(client: Client, file: Blob | Buffer | File, options: OneDriveLargeFileUploadOptions): Promise<OneDriveLargeFileUploadTask<Blob | ArrayBuffer | Buffer>> { | ||
if (!client || !file || !options) { | ||
throw new GraphClientError("Please provide the Graph client instance, file object and OneDriveLargeFileUploadOptions value"); | ||
} | ||
const name: string = options.fileName; | ||
@@ -99,18 +118,31 @@ let content; | ||
} | ||
const fileObj = new FileUpload(content, name, size); | ||
return this.createTaskWithFileObject<Blob | ArrayBuffer | Buffer>(client, fileObj, options); | ||
} | ||
try { | ||
const requestUrl = OneDriveLargeFileUploadTask.constructCreateSessionUrl(options.fileName, options.path); | ||
const session = await OneDriveLargeFileUploadTask.createUploadSession(client, requestUrl, options.fileName); | ||
const rangeSize = getValidRangeSize(options.rangeSize); | ||
const fileObj: FileObject = { | ||
name, | ||
content, | ||
size, | ||
}; | ||
return new OneDriveLargeFileUploadTask(client, fileObj, session, { | ||
rangeSize, | ||
}); | ||
} catch (err) { | ||
throw err; | ||
/** | ||
* @public | ||
* @static | ||
* @async | ||
* Creates a OneDriveLargeFileUploadTask | ||
* @param {Client} client - The GraphClient instance | ||
* @param {FileObject} file - FileObject instance | ||
* @param {OneDriveLargeFileUploadOptions} options - The options for upload task | ||
* @returns The promise that will be resolves to OneDriveLargeFileUploadTask instance | ||
*/ | ||
public static async createTaskWithFileObject<T>(client: Client, fileObject: FileObject<T>, options: OneDriveLargeFileUploadOptions): Promise<OneDriveLargeFileUploadTask<T>> { | ||
if (!client || !fileObject || !options) { | ||
throw new GraphClientError("Please provide the Graph client instance, FileObject interface implementation and OneDriveLargeFileUploadOptions value"); | ||
} | ||
const requestUrl = OneDriveLargeFileUploadTask.constructCreateSessionUrl(options.fileName, options.path); | ||
const uploadSessionPayload: OneDriveFileUploadSessionPayLoad = { | ||
fileName: options.fileName, | ||
conflictBehavior: options.conflictBehavior, | ||
}; | ||
const session = await OneDriveLargeFileUploadTask.createUploadSession(client, requestUrl, uploadSessionPayload); | ||
const rangeSize = getValidRangeSize(options.rangeSize); | ||
return new OneDriveLargeFileUploadTask(client, fileObject, session, { | ||
rangeSize, | ||
uploadEventHandlers: options.uploadEventHandlers, | ||
}); | ||
} | ||
@@ -126,16 +158,13 @@ | ||
* @param {string} fileName - The name of a file to upload, (with extension) | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise that resolves to LargeFileUploadSession | ||
*/ | ||
public static async createUploadSession(client: Client, requestUrl: string, fileName: string): Promise<any> { | ||
public static async createUploadSession(client: Client, requestUrl: string, payloadOptions: OneDriveFileUploadSessionPayLoad): Promise<LargeFileUploadSession> { | ||
const payload = { | ||
item: { | ||
"@microsoft.graph.conflictBehavior": "rename", | ||
name: fileName, | ||
"@microsoft.graph.conflictBehavior": payloadOptions?.conflictBehavior || "rename", | ||
name: payloadOptions?.fileName, | ||
}, | ||
}; | ||
try { | ||
return super.createUploadSession(client, requestUrl, payload); | ||
} catch (err) { | ||
throw err; | ||
} | ||
return super.createUploadSession(client, requestUrl, payload); | ||
} | ||
@@ -153,3 +182,3 @@ | ||
*/ | ||
public constructor(client: Client, file: FileObject, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions) { | ||
public constructor(client: Client, file: FileObject<T>, uploadSession: LargeFileUploadSession, options: LargeFileUploadTaskOptions) { | ||
super(client, file, uploadSession, options); | ||
@@ -162,16 +191,13 @@ } | ||
* @param {string} requestUrl - The URL to commit the upload session | ||
* @param {string} conflictBehavior - Conflict behaviour option. Default is 'rename' | ||
* @returns The promise resolves to committed response | ||
*/ | ||
public async commit(requestUrl: string): Promise<any> { | ||
try { | ||
const payload = { | ||
name: this.file.name, | ||
"@microsoft.graph.conflictBehavior": "rename", | ||
"@microsoft.graph.sourceUrl": this.uploadSession.url, | ||
}; | ||
return await this.client.api(requestUrl).put(payload); | ||
} catch (err) { | ||
throw err; | ||
} | ||
public async commit(requestUrl: string, conflictBehavior = "rename"): Promise<unknown> { | ||
const payload = { | ||
name: this.file.name, | ||
"@microsoft.graph.conflictBehavior": conflictBehavior, | ||
"@microsoft.graph.sourceUrl": this.uploadSession.url, | ||
}; | ||
return await this.client.api(requestUrl).put(payload); | ||
} | ||
} |
@@ -15,3 +15,2 @@ /** | ||
import { MiddlewareOptions } from "../middleware/options/IMiddlewareOptions"; | ||
import { ResponseType } from "../ResponseType"; | ||
@@ -142,23 +141,19 @@ /** | ||
private async fetchAndUpdateNextPageData(): Promise<any> { | ||
try { | ||
let graphRequest = this.client.api(this.nextLink); | ||
if (this.requestOptions) { | ||
if (this.requestOptions.headers) { | ||
graphRequest = graphRequest.headers(this.requestOptions.headers); | ||
} | ||
if (this.requestOptions.middlewareOptions) { | ||
graphRequest = graphRequest.middlewareOptions(this.requestOptions.middlewareOptions); | ||
} | ||
if (this.requestOptions.options) { | ||
graphRequest = graphRequest.options(this.requestOptions.options); | ||
} | ||
let graphRequest = this.client.api(this.nextLink); | ||
if (this.requestOptions) { | ||
if (this.requestOptions.headers) { | ||
graphRequest = graphRequest.headers(this.requestOptions.headers); | ||
} | ||
if (this.requestOptions.middlewareOptions) { | ||
graphRequest = graphRequest.middlewareOptions(this.requestOptions.middlewareOptions); | ||
} | ||
if (this.requestOptions.options) { | ||
graphRequest = graphRequest.options(this.requestOptions.options); | ||
} | ||
} | ||
const response: PageCollection = await graphRequest.get(); | ||
this.collection = response.value; | ||
this.nextLink = response["@odata.nextLink"]; | ||
this.deltaLink = response["@odata.deltaLink"]; | ||
} catch (error) { | ||
throw error; | ||
} | ||
const response: PageCollection = await graphRequest.get(); | ||
this.collection = response.value; | ||
this.nextLink = response["@odata.nextLink"]; | ||
this.deltaLink = response["@odata.deltaLink"]; | ||
} | ||
@@ -183,18 +178,14 @@ | ||
public async iterate(): Promise<any> { | ||
try { | ||
let advance = this.iterationHelper(); | ||
while (advance) { | ||
if (this.nextLink !== undefined) { | ||
await this.fetchAndUpdateNextPageData(); | ||
advance = this.iterationHelper(); | ||
} else { | ||
advance = false; | ||
} | ||
let advance = this.iterationHelper(); | ||
while (advance) { | ||
if (this.nextLink !== undefined) { | ||
await this.fetchAndUpdateNextPageData(); | ||
advance = this.iterationHelper(); | ||
} else { | ||
advance = false; | ||
} | ||
if (this.nextLink === undefined && this.collection.length === 0) { | ||
this.complete = true; | ||
} | ||
} catch (error) { | ||
throw error; | ||
} | ||
if (this.nextLink === undefined && this.collection.length === 0) { | ||
this.complete = true; | ||
} | ||
} | ||
@@ -210,7 +201,3 @@ | ||
public async resume(): Promise<any> { | ||
try { | ||
return this.iterate(); | ||
} catch (error) { | ||
throw error; | ||
} | ||
return this.iterate(); | ||
} | ||
@@ -217,0 +204,0 @@ |
@@ -15,2 +15,2 @@ /** | ||
export const PACKAGE_VERSION = "2.2.1"; | ||
export const PACKAGE_VERSION = "3.0.0-Preview.1"; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1226437
2
445
22573
9
44
2
182
+ Addedtslib@2.8.1(transitive)
- Removedmsal@^1.4.4
- Removedmsal@1.4.18(transitive)
- Removedtslib@1.14.1(transitive)
Updated@babel/runtime@^7.12.5
Updatedtslib@^2.2.0