This commit is contained in:
Amar Zavery 2017-09-13 09:42:16 -07:00
Родитель 54fb56b756
Коммит 1636d476ea
138 изменённых файлов: 17400 добавлений и 42 удалений

37
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
*.bmp binary
*.dll binary
*.gif binary
*.jpg binary
*.png binary
*.snk binary
*.exe binary
*.wmv binary
*.mp4 binary
*.ismv binary
*.isma binary
*.ascx text
*.cmd text
*.config text
*.cs text diff=csharp
*.csproj text merge=union
*.edmx text
*.htm text
*.html text
*.json text eol=lf
*.ts text eol=lf
*.js text eol=lf
*.msbuild text
*.nuspec text
*.resx text
*.ruleset text
*.StyleCop text
*.targets text
*.txt text
*.xml text
*.sln text eol=crlf merge=union

111
.gitignore поставляемый
Просмотреть файл

@ -1,59 +1,86 @@
# Logs #### linux gitignore
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data *~
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover # KDE directory preferences
lib-cov .directory
# Coverage directory used by tools like istanbul # Linux trash folder which might appear on any partition or disk
coverage .Trash-*
# nyc test coverage /obj/*
.nyc_output /node_modules
.ntvs_analysis.dat
.ntvs_analysis.*
npm-debug.log
tmp/*
packages/*
*.njsperf
.vs/
bin/*
/.vscode/*
ValidationTool.njsproj
ValidationTool.sln
.vscode/launch.json
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) #### win gitignore
.grunt
# Bower dependency directory (https://bower.io/) # Windows image file caches
bower_components Thumbs.db
ehthumbs.db
# node-waf configuration # Folder config file
.lock-wscript Desktop.ini
# Compiled binary addons (http://nodejs.org/api/addons.html) # Recycle Bin used on file shares
build/Release $RECYCLE.BIN/
# Dependency directories # Windows Installer files
node_modules/ *.cab
jspm_packages/ *.msi
*.msm
*.msp
# Typescript v1 declaration files # Windows shortcuts
typings/ *.lnk
# Optional npm cache directory
.npm
# Optional eslint cache #### osx gitignore
.eslintcache
# Optional REPL history .DS_Store
.node_repl_history .AppleDouble
.LSOverride
# Output of 'npm pack' # Icon must end with two \r
*.tgz Icon
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file # Thumbnails
.env ._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
node_modules
#### JetBrains
.idea
# ignore code gen virtual env folder
SdkCodeGen
output/*
# Typescript output

7
.npmignore Normal file
Просмотреть файл

@ -0,0 +1,7 @@
.vscode/
node_modules/
samples/
test/
.travis.yml
.gitignore
gulpfile.js

5
.travis.yml Normal file
Просмотреть файл

@ -0,0 +1,5 @@
language: node_js
sudo: false
node_js:
- "6"
- "8"

Просмотреть файл

@ -1,3 +1,23 @@
# ms-rest-js
Runtime for isomorphic javascript libraries (that work in the browser and node.js environemnt) generated via [Autorest](https://github.com/Azure/Autorest).
## Requirements
- node.js version > 6.x
- npm install -g typescript
## Installation
- After cloning the repo, execute `npm install`
## Execution
### node.js
- Set the subscriptionId and token
- Run `node samples/node-sample.js`
### In the browser
- Set the subscriptionId and token and then run
- Open index.html file in the browser. It should show the response from GET request on the storage account. From Chrome type Ctrl + Shift + I and you can see the logs in console.
# Contributing # Contributing

45
dist/lib/credentials/basicAuthenticationCredentials.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,45 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const constants_1 = require("../util/constants");
const HeaderConstants = constants_1.Constants.HeaderConstants;
const DEFAULT_AUTHORIZATION_SCHEME = "Basic";
/**
* Creates a new BasicAuthenticationCredentials object.
*
* @constructor
* @param {string} userName User name.
* @param {string} password Password.
* @param {string} [authorizationScheme] The authorization scheme.
*/
class BasicAuthenticationCredentials {
constructor(userName, password, authorizationScheme = DEFAULT_AUTHORIZATION_SCHEME) {
this.authorizationScheme = DEFAULT_AUTHORIZATION_SCHEME;
if (userName === null || userName === undefined || typeof userName.valueOf() !== "string") {
throw new Error("userName cannot be null or undefined and must be of type string.");
}
if (password === null || password === undefined || typeof password.valueOf() !== "string") {
throw new Error("password cannot be null or undefined and must be of type string.");
}
this.userName = userName;
this.password = password;
this.authorizationScheme = authorizationScheme;
}
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @returns {Promise<WebResource>} - The signed request object.
*/
signRequest(webResource) {
const credentials = `${this.userName}:${this.password}`;
const encodedCredentials = `${this.authorizationScheme} ${Buffer.from(credentials).toString("base64")}`;
if (!webResource.headers)
webResource.headers = {};
webResource.headers[HeaderConstants.AUTHORIZATION] = encodedCredentials;
return Promise.resolve(webResource);
}
}
exports.BasicAuthenticationCredentials = BasicAuthenticationCredentials;
//# sourceMappingURL=basicAuthenticationCredentials.js.map

1
dist/lib/credentials/basicAuthenticationCredentials.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"basicAuthenticationCredentials.js","sourceRoot":"","sources":["../../../lib/credentials/basicAuthenticationCredentials.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,iDAA8C;AAG9C,MAAM,eAAe,GAAG,qBAAS,CAAC,eAAe,CAAC;AAClD,MAAM,4BAA4B,GAAG,OAAO,CAAC;AAE7C;;;;;;;GAOG;AACH;IAIE,YAAY,QAAgB,EAAE,QAAgB,EAAE,sBAA8B,4BAA4B;QAD1G,wBAAmB,GAAW,4BAA4B,CAAC;QAEzD,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC1F,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QACD,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC1F,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,WAAwB;QAClC,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,kBAAkB,GAAG,GAAG,IAAI,CAAC,mBAAmB,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;YAAC,WAAW,CAAC,OAAO,GAAG,EAAE,CAAC;QACnD,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,kBAAkB,CAAC;QACxE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;CACF;AA7BD,wEA6BC"}

5
dist/lib/credentials/serviceClientCredentials.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=serviceClientCredentials.js.map

1
dist/lib/credentials/serviceClientCredentials.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"serviceClientCredentials.js","sourceRoot":"","sources":["../../../lib/credentials/serviceClientCredentials.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F"}

38
dist/lib/credentials/tokenCredentials.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,38 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const constants_1 = require("../util/constants");
const HeaderConstants = constants_1.Constants.HeaderConstants;
const DEFAULT_AUTHORIZATION_SCHEME = "Bearer";
/**
* Creates a new TokenCredentials object.
*
* @constructor
* @param {string} token The token.
* @param {string} authorizationScheme The authorization scheme.
*/
class TokenCredentials {
constructor(token, authorizationScheme = DEFAULT_AUTHORIZATION_SCHEME) {
this.authorizationScheme = DEFAULT_AUTHORIZATION_SCHEME;
if (!token) {
throw new Error("token cannot be null or undefined.");
}
this.token = token;
this.authorizationScheme = authorizationScheme;
}
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @return {Promise<WebResource>} The signed request object.
*/
signRequest(webResource) {
if (!webResource.headers)
webResource.headers = {};
webResource.headers[HeaderConstants.AUTHORIZATION] = `${this.authorizationScheme} ${this.token}`;
return Promise.resolve(webResource);
}
}
exports.TokenCredentials = TokenCredentials;
//# sourceMappingURL=tokenCredentials.js.map

1
dist/lib/credentials/tokenCredentials.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"tokenCredentials.js","sourceRoot":"","sources":["../../../lib/credentials/tokenCredentials.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,iDAA8C;AAI9C,MAAM,eAAe,GAAG,qBAAS,CAAC,eAAe,CAAC;AAClD,MAAM,4BAA4B,GAAG,QAAQ,CAAC;AAE9C;;;;;;GAMG;AACH;IAIE,YAAY,KAAa,EAAE,sBAA8B,4BAA4B;QAFrF,wBAAmB,GAAW,4BAA4B,CAAC;QAGzD,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,WAAwB;QAClC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;YAAC,WAAW,CAAC,OAAO,GAAG,EAAE,CAAC;QACnD,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACjG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;CACF;AAvBD,4CAuBC"}

15
dist/lib/filters/baseFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
class BaseFilter {
constructor() { }
before(request) {
return Promise.resolve(request);
}
after(response) {
return Promise.resolve(response);
}
}
exports.BaseFilter = BaseFilter;
//# sourceMappingURL=baseFilter.js.map

1
dist/lib/filters/baseFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"baseFilter.js","sourceRoot":"","sources":["../../../lib/filters/baseFilter.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAK/F;IAEE,gBAAgB,CAAC;IAEjB,MAAM,CAAC,OAAoB;QACzB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,QAA+B;QACnC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;CACF;AAXD,gCAWC"}

116
dist/lib/filters/exponentialRetryPolicyFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,116 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const baseFilter_1 = require("./baseFilter");
const utils = require("../util/utils");
/**
* @class
* Instantiates a new "ExponentialRetryPolicyFilter" instance.
*
* @constructor
* @param {number} retryCount The client retry count.
* @param {number} retryInterval The client retry interval, in milliseconds.
* @param {number} minRetryInterval The minimum retry interval, in milliseconds.
* @param {number} maxRetryInterval The maximum retry interval, in milliseconds.
*/
class ExponentialRetryPolicyFilter extends baseFilter_1.BaseFilter {
constructor(retryCount, retryInterval, minRetryInterval, maxRetryInterval) {
super();
this.DEFAULT_CLIENT_RETRY_INTERVAL = 1000 * 30;
this.DEFAULT_CLIENT_RETRY_COUNT = 3;
this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 90;
this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL = 1000 * 3;
this.retryCount = typeof retryCount === "number" ? retryCount : this.DEFAULT_CLIENT_RETRY_COUNT;
this.retryInterval = typeof retryInterval === "number" ? retryInterval : this.DEFAULT_CLIENT_RETRY_INTERVAL;
this.minRetryInterval = typeof minRetryInterval === "number" ? minRetryInterval : this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL;
this.maxRetryInterval = typeof maxRetryInterval === "number" ? maxRetryInterval : this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
}
/**
* Determines if the operation should be retried and how long to wait until the next retry.
*
* @param {number} statusCode The HTTP status code.
* @param {RetryData} retryData The retry data.
* @return {boolean} True if the operation qualifies for a retry; false otherwise.
*/
shouldRetry(statusCode, retryData) {
if ((statusCode < 500 && statusCode !== 408) || statusCode === 501 || statusCode === 505) {
return false;
}
let currentCount;
if (!retryData) {
throw new Error("retryData for the ExponentialRetryPolicyFilter cannot be null.");
}
else {
currentCount = (retryData && retryData.retryCount);
}
return (currentCount < this.retryCount);
}
/**
* Updates the retry data for the next attempt.
*
* @param {RetryData} retryData The retry data.
* @param {object} err The operation"s error, if any.
*/
updateRetryData(retryData, err) {
if (!retryData) {
retryData = {
retryCount: 0,
retryInterval: 0
};
}
if (err) {
if (retryData.error) {
err.innerError = retryData.error;
}
retryData.error = err;
}
// Adjust retry count
retryData.retryCount++;
// Adjust retry interval
let incrementDelta = Math.pow(2, retryData.retryCount) - 1;
const boundedRandDelta = this.retryInterval * 0.8 +
Math.floor(Math.random() * (this.retryInterval * 1.2 - this.retryInterval * 0.8));
incrementDelta *= boundedRandDelta;
retryData.retryInterval = Math.min(this.minRetryInterval + incrementDelta, this.maxRetryInterval);
return retryData;
}
retry(operationResponse, retryData, err) {
return __awaiter(this, void 0, void 0, function* () {
const self = this;
const response = operationResponse.response;
retryData = self.updateRetryData(retryData, err);
if (!utils.objectIsNull(response) && self.shouldRetry(response.status, retryData)) {
try {
yield utils.delay(retryData.retryInterval);
const res = yield utils.dispatchRequest(operationResponse.request);
return self.retry(res, retryData, err);
}
catch (err) {
return self.retry(operationResponse, retryData, err);
}
}
else {
if (!utils.objectIsNull(err)) {
// If the operation failed in the end, return all errors instead of just the last one
err = retryData.error;
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
}
});
}
after(operationResponse) {
return this.retry(operationResponse);
}
}
exports.ExponentialRetryPolicyFilter = ExponentialRetryPolicyFilter;
//# sourceMappingURL=exponentialRetryPolicyFilter.js.map

1
dist/lib/filters/exponentialRetryPolicyFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"exponentialRetryPolicyFilter.js","sourceRoot":"","sources":["../../../lib/filters/exponentialRetryPolicyFilter.ts"],"names":[],"mappings":"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"}

21
dist/lib/filters/logFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const baseFilter_1 = require("./baseFilter");
class LogFilter extends baseFilter_1.BaseFilter {
constructor(logger = console.log) {
super();
this.logger = logger;
}
after(operationResponse) {
const self = this;
self.logger(`>> Request: ${JSON.stringify(operationResponse.request, undefined, 2)}`);
self.logger(`>> Response status code: ${operationResponse.response.status}`);
const responseBody = operationResponse.bodyAsText;
self.logger(`>> Body: ${responseBody}`);
return Promise.resolve(operationResponse);
}
}
exports.LogFilter = LogFilter;
//# sourceMappingURL=logFilter.js.map

1
dist/lib/filters/logFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"logFilter.js","sourceRoot":"","sources":["../../../lib/filters/logFilter.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,6CAA0C;AAG1C,eAAuB,SAAQ,uBAAU;IAIvC,YAAY,SAAc,OAAO,CAAC,GAAG;QACnC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,iBAAwC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,MAAM,CAAC,4BAA4B,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,MAAM,YAAY,GAAG,iBAAiB,CAAC,UAAU,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC;CACF;AAjBD,8BAiBC"}

52
dist/lib/filters/msRestUserAgentFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,52 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const baseFilter_1 = require("./baseFilter");
const constants_1 = require("../util/constants");
const os = require("os");
const isNode = require("detect-node");
const HeaderConstants = constants_1.Constants.HeaderConstants;
class MsRestUserAgentFilter extends baseFilter_1.BaseFilter {
constructor(userAgentInfo) {
super();
this.userAgentInfo = userAgentInfo;
}
tagRequest(request) {
if (isNode) {
const osInfo = `(${os.arch()}-${os.type()}-${os.release()})`;
if (this.userAgentInfo.indexOf(osInfo) === -1) {
this.userAgentInfo.unshift(osInfo);
}
const runtimeInfo = `Node/${process.version}`;
if (this.userAgentInfo.indexOf(runtimeInfo) === -1) {
this.userAgentInfo.unshift(runtimeInfo);
}
const nodeSDKSignature = `Azure-SDK-For-Node`;
if (this.userAgentInfo.indexOf(nodeSDKSignature) === -1) {
const azureRuntime = `ms-rest-azure`;
let insertIndex = this.userAgentInfo.indexOf(azureRuntime);
// insert after azureRuntime, otherwise, insert last.
insertIndex = insertIndex < 0 ? this.userAgentInfo.length : insertIndex + 1;
this.userAgentInfo.splice(insertIndex, 0, nodeSDKSignature);
}
if (!request.headers)
request.headers = {};
request.headers[HeaderConstants.USER_AGENT] = this.userAgentInfo.join(" ");
}
return Promise.resolve(request);
}
before(request) {
const self = this;
if (!request.headers)
request.headers = {};
if (!request.headers[HeaderConstants.USER_AGENT]) {
return self.tagRequest(request);
}
else {
return Promise.resolve(request);
}
}
}
exports.MsRestUserAgentFilter = MsRestUserAgentFilter;
//# sourceMappingURL=msRestUserAgentFilter.js.map

1
dist/lib/filters/msRestUserAgentFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"msRestUserAgentFilter.js","sourceRoot":"","sources":["../../../lib/filters/msRestUserAgentFilter.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,6CAA0C;AAE1C,iDAA8C;AAC9C,yBAAyB;AAEzB,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,qBAAS,CAAC,eAAe,CAAC;AAElD,2BAAmC,SAAQ,uBAAU;IAInD,YAAY,aAA4B;QACtC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED,UAAU,CAAC,OAAoB;QAC7B,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC;YAC7D,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;YAED,MAAM,WAAW,GAAG,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YAC9C,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;YAC9C,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,MAAM,YAAY,GAAG,eAAe,CAAC;gBAErC,IAAI,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC3D,qDAAqD;gBACrD,WAAW,GAAG,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,WAAW,GAAG,CAAC,CAAC;gBAC5E,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;YAC9D,CAAC;YACD,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;YAC3C,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,OAAoB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;YAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;QAC3C,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;CACF;AA7CD,sDA6CC"}

59
dist/lib/filters/redirectFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,59 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
const baseFilter_1 = require("./baseFilter");
const utils = require("../util/utils");
const parse = require("url-parse");
class RedirectFilter extends baseFilter_1.BaseFilter {
constructor(maximumRetries = 20) {
super();
this.maximumRetries = maximumRetries;
}
handleRedirect(operationResponse, currentRetries) {
return __awaiter(this, void 0, void 0, function* () {
const request = operationResponse.request;
const response = operationResponse.response;
if (response && response.headers && response.headers.get("location") &&
(response.status === 300 || response.status === 307 || (response.status === 303 && request.method === "POST")) &&
(!this.maximumRetries || currentRetries < this.maximumRetries)) {
if (parse(response.headers.get("location")).hostname) {
request.url = response.headers.get("location");
}
else {
const urlObject = parse(request.url);
urlObject.set("pathname", response.headers.get("location"));
request.url = urlObject.href;
}
// POST request with Status code 303 should be converted into a
// redirected GET request if the redirect url is present in the location header
if (response.status === 303) {
request.method = "GET";
}
let res;
try {
res = yield utils.dispatchRequest(request);
currentRetries++;
}
catch (err) {
return Promise.reject(err);
}
return this.handleRedirect(res, currentRetries);
}
return Promise.resolve(operationResponse);
});
}
after(operationResponse) {
return this.handleRedirect(operationResponse, 0);
}
}
exports.RedirectFilter = RedirectFilter;
//# sourceMappingURL=redirectFilter.js.map

1
dist/lib/filters/redirectFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"redirectFilter.js","sourceRoot":"","sources":["../../../lib/filters/redirectFilter.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,4DAA4D;AAC5D,+FAA+F;AAC/F,6CAA0C;AAE1C,uCAAuC;AAEvC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAEnC,oBAA4B,SAAQ,uBAAU;IAI5C,YAAY,cAAc,GAAG,EAAE;QAC7B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAEK,cAAc,CAAC,iBAAwC,EAAE,cAAsB;;YACnF,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC;YAC5C,EAAE,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;gBAClE,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;gBAC9G,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;gBACjE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACrD,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAW,CAAC;gBAC3D,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBACrC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAW,CAAC,CAAC;oBACtE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;gBAC/B,CAAC;gBACD,+DAA+D;gBAC/D,+EAA+E;gBAC/E,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC5B,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;gBACzB,CAAC;gBACD,IAAI,GAA0B,CAAC;gBAC/B,IAAI,CAAC;oBACH,GAAG,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;oBAC3C,cAAc,EAAE,CAAC;gBACnB,CAAC;gBAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBACb,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7B,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC5C,CAAC;KAAA;IAED,KAAK,CAAC,iBAAwC;QAC5C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;CACF;AA1CD,wCA0CC"}

191
dist/lib/filters/rpRegistrationFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,191 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
const baseFilter_1 = require("./baseFilter");
const utils = require("../util/utils");
let retryTimeout = 30;
class RPRegistrationFilter extends baseFilter_1.BaseFilter {
constructor(retryTimeout = 30) {
super();
retryTimeout = retryTimeout;
}
after(operationResponse) {
return __awaiter(this, void 0, void 0, function* () {
let rpName, urlPrefix;
const options = operationResponse.request;
if (operationResponse.response.status === 409) {
rpName = this.checkRPNotRegisteredError(operationResponse.bodyAsText);
}
if (rpName) {
urlPrefix = this.extractSubscriptionUrl(options.url);
let registrationStatus = false;
try {
registrationStatus = yield this.registerRP(urlPrefix, rpName, options);
}
catch (err) {
// Autoregistration of ${provider} failed for some reason. We will not return this error
// instead will return the initial response with 409 status code back to the user.
// do nothing here as we are returning the original response at the end of this method.
}
if (registrationStatus) {
// Retry the original request. We have to change the x-ms-client-request-id
// otherwise Azure endpoint will return the initial 409 (cached) response.
options.headers["x-ms-client-request-id"] = utils.generateUuid();
let finalRes;
try {
finalRes = yield utils.dispatchRequest(options);
}
catch (err) {
return Promise.reject(err);
}
return Promise.resolve(finalRes);
}
}
return Promise.resolve(operationResponse);
});
}
/**
* Reuses the headers of the original request and url (if specified).
* @param {WebResource} originalRequest The original request
* @param {boolean} reuseUrlToo Should the url from the original request be reused as well. Default false.
* @returns {object} reqOptions - A new request object with desired headers.
*/
getRequestEssentials(originalRequest, reuseUrlToo = false) {
const reqOptions = {
headers: {}
};
if (reuseUrlToo) {
reqOptions.url = originalRequest.url;
}
// Copy over the original request headers. This will get us the auth token and other useful stuff from
// the original request header. Thus making it easier to make requests from this filter.
for (const h in originalRequest.headers) {
reqOptions.headers[h] = originalRequest.headers[h];
}
// We have to change the x-ms-client-request-id otherwise Azure endpoint
// will return the initial 409 (cached) response.
reqOptions.headers["x-ms-client-request-id"] = utils.generateUuid();
// Set content-type to application/json
reqOptions.headers["Content-Type"] = "application/json; charset=utf-8";
return reqOptions;
}
/**
* Validates the error code and message associated with 409 response status code. If it matches to that of
* RP not registered then it returns the name of the RP else returns undefined.
* @param {string} body - The response body received after making the original request.
* @returns {string} result The name of the RP if condition is satisfied else undefined.
*/
checkRPNotRegisteredError(body) {
let result, responseBody;
if (body) {
try {
responseBody = JSON.parse(body);
}
catch (err) {
// do nothing;
}
if (responseBody && responseBody.error && responseBody.error.message &&
responseBody.error.code && responseBody.error.code === "MissingSubscriptionRegistration") {
const matchRes = responseBody.error.message.match(/.*'(.*)'/i);
if (matchRes) {
result = matchRes.pop();
}
}
}
return result;
}
/**
* Extracts the first part of the URL, just after subscription:
* https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
* @param {string} url - The original request url
* @returns {string} urlPrefix The url prefix as explained above.
*/
extractSubscriptionUrl(url) {
let result;
const matchRes = url.match(/.*\/subscriptions\/[a-f0-9-]+\//ig);
if (matchRes && matchRes[0]) {
result = matchRes[0];
}
else {
throw new Error(`Unable to extract subscriptionId from the given url - ${url}.`);
}
return result;
}
/**
* Registers the given provider.
* @param {string} urlPrefix - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
* @param {string} provider - The provider name to be registered.
* @param {object} originalRequest - The original request sent by the user that returned a 409 response
* with a message that the provider is not registered.
* @param {registrationCallback} callback - The callback that handles the RP registration
*/
registerRP(urlPrefix, provider, originalRequest) {
return __awaiter(this, void 0, void 0, function* () {
const postUrl = `${urlPrefix}providers/${provider}/register?api-version=2016-02-01`;
const getUrl = `${urlPrefix}providers/${provider}?api-version=2016-02-01`;
const reqOptions = this.getRequestEssentials(originalRequest);
reqOptions.method = "POST";
reqOptions.url = postUrl;
let res;
try {
res = yield utils.dispatchRequest(reqOptions);
}
catch (err) {
return Promise.reject(err);
}
if (res.response.status !== 200) {
return Promise.reject(new Error(`Autoregistration of ${provider} failed. Please try registering manually.`));
}
let statusRes = false;
try {
statusRes = yield this.getRegistrationStatus(getUrl, originalRequest);
}
catch (err) {
return Promise.reject(err);
}
return Promise.resolve(statusRes);
});
}
/**
* Polls the registration status of the provider that was registered. Polling happens at an interval of 30 seconds.
* Polling will happen till the registrationState property of the response body is "Registered".
* @param {string} url - The request url for polling
* @param {object} originalRequest - The original request sent by the user that returned a 409 response
* with a message that the provider is not registered.
* @returns {Promise<boolean>} promise - True if RP Registration is successful.
*/
getRegistrationStatus(url, originalRequest) {
return __awaiter(this, void 0, void 0, function* () {
const reqOptions = this.getRequestEssentials(originalRequest);
let res;
let result = false;
reqOptions.url = url;
reqOptions.method = "GET";
try {
res = yield utils.dispatchRequest(reqOptions);
}
catch (err) {
return Promise.reject(err);
}
const obj = res.bodyAsJson;
if (res.bodyAsJson && obj.registrationState && obj.registrationState === "Registered") {
result = true;
}
else {
setTimeout(() => { return this.getRegistrationStatus(url, originalRequest); }, retryTimeout * 1000);
}
return Promise.resolve(result);
});
}
}
exports.RPRegistrationFilter = RPRegistrationFilter;
//# sourceMappingURL=rpRegistrationFilter.js.map

1
dist/lib/filters/rpRegistrationFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"rpRegistrationFilter.js","sourceRoot":"","sources":["../../../lib/filters/rpRegistrationFilter.ts"],"names":[],"mappings":"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"}

17
dist/lib/filters/signingFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const baseFilter_1 = require("./baseFilter");
class SigningFilter extends baseFilter_1.BaseFilter {
constructor(authenticationProvider) {
super();
this.authenticationProvider = authenticationProvider;
}
before(request) {
const self = this;
return self.authenticationProvider.signRequest(request);
}
}
exports.SigningFilter = SigningFilter;
//# sourceMappingURL=signingFilter.js.map

1
dist/lib/filters/signingFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"signingFilter.js","sourceRoot":"","sources":["../../../lib/filters/signingFilter.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,6CAA0C;AAI1C,mBAA2B,SAAQ,uBAAU;IAI3C,YAAY,sBAAgD;QAC1D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,OAAoB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AAbD,sCAaC"}

115
dist/lib/filters/systemErrorRetryPolicyFilter.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,115 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const baseFilter_1 = require("./baseFilter");
const utils = require("../util/utils");
/**
* @class
* Instantiates a new "ExponentialRetryPolicyFilter" instance.
*
* @constructor
* @param {number} retryCount The client retry count.
* @param {number} retryInterval The client retry interval, in milliseconds.
* @param {number} minRetryInterval The minimum retry interval, in milliseconds.
* @param {number} maxRetryInterval The maximum retry interval, in milliseconds.
*/
class SystemErrorRetryPolicyFilter extends baseFilter_1.BaseFilter {
constructor(retryCount, retryInterval, minRetryInterval, maxRetryInterval) {
super();
this.DEFAULT_CLIENT_RETRY_INTERVAL = 1000 * 30;
this.DEFAULT_CLIENT_RETRY_COUNT = 3;
this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 90;
this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL = 1000 * 3;
this.retryCount = typeof retryCount === "number" ? retryCount : this.DEFAULT_CLIENT_RETRY_COUNT;
this.retryInterval = typeof retryInterval === "number" ? retryInterval : this.DEFAULT_CLIENT_RETRY_INTERVAL;
this.minRetryInterval = typeof minRetryInterval === "number" ? minRetryInterval : this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL;
this.maxRetryInterval = typeof maxRetryInterval === "number" ? maxRetryInterval : this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
}
/**
* Determines if the operation should be retried and how long to wait until the next retry.
*
* @param {number} statusCode The HTTP status code.
* @param {RetryData} retryData The retry data.
* @return {boolean} True if the operation qualifies for a retry; false otherwise.
*/
shouldRetry(retryData) {
let currentCount;
if (!retryData) {
throw new Error("retryData for the SystemErrorRetryPolicyFilter cannot be null.");
}
else {
currentCount = (retryData && retryData.retryCount);
}
return (currentCount < this.retryCount);
}
/**
* Updates the retry data for the next attempt.
*
* @param {RetryData} retryData The retry data.
* @param {object} err The operation"s error, if any.
*/
updateRetryData(retryData, err) {
if (!retryData) {
retryData = {
retryCount: 0,
retryInterval: 0
};
}
if (err) {
if (retryData.error) {
err.innerError = retryData.error;
}
retryData.error = err;
}
// Adjust retry count
retryData.retryCount++;
// Adjust retry interval
let incrementDelta = Math.pow(2, retryData.retryCount) - 1;
const boundedRandDelta = this.retryInterval * 0.8 +
Math.floor(Math.random() * (this.retryInterval * 1.2 - this.retryInterval * 0.8));
incrementDelta *= boundedRandDelta;
retryData.retryInterval = Math.min(this.minRetryInterval + incrementDelta, this.maxRetryInterval);
return retryData;
}
retry(operationResponse, retryData, err) {
return __awaiter(this, void 0, void 0, function* () {
const self = this;
retryData = self.updateRetryData(retryData, err);
if (err && err.code && self.shouldRetry(retryData) &&
(err.code === "ETIMEDOUT" || err.code === "ESOCKETTIMEDOUT" || err.code === "ECONNREFUSED" ||
err.code === "ECONNRESET" || err.code === "ENOENT")) {
// If previous operation ended with an error and the policy allows a retry, do that
try {
yield utils.delay(retryData.retryInterval);
const res = yield utils.dispatchRequest(operationResponse.request);
return self.retry(res, retryData, err);
}
catch (err) {
return self.retry(operationResponse, retryData, err);
}
}
else {
if (!utils.objectIsNull(err)) {
// If the operation failed in the end, return all errors instead of just the last one
err = retryData.error;
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
}
});
}
after(operationResponse) {
return this.retry(operationResponse); // See: https://github.com/Microsoft/TypeScript/issues/7426
}
}
exports.SystemErrorRetryPolicyFilter = SystemErrorRetryPolicyFilter;
//# sourceMappingURL=systemErrorRetryPolicyFilter.js.map

1
dist/lib/filters/systemErrorRetryPolicyFilter.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"systemErrorRetryPolicyFilter.js","sourceRoot":"","sources":["../../../lib/filters/systemErrorRetryPolicyFilter.ts"],"names":[],"mappings":"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"}

36
dist/lib/httpOperationResponse.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Wrapper object for http request and response. Deserialized object is stored in
* the `body` property.
* @class
* Initializes a new instance of the HttpOperationResponse class.
* @constructor
*/
class HttpOperationResponse {
constructor(request, response, body) {
/**
* Reference to the original request object.
* [WebResource] object.
* @type {object}
*/
this.request = request;
/**
* Reference to the original response object.
* [ServerResponse] object.
* @type {object}
*/
this.response = response;
/**
* The response object.
* @type {object}
*/
this.bodyAsStream = body;
this.bodyAsText = null;
this.bodyAsJson = null;
}
}
exports.HttpOperationResponse = HttpOperationResponse;
//# sourceMappingURL=httpOperationResponse.js.map

1
dist/lib/httpOperationResponse.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"httpOperationResponse.js","sourceRoot":"","sources":["../../lib/httpOperationResponse.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAI/F;;;;;;GAMG;AACH;IAsBE,YAAY,OAAoB,EAAE,QAAkB,EAAE,IAA2B;QAC/E;;;;WAIG;QACH,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB;;;;WAIG;QACH,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB;;;WAGG;QACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;CACF;AA7CD,sDA6CC"}

53
dist/lib/msRest.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,53 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const webResource_1 = require("./webResource");
exports.WebResource = webResource_1.WebResource;
const httpOperationResponse_1 = require("./httpOperationResponse");
exports.HttpOperationResponse = httpOperationResponse_1.HttpOperationResponse;
const restError_1 = require("./restError");
exports.RestError = restError_1.RestError;
const serviceClient_1 = require("./serviceClient");
exports.ServiceClient = serviceClient_1.ServiceClient;
const constants_1 = require("./util/constants");
exports.Constants = constants_1.Constants;
const requestPipeline_1 = require("./requestPipeline");
exports.RequestPipeline = requestPipeline_1.RequestPipeline;
const logFilter_1 = require("./filters/logFilter");
exports.LogFilter = logFilter_1.LogFilter;
const baseFilter_1 = require("./filters/baseFilter");
exports.BaseFilter = baseFilter_1.BaseFilter;
const exponentialRetryPolicyFilter_1 = require("./filters/exponentialRetryPolicyFilter");
exports.ExponentialRetryPolicyFilter = exponentialRetryPolicyFilter_1.ExponentialRetryPolicyFilter;
const systemErrorRetryPolicyFilter_1 = require("./filters/systemErrorRetryPolicyFilter");
exports.SystemErrorRetryPolicyFilter = systemErrorRetryPolicyFilter_1.SystemErrorRetryPolicyFilter;
const redirectFilter_1 = require("./filters/redirectFilter");
exports.RedirectFilter = redirectFilter_1.RedirectFilter;
const signingFilter_1 = require("./filters/signingFilter");
exports.SigningFilter = signingFilter_1.SigningFilter;
const msRestUserAgentFilter_1 = require("./filters/msRestUserAgentFilter");
exports.MsRestUserAgentFilter = msRestUserAgentFilter_1.MsRestUserAgentFilter;
const serializer_1 = require("./serializer");
exports.MapperType = serializer_1.MapperType;
exports.Serializer = serializer_1.Serializer;
exports.serializeObject = serializer_1.serializeObject;
const utils_1 = require("./util/utils");
exports.stripRequest = utils_1.stripRequest;
exports.stripResponse = utils_1.stripResponse;
exports.delay = utils_1.delay;
exports.executePromisesSequentially = utils_1.executePromisesSequentially;
exports.generateUuid = utils_1.generateUuid;
exports.encodeUri = utils_1.encodeUri;
exports.promiseToCallback = utils_1.promiseToCallback;
exports.promiseToServiceCallback = utils_1.promiseToServiceCallback;
exports.isValidUuid = utils_1.isValidUuid;
exports.dispatchRequest = utils_1.dispatchRequest;
// Credentials
const tokenCredentials_1 = require("./credentials/tokenCredentials");
exports.TokenCredentials = tokenCredentials_1.TokenCredentials;
const basicAuthenticationCredentials_1 = require("./credentials/basicAuthenticationCredentials");
exports.BasicAuthenticationCredentials = basicAuthenticationCredentials_1.BasicAuthenticationCredentials;
const isStream = require("is-stream");
exports.isStream = isStream;
//# sourceMappingURL=msRest.js.map

1
dist/lib/msRest.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"msRest.js","sourceRoot":"","sources":["../../lib/msRest.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAE/F,+CAAoH;AAiClH,sBAjCO,yBAAW,CAiCP;AAhCb,mEAAgE;AAgCG,gCAhC1D,6CAAqB,CAgC0D;AA/BxF,2CAAwC;AAkCA,oBAlC/B,qBAAS,CAkC+B;AAjCjD,mDAAsE;AA8BoB,wBA9BjF,6BAAa,CA8BiF;AA7BvG,gDAA6C;AA6B4D,oBA7BhG,qBAAS,CA6BgG;AA5BlH,uDAAqE;AA4B+C,0BA5B3G,iCAAe,CA4B2G;AA3BnI,mDAAgD;AA4BwB,oBA5B/D,qBAAS,CA4B+D;AA3BjF,qDAAkD;AA2BU,qBA3BnD,uBAAU,CA2BmD;AA1BtE,yFAAsF;AA0BmB,uCA1BhG,2DAA4B,CA0BgG;AAzBrI,yFAAsF;AA0BpF,uCA1BO,2DAA4B,CA0BP;AAzB9B,6DAA0D;AA2BH,yBA3B9C,+BAAc,CA2B8C;AA1BrE,2DAAwD;AAwBxB,wBAxBvB,6BAAa,CAwBuB;AAvB7C,2EAAwE;AAuBzB,gCAvBtC,6CAAqB,CAuBsC;AAtBpE,6CAIsB;AAcsE,qBAhBvE,uBAAU,CAgBuE;AACvC,qBAhB7C,uBAAU,CAgB6C;AAAE,0BAhB1B,4BAAe,CAgB0B;AAd1F,wCAIsB;AAagD,uBAhBpE,oBAAY,CAgBoE;AAAE,wBAhBpE,qBAAa,CAgBoE;AAAE,gBAhBpE,aAAK,CAgBoE;AAAE,sCAfxG,mCAA2B,CAewG;AACnI,uBAhB6B,oBAAY,CAgB7B;AAAe,oBAhBgB,iBAAS,CAgBhB;AAAmE,4BAfvG,yBAAiB,CAeuG;AACxH,mCAhBmB,gCAAwB,CAgBnB;AADV,sBAf+B,mBAAW,CAe/B;AACW,0BAhBsB,uBAAe,CAgBtB;AAbrD,cAAc;AACd,qEAAkE;AAO0B,2BAPnF,mCAAgB,CAOmF;AAN5G,iGAA8F;AAQ5F,yCARO,+DAA8B,CAQP;AANhC,sCAAsC;AASV,4BAAQ"}

51
dist/lib/requestPipeline.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,51 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const utils = require("./util/utils");
class RequestPipeline {
constructor(filters, requestOptions) {
this.filters = filters || [];
this.requestOptions = requestOptions || {};
}
addFilter(f) {
this.filters.push(f);
return;
}
create() {
const self = this;
let pipeline = [];
if (self.filters && self.filters.length) {
const beforeFilters = [];
const afterFilters = [];
for (let i = 0; i < self.filters.length; i++) {
const filter = self.filters[i];
if (filter.before && typeof filter.before === "function") {
beforeFilters.push(filter.before.bind(filter));
}
if (filter.after && typeof filter.after === "function") {
afterFilters.push(filter.after.bind(filter));
}
} // end-of-for-loop
// add the request sink
beforeFilters.push(self.requestSink.bind(self));
pipeline = beforeFilters.concat(afterFilters);
}
else {
pipeline.push(self.requestSink.bind(self));
}
const requestFun = (request) => {
if (!request.headers)
request.headers = {};
return utils.executePromisesSequentially(pipeline, request);
};
return requestFun;
}
requestSink(options) {
if (this.requestOptions.method)
delete this.requestOptions.method;
return utils.dispatchRequest(options);
}
}
exports.RequestPipeline = RequestPipeline;
//# sourceMappingURL=requestPipeline.js.map

1
dist/lib/requestPipeline.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"requestPipeline.js","sourceRoot":"","sources":["../../lib/requestPipeline.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAK/F,sCAAsC;AAKtC;IAIE,YAAY,OAAsB,EAAE,cAA4B;QAC9D,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,cAAc,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,SAAS,CAAC,CAAa;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC;IACT,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,IAAI,QAAQ,GAAoB,EAAE,CAAC;QACnC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,MAAM,aAAa,GAAoB,EAAE,CAAC;YAC1C,MAAM,YAAY,GAAoB,EAAE,CAAC;YACzC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC/B,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;oBACzD,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjD,CAAC;gBACD,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC;oBACvD,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC,CAAA,kBAAkB;YACnB,uBAAuB;YACvB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,UAAU,GAAoB,CAAC,OAAoB;YACvD,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9D,CAAC,CAAC;QACF,MAAM,CAAC,UAAU,CAAC;IACpB,CAAC;IAED,WAAW,CAAC,OAAoB;QAC9B,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;QAClE,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;CACF;AA9CD,0CA8CC"}

16
dist/lib/restError.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,16 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
class RestError extends Error {
constructor(message, code, statusCode, request, response, body) {
super(message);
this.code = code;
this.statusCode = statusCode;
this.request = request;
this.response = response;
this.body = body;
}
}
exports.RestError = RestError;
//# sourceMappingURL=restError.js.map

1
dist/lib/restError.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"restError.js","sourceRoot":"","sources":["../../lib/restError.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAI/F,eAAuB,SAAQ,KAAK;IAMlC,YAAY,OAAe,EAAE,IAAa,EAAE,UAAmB,EAAE,OAAqB,EAAE,QAAmB,EAAE,IAAU;QACrH,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAdD,8BAcC"}

703
dist/lib/serializer.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,703 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const utils = require("./util/utils");
const moment_1 = require("moment");
const isBuffer = require("is-buffer");
const isStream = require("is-stream");
class Serializer {
constructor(mappers) {
this.modelMappers = mappers;
}
validateConstraints(mapper, value, objectName) {
if (mapper.constraints && (value !== null || value !== undefined)) {
Object.keys(mapper.constraints).forEach((constraintType) => {
if (constraintType.match(/^ExclusiveMaximum$/ig) !== null) {
if (value >= mapper.constraints.ExclusiveMaximum) {
throw new Error(`"${objectName}" with value "${value}" should satify the constraint "ExclusiveMaximum": ${mapper.constraints.ExclusiveMaximum}.`);
}
}
else if (constraintType.match(/^ExclusiveMinimum$/ig) !== null) {
if (value <= mapper.constraints.ExclusiveMinimum) {
throw new Error(`${objectName} " with value "${value} " should satify the constraint "ExclusiveMinimum": ${mapper.constraints.ExclusiveMinimum}.`);
}
}
else if (constraintType.match(/^InclusiveMaximum$/ig) !== null) {
if (value > mapper.constraints.InclusiveMaximum) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "InclusiveMaximum": ${mapper.constraints.InclusiveMaximum}.`);
}
}
else if (constraintType.match(/^InclusiveMinimum$/ig) !== null) {
if (value < mapper.constraints.InclusiveMinimum) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "InclusiveMinimum": ${mapper.constraints.InclusiveMinimum}.`);
}
}
else if (constraintType.match(/^MaxItems$/ig) !== null) {
if (value.length > mapper.constraints.MaxItems) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MaxItems": ${mapper.constraints.MaxItems}.`);
}
}
else if (constraintType.match(/^MaxLength$/ig) !== null) {
if (value.length > mapper.constraints.MaxLength) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MaxLength": ${mapper.constraints.MaxLength}.`);
}
}
else if (constraintType.match(/^MinItems$/ig) !== null) {
if (value.length < mapper.constraints.MinItems) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MinItems": ${mapper.constraints.MinItems}.`);
}
}
else if (constraintType.match(/^MinLength$/ig) !== null) {
if (value.length < mapper.constraints.MinLength) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MinLength": ${mapper.constraints.MinLength}.`);
}
}
else if (constraintType.match(/^MultipleOf$/ig) !== null) {
if (value.length % mapper.constraints.MultipleOf !== 0) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MultipleOf": ${mapper.constraints.MultipleOf}.`);
}
}
else if (constraintType.match(/^Pattern$/ig) !== null) {
if (value.match(mapper.constraints.Pattern.split("/").join("\/")) === null) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "Pattern": ${mapper.constraints.Pattern}.`);
}
}
else if (constraintType.match(/^UniqueItems/ig) !== null) {
if (mapper.constraints.UniqueItems) {
if (value.length !== value.filter((item, i, ar) => { {
return ar.indexOf(item) === i;
} }).length) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "UniqueItems": ${mapper.constraints.UniqueItems}`);
}
}
}
});
}
}
trimEnd(str, ch) {
let len = str.length;
while ((len - 1) >= 0 && str[len - 1] === ch) {
--len;
}
return str.substr(0, len);
}
bufferToBase64Url(buffer) {
if (!buffer) {
return undefined;
}
if (!isBuffer(buffer)) {
throw new Error(`Please provide an input of type Buffer for converting to Base64Url.`);
}
// Buffer to Base64.
const str = buffer.toString("base64");
// Base64 to Base64Url.
return this.trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_");
}
base64UrlToBuffer(str) {
if (!str) {
return undefined;
}
if (str && typeof str.valueOf() !== "string") {
throw new Error("Please provide an input of type string for converting to Buffer");
}
// Base64Url to Base64.
str = str.replace(/\-/g, "+").replace(/\_/g, "/");
// Base64 to Buffer.
return Buffer.from(str, "base64");
}
splitSerializeName(prop) {
const classes = [];
let partialclass = "";
const subwords = prop.split(".");
subwords.forEach((item) => {
if (item.charAt(item.length - 1) === "\\") {
partialclass += item.substr(0, item.length - 1) + ".";
}
else {
partialclass += item;
classes.push(partialclass);
partialclass = "";
}
});
return classes;
}
dateToUnixTime(d) {
if (!d) {
return undefined;
}
if (typeof d.valueOf() === "string") {
d = new Date(d);
}
return Math.floor(d.getTime() / 1000);
}
unixTimeToDate(n) {
if (!n) {
return undefined;
}
return new Date(n * 1000);
}
serializeBasicTypes(typeName, objectName, value) {
if (value !== null && value !== undefined) {
if (typeName.match(/^Number$/ig) !== null) {
if (typeof value !== "number") {
throw new Error(`${objectName} with value ${value} must be of type number.`);
}
}
else if (typeName.match(/^String$/ig) !== null) {
if (typeof value.valueOf() !== "string") {
throw new Error(`${objectName} with value "${value}" must be of type string.`);
}
}
else if (typeName.match(/^Uuid$/ig) !== null) {
if (!(typeof value.valueOf() === "string" && utils.isValidUuid(value))) {
throw new Error(`${objectName} with value "${value}" must be of type string and a valid uuid.`);
}
}
else if (typeName.match(/^Boolean$/ig) !== null) {
if (typeof value !== "boolean") {
throw new Error(`${objectName} with value ${value} must be of type boolean.`);
}
}
else if (typeName.match(/^Object$/ig) !== null) {
if (typeof value !== "object") {
throw new Error(`${objectName} must be of type object.`);
}
}
else if (typeName.match(/^Stream$/ig) !== null) {
if (!isStream(value)) {
throw new Error(`${objectName} must be of type stream.`);
}
}
}
return value;
}
serializeEnumType(objectName, allowedValues, value) {
if (!allowedValues) {
throw new Error(`Please provide a set of allowedValues to validate ${objectName} as an Enum Type.`);
}
const isPresent = allowedValues.some((item) => {
if (typeof item.valueOf() === "string") {
return item.toLowerCase() === value.toLowerCase();
}
return item === value;
});
if (!isPresent) {
throw new Error(`${value} is not a valid value for ${objectName}. The valid values are: ${JSON.stringify(allowedValues)}.`);
}
return value;
}
serializeBufferType(objectName, value) {
if (value !== null && value !== undefined) {
if (!isBuffer(value)) {
throw new Error(`${objectName} must be of type Buffer.`);
}
value = value.toString("base64");
}
return value;
}
serializeBase64UrlType(objectName, value) {
if (value !== null && value !== undefined) {
if (!isBuffer(value)) {
throw new Error(`${objectName} must be of type Buffer.`);
}
value = this.bufferToBase64Url(value);
}
return value;
}
serializeDateTypes(typeName, value, objectName) {
if (value !== null && value !== undefined) {
if (typeName.match(/^Date$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`);
}
value = (value instanceof Date) ? value.toISOString().substring(0, 10) : new Date(value).toISOString().substring(0, 10);
}
else if (typeName.match(/^DateTime$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`);
}
value = (value instanceof Date) ? value.toISOString() : new Date(value).toISOString();
}
else if (typeName.match(/^DateTimeRfc1123$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123 format.`);
}
value = (value instanceof Date) ? value.toUTCString() : new Date(value).toUTCString();
}
else if (typeName.match(/^UnixTime$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123/ISO8601 format ` +
`for it to be serialized in UnixTime/Epoch format.`);
}
value = this.dateToUnixTime(value);
}
else if (typeName.match(/^TimeSpan$/ig) !== null) {
if (!moment_1.isDuration(value)) {
throw new Error(`${objectName} must be a TimeSpan/Duration.`);
}
value = value.toISOString();
}
}
return value;
}
serializeSequenceType(mapper, object, objectName) {
if (!Array.isArray(object)) {
throw new Error(`${objectName} must be of type Array.`);
}
if (!mapper.type.element || typeof mapper.type.element !== "object") {
throw new Error(`element" metadata for an Array must be defined in the ` +
`mapper and it must of type "object" in ${objectName}.`);
}
const tempArray = [];
for (let i = 0; i < object.length; i++) {
tempArray[i] = this.serialize(mapper.type.element, object[i], objectName);
}
return tempArray;
}
serializeDictionaryType(mapper, object, objectName) {
if (typeof object !== "object") {
throw new Error(`${objectName} must be of type object.`);
}
if (!mapper.type.value || typeof mapper.type.value !== "object") {
throw new Error(`"value" metadata for a Dictionary must be defined in the ` +
`mapper and it must of type "object" in ${objectName}.`);
}
const tempDictionary = {};
for (const key in object) {
if (object.hasOwnProperty(key)) {
tempDictionary[key] = this.serialize(mapper.type.value, object[key], objectName);
}
}
return tempDictionary;
}
serializeCompositeType(mapper, object, objectName) {
// check for polymorphic discriminator
if (mapper.type.polymorphicDiscriminator) {
mapper = this.getPolymorphicMapper(mapper, object, objectName, "serialize");
}
const payload = {};
let modelMapper = {
required: false,
serializedName: "serializedName",
type: {
name: "Composite",
className: "className",
modelProperties: {}
}
};
if (object !== null && object !== undefined) {
let modelProps = mapper.type.modelProperties;
if (!modelProps) {
if (!mapper.type.className) {
throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper, undefined, 2)}".`);
}
// get the mapper if modelProperties of the CompositeType is not present and
// then get the modelProperties from it.
modelMapper = this.modelMappers[mapper.type.className];
if (!modelMapper) {
throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}".`);
}
modelProps = modelMapper.type.modelProperties;
if (!modelProps) {
throw new Error(`modelProperties cannot be null or undefined in the ` +
`mapper "${JSON.stringify(modelMapper)}" of type "${mapper.type.className}" for object "${objectName}".`);
}
}
for (const key in modelProps) {
if (modelProps.hasOwnProperty(key)) {
const paths = this.splitSerializeName(modelProps[key].serializedName);
const propName = paths.pop();
let parentObject = payload;
paths.forEach((pathName) => {
const childObject = parentObject[pathName];
if ((childObject === null || childObject === undefined) && (object[key] !== null && object[key] !== undefined)) {
parentObject[pathName] = {};
}
parentObject = parentObject[pathName];
});
// make sure required properties of the CompositeType are present
if (modelProps[key].required && !modelProps[key].isConstant) {
if (object[key] === null || object[key] === undefined) {
throw new Error(`${key}" cannot be null or undefined in "${objectName}".`);
}
}
// make sure that readOnly properties are not sent on the wire
if (modelProps[key].readOnly) {
continue;
}
// serialize the property if it is present in the provided object instance
if (((parentObject !== null && parentObject !== undefined) && (modelProps[key].defaultValue !== null && modelProps[key].defaultValue !== undefined)) ||
(object[key] !== null && object[key] !== undefined)) {
let propertyObjectName = objectName;
if (modelProps[key].serializedName !== "")
propertyObjectName = objectName + "." + modelProps[key].serializedName;
const propertyMapper = modelProps[key];
const serializedValue = this.serialize(propertyMapper, object[key], propertyObjectName);
if (propName !== null && propName !== undefined)
parentObject[propName] = serializedValue;
}
}
}
return payload;
}
return object;
}
/**
* Serialize the given object based on its metadata defined in the mapper
*
* @param {Mapper} mapper The mapper which defines the metadata of the serializable object
*
* @param {object|string|Array|number|boolean|Date|stream} object A valid Javascript object to be serialized
*
* @param {string} objectName Name of the serialized object
*
* @returns {object|string|Array|number|boolean|Date|stream} A valid serialized Javascript object
*/
serialize(mapper, object, objectName) {
let payload = {};
const mapperType = mapper.type.name;
if (!objectName)
objectName = mapper.serializedName;
if (mapperType.match(/^Sequence$/ig) !== null)
payload = [];
// Throw if required and object is null or undefined
if (mapper.required && (object === null || object === undefined) && !mapper.isConstant) {
throw new Error(`${objectName} cannot be null or undefined.`);
}
// Set Defaults
if ((mapper.defaultValue !== null && mapper.defaultValue !== undefined) &&
(object === null || object === undefined)) {
object = mapper.defaultValue;
}
if (mapper.isConstant)
object = mapper.defaultValue;
// Validate Constraints if any
this.validateConstraints(mapper, object, objectName);
if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/ig) !== null) {
payload = this.serializeBasicTypes(mapperType, objectName, object);
}
else if (mapperType.match(/^Enum$/ig) !== null) {
const enumMapper = mapper;
payload = this.serializeEnumType(objectName, enumMapper.type.allowedValues, object);
}
else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/ig) !== null) {
payload = this.serializeDateTypes(mapperType, object, objectName);
}
else if (mapperType.match(/^ByteArray$/ig) !== null) {
payload = this.serializeBufferType(objectName, object);
}
else if (mapperType.match(/^Base64Url$/ig) !== null) {
payload = this.serializeBase64UrlType(objectName, object);
}
else if (mapperType.match(/^Sequence$/ig) !== null) {
payload = this.serializeSequenceType(mapper, object, objectName);
}
else if (mapperType.match(/^Dictionary$/ig) !== null) {
payload = this.serializeDictionaryType(mapper, object, objectName);
}
else if (mapperType.match(/^Composite$/ig) !== null) {
payload = this.serializeCompositeType(mapper, object, objectName);
}
return payload;
}
deserializeCompositeType(mapper, responseBody, objectName) {
/*jshint validthis: true */
// check for polymorphic discriminator
if (mapper.type.polymorphicDiscriminator) {
mapper = this.getPolymorphicMapper(mapper, responseBody, objectName, "deserialize");
}
let instance = {};
let modelMapper = {
required: false,
serializedName: "serializedName",
type: {
name: "Composite"
}
};
if (responseBody !== null && responseBody !== undefined) {
let modelProps = mapper.type.modelProperties;
if (!modelProps) {
if (!mapper.type.className) {
throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper)}"`);
}
// get the mapper if modelProperties of the CompositeType is not present and
// then get the modelProperties from it.
modelMapper = this.modelMappers[mapper.type.className];
if (!modelMapper) {
throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}"`);
}
modelProps = modelMapper.type.modelProperties;
if (!modelProps) {
throw new Error(`modelProperties cannot be null or undefined in the ` +
`mapper "${JSON.stringify(modelMapper)}" of type "${mapper.type.className}" for responseBody "${objectName}".`);
}
}
for (const key in modelProps) {
if (modelProps.hasOwnProperty(key)) {
const jpath = ["responseBody"];
const paths = this.splitSerializeName(modelProps[key].serializedName);
paths.forEach((item) => {
jpath.push(`["${item}"]`);
});
// deserialize the property if it is present in the provided responseBody instance
let propertyInstance;
try {
/*jslint evil: true */
propertyInstance = eval(jpath.join(""));
}
catch (err) {
continue;
}
let propertyObjectName = objectName;
if (modelProps[key].serializedName !== "")
propertyObjectName = objectName + "." + modelProps[key].serializedName;
const propertyMapper = modelProps[key];
let serializedValue;
// paging
if (Array.isArray(responseBody[key]) && modelProps[key].serializedName === "") {
propertyInstance = responseBody[key];
instance = this.deserialize(propertyMapper, propertyInstance, propertyObjectName);
}
else if (propertyInstance !== null && propertyInstance !== undefined) {
serializedValue = this.deserialize(propertyMapper, propertyInstance, propertyObjectName);
instance[key] = serializedValue;
}
}
}
return instance;
}
return responseBody;
}
deserializeDictionaryType(mapper, responseBody, objectName) {
/*jshint validthis: true */
if (!mapper.type.value || typeof mapper.type.value !== "object") {
throw new Error(`"value" metadata for a Dictionary must be defined in the ` +
`mapper and it must of type "object" in ${objectName}`);
}
if (responseBody) {
const tempDictionary = {};
for (const key in responseBody) {
if (responseBody.hasOwnProperty(key)) {
tempDictionary[key] = this.deserialize(mapper.type.value, responseBody[key], objectName);
}
}
return tempDictionary;
}
return responseBody;
}
deserializeSequenceType(mapper, responseBody, objectName) {
/*jshint validthis: true */
if (!mapper.type.element || typeof mapper.type.element !== "object") {
throw new Error(`element" metadata for an Array must be defined in the ` +
`mapper and it must of type "object" in ${objectName}`);
}
if (responseBody) {
const tempArray = [];
for (let i = 0; i < responseBody.length; i++) {
tempArray[i] = this.deserialize(mapper.type.element, responseBody[i], objectName);
}
return tempArray;
}
return responseBody;
}
/**
* Deserialize the given object based on its metadata defined in the mapper
*
* @param {object} mapper The mapper which defines the metadata of the serializable object
*
* @param {object|string|Array|number|boolean|Date|stream} responseBody A valid Javascript entity to be deserialized
*
* @param {string} objectName Name of the deserialized object
*
* @returns {object|string|Array|number|boolean|Date|stream} A valid deserialized Javascript object
*/
deserialize(mapper, responseBody, objectName) {
if (responseBody === null || responseBody === undefined)
return responseBody;
let payload;
const mapperType = mapper.type.name;
if (!objectName)
objectName = mapper.serializedName;
if (mapperType.match(/^Sequence$/ig) !== null)
payload = [];
if (mapperType.match(/^(Number|String|Boolean|Enum|Object|Stream|Uuid)$/ig) !== null) {
payload = responseBody;
}
else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/ig) !== null) {
payload = new Date(responseBody);
}
else if (mapperType.match(/^TimeSpan$/ig) !== null) {
payload = moment_1.duration(responseBody);
}
else if (mapperType.match(/^UnixTime$/ig) !== null) {
payload = this.unixTimeToDate(responseBody);
}
else if (mapperType.match(/^ByteArray$/ig) !== null) {
payload = Buffer.from(responseBody, "base64");
}
else if (mapperType.match(/^Base64Url$/ig) !== null) {
payload = this.base64UrlToBuffer(responseBody);
}
else if (mapperType.match(/^Sequence$/ig) !== null) {
payload = this.deserializeSequenceType(mapper, responseBody, objectName);
}
else if (mapperType.match(/^Dictionary$/ig) !== null) {
payload = this.deserializeDictionaryType(mapper, responseBody, objectName);
}
else if (mapperType.match(/^Composite$/ig) !== null) {
payload = this.deserializeCompositeType(mapper, responseBody, objectName);
}
if (mapper.isConstant)
payload = mapper.defaultValue;
return payload;
}
getPolymorphicMapper(mapper, object, objectName, mode) {
// check for polymorphic discriminator
// Until version 1.15.1, "polymorphicDiscriminator" in the mapper was a string. This method was not effective when the
// polymorphicDiscriminator property had a dot in it"s name. So we have comeup with a desgin where polymorphicDiscriminator
// will be an object that contains the clientName (normalized property name, ex: "odatatype") and
// the serializedName (ex: "odata.type") (We do not escape the dots with double backslash in this case as it is not required)
// Thus when serializing, the user will give us an object which will contain the normalizedProperty hence we will lookup
// the clientName of the polmorphicDiscriminator in the mapper and during deserialization from the responseBody we will
// lookup the serializedName of the polmorphicDiscriminator in the mapper. This will help us in selecting the correct mapper
// for the model that needs to be serializes or deserialized.
// We need this routing for backwards compatibility. This will absorb the breaking change in the mapper and allow new versions
// of the runtime to work seamlessly with older version (>= 0.17.0-Nightly20161008) of Autorest generated node.js clients.
if (mapper.type.polymorphicDiscriminator) {
if (typeof mapper.type.polymorphicDiscriminator.valueOf() === "string") {
return this.getPolymorphicMapperStringVersion(mapper, object, objectName);
}
else if (mapper.type.polymorphicDiscriminator instanceof Object) {
return this.getPolymorphicMapperObjectVersion(mapper, object, objectName, mode);
}
else {
throw new Error(`The polymorphicDiscriminator for "${objectName}" is neither a string nor an object.`);
}
}
return mapper;
}
// processes new version of the polymorphicDiscriminator in the mapper.
getPolymorphicMapperObjectVersion(mapper, object, objectName, mode) {
// check for polymorphic discriminator
let polymorphicPropertyName = "";
if (mode === "serialize") {
polymorphicPropertyName = "clientName";
}
else if (mode === "deserialize") {
polymorphicPropertyName = "serializedName";
}
else {
throw new Error(`The given mode "${mode}" for getting the polymorphic mapper for "${objectName}" is inavlid.`);
}
const discriminatorAsObject = mapper.type.polymorphicDiscriminator;
if (discriminatorAsObject &&
discriminatorAsObject[polymorphicPropertyName] !== null &&
discriminatorAsObject[polymorphicPropertyName] !== undefined) {
if (object === null || object === undefined) {
throw new Error(`${objectName}" cannot be null or undefined. ` +
`"${discriminatorAsObject[polymorphicPropertyName]}" is the ` +
`polmorphicDiscriminator and is a required property.`);
}
if (object[discriminatorAsObject[polymorphicPropertyName]] === null ||
object[discriminatorAsObject[polymorphicPropertyName]] === undefined) {
throw new Error(`No discriminator field "${discriminatorAsObject[polymorphicPropertyName]}" was found in "${objectName}".`);
}
let indexDiscriminator = undefined;
if (object[discriminatorAsObject[polymorphicPropertyName]] === mapper.type.uberParent) {
indexDiscriminator = object[discriminatorAsObject[polymorphicPropertyName]];
}
else {
indexDiscriminator = mapper.type.uberParent + "." + object[discriminatorAsObject[polymorphicPropertyName]];
}
if (!this.modelMappers.discriminators[indexDiscriminator]) {
throw new Error(`${discriminatorAsObject[polymorphicPropertyName]}": ` +
`"${object[discriminatorAsObject[polymorphicPropertyName]]}" in "${objectName}" is not a valid ` +
`discriminator as a corresponding model class for the disciminator "${indexDiscriminator}" ` +
`was not found in this.modelMappers.discriminators object.`);
}
mapper = this.modelMappers.discriminators[indexDiscriminator];
}
return mapper;
}
// processes old version of the polymorphicDiscriminator in the mapper.
getPolymorphicMapperStringVersion(mapper, object, objectName) {
// check for polymorphic discriminator
const discriminatorAsString = mapper.type.polymorphicDiscriminator;
if (discriminatorAsString !== null && discriminatorAsString !== undefined) {
if (object === null || object === undefined) {
throw new Error(`${objectName}" cannot be null or undefined. "${discriminatorAsString}" is the ` +
`polmorphicDiscriminator and is a required property.`);
}
if (object[discriminatorAsString] === null || object[discriminatorAsString] === undefined) {
throw new Error(`No discriminator field "${discriminatorAsString}" was found in "${objectName}".`);
}
let indexDiscriminator = undefined;
if (object[discriminatorAsString] === mapper.type.uberParent) {
indexDiscriminator = object[discriminatorAsString];
}
else {
indexDiscriminator = mapper.type.uberParent + "." + object[discriminatorAsString];
}
if (!this.modelMappers.discriminators[indexDiscriminator]) {
throw new Error(`${discriminatorAsString}": ` +
`"${object[discriminatorAsString]}" in "${objectName}" is not a valid ` +
`discriminator as a corresponding model class for the disciminator "${indexDiscriminator}" ` +
`was not found in this.models.discriminators object.`);
}
mapper = this.modelMappers.discriminators[indexDiscriminator];
}
return mapper;
}
}
exports.Serializer = Serializer;
function serializeObject(toSerialize) {
if (toSerialize === null || toSerialize === undefined)
return undefined;
if (isBuffer(toSerialize)) {
toSerialize = toSerialize.toString("base64");
return toSerialize;
}
else if (toSerialize instanceof Date) {
return toSerialize.toISOString();
}
else if (Array.isArray(toSerialize)) {
const array = [];
for (let i = 0; i < toSerialize.length; i++) {
array.push(serializeObject(toSerialize[i]));
}
return array;
}
else if (typeof toSerialize === "object") {
const dictionary = {};
for (const property in toSerialize) {
dictionary[property] = serializeObject(toSerialize[property]);
}
return dictionary;
}
return toSerialize;
}
exports.serializeObject = serializeObject;
exports.MapperType = utils.strEnum([
"Base64Url",
"Boolean",
"ByteArray",
"Composite",
"Date",
"DateTime",
"DateTimeRfc1123",
"Dictionary",
"Enum",
"Number",
"Object",
"Sequence",
"String",
"Stream",
"TimeSpan",
"UnixTime"
]);
//# sourceMappingURL=serializer.js.map

1
dist/lib/serializer.js.map поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

110
dist/lib/serviceClient.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,110 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const requestPipeline_1 = require("./requestPipeline");
const exponentialRetryPolicyFilter_1 = require("./filters/exponentialRetryPolicyFilter");
const systemErrorRetryPolicyFilter_1 = require("./filters/systemErrorRetryPolicyFilter");
const redirectFilter_1 = require("./filters/redirectFilter");
const signingFilter_1 = require("./filters/signingFilter");
const rpRegistrationFilter_1 = require("./filters/rpRegistrationFilter");
const msRestUserAgentFilter_1 = require("./filters/msRestUserAgentFilter");
const webResource_1 = require("./webResource");
const constants_1 = require("./util/constants");
/**
* @class
* Initializes a new instance of the ServiceClient.
*/
class ServiceClient {
/**
* The ServiceClient constructor
* @constructor
* @param {ServiceClientCredentials }[credentials] - BasicAuthenticationCredentials or
* TokenCredentials object used for authentication.
* @param { ServiceClientOptions } [options] The service client options that govern the behavior of the client.
*/
constructor(credentials, options) {
if (!options) {
options = {};
}
if (!options.requestOptions) {
options.requestOptions = {};
}
if (!options.filters) {
options.filters = [];
}
this.userAgentInfo = { value: [] };
if (credentials && !credentials.signRequest) {
throw new Error("credentials argument needs to implement signRequest method");
}
try {
const moduleName = "ms-rest-js";
const moduleVersion = constants_1.Constants.msRestVersion;
this.addUserAgentInfo(`${moduleName}/${moduleVersion}`);
}
catch (err) {
// do nothing
}
if (credentials) {
options.filters.push(new signingFilter_1.SigningFilter(credentials));
}
options.filters.push(new msRestUserAgentFilter_1.MsRestUserAgentFilter(this.userAgentInfo.value));
options.filters.push(new redirectFilter_1.RedirectFilter());
options.filters.push(new rpRegistrationFilter_1.RPRegistrationFilter(options.rpRegistrationRetryTimeout));
if (!options.noRetryPolicy) {
options.filters.push(new exponentialRetryPolicyFilter_1.ExponentialRetryPolicyFilter());
options.filters.push(new systemErrorRetryPolicyFilter_1.SystemErrorRetryPolicyFilter());
}
this.pipeline = new requestPipeline_1.RequestPipeline(options.filters, options.requestOptions).create();
}
/**
* Adds custom information to user agent header
* @param {any} additionalUserAgentInfo - information to be added to user agent header, as string.
*/
addUserAgentInfo(additionalUserAgentInfo) {
if (this.userAgentInfo.value.indexOf(additionalUserAgentInfo) === -1) {
this.userAgentInfo.value.push(additionalUserAgentInfo);
}
return;
}
sendRequest(options) {
return __awaiter(this, void 0, void 0, function* () {
if (options === null || options === undefined || typeof options !== "object") {
throw new Error("options cannot be null or undefined and it must be of type object.");
}
let httpRequest;
try {
if (options instanceof webResource_1.WebResource) {
options.validateRequestProperties();
httpRequest = options;
}
else {
httpRequest = new webResource_1.WebResource();
httpRequest = httpRequest.prepare(options);
}
}
catch (error) {
return Promise.reject(error);
}
// send request
let operationResponse;
try {
operationResponse = yield this.pipeline(httpRequest);
}
catch (err) {
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
});
}
}
exports.ServiceClient = ServiceClient;
//# sourceMappingURL=serviceClient.js.map

1
dist/lib/serviceClient.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"serviceClient.js","sourceRoot":"","sources":["../../lib/serviceClient.ts"],"names":[],"mappings":"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"}

78
dist/lib/util/constants.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,78 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Constants = {
/**
* The ms-rest version
* @const
* @type {string}
*/
msRestVersion: "0.1.0",
/**
* Specifies HTTP.
*
* @const
* @type {string}
*/
HTTP: "http:",
/**
* Specifies HTTPS.
*
* @const
* @type {string}
*/
HTTPS: "https:",
/**
* Specifies HTTP Proxy.
*
* @const
* @type {string}
*/
HTTP_PROXY: "HTTP_PROXY",
/**
* Specifies HTTPS Proxy.
*
* @const
* @type {string}
*/
HTTPS_PROXY: "HTTPS_PROXY",
HttpConstants: {
/**
* Http Verbs
*
* @const
* @enum {string}
*/
HttpVerbs: {
PUT: "PUT",
GET: "GET",
DELETE: "DELETE",
POST: "POST",
MERGE: "MERGE",
HEAD: "HEAD",
PATCH: "PATCH"
},
},
/**
* Defines constants for use with HTTP headers.
*/
HeaderConstants: {
/**
* The Authorization header.
*
* @const
* @type {string}
*/
AUTHORIZATION: "authorization",
AUTHORIZATION_SCHEME: "Bearer",
/**
* The UserAgent header.
*
* @const
* @type {string}
*/
USER_AGENT: "User-Agent"
}
};
//# sourceMappingURL=constants.js.map

1
dist/lib/util/constants.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../lib/util/constants.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAElF,QAAA,SAAS,GAAG;IAEvB;;;;OAIG;IACH,aAAa,EAAE,OAAO;IAEtB;;;;;OAKG;IACH,IAAI,EAAE,OAAO;IAEb;;;;;OAKG;IACH,KAAK,EAAE,QAAQ;IAEf;;;;;OAKG;IACH,UAAU,EAAE,YAAY;IAExB;;;;;OAKG;IACH,WAAW,EAAE,aAAa;IAE1B,aAAa,EAAE;QACb;;;;;WAKG;QACH,SAAS,EAAE;YACT,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;YACV,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf;KACF;IAED;;OAEG;IACH,eAAe,EAAE;QACf;;;;;WAKG;QACH,aAAa,EAAE,eAAe;QAE9B,oBAAoB,EAAE,QAAQ;QAE9B;;;;;WAKG;QACH,UAAU,EAAE,YAAY;KACzB;CACF,CAAC"}

329
dist/lib/util/utils.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,329 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const uuid = require("uuid");
const FormData = require("form-data");
const webResource_1 = require("../webResource");
const constants_1 = require("./constants");
const restError_1 = require("../restError");
const httpOperationResponse_1 = require("../httpOperationResponse");
/**
* Provides the fetch() method based on the environment.
* @returns {fetch} fetch - The fetch() method available in the environment to make requests
*/
function getFetch() {
// using window.Fetch in Edge gives a TypeMismatchError
// (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8546263/).
// Hence we will be using the fetch-ponyfill for Edge.
if (typeof window !== "undefined" && window.fetch && window.navigator &&
window.navigator.userAgent && window.navigator.userAgent.indexOf("Edge/") === -1) {
return window.fetch.bind(window);
}
return require("fetch-ponyfill")({ useCookie: true }).fetch;
}
exports.getFetch = getFetch;
/**
* A constant that provides the fetch() method based on the environment.
*/
exports.myFetch = getFetch();
/**
* Checks if a parsed URL is HTTPS
*
* @param {object} urlToCheck The url to check
* @return {boolean} True if the URL is HTTPS; false otherwise.
*/
function urlIsHTTPS(urlToCheck) {
return urlToCheck.protocol.toLowerCase() === constants_1.Constants.HTTPS;
}
exports.urlIsHTTPS = urlIsHTTPS;
/**
* Checks if a value is null or undefined.
*
* @param {object} value The value to check for null or undefined.
* @return {boolean} True if the value is null or undefined, false otherwise.
*/
// TODO: Audit the usages of this and remove them.
// Read: https://medium.com/@basarat/null-vs-undefined-in-typescript-land-dc0c7a5f240a
// https://github.com/Microsoft/TypeScript/issues/7426
function objectIsNull(value) {
return value === null || value === undefined;
}
exports.objectIsNull = objectIsNull;
/**
* Encodes an URI.
*
* @param {string} uri The URI to be encoded.
* @return {string} The encoded URI.
*/
function encodeUri(uri) {
return encodeURIComponent(uri)
.replace(/!/g, "%21")
.replace(/"/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29")
.replace(/\*/g, "%2A");
}
exports.encodeUri = encodeUri;
/**
* Returns a stripped version of the Http Response which only contains body,
* headers and the status.
*
* @param {nodeFetch.Response} response - The Http Response
*
* @return {object} strippedResponse - The stripped version of Http Response.
*/
function stripResponse(response) {
const strippedResponse = {};
strippedResponse.body = response.body;
strippedResponse.headers = response.headers;
strippedResponse.status = response.status;
return strippedResponse;
}
exports.stripResponse = stripResponse;
/**
* Returns a stripped version of the Http Request that does not contain the
* Authorization header.
*
* @param {object} request - The Http Request object
*
* @return {object} strippedRequest - The stripped version of Http Request.
*/
function stripRequest(request) {
let strippedRequest = new webResource_1.WebResource();
try {
strippedRequest = JSON.parse(JSON.stringify(request));
if (strippedRequest.headers && strippedRequest.headers.Authorization) {
delete strippedRequest.headers.Authorization;
}
else if (strippedRequest.headers && strippedRequest.headers.authorization) {
delete strippedRequest.headers.authorization;
}
}
catch (err) {
const errMsg = err.message;
err.message = `Error - "${errMsg}" occured while creating a stripped version of the request object - "${request}".`;
return err;
}
return strippedRequest;
}
exports.stripRequest = stripRequest;
/**
* Validates the given uuid as a string
*
* @param {string} uuid - The uuid as a string that needs to be validated
*
* @return {boolean} result - True if the uuid is valid; false otherwise.
*/
function isValidUuid(uuid) {
const validUuidRegex = new RegExp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", "ig");
return validUuidRegex.test(uuid);
}
exports.isValidUuid = isValidUuid;
/**
* Provides an array of values of an object. For example
* for a given object { "a": "foo", "b": "bar" }, the method returns ["foo", "bar"].
*
* @param {object} obj - An object whose properties need to be enumerated so that it"s values can be provided as an array
*
* @return {array} result - An array of values of the given object.
*/
function objectValues(obj) {
const result = [];
if (obj && obj instanceof Object) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result.push(obj[key]);
}
}
}
else {
throw new Error(`The provided object ${JSON.stringify(obj, undefined, 2)} is not a valid object that can be ` +
`enumerated to provide its values as an array.`);
}
return result;
}
exports.objectValues = objectValues;
/**
* Generated UUID
*
* @return {string} RFC4122 v4 UUID.
*/
function generateUuid() {
return uuid.v4();
}
exports.generateUuid = generateUuid;
/*
* Executes an array of promises sequentially. Inspiration of this method is here:
* https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html. An awesome blog on promises!
*
* @param {Array} promiseFactories An array of promise factories(A function that return a promise)
*
* @param {any} [kickstart] Input to the first promise that is used to kickstart the promise chain.
* If not provided then the promise chain starts with undefined.
*
* @return A chain of resolved or rejected promises
*/
function executePromisesSequentially(promiseFactories, kickstart) {
let result = Promise.resolve(kickstart);
promiseFactories.forEach((promiseFactory) => {
result = result.then(promiseFactory);
});
return result;
}
exports.executePromisesSequentially = executePromisesSequentially;
/*
* Merges source object into the target object
* @param {object} source The object that needs to be merged
*
* @param {object} target The object to be merged into
*
* @returns {object} target - Returns the merged target object.
*/
function mergeObjects(source, target) {
Object.keys(source).forEach((key) => {
target[key] = source[key];
});
return target;
}
exports.mergeObjects = mergeObjects;
/**
* A wrapper for setTimeout that resolves a promise after t milliseconds.
* @param {number} t - The number of milliseconds to be delayed.
* @param {T} value - The value to be resolved with after a timeout of t milliseconds.
* @returns {Promise<T>} - Resolved promise
*/
function delay(t, value) {
return new Promise((resolve) => setTimeout(() => resolve(value), t));
}
exports.delay = delay;
/**
* Utility function to create a K:V from a list of strings
*/
function strEnum(o) {
return o.reduce((res, key) => {
res[key] = key;
return res;
}, Object.create(null));
}
exports.strEnum = strEnum;
/**
* Converts a Promise to a callback.
* @param {Promise<any>} promise - The Promise to be converted to a callback
* @returns {Function} fn - A function that takes the callback (cb: Function): void
*/
function promiseToCallback(promise) {
if (typeof promise.then !== "function") {
throw new Error("The provided input is not a Promise.");
}
return (cb) => {
promise.then((data) => {
process.nextTick(cb, undefined, data);
}, (err) => {
process.nextTick(cb, err);
});
};
}
exports.promiseToCallback = promiseToCallback;
/**
* Converts a Promise to a service callback.
* @param {Promise<HttpOperationResponse>} promise - The Promise of HttpOperationResponse to be converted to a service callback
* @returns {Function} fn - A function that takes the service callback (cb: ServiceCallback<T>): void
*/
function promiseToServiceCallback(promise) {
if (typeof promise.then !== "function") {
throw new Error("The provided input is not a Promise.");
}
return (cb) => {
promise.then((data) => {
process.nextTick(cb, undefined, data.bodyAsJson, data.request, data.response);
}, (err) => {
process.nextTick(cb, err);
});
};
}
exports.promiseToServiceCallback = promiseToServiceCallback;
/**
* Sends the request and returns the received response.
* @param {WebResource} options - The request to be sent.
* @returns {Promise<HttpOperationResponse} operationResponse - The response object.
*/
function dispatchRequest(options) {
return __awaiter(this, void 0, void 0, function* () {
if (!options) {
return Promise.reject(new Error("options (WebResource) cannot be null or undefined and must be of type object."));
}
if (options.formData) {
const formData = options.formData;
const requestForm = new FormData();
const appendFormValue = (key, value) => {
if (value && value.hasOwnProperty("value") && value.hasOwnProperty("options")) {
requestForm.append(key, value.value, value.options);
}
else {
requestForm.append(key, value);
}
};
for (const formKey in formData) {
if (formData.hasOwnProperty(formKey)) {
const formValue = formData[formKey];
if (formValue instanceof Array) {
for (let j = 0; j < formValue.length; j++) {
appendFormValue(formKey, formValue[j]);
}
}
else {
appendFormValue(formKey, formValue);
}
}
}
options.body = requestForm;
options.formData = undefined;
if (options.headers && options.headers["Content-Type"] &&
options.headers["Content-Type"].indexOf("multipart/form-data") > -1 && typeof requestForm.getBoundary === "function") {
options.headers["Content-Type"] = `multipart/form-data; boundary=${requestForm.getBoundary()}`;
}
}
let res;
try {
res = yield exports.myFetch(options.url, options);
}
catch (err) {
return Promise.reject(err);
}
const operationResponse = new httpOperationResponse_1.HttpOperationResponse(options, res, res.body);
if (!options.rawResponse) {
try {
operationResponse.bodyAsText = yield res.text();
}
catch (err) {
const msg = `Error "${err}" occured while converting the raw response body into string.`;
const errCode = err.code || "RAWTEXT_CONVERSION_ERROR";
const e = new restError_1.RestError(msg, errCode, res.status, options, res, res.body);
return Promise.reject(e);
}
try {
if (operationResponse.bodyAsText) {
operationResponse.bodyAsJson = JSON.parse(operationResponse.bodyAsText);
}
}
catch (err) {
const msg = `Error "${err}" occured while executing JSON.parse on the response body - ${operationResponse.bodyAsText}.`;
const errCode = err.code || "JSON_PARSE_ERROR";
const e = new restError_1.RestError(msg, errCode, res.status, options, res, operationResponse.bodyAsText);
return Promise.reject(e);
}
}
return Promise.resolve(operationResponse);
});
}
exports.dispatchRequest = dispatchRequest;
//# sourceMappingURL=utils.js.map

1
dist/lib/util/utils.js.map поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

206
dist/lib/webResource.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,206 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./util/utils");
const serializer_1 = require("./serializer");
/**
* Creates a new WebResource object.
*
* This class provides an abstraction over a REST call by being library / implementation agnostic and wrapping the necessary
* properties to initiate a request.
*
* @constructor
*/
class WebResource {
constructor(url, method, body, query, headers = {}, rawResponse = false) {
this.headers = {};
this.rawResponse = rawResponse;
this.url = url || "";
this.method = method || "GET";
this.headers = headers || {};
this.body = body;
this.query = query;
this.formData = undefined;
}
/**
* Validates that the required properties such as method, url, headers["Content-Type"],
* headers["accept-language"] are defined. It will throw an error if one of the above
* mentioned properties are not defined.
*/
validateRequestProperties() {
if (!this.method || !this.url || !this.headers["Content-Type"] || !this.headers["accept-language"]) {
throw new Error("method, url, headers[\"Content-Type\"], headers[\"accept-language\"] are " +
"required properties before making a request. Either provide them or use WebResource.prepare() method.");
}
return;
}
/**
* Prepares the request.
* @param {RequestPrepareOptions} options - Options to provide for preparing the request.
* @returns {object} WebResource Returns the prepared WebResource (HTTP Request) object that needs to be given to the request pipeline.
*/
prepare(options) {
if (options === null || options === undefined || typeof options !== "object") {
throw new Error("options cannot be null or undefined and must be of type object");
}
if (options.method === null || options.method === undefined || typeof options.method.valueOf() !== "string") {
throw new Error("options.method cannot be null or undefined and it must be of type string.");
}
if (options.url && options.pathTemplate) {
throw new Error("options.url and options.pathTemplate are mutually exclusive. Please provide either of them.");
}
if ((options.pathTemplate === null || options.pathTemplate === undefined || typeof options.pathTemplate.valueOf() !== "string") && (options.url === null || options.url === undefined || typeof options.url.valueOf() !== "string")) {
throw new Error("Please provide either options.pathTemplate or options.url. Currently none of them were provided.");
}
// set the url if it is provided.
if (options.url) {
if (typeof options.url !== "string") {
throw new Error("options.url must be of type \"string\".");
}
this.url = options.url;
}
// set the method
if (options.method) {
const validMethods = ["GET", "PUT", "HEAD", "DELETE", "OPTIONS", "POST", "PATCH", "TRACE"];
if (validMethods.indexOf(options.method.toUpperCase()) === -1) {
throw new Error("The provided method \"" + options.method + "\" is invalid. Supported HTTP methods are: " + JSON.stringify(validMethods));
}
}
this.method = options.method.toUpperCase();
// construct the url if path template is provided
if (options.pathTemplate) {
if (typeof options.pathTemplate !== "string") {
throw new Error("options.pathTemplate must be of type \"string\".");
}
if (!options.baseUrl) {
options.baseUrl = "https://management.azure.com";
}
const baseUrl = options.baseUrl;
let url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + (options.pathTemplate.startsWith("/") ? options.pathTemplate.slice(1) : options.pathTemplate);
const segments = url.match(/({\w*\s*\w*})/ig);
if (segments && segments.length) {
if (options.pathParameters === null || options.pathParameters === undefined || typeof options.pathParameters !== "object") {
throw new Error(`pathTemplate: ${options.pathTemplate} has been provided. Hence, options.pathParameters ` +
`cannot be null or undefined and must be of type "object".`);
}
segments.forEach(function (item) {
const pathParamName = item.slice(1, -1);
const pathParam = options.pathParameters[pathParamName];
if (pathParam === null || pathParam === undefined || !(typeof pathParam === "string" || typeof pathParam === "object")) {
throw new Error(`pathTemplate: ${options.pathTemplate} contains the path parameter ${pathParamName}` +
` however, it is not present in ${options.pathParameters} - ${JSON.stringify(options.pathParameters, undefined, 2)}.` +
`The value of the path parameter can either be a "string" of the form { ${pathParamName}: "some sample value" } or ` +
`it can be an "object" of the form { "${pathParamName}": { value: "some sample value", skipUrlEncoding: true } }.`);
}
if (typeof pathParam.valueOf() === "string") {
url = url.replace(item, encodeURIComponent(pathParam));
}
if (typeof pathParam.valueOf() === "object") {
if (!pathParam.value) {
throw new Error(`options.pathParameters[${pathParamName}] is of type "object" but it does not contain a "value" property.`);
}
if (pathParam.skipUrlEncoding) {
url = url.replace(item, pathParam.value);
}
else {
url = url.replace(item, encodeURIComponent(pathParam.value));
}
}
});
}
this.url = url;
}
// append query parameters to the url if they are provided. They can be provided with pathTemplate or url option.
if (options.queryParameters) {
if (typeof options.queryParameters !== "object") {
throw new Error(`options.queryParameters must be of type object. It should be a JSON object ` +
`of "query-parameter-name" as the key and the "query-parameter-value" as the value. ` +
`The "query-parameter-value" may be fo type "string" or an "object" of the form { value: "query-parameter-value", skipUrlEncoding: true }.`);
}
// append question mark if it is not present in the url
if (this.url && this.url.indexOf("?") === -1) {
this.url += "?";
}
// construct queryString
const queryParams = [];
const queryParameters = options.queryParameters;
// We need to populate this.query as a dictionary if the request is being used for Sway's validateRequest().
this.query = {};
for (const queryParamName in queryParameters) {
const queryParam = queryParameters[queryParamName];
if (queryParam) {
if (typeof queryParam === "string") {
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam));
this.query[queryParamName] = encodeURIComponent(queryParam);
}
else if (typeof queryParam === "object") {
if (!queryParam.value) {
throw new Error(`options.queryParameters[${queryParamName}] is of type "object" but it does not contain a "value" property.`);
}
if (queryParam.skipUrlEncoding) {
queryParams.push(queryParamName + "=" + queryParam.value);
this.query[queryParamName] = queryParam.value;
}
else {
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam.value));
this.query[queryParamName] = encodeURIComponent(queryParam.value);
}
}
}
} // end-of-for
// append the queryString
this.url += queryParams.join("&");
}
// add headers to the request if they are provided
if (options.headers) {
const headers = options.headers;
for (const headerName in headers) {
if (headers.hasOwnProperty(headerName)) {
this.headers[headerName] = headers[headerName];
}
}
}
// ensure accept-language is set correctly
if (!this.headers["accept-language"]) {
this.headers["accept-language"] = "en-US";
}
// ensure the request-id is set correctly
if (!this.headers["x-ms-client-request-id"] && !options.disableClientRequestId) {
this.headers["x-ms-client-request-id"] = utils_1.generateUuid();
}
// default
if (!this.headers["Content-Type"]) {
this.headers["Content-Type"] = "application/json; charset=utf-8";
}
// set the request body. request.js automatically sets the Content-Length request header, so we need not set it explicilty
this.body = undefined;
if (options.body !== null && options.body !== undefined) {
// body as a stream special case. set the body as-is and check for some special request headers specific to sending a stream.
if (options.bodyIsStream) {
this.body = options.body;
if (!this.headers["Transfer-Encoding"]) {
this.headers["Transfer-Encoding"] = "chunked";
}
if (this.headers["Content-Type"] !== "application/octet-stream") {
this.headers["Content-Type"] = "application/octet-stream";
}
}
else {
let serializedBody = undefined;
if (options.serializationMapper) {
serializedBody = new serializer_1.Serializer(options.mappers).serialize(options.serializationMapper, options.body, "requestBody");
}
if (options.disableJsonStringifyOnBody) {
this.body = serializedBody || options.body;
}
else {
this.body = serializedBody ? JSON.stringify(serializedBody) : JSON.stringify(options.body);
}
}
}
return this;
}
}
exports.WebResource = WebResource;
//# sourceMappingURL=webResource.js.map

1
dist/lib/webResource.js.map поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

96
dist/test/credentialTests.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,96 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const msRest = require("../lib/msRest");
const should = require("should");
const TokenCredentials = msRest.TokenCredentials;
const BasicAuthenticationCredentials = msRest.BasicAuthenticationCredentials;
const dummyToken = "A-dummy-access-token";
const fakeScheme = "fake-auth-scheme";
const dummyuserName = "dummy@mummy.com";
const dummyPassword = "IL0veDummies";
describe("Token credentials", () => {
describe("usage", () => {
it("should set auth header with bearer scheme in request", (done) => {
const creds = new TokenCredentials(dummyToken);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest) => {
should.exist(signedRequest.headers["authorization"]);
signedRequest.headers["authorization"].should.match(new RegExp("^Bearer\\s+" + dummyToken + "$"));
done();
});
});
it("should set auth header with custom scheme in request", (done) => {
const creds = new TokenCredentials(dummyToken, fakeScheme);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest) => {
should.exist(signedRequest.headers["authorization"]);
signedRequest.headers["authorization"].should.match(new RegExp("^" + fakeScheme + "\\s+" + dummyToken + "$"));
done();
});
});
});
describe("construction", () => {
it("should succeed with token", () => {
(() => {
new TokenCredentials(dummyToken);
}).should.not.throw();
});
// it("should fail without credentials", () => {
// (() => {
// new TokenCredentials();
// }).should.throw();
// });
// it("should fail without token", () => {
// (() => {
// new TokenCredentials(null, fakeScheme);
// }).should.throw();
// });
});
});
describe("Basic Authentication credentials", () => {
const encodedCredentials = Buffer.from(dummyuserName + ":" + dummyPassword).toString("base64");
describe("usage", () => {
it("should base64 encode the username and password and set auth header with baisc scheme in request", (done) => {
const creds = new BasicAuthenticationCredentials(dummyuserName, dummyPassword);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest) => {
signedRequest.headers.should.have.property("authorization");
signedRequest.headers["authorization"].should.match(new RegExp("^Basic\\s+" + encodedCredentials + "$"));
done();
});
});
it("should base64 encode the username and password and set auth header with custom scheme in request", (done) => {
const creds = new BasicAuthenticationCredentials(dummyuserName, dummyPassword, fakeScheme);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest) => {
signedRequest.headers.should.have.property("authorization");
signedRequest.headers["authorization"].should.match(new RegExp("^" + fakeScheme + "\\s+" + encodedCredentials + "$"));
done();
});
});
});
describe("construction", () => {
it("should succeed with userName and password", () => {
(() => {
new BasicAuthenticationCredentials(dummyuserName, dummyPassword);
}).should.not.throw();
});
// it("should fail without credentials", () => {
// (() => {
// new BasicAuthenticationCredentials(null, null);
// }).should.throw();
// });
// it("should fail without userName and password", () => {
// (() => {
// new BasicAuthenticationCredentials(null, null, fakeScheme);
// }).should.throw();
// });
});
});
//# sourceMappingURL=credentialTests.js.map

1
dist/test/credentialTests.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"credentialTests.js","sourceRoot":"","sources":["../../test/credentialTests.ts"],"names":[],"mappings":"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"}

590
dist/test/data/TestClient/lib/models/mappers.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,590 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
*/
let internalMappers = {};
internalMappers.Cat = {
required: false,
serializedName: "cat",
type: {
name: "Composite",
className: "Cat",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
},
color: {
required: false,
serializedName: "color",
type: {
name: "String"
}
},
hates: {
required: false,
serializedName: "hates",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "DogElementType",
type: {
name: "Composite",
className: "Dog"
}
}
}
}
}
}
};
internalMappers.Dog = {
required: false,
serializedName: "dog",
type: {
name: "Composite",
className: "Dog",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
},
food: {
required: false,
serializedName: "food",
type: {
name: "String"
}
}
}
}
};
internalMappers.Fish = {
required: false,
serializedName: "Fish",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
}
}
}
};
internalMappers.Invoice = {
required: false,
serializedName: "Invoice",
type: {
name: "Composite",
className: "Invoice",
modelProperties: {
invId: {
serializedName: "invoiceId",
required: true,
type: {
name: "Number"
}
},
invDate: {
serializedName: "invDate",
required: false,
type: {
name: "Date"
}
},
invProducts: {
serializedName: "invProducts",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Dictionary",
value: {
type: {
name: "Composite",
className: "Product"
}
}
}
}
}
}
}
}
};
internalMappers.Pet = {
required: false,
serializedName: "pet",
type: {
name: "Composite",
className: "Pet",
polymorphicDiscriminator: "pet.type",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
}
}
}
};
internalMappers.PetGallery = {
required: false,
serializedName: "PetGallery",
type: {
name: "Composite",
className: "PetGallery",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pets: {
required: false,
serializedName: "pets",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "petElementType",
type: {
name: "Composite",
polymorphicDiscriminator: "pet.type",
uberParent: "Pet",
className: "Pet"
}
}
}
}
}
}
};
internalMappers.Product = {
required: false,
serializedName: "Product",
type: {
name: "Composite",
className: "Product",
modelProperties: {
id: {
serializedName: "id",
constraints: {},
required: true,
type: {
name: "Number"
}
},
name: {
serializedName: "name",
required: true,
type: {
name: "String"
}
},
provisioningState: {
serializedName: "properties.provisioningState",
required: false,
type: {
name: "Enum",
allowedValues: ["Creating", "Failed", "Succeeded"]
}
},
tags: {
serializedName: "tags",
required: false,
type: {
name: "Dictionary",
value: {
type: {
name: "String"
}
}
}
},
dispatchTime: {
serializedName: "dispatchTime",
required: false,
type: {
name: "DateTime"
}
},
invoiceInfo: {
serializedName: "invoiceInfo",
required: false,
type: {
name: "Composite",
className: "Invoice"
}
},
subProducts: {
serializedName: "subProducts",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "SubProduct"
}
}
}
}
}
}
};
internalMappers.ProductListResult = {
required: false,
serializedName: "ProductListResult",
type: {
name: "Composite",
className: "ProductListResult",
modelProperties: {
value: {
serializedName: "",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "Product"
}
}
}
}
}
}
};
internalMappers.ProductListResultNextLink = {
required: false,
serializedName: "ProductListResultNextLink",
type: {
name: "Composite",
className: "ProductListResultNextLink",
modelProperties: {
value: {
serializedName: "",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "Product"
}
}
}
},
nextLink: {
serializedName: "nextLink",
required: false,
type: {
name: "String"
}
}
}
}
};
internalMappers.SawShark = {
required: false,
serializedName: "sawshark",
type: {
name: "Composite",
className: "Sawshark",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
},
age: {
required: false,
serializedName: "age",
type: {
name: "Number"
}
},
birthday: {
required: true,
serializedName: "birthday",
type: {
name: "DateTime"
}
},
picture: {
required: false,
serializedName: "picture",
type: {
name: "ByteArray"
}
}
}
}
};
internalMappers.Shark = {
required: false,
serializedName: "shark",
type: {
name: "Composite",
className: "Shark",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
},
age: {
required: false,
serializedName: "age",
type: {
name: "Number"
}
},
birthday: {
required: true,
serializedName: "birthday",
type: {
name: "DateTime"
}
}
}
}
};
internalMappers.SubProduct = {
required: false,
serializedName: "SubProduct",
type: {
name: "Composite",
className: "SubProduct",
modelProperties: {
subId: {
serializedName: "subId",
required: true,
type: {
name: "Number"
}
},
subName: {
serializedName: "subName",
required: true,
type: {
name: "String"
}
},
provisioningState: {
serializedName: "provisioningState",
required: false,
type: {
name: "Enum",
allowedValues: ["Creating", "Failed", "Succeeded"]
}
},
makeTime: {
serializedName: "makeTime",
required: false,
type: {
name: "DateTime"
}
},
invoiceInfo: {
serializedName: "invoiceInfo",
required: false,
type: {
name: "Composite",
className: "Invoice"
}
}
}
}
};
internalMappers.discriminators = {
"Fish": internalMappers.Fish,
"Fish.shark": internalMappers.Shark,
"Fish.sawshark": internalMappers.SawShark,
"Pet": internalMappers.Pet,
"Pet.Cat": internalMappers.Cat,
"Pet.Dog": internalMappers.Dog
};
exports.Mappers = internalMappers;
//# sourceMappingURL=mappers.js.map

1
dist/test/data/TestClient/lib/models/mappers.js.map поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

49
dist/test/data/TestClient/lib/testClient.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,49 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
*
* Code generated by Microsoft (R) AutoRest Code Generator 0.14.0.0
* Changes may cause incorrect behavior and will be lost if the code is
* regenerated.
*/
/* jshint latedef:false */
/* jshint forin:false */
/* jshint noempty:false */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const msRest = require("../../../../lib/msRest");
const mappers_1 = require("./models/mappers");
/**
* @class
* Initializes a new instance of the TestClient class.
* @constructor
*
* @param {string} [baseUri] - The base URI of the service.
*
* @param {object} [options] - The parameter options
*
* @param {Array} [options.filters] - Filters to be added to the request pipeline
*
* @param {object} [options.requestOptions] - Options for the underlying request object
* {@link https://github.com/request/request#requestoptions-callback Options doc}
*
* @param {bool} [options.noRetryPolicy] - If set to true, turn off default retry policy
*/
class TestClient extends msRest.ServiceClient {
constructor(baseUri, options) {
if (!options)
options = {};
super(undefined, options);
this.baseUri = baseUri;
if (!this.baseUri) {
this.baseUri = 'https://management.azure.com';
}
if (!this.acceptLanguage) {
this.acceptLanguage = 'en-US';
}
this.serializer = new msRest.Serializer(mappers_1.Mappers);
}
}
exports.TestClient = TestClient;
//# sourceMappingURL=testClient.js.map

1
dist/test/data/TestClient/lib/testClient.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"testClient.js","sourceRoot":"","sources":["../../../../../test/data/TestClient/lib/testClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,0BAA0B;AAC1B,wBAAwB;AACxB,0BAA0B;AAE1B,YAAY,CAAC;;AAEb,iDAAiD;AACjD,8CAA2C;AAE3C;;;;;;;;;;;;;;;GAeG;AAEH,gBAAiB,SAAQ,MAAM,CAAC,aAAa;IAK3C,YAAY,OAAe,EAAE,OAAqC;QAChE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;QAC3B,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,8BAA8B,CAAC;QAChD,CAAC;QAED,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,iBAAO,CAAC,CAAC;IACnD,CAAC;CACF;AAEQ,gCAAU"}

41
dist/test/logFilterTests.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,41 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const webResource_1 = require("../lib/webResource");
const httpOperationResponse_1 = require("../lib/httpOperationResponse");
const logFilter_1 = require("../lib/filters/logFilter");
const node_fetch_1 = require("node-fetch");
describe("Log filter", () => {
it("should log messages when a logger object is provided", (done) => {
const expected = `>> Request: {
"headers": {},
"rawResponse": false,
"url": "https://foo.com",
"method": "PUT",
"body": {
"a": 1
}
}
>> Response status code: 200
>> Body: null
`;
let output = "";
const logger = (message) => { output += message + "\n"; };
const lf = new logFilter_1.LogFilter(logger);
const req = new webResource_1.WebResource("https://foo.com", "PUT", { "a": 1 });
const res = new node_fetch_1.Response();
const opRes = new httpOperationResponse_1.HttpOperationResponse(req, res, res.body);
lf.after(opRes).then(() => {
//console.dir(output, { depth: null });
//console.log(">>>>>>>");
//console.dir(expected);
assert.deepEqual(output, expected);
done();
}).catch((err) => {
done(err);
});
});
});
//# sourceMappingURL=logFilterTests.js.map

1
dist/test/logFilterTests.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"logFilterTests.js","sourceRoot":"","sources":["../../test/logFilterTests.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;AAG/F,iCAAiC;AACjC,oDAAiD;AACjD,wEAAqE;AACrE,wDAAqD;AAErD,2CAAsC;AAEtC,QAAQ,CAAC,YAAY,EAAE;IAErB,EAAE,CAAC,sDAAsD,EAAE,CAAC,IAAI;QAC9D,MAAM,QAAQ,GAAG;;;;;;;;;;;CAWpB,CAAC;QACE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,MAAM,GAAa,CAAC,OAAe,OAAa,MAAM,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClF,MAAM,EAAE,GAAG,IAAI,qBAAS,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,yBAAW,CAAC,iBAAiB,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAClE,MAAM,GAAG,GAAG,IAAI,qBAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,6CAAqB,CAAC,GAAG,EAAE,GAAU,EAAE,GAAG,CAAC,IAAW,CAAC,CAAC;QAC1E,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;YACnB,uCAAuC;YACvC,yBAAyB;YACzB,wBAAwB;YACxB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACnC,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU;YAClB,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

746
dist/test/serializationTests.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,746 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const moment = require("moment");
const msRest = require("../lib/msRest");
const should = require("should");
const testClient_1 = require("./data/TestClient/lib/testClient");
const mappers_1 = require("./data/Testclient/lib/models/mappers");
let Serializer = new msRest.Serializer({});
let valid_uuid = "ceaafd1e-f936-429f-bbfc-82ee75dddc33";
describe("msrest", function () {
describe("serializeObject", function () {
it("should correctly serialize a Date Object", function (done) {
let dateObj = new Date("2015-01-01");
let dateISO = "2015-01-01T00:00:00.000Z";
msRest.serializeObject(dateObj).should.equal(dateISO);
done();
});
it("should correctly serialize a Date object with max value", function (done) {
let serializedDateString = msRest.serializeObject(new Date("9999-12-31T23:59:59-12:00"));
serializedDateString.should.equal("+010000-01-01T11:59:59.000Z");
done();
});
it("should correctly serialize a Buffer Object", function (done) {
let bufferObj = new Buffer("Javascript");
let base64str = "SmF2YXNjcmlwdA==";
msRest.serializeObject(bufferObj).should.equal(base64str);
done();
});
it("should correctly serialize Primitive types", function (done) {
msRest.serializeObject(true).should.equal(true);
msRest.serializeObject(false).should.equal(false);
msRest.serializeObject("true").should.equal("true");
msRest.serializeObject(1).should.equal(1);
msRest.serializeObject(100.0123).should.equal(100.0123);
assert.equal(msRest.serializeObject(null), null);
done();
});
it("should correctly serialize an empty array and an empty dictionary", function (done) {
assert.deepEqual(msRest.serializeObject([]), []);
assert.deepEqual(msRest.serializeObject({}), {});
done();
});
it("should correctly serialize a complex JSON object", function (done) {
let o1 = {
"p1": "value1",
"p2": "value2",
"top-buf": new Buffer("top string", "utf-8"),
"top-date": new Date("2014"),
"top-dates": [new Date("1900"), new Date("1901")],
"insider": {
"insider-buf": new Buffer("insider string", "utf-8"),
"insider-date": new Date("2015"),
"insider-dates": [new Date("2100"), new Date("2101")],
"insider-dictionary": {
"k1": new Date("2015"),
"k2": new Date("2016"),
"k3": new Date("2017")
},
"top-complex": {
"id": 1,
"name": "Joey",
"age": 23.36,
"male": true,
"birthday": "1992-01-01T00:00:00.000Z",
"anniversary": new Date("2013-12-08"),
"memory": new Buffer("Yadadadada")
}
}
};
let o2 = {
p1: "value1",
p2: "value2",
"top-buf": "dG9wIHN0cmluZw==",
"top-date": "2014-01-01T00:00:00.000Z",
"top-dates": [
"1900-01-01T00:00:00.000Z",
"1901-01-01T00:00:00.000Z"
],
insider: {
"insider-buf": "aW5zaWRlciBzdHJpbmc=",
"insider-date": "2015-01-01T00:00:00.000Z",
"insider-dates": [
"2100-01-01T00:00:00.000Z",
"2101-01-01T00:00:00.000Z"
],
"insider-dictionary": {
k1: "2015-01-01T00:00:00.000Z",
k2: "2016-01-01T00:00:00.000Z",
k3: "2017-01-01T00:00:00.000Z"
},
"top-complex": {
id: 1,
name: "Joey",
age: 23.36,
male: true,
birthday: "1992-01-01T00:00:00.000Z",
anniversary: "2013-12-08T00:00:00.000Z",
memory: "WWFkYWRhZGFkYQ=="
}
}
};
assert.deepEqual(msRest.serializeObject(o1), o2);
done();
});
});
describe("serialize", function () {
let invalid_uuid = "abcd-efgd90-90890jkh";
it("should correctly serialize a string", function (done) {
let mapper = { type: { name: "String" }, required: false, serializedName: "string" };
let serializedObject = Serializer.serialize(mapper, "foo", "stringBody");
serializedObject.should.equal("foo");
done();
});
it("should correctly serialize a uuid", function (done) {
let mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
let serializedObject = Serializer.serialize(mapper, valid_uuid, "uuidBody");
serializedObject.should.equal(valid_uuid);
done();
});
it("should throw an error if the value is not a valid Uuid", function (done) {
let mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
try {
Serializer.serialize(mapper, invalid_uuid, "uuidBody");
}
catch (error) {
error.message.should.match(/.*with value.*must be of type string and a valid uuid/ig);
done();
}
});
it("should correctly serialize a number", function (done) {
let mapper = { type: { name: "Number" }, required: false, serializedName: "Number" };
let serializedObject = Serializer.serialize(mapper, 1.506, "stringBody");
serializedObject.should.equal(1.506);
done();
});
it("should correctly serialize a boolean", function (done) {
let mapper = { type: { name: "Boolean" }, required: false, serializedName: "Boolean" };
let serializedObject = Serializer.serialize(mapper, false, "stringBody");
serializedObject.should.equal(false);
done();
});
it("should correctly serialize an Enum", function (done) {
let mapper = { type: { name: "Enum", allowedValues: [1, 2, 3, 4] }, required: false, serializedName: "Enum" };
let serializedObject = Serializer.serialize(mapper, 1, "enumBody");
serializedObject.should.equal(1);
done();
});
it("should throw an error if the value is not valid for an Enum", function (done) {
let mapper = { type: { name: "Enum", allowedValues: [1, 2, 3, 4] }, required: false, serializedName: "Enum" };
try {
Serializer.serialize(mapper, 6, "enumBody");
}
catch (error) {
error.message.should.match(/6 is not a valid value for enumBody\. The valid values are: \[1,2,3,4\]/ig);
done();
}
});
it("should correctly serialize a Buffer Object", function (done) {
let mapper = { type: { name: "ByteArray" }, required: false, serializedName: "ByteArray" };
let bufferObj = new Buffer("Javascript");
let base64str = "SmF2YXNjcmlwdA==";
let serializedObject = Serializer.serialize(mapper, bufferObj, "stringBody");
serializedObject.should.equal(base64str);
done();
});
it("should correctly serialize a Date Object", function (done) {
let dateObj = new Date("2015-01-01");
let dateISO = "2015-01-01";
let mapper = { type: { name: "Date" }, required: false, serializedName: "Date" };
Serializer.serialize(mapper, dateObj, "dateObj").should.equal(dateISO);
done();
});
it("should correctly serialize a Date object with max value", function (done) {
let mapper = { type: { name: "DateTime" }, required: false, serializedName: "DateTime" };
let serializedDateString = Serializer.serialize(mapper, new Date("9999-12-31T23:59:59-12:00"), "dateTimeObj");
should.equal(serializedDateString, "+010000-01-01T11:59:59.000Z");
done();
});
it("should correctly serialize a Date object with max value and format UnixTime", function (done) {
let mapper = { type: { name: "UnixTime" }, required: false, serializedName: "UnixTime" };
let serializedDate = Serializer.serialize(mapper, new Date("9999-12-31T23:59:59-12:00"), "dateTimeObj");
serializedDate.should.equal(253402343999);
done();
});
it("should correctly serialize a string in DateTimeRfc1123", function (done) {
let mapper = { type: { name: "DateTimeRfc1123" }, required: false, serializedName: "DateTimeRfc1123" };
let rfc = new Date("Mon, 01 Jan 0001 00:00:00 GMT");
let serializedDateString = Serializer.serialize(mapper, rfc, "dateTimeObj");
serializedDateString.should.equal("Mon, 01 Jan 2001 00:00:00 GMT");
done();
});
it("should correctly serialize a duration object", function (done) {
let mapper = { type: { name: "TimeSpan" }, required: false, serializedName: "TimeSpan" };
let duration = moment.duration({ days: 123, hours: 22, minutes: 14, seconds: 12, milliseconds: 11 });
let serializedDateString = Serializer.serialize(mapper, duration, "dateTimeObj");
serializedDateString.should.equal("P123DT22H14M12.010999999998603S");
done();
});
it("should correctly serialize an array of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
type: { name: "String" },
required: true,
serializedName: "sequenceElement"
}
}
};
let array = ["One", "Two", "three"];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize an array of array of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Number"
}
}
}
}
}
};
let array = [[1], [2], [1, 2, 3]];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize an array of dictionary of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Boolean"
}
}
}
}
}
};
let array = [{ 1: true }, { 2: false }, { 1: true, 2: false, 3: true }];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize a dictionary of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "String"
}
}
}
};
let dict = { 1: "One", 2: "Two", 3: "three" };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a dictionary of array of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Number"
}
}
}
}
}
};
let dict = { "One": [1], "Two": [1, 2], "three": [1, 2, 3] };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a dictionary of dictionary of primitives", function (done) {
let mapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Boolean"
}
}
}
}
}
};
let dict = { 1: { "One": true }, 2: { "Two": false }, 3: { "three": true } };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a composite type", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.Product;
let productObj = {
id: 101,
name: "TestProduct",
provisioningState: "Succeeded",
tags: {
tag1: "value1",
tag2: "value2"
},
dispatchTime: new Date("2015-01-01T12:35:36.009Z"),
invoiceInfo: {
invId: 1002,
invDate: "2015-12-25",
invProducts: [
{
"Product1": {
id: 101,
name: "TestProduct"
}
},
{
"Product2": {
id: 104,
name: "TestProduct1"
}
}
]
},
subProducts: [
{
subId: 102,
subName: "SubProduct1",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invId: 1002,
invDate: "2015-12-25"
}
},
{
subId: 103,
subName: "SubProduct2",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invId: 1003,
invDate: "2015-12-25"
}
}
]
};
let serializedProduct = client.serializer.serialize(mapper, productObj, "productObject");
for (let prop in serializedProduct) {
if (prop === "properties") {
serializedProduct[prop].provisioningState.should.equal(productObj.provisioningState);
}
else if (prop === "id") {
serializedProduct[prop].should.equal(productObj.id);
}
else if (prop === "name") {
serializedProduct[prop].should.equal(productObj.name);
}
else if (prop === "tags") {
JSON.stringify(serializedProduct[prop]).should.equal(JSON.stringify(productObj.tags));
}
else if (prop === "dispatchTime") {
JSON.stringify(serializedProduct[prop]).should.equal(JSON.stringify(productObj.dispatchTime));
}
else if (prop === "invoiceInfo") {
(JSON.stringify(serializedProduct[prop]).length - JSON.stringify(productObj.invoiceInfo).length).should.equal(4);
}
else if (prop === "subProducts") {
(JSON.stringify(serializedProduct[prop]).length - JSON.stringify(productObj.subProducts).length).should.equal(8);
}
}
done();
});
it("should correctly serialize object version of polymorphic discriminator", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.SawShark;
let sawshark = {
"fishtype": "sawshark",
"age": 22,
"birthday": new Date("2012-01-05T01:00:00Z"),
"species": "king",
"length": 1.0,
"picture": new Buffer([255, 255, 255, 255, 254]),
"siblings": [
{
"fishtype": "shark",
"age": 6,
"birthday": new Date("2012-01-05T01:00:00Z"),
"length": 20.0,
"species": "predator"
},
{
"fishtype": "sawshark",
"age": 105,
"birthday": new Date("1900-01-05T01:00:00Z"),
"length": 10.0,
"picture": new Buffer([255, 255, 255, 255, 254]),
"species": "dangerous"
}
]
};
let serializedSawshark = client.serializer.serialize(mapper, sawshark, "result");
serializedSawshark.age.should.equal(22);
serializedSawshark["fish.type"].should.equal("sawshark");
serializedSawshark.siblings.length.should.equal(2);
serializedSawshark.siblings[0]["fish.type"].should.equal("shark");
serializedSawshark.siblings[0].age.should.equal(6);
serializedSawshark.siblings[0].birthday.should.equal(new Date("2012-01-05T01:00:00Z").toISOString());
serializedSawshark.siblings[1]["fish.type"].should.equal("sawshark");
serializedSawshark.siblings[1].age.should.equal(105);
serializedSawshark.siblings[1].birthday.should.equal(new Date("1900-01-05T01:00:00Z").toISOString());
serializedSawshark.siblings[1].picture.should.equal("//////4=");
serializedSawshark.picture.should.equal("//////4=");
done();
});
it("should correctly serialize string version of polymorphic discriminator", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.PetGallery;
let petgallery = {
"id": 1,
"name": "Fav pet gallery",
"pets": [
{
"id": 2,
"name": "moti",
"food": "buiscuit",
"pet.type": "Dog",
"pettype": "Dog"
},
{
"id": 3,
"name": "billa",
"color": "red",
"pet.type": "Cat",
"pettype": "Cat" // In string version the user has to pass the actual property with dot and the normalized one.
}
]
};
let serializedPetGallery = client.serializer.serialize(mapper, petgallery, "result");
serializedPetGallery.id.should.equal(1);
serializedPetGallery.name.should.equal("Fav pet gallery");
serializedPetGallery.pets.length.should.equal(2);
serializedPetGallery.pets[0]["pet.type"].should.equal("Dog");
serializedPetGallery.pets[0].id.should.equal(2);
serializedPetGallery.pets[0].name.should.equal("moti");
serializedPetGallery.pets[0].food.should.equal("buiscuit");
serializedPetGallery.pets[1]["pet.type"].should.equal("Cat");
serializedPetGallery.pets[1].id.should.equal(3);
serializedPetGallery.pets[1].name.should.equal("billa");
serializedPetGallery.pets[1].color.should.equal("red");
done();
});
});
describe("deserialize", function () {
it("should correctly deserialize a uuid", function (done) {
let mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
let serializedObject = Serializer.deserialize(mapper, valid_uuid, "uuidBody");
serializedObject.should.equal(valid_uuid);
done();
});
it("should correctly deserialize a composite type", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.Product;
let responseBody = {
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
},
tags: {
tag1: "value1",
tag2: "value2"
},
dispatchTime: new Date("2015-01-01T12:35:36.009Z"),
invoiceInfo: {
invoiceId: 1002,
invDate: "2015-12-25",
invProducts: [
{
"Product1": {
id: 101,
name: "TestProduct"
}
},
{
"Product2": {
id: 104,
name: "TestProduct1"
}
}
]
},
subProducts: [
{
subId: 102,
subName: "SubProduct1",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invoiceId: 1002,
invDate: "2015-12-25"
}
},
{
subId: 103,
subName: "SubProduct2",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invoiceId: 1003,
invDate: "2015-12-25"
}
}
]
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
for (let prop in deserializedProduct) {
if (prop === "provisioningState") {
deserializedProduct.provisioningState.should.equal(responseBody.properties.provisioningState);
}
else if (prop === "id") {
deserializedProduct[prop].should.equal(responseBody.id);
}
else if (prop === "name") {
deserializedProduct[prop].should.equal(responseBody.name);
}
else if (prop === "tags") {
JSON.stringify(deserializedProduct[prop]).should.equal(JSON.stringify(responseBody.tags));
}
else if (prop === "dispatchTime") {
JSON.stringify(deserializedProduct[prop]).should.equal(JSON.stringify(responseBody.dispatchTime));
}
else if (prop === "invoiceInfo") {
(JSON.stringify(deserializedProduct[prop]).length - JSON.stringify(responseBody.invoiceInfo).length).should.equal(10);
}
else if (prop === "subProducts") {
(JSON.stringify(deserializedProduct[prop]).length - JSON.stringify(responseBody.subProducts).length).should.equal(20);
}
}
done();
});
it("should correctly deserialize a pageable type without nextLink", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.ProductListResult;
let responseBody = {
value: [
{
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
}
},
{
id: 104,
name: "TestProduct1",
properties: {
provisioningState: "Failed"
}
}
]
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
(Array.isArray(deserializedProduct)).should.be.true;
deserializedProduct.length.should.equal(2);
for (let i = 0; i < deserializedProduct.length; i++) {
if (i === 0) {
deserializedProduct[i].id.should.equal(101);
deserializedProduct[i].name.should.equal("TestProduct");
deserializedProduct[i].provisioningState.should.equal("Succeeded");
}
else if (i === 1) {
deserializedProduct[i].id.should.equal(104);
deserializedProduct[i].name.should.equal("TestProduct1");
deserializedProduct[i].provisioningState.should.equal("Failed");
}
}
done();
});
it("should correctly deserialize a pageable type with nextLink", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.ProductListResultNextLink;
let responseBody = {
value: [
{
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
}
},
{
id: 104,
name: "TestProduct1",
properties: {
provisioningState: "Failed"
}
}
],
nextLink: "https://helloworld.com"
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
(Array.isArray(deserializedProduct)).should.be.true;
deserializedProduct.length.should.equal(2);
deserializedProduct.nextLink.should.equal("https://helloworld.com");
for (let i = 0; i < deserializedProduct.length; i++) {
if (i === 0) {
deserializedProduct[i].id.should.equal(101);
deserializedProduct[i].name.should.equal("TestProduct");
deserializedProduct[i].provisioningState.should.equal("Succeeded");
}
else if (i === 1) {
deserializedProduct[i].id.should.equal(104);
deserializedProduct[i].name.should.equal("TestProduct1");
deserializedProduct[i].provisioningState.should.equal("Failed");
}
}
done();
});
it("should correctly deserialize object version of polymorphic discriminator", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.Fish;
let responseBody = {
"fish.type": "sawshark",
"age": 22,
"birthday": new Date("2012-01-05T01:00:00Z").toISOString(),
"species": "king",
"length": 1.0,
"picture": new Buffer([255, 255, 255, 255, 254]).toString(),
"siblings": [
{
"fish.type": "shark",
"age": 6,
"birthday": new Date("2012-01-05T01:00:00Z"),
"length": 20.0,
"species": "predator"
},
{
"fish.type": "sawshark",
"age": 105,
"birthday": new Date("1900-01-05T01:00:00Z").toISOString(),
"length": 10.0,
"picture": new Buffer([255, 255, 255, 255, 254]).toString(),
"species": "dangerous"
}
]
};
let deserializedSawshark = client.serializer.deserialize(mapper, responseBody, "responseBody");
deserializedSawshark.age.should.equal(22);
deserializedSawshark.fishtype.should.equal("sawshark");
deserializedSawshark.siblings.length.should.equal(2);
deserializedSawshark.siblings[0].fishtype.should.equal("shark");
deserializedSawshark.siblings[0].age.should.equal(6);
deserializedSawshark.siblings[0].birthday.toISOString().should.equal("2012-01-05T01:00:00.000Z");
deserializedSawshark.siblings[1].fishtype.should.equal("sawshark");
deserializedSawshark.siblings[1].age.should.equal(105);
deserializedSawshark.siblings[1].birthday.toISOString().should.equal("1900-01-05T01:00:00.000Z");
done();
});
it("should correctly deserialize string version of polymorphic discriminator", function (done) {
let client = new testClient_1.TestClient("http://localhost:9090");
let mapper = mappers_1.Mappers.PetGallery;
let petgallery = {
"id": 1,
"name": "Fav pet gallery",
"pets": [
{
"id": 2,
"name": "moti",
"food": "buiscuit",
"pet.type": "Dog",
},
{
"id": 3,
"name": "billa",
"color": "red",
"pet.type": "Cat",
}
]
};
let deserializedPetGallery = client.serializer.deserialize(mapper, petgallery, "result");
deserializedPetGallery.id.should.equal(1);
deserializedPetGallery.name.should.equal("Fav pet gallery");
deserializedPetGallery.pets.length.should.equal(2);
deserializedPetGallery.pets[0]["pettype"].should.equal("Dog");
deserializedPetGallery.pets[0].id.should.equal(2);
deserializedPetGallery.pets[0].name.should.equal("moti");
deserializedPetGallery.pets[0].food.should.equal("buiscuit");
deserializedPetGallery.pets[1]["pettype"].should.equal("Cat");
deserializedPetGallery.pets[1].id.should.equal(3);
deserializedPetGallery.pets[1].name.should.equal("billa");
deserializedPetGallery.pets[1].color.should.equal("red");
done();
});
});
});
//# sourceMappingURL=serializationTests.js.map

1
dist/test/serializationTests.js.map поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

65
dist/test/userAgentFilterTests.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,65 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const webResource_1 = require("../lib/webResource");
const msRestUserAgentFilter_1 = require("../lib/filters/msRestUserAgentFilter");
const constants_1 = require("../lib/util/constants");
const should = require("should");
const userAgentHeader = constants_1.Constants.HeaderConstants.USER_AGENT;
describe("ms-rest user agent filter", () => {
it("should construct user agent header when supplied empty array", (done) => {
const userAgentArray = [];
const userAgentFilter = new msRestUserAgentFilter_1.MsRestUserAgentFilter(userAgentArray);
const resource = new webResource_1.WebResource();
resource.headers = {};
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
resource.headers[userAgentHeader].should.containEql("Node");
resource.headers[userAgentHeader].should.containEql("Azure-SDK-For-Node");
done();
}).catch((err) => { done(err); });
});
it("should not modify user agent header if already present", (done) => {
const genericRuntime = "ms-rest";
const azureRuntime = "ms-rest-azure";
const azureSDK = "Azure-SDK-For-Node";
const userAgentArray = [`${genericRuntime}/v1.0.0`, `${azureRuntime}/v1.0.0`];
const userAgentFilter = new msRestUserAgentFilter_1.MsRestUserAgentFilter(userAgentArray);
const customUA = "my custom user agent";
const resource = new webResource_1.WebResource();
resource.headers = {};
resource.headers[userAgentHeader] = customUA;
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
const actualUA = resource.headers[userAgentHeader];
actualUA.should.not.containEql("Node");
actualUA.should.not.containEql(azureSDK);
actualUA.should.not.containEql(azureRuntime);
actualUA.should.containEql(customUA);
done();
}).catch((err) => { done(err); });
});
it("should insert azure-sdk-for-node at right position", (done) => {
const genericRuntime = "ms-rest";
const azureRuntime = "ms-rest-azure";
const azureSDK = "Azure-SDK-For-Node";
const userAgentArray = [`${genericRuntime}/v1.0.0`, `${azureRuntime}/v1.0.0`];
const userAgentFilter = new msRestUserAgentFilter_1.MsRestUserAgentFilter(userAgentArray);
const resource = new webResource_1.WebResource();
resource.headers = {};
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
const deconstructedUserAgent = resource.headers[userAgentHeader].split(" ");
should.ok(deconstructedUserAgent);
const indexOfAzureRuntime = deconstructedUserAgent.findIndex((e) => e.startsWith(azureRuntime));
assert.notEqual(indexOfAzureRuntime, -1, `did not find ${azureRuntime} in user agent`);
const indexOfAzureSDK = deconstructedUserAgent.indexOf(azureSDK);
assert.notEqual(indexOfAzureSDK, -1, `did not find ${azureSDK} in user agent`);
assert.equal(indexOfAzureSDK, 1 + indexOfAzureRuntime, `${azureSDK} is not in the right place in user agent string`);
done();
}).catch((err) => { done(err); });
});
});
//# sourceMappingURL=userAgentFilterTests.js.map

1
dist/test/userAgentFilterTests.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"userAgentFilterTests.js","sourceRoot":"","sources":["../../test/userAgentFilterTests.ts"],"names":[],"mappings":"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"}

30
gulpfile.js Normal file
Просмотреть файл

@ -0,0 +1,30 @@
var gulp = require("gulp"),
tslint = require("gulp-tslint"),
tsc = require("gulp-typescript"),
sourcemaps = require("gulp-sourcemaps"),
runSequence = require("run-sequence"),
mocha = require("gulp-mocha");
gulp.task('default', function () {
console.log("run gulp -T to see all available tasks.\n");
});
gulp.task("lint", () =>
gulp.src([
"lib/**/**.ts",
"test/**/**.ts"
])
.pipe(tslint({
formatter: "verbose"
}))
.pipe(tslint.report())
);
// TODO: Doesn't yet confirm to folder structure
gulp.task("build", () =>
gulp.src([
"lib/**/**.ts"
])
.pipe(tsc(tsc.createProject("tsconfig.json")))
.js.pipe(gulp.dest("dist/lib/"))
);

Просмотреть файл

@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { Constants } from "../util/constants";
import { WebResource } from "../webResource";
import { ServiceClientCredentials } from "./serviceClientCredentials";
const HeaderConstants = Constants.HeaderConstants;
const DEFAULT_AUTHORIZATION_SCHEME = "Basic";
/**
* Creates a new BasicAuthenticationCredentials object.
*
* @constructor
* @param {string} userName User name.
* @param {string} password Password.
* @param {string} [authorizationScheme] The authorization scheme.
*/
export class BasicAuthenticationCredentials implements ServiceClientCredentials {
userName: string;
password: string;
authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME;
constructor(userName: string, password: string, authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME) {
if (userName === null || userName === undefined || typeof userName.valueOf() !== "string") {
throw new Error("userName cannot be null or undefined and must be of type string.");
}
if (password === null || password === undefined || typeof password.valueOf() !== "string") {
throw new Error("password cannot be null or undefined and must be of type string.");
}
this.userName = userName;
this.password = password;
this.authorizationScheme = authorizationScheme;
}
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @returns {Promise<WebResource>} - The signed request object.
*/
signRequest(webResource: WebResource) {
const credentials = `${this.userName}:${this.password}`;
const encodedCredentials = `${this.authorizationScheme} ${Buffer.from(credentials).toString("base64")}`;
if (!webResource.headers) webResource.headers = {};
webResource.headers[HeaderConstants.AUTHORIZATION] = encodedCredentials;
return Promise.resolve(webResource);
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource } from "../webResource";
export interface ServiceClientCredentials {
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} webResource The WebResource/request to be signed.
* @returns {Promise<WebResource>} The signed request object;
*/
signRequest(webResource: WebResource): Promise<WebResource>;
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { Constants } from "../util/constants";
import { WebResource } from "../webResource";
import { ServiceClientCredentials } from "./serviceClientCredentials";
const HeaderConstants = Constants.HeaderConstants;
const DEFAULT_AUTHORIZATION_SCHEME = "Bearer";
/**
* Creates a new TokenCredentials object.
*
* @constructor
* @param {string} token The token.
* @param {string} authorizationScheme The authorization scheme.
*/
export class TokenCredentials implements ServiceClientCredentials {
token: string;
authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME;
constructor(token: string, authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME) {
if (!token) {
throw new Error("token cannot be null or undefined.");
}
this.token = token;
this.authorizationScheme = authorizationScheme;
}
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @return {Promise<WebResource>} The signed request object.
*/
signRequest(webResource: WebResource) {
if (!webResource.headers) webResource.headers = {};
webResource.headers[HeaderConstants.AUTHORIZATION] = `${this.authorizationScheme} ${this.token}`;
return Promise.resolve(webResource);
}
}

18
lib/filters/baseFilter.ts Normal file
Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource } from "../webResource";
import { HttpOperationResponse } from "../httpOperationResponse";
export class BaseFilter {
constructor() { }
before(request: WebResource): Promise<WebResource> {
return Promise.resolve(request);
}
after(response: HttpOperationResponse): Promise<HttpOperationResponse> {
return Promise.resolve(response);
}
}

Просмотреть файл

@ -0,0 +1,132 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import * as utils from "../util/utils";
import { HttpOperationResponse } from "../httpOperationResponse";
export interface RetryData {
retryCount: number;
retryInterval: number;
error?: RetryError;
}
export interface RetryError extends Error {
message: string;
code?: string;
innerError?: RetryError;
}
/**
* @class
* Instantiates a new "ExponentialRetryPolicyFilter" instance.
*
* @constructor
* @param {number} retryCount The client retry count.
* @param {number} retryInterval The client retry interval, in milliseconds.
* @param {number} minRetryInterval The minimum retry interval, in milliseconds.
* @param {number} maxRetryInterval The maximum retry interval, in milliseconds.
*/
export class ExponentialRetryPolicyFilter extends BaseFilter {
retryCount: number;
retryInterval: number;
minRetryInterval: number;
maxRetryInterval: number;
DEFAULT_CLIENT_RETRY_INTERVAL = 1000 * 30;
DEFAULT_CLIENT_RETRY_COUNT = 3;
DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 90;
DEFAULT_CLIENT_MIN_RETRY_INTERVAL = 1000 * 3;
constructor(retryCount?: number, retryInterval?: number, minRetryInterval?: number, maxRetryInterval?: number) {
super();
this.retryCount = typeof retryCount === "number" ? retryCount : this.DEFAULT_CLIENT_RETRY_COUNT;
this.retryInterval = typeof retryInterval === "number" ? retryInterval : this.DEFAULT_CLIENT_RETRY_INTERVAL;
this.minRetryInterval = typeof minRetryInterval === "number" ? minRetryInterval : this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL;
this.maxRetryInterval = typeof maxRetryInterval === "number" ? maxRetryInterval : this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
}
/**
* Determines if the operation should be retried and how long to wait until the next retry.
*
* @param {number} statusCode The HTTP status code.
* @param {RetryData} retryData The retry data.
* @return {boolean} True if the operation qualifies for a retry; false otherwise.
*/
shouldRetry(statusCode: number, retryData: RetryData): boolean {
if ((statusCode < 500 && statusCode !== 408) || statusCode === 501 || statusCode === 505) {
return false;
}
let currentCount: number;
if (!retryData) {
throw new Error("retryData for the ExponentialRetryPolicyFilter cannot be null.");
} else {
currentCount = (retryData && retryData.retryCount);
}
return (currentCount < this.retryCount);
}
/**
* Updates the retry data for the next attempt.
*
* @param {RetryData} retryData The retry data.
* @param {object} err The operation"s error, if any.
*/
updateRetryData(retryData?: RetryData, err?: RetryError): RetryData {
if (!retryData) {
retryData = {
retryCount: 0,
retryInterval: 0
};
}
if (err) {
if (retryData.error) {
err.innerError = retryData.error;
}
retryData.error = err;
}
// Adjust retry count
retryData.retryCount++;
// Adjust retry interval
let incrementDelta = Math.pow(2, retryData.retryCount) - 1;
const boundedRandDelta = this.retryInterval * 0.8 +
Math.floor(Math.random() * (this.retryInterval * 1.2 - this.retryInterval * 0.8));
incrementDelta *= boundedRandDelta;
retryData.retryInterval = Math.min(this.minRetryInterval + incrementDelta, this.maxRetryInterval);
return retryData;
}
async retry(operationResponse: HttpOperationResponse, retryData?: RetryData, err?: RetryError): Promise<HttpOperationResponse> {
const self = this;
const response = operationResponse.response;
retryData = self.updateRetryData(retryData, err);
if (!utils.objectIsNull(response) && self.shouldRetry(response.status, retryData)) {
try {
await utils.delay(retryData.retryInterval);
const res: HttpOperationResponse = await utils.dispatchRequest(operationResponse.request);
return self.retry(res, retryData, err);
} catch (err) {
return self.retry(operationResponse, retryData, err);
}
} else {
if (!utils.objectIsNull(err)) {
// If the operation failed in the end, return all errors instead of just the last one
err = retryData.error;
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
}
}
after(operationResponse: HttpOperationResponse): Promise<HttpOperationResponse> {
return this.retry(operationResponse);
}
}

24
lib/filters/logFilter.ts Normal file
Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import { HttpOperationResponse } from "../httpOperationResponse";
export class LogFilter extends BaseFilter {
logger?: any;
constructor(logger: any = console.log) {
super();
this.logger = logger;
}
after(operationResponse: HttpOperationResponse): Promise<HttpOperationResponse> {
const self = this;
self.logger(`>> Request: ${JSON.stringify(operationResponse.request, undefined, 2)}`);
self.logger(`>> Response status code: ${operationResponse.response.status}`);
const responseBody = operationResponse.bodyAsText;
self.logger(`>> Body: ${responseBody}`);
return Promise.resolve(operationResponse);
}
}

Просмотреть файл

@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import { WebResource } from "../webResource";
import { Constants } from "../util/constants";
import * as os from "os";
const isNode = require("detect-node");
const HeaderConstants = Constants.HeaderConstants;
export class MsRestUserAgentFilter extends BaseFilter {
userAgentInfo: Array<string>;
constructor(userAgentInfo: Array<string>) {
super();
this.userAgentInfo = userAgentInfo;
}
tagRequest(request: WebResource): Promise<WebResource> {
if (isNode) {
const osInfo = `(${os.arch()}-${os.type()}-${os.release()})`;
if (this.userAgentInfo.indexOf(osInfo) === -1) {
this.userAgentInfo.unshift(osInfo);
}
const runtimeInfo = `Node/${process.version}`;
if (this.userAgentInfo.indexOf(runtimeInfo) === -1) {
this.userAgentInfo.unshift(runtimeInfo);
}
const nodeSDKSignature = `Azure-SDK-For-Node`;
if (this.userAgentInfo.indexOf(nodeSDKSignature) === -1) {
const azureRuntime = `ms-rest-azure`;
let insertIndex = this.userAgentInfo.indexOf(azureRuntime);
// insert after azureRuntime, otherwise, insert last.
insertIndex = insertIndex < 0 ? this.userAgentInfo.length : insertIndex + 1;
this.userAgentInfo.splice(insertIndex, 0, nodeSDKSignature);
}
if (!request.headers) request.headers = {};
request.headers[HeaderConstants.USER_AGENT] = this.userAgentInfo.join(" ");
}
return Promise.resolve(request);
}
before(request: WebResource): Promise<WebResource> {
const self = this;
if (!request.headers) request.headers = {};
if (!request.headers[HeaderConstants.USER_AGENT]) {
return self.tagRequest(request);
} else {
return Promise.resolve(request);
}
}
}

Просмотреть файл

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import { HttpOperationResponse } from "../httpOperationResponse";
import * as utils from "../util/utils";
const parse = require("url-parse");
export class RedirectFilter extends BaseFilter {
maximumRetries?: number;
constructor(maximumRetries = 20) {
super();
this.maximumRetries = maximumRetries;
}
async handleRedirect(operationResponse: HttpOperationResponse, currentRetries: number): Promise<HttpOperationResponse> {
const request = operationResponse.request;
const response = operationResponse.response;
if (response && response.headers && response.headers.get("location") &&
(response.status === 300 || response.status === 307 || (response.status === 303 && request.method === "POST")) &&
(!this.maximumRetries || currentRetries < this.maximumRetries)) {
if (parse(response.headers.get("location")).hostname) {
request.url = response.headers.get("location") as string;
} else {
const urlObject = parse(request.url);
urlObject.set("pathname", response.headers.get("location") as string);
request.url = urlObject.href;
}
// POST request with Status code 303 should be converted into a
// redirected GET request if the redirect url is present in the location header
if (response.status === 303) {
request.method = "GET";
}
let res: HttpOperationResponse;
try {
res = await utils.dispatchRequest(request);
currentRetries++;
} catch (err) {
return Promise.reject(err);
}
return this.handleRedirect(res, currentRetries);
}
return Promise.resolve(operationResponse);
}
after(operationResponse: HttpOperationResponse): Promise<HttpOperationResponse> {
return this.handleRedirect(operationResponse, 0);
}
}

Просмотреть файл

@ -0,0 +1,180 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import { HttpOperationResponse } from "../httpOperationResponse";
import { WebResource } from "../webResource";
import * as utils from "../util/utils";
let retryTimeout = 30;
export class RPRegistrationFilter extends BaseFilter {
constructor(retryTimeout = 30) {
super();
retryTimeout = retryTimeout;
}
async after(operationResponse: HttpOperationResponse): Promise<HttpOperationResponse> {
let rpName, urlPrefix;
const options = operationResponse.request;
if (operationResponse.response.status === 409) {
rpName = this.checkRPNotRegisteredError(operationResponse.bodyAsText as string);
}
if (rpName) {
urlPrefix = this.extractSubscriptionUrl(options.url);
let registrationStatus = false;
try {
registrationStatus = await this.registerRP(urlPrefix, rpName, options);
} catch (err) {
// Autoregistration of ${provider} failed for some reason. We will not return this error
// instead will return the initial response with 409 status code back to the user.
// do nothing here as we are returning the original response at the end of this method.
}
if (registrationStatus) {
// Retry the original request. We have to change the x-ms-client-request-id
// otherwise Azure endpoint will return the initial 409 (cached) response.
options.headers["x-ms-client-request-id"] = utils.generateUuid();
let finalRes: HttpOperationResponse;
try {
finalRes = await utils.dispatchRequest(options);
} catch (err) {
return Promise.reject(err);
}
return Promise.resolve(finalRes);
}
}
return Promise.resolve(operationResponse);
}
/**
* Reuses the headers of the original request and url (if specified).
* @param {WebResource} originalRequest The original request
* @param {boolean} reuseUrlToo Should the url from the original request be reused as well. Default false.
* @returns {object} reqOptions - A new request object with desired headers.
*/
getRequestEssentials(originalRequest: WebResource, reuseUrlToo = false): any {
const reqOptions: any = {
headers: {}
};
if (reuseUrlToo) {
reqOptions.url = originalRequest.url;
}
// Copy over the original request headers. This will get us the auth token and other useful stuff from
// the original request header. Thus making it easier to make requests from this filter.
for (const h in originalRequest.headers) {
reqOptions.headers[h] = originalRequest.headers[h];
}
// We have to change the x-ms-client-request-id otherwise Azure endpoint
// will return the initial 409 (cached) response.
reqOptions.headers["x-ms-client-request-id"] = utils.generateUuid();
// Set content-type to application/json
reqOptions.headers["Content-Type"] = "application/json; charset=utf-8";
return reqOptions;
}
/**
* Validates the error code and message associated with 409 response status code. If it matches to that of
* RP not registered then it returns the name of the RP else returns undefined.
* @param {string} body - The response body received after making the original request.
* @returns {string} result The name of the RP if condition is satisfied else undefined.
*/
checkRPNotRegisteredError(body: string): string {
let result, responseBody;
if (body) {
try {
responseBody = JSON.parse(body);
} catch (err) {
// do nothing;
}
if (responseBody && responseBody.error && responseBody.error.message &&
responseBody.error.code && responseBody.error.code === "MissingSubscriptionRegistration") {
const matchRes = responseBody.error.message.match(/.*'(.*)'/i);
if (matchRes) {
result = matchRes.pop();
}
}
}
return result;
}
/**
* Extracts the first part of the URL, just after subscription:
* https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
* @param {string} url - The original request url
* @returns {string} urlPrefix The url prefix as explained above.
*/
extractSubscriptionUrl(url: string): string {
let result;
const matchRes = url.match(/.*\/subscriptions\/[a-f0-9-]+\//ig);
if (matchRes && matchRes[0]) {
result = matchRes[0];
} else {
throw new Error(`Unable to extract subscriptionId from the given url - ${url}.`);
}
return result;
}
/**
* Registers the given provider.
* @param {string} urlPrefix - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
* @param {string} provider - The provider name to be registered.
* @param {object} originalRequest - The original request sent by the user that returned a 409 response
* with a message that the provider is not registered.
* @param {registrationCallback} callback - The callback that handles the RP registration
*/
async registerRP(urlPrefix: string, provider: string, originalRequest: WebResource): Promise<boolean> {
const postUrl = `${urlPrefix}providers/${provider}/register?api-version=2016-02-01`;
const getUrl = `${urlPrefix}providers/${provider}?api-version=2016-02-01`;
const reqOptions = this.getRequestEssentials(originalRequest);
reqOptions.method = "POST";
reqOptions.url = postUrl;
let res: HttpOperationResponse;
try {
res = await utils.dispatchRequest(reqOptions);
} catch (err) {
return Promise.reject(err);
}
if (res.response.status !== 200) {
return Promise.reject(new Error(`Autoregistration of ${provider} failed. Please try registering manually.`));
}
let statusRes = false;
try {
statusRes = await this.getRegistrationStatus(getUrl, originalRequest);
} catch (err) {
return Promise.reject(err);
}
return Promise.resolve(statusRes);
}
/**
* Polls the registration status of the provider that was registered. Polling happens at an interval of 30 seconds.
* Polling will happen till the registrationState property of the response body is "Registered".
* @param {string} url - The request url for polling
* @param {object} originalRequest - The original request sent by the user that returned a 409 response
* with a message that the provider is not registered.
* @returns {Promise<boolean>} promise - True if RP Registration is successful.
*/
async getRegistrationStatus(url: string, originalRequest: WebResource): Promise<boolean> {
const reqOptions: any = this.getRequestEssentials(originalRequest);
let res: HttpOperationResponse;
let result = false;
reqOptions.url = url;
reqOptions.method = "GET";
try {
res = await utils.dispatchRequest(reqOptions);
} catch (err) {
return Promise.reject(err);
}
const obj = (res.bodyAsJson as any);
if (res.bodyAsJson && obj.registrationState && obj.registrationState === "Registered") {
result = true;
} else {
setTimeout(() => { return this.getRegistrationStatus(url, originalRequest); }, retryTimeout * 1000);
}
return Promise.resolve(result);
}
}

Просмотреть файл

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import { WebResource } from "../webResource";
import { ServiceClientCredentials } from "../credentials/serviceClientCredentials";
export class SigningFilter extends BaseFilter {
authenticationProvider: ServiceClientCredentials;
constructor(authenticationProvider: ServiceClientCredentials) {
super();
this.authenticationProvider = authenticationProvider;
}
before(request: WebResource): Promise<WebResource> {
const self = this;
return self.authenticationProvider.signRequest(request);
}
}

Просмотреть файл

@ -0,0 +1,129 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { BaseFilter } from "./baseFilter";
import * as utils from "../util/utils";
import { HttpOperationResponse } from "../httpOperationResponse";
export interface RetryData {
retryCount: number;
retryInterval: number;
error?: RetryError;
}
export interface RetryError extends Error {
message: string;
code?: string;
innerError?: RetryError;
}
/**
* @class
* Instantiates a new "ExponentialRetryPolicyFilter" instance.
*
* @constructor
* @param {number} retryCount The client retry count.
* @param {number} retryInterval The client retry interval, in milliseconds.
* @param {number} minRetryInterval The minimum retry interval, in milliseconds.
* @param {number} maxRetryInterval The maximum retry interval, in milliseconds.
*/
export class SystemErrorRetryPolicyFilter extends BaseFilter {
retryCount: number;
retryInterval: number;
minRetryInterval: number;
maxRetryInterval: number;
DEFAULT_CLIENT_RETRY_INTERVAL = 1000 * 30;
DEFAULT_CLIENT_RETRY_COUNT = 3;
DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 90;
DEFAULT_CLIENT_MIN_RETRY_INTERVAL = 1000 * 3;
constructor(retryCount?: number, retryInterval?: number, minRetryInterval?: number, maxRetryInterval?: number) {
super();
this.retryCount = typeof retryCount === "number" ? retryCount : this.DEFAULT_CLIENT_RETRY_COUNT;
this.retryInterval = typeof retryInterval === "number" ? retryInterval : this.DEFAULT_CLIENT_RETRY_INTERVAL;
this.minRetryInterval = typeof minRetryInterval === "number" ? minRetryInterval : this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL;
this.maxRetryInterval = typeof maxRetryInterval === "number" ? maxRetryInterval : this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
}
/**
* Determines if the operation should be retried and how long to wait until the next retry.
*
* @param {number} statusCode The HTTP status code.
* @param {RetryData} retryData The retry data.
* @return {boolean} True if the operation qualifies for a retry; false otherwise.
*/
shouldRetry(retryData: RetryData): boolean {
let currentCount;
if (!retryData) {
throw new Error("retryData for the SystemErrorRetryPolicyFilter cannot be null.");
} else {
currentCount = (retryData && retryData.retryCount);
}
return (currentCount < this.retryCount);
}
/**
* Updates the retry data for the next attempt.
*
* @param {RetryData} retryData The retry data.
* @param {object} err The operation"s error, if any.
*/
updateRetryData(retryData?: RetryData, err?: RetryError): RetryData {
if (!retryData) {
retryData = {
retryCount: 0,
retryInterval: 0
};
}
if (err) {
if (retryData.error) {
err.innerError = retryData.error;
}
retryData.error = err;
}
// Adjust retry count
retryData.retryCount++;
// Adjust retry interval
let incrementDelta = Math.pow(2, retryData.retryCount) - 1;
const boundedRandDelta = this.retryInterval * 0.8 +
Math.floor(Math.random() * (this.retryInterval * 1.2 - this.retryInterval * 0.8));
incrementDelta *= boundedRandDelta;
retryData.retryInterval = Math.min(this.minRetryInterval + incrementDelta, this.maxRetryInterval);
return retryData;
}
async retry(operationResponse: HttpOperationResponse, retryData?: RetryData, err?: RetryError): Promise<HttpOperationResponse> {
const self = this;
retryData = self.updateRetryData(retryData, err);
if (err && err.code && self.shouldRetry(retryData) &&
(err.code === "ETIMEDOUT" || err.code === "ESOCKETTIMEDOUT" || err.code === "ECONNREFUSED" ||
err.code === "ECONNRESET" || err.code === "ENOENT")) {
// If previous operation ended with an error and the policy allows a retry, do that
try {
await utils.delay(retryData.retryInterval);
const res: HttpOperationResponse = await utils.dispatchRequest(operationResponse.request);
return self.retry(res, retryData, err);
} catch (err) {
return self.retry(operationResponse, retryData, err);
}
} else {
if (!utils.objectIsNull(err)) {
// If the operation failed in the end, return all errors instead of just the last one
err = retryData.error;
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
}
}
after(operationResponse: HttpOperationResponse): Promise<HttpOperationResponse> {
return this.retry(operationResponse); // See: https://github.com/Microsoft/TypeScript/issues/7426
}
}

Просмотреть файл

@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource } from "./webResource";
/**
* Wrapper object for http request and response. Deserialized object is stored in
* the `body` property.
* @class
* Initializes a new instance of the HttpOperationResponse class.
* @constructor
*/
export class HttpOperationResponse {
/**
* The raw request
*/
request: WebResource;
/**
* The raw response
*/
response: Response;
/**
* The response body as a readable stream
*/
bodyAsStream: ReadableStream | null;
/**
* The response body as text (string format)
*/
bodyAsText: string | null;
/**
* The response body as parsed JSON
*/
bodyAsJson: { [key: string]: any } | Array<any> | string | number | boolean | null | void;
constructor(request: WebResource, response: Response, body: ReadableStream | null) {
/**
* Reference to the original request object.
* [WebResource] object.
* @type {object}
*/
this.request = request;
/**
* Reference to the original response object.
* [ServerResponse] object.
* @type {object}
*/
this.response = response;
/**
* The response object.
* @type {object}
*/
this.bodyAsStream = body;
this.bodyAsText = null;
this.bodyAsJson = null;
}
}

42
lib/msRest.ts Normal file
Просмотреть файл

@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource, RequestPrepareOptions, HttpMethods, ParameterValue, RequestOptionsBase } from "./webResource";
import { HttpOperationResponse } from "./httpOperationResponse";
import { RestError } from "./restError";
import { ServiceClient, ServiceClientOptions } from "./serviceClient";
import { Constants } from "./util/constants";
import { RequestPipeline, RequestFunction } from "./requestPipeline";
import { LogFilter } from "./filters/logFilter";
import { BaseFilter } from "./filters/baseFilter";
import { ExponentialRetryPolicyFilter } from "./filters/exponentialRetryPolicyFilter";
import { SystemErrorRetryPolicyFilter } from "./filters/systemErrorRetryPolicyFilter";
import { RedirectFilter } from "./filters/redirectFilter";
import { SigningFilter } from "./filters/signingFilter";
import { MsRestUserAgentFilter } from "./filters/msRestUserAgentFilter";
import {
BaseMapperType, CompositeMapper, DictionaryMapper, EnumMapper, Mapper,
MapperConstraints, MapperType, PolymorphicDiscriminator,
SequenceMapper, Serializer, UrlParameterValue, serializeObject
} from "./serializer";
import {
stripRequest, stripResponse, delay,
executePromisesSequentially, generateUuid, encodeUri, ServiceCallback,
promiseToCallback, promiseToServiceCallback, isValidUuid, dispatchRequest
} from "./util/utils";
// Credentials
import { TokenCredentials } from "./credentials/tokenCredentials";
import { BasicAuthenticationCredentials } from "./credentials/basicAuthenticationCredentials";
import { ServiceClientCredentials } from "./credentials/serviceClientCredentials";
import * as isStream from "is-stream";
export {
BaseMapperType, CompositeMapper, DictionaryMapper, EnumMapper, Mapper, MapperConstraints, MapperType,
PolymorphicDiscriminator, SequenceMapper, UrlParameterValue, Serializer, serializeObject, TokenCredentials,
WebResource, RequestPrepareOptions, HttpMethods, ParameterValue, HttpOperationResponse, ServiceClient, Constants, RequestPipeline,
BasicAuthenticationCredentials, ServiceClientCredentials, BaseFilter, LogFilter, ServiceClientOptions, ExponentialRetryPolicyFilter,
SystemErrorRetryPolicyFilter, SigningFilter, MsRestUserAgentFilter, stripRequest, stripResponse, delay, executePromisesSequentially,
generateUuid, isValidUuid, encodeUri, RestError, RequestOptionsBase, RequestFunction, ServiceCallback, promiseToCallback,
promiseToServiceCallback, isStream, dispatchRequest, RedirectFilter
};

58
lib/requestPipeline.ts Normal file
Просмотреть файл

@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource } from "./webResource";
import { HttpOperationResponse } from "./httpOperationResponse";
import { BaseFilter } from "./filters/baseFilter";
import * as utils from "./util/utils";
export interface RequestFunction {
(webResource: WebResource): Promise<HttpOperationResponse>;
}
export class RequestPipeline {
filters: BaseFilter[];
requestOptions: RequestInit;
constructor(filters?: BaseFilter[], requestOptions?: RequestInit) {
this.filters = filters || [];
this.requestOptions = requestOptions || {};
}
addFilter(f: BaseFilter): void {
this.filters.push(f);
return;
}
create(): RequestFunction {
const self = this;
let pipeline: Array<Function> = [];
if (self.filters && self.filters.length) {
const beforeFilters: Array<Function> = [];
const afterFilters: Array<Function> = [];
for (let i = 0; i < self.filters.length; i++) {
const filter = self.filters[i];
if (filter.before && typeof filter.before === "function") {
beforeFilters.push(filter.before.bind(filter));
}
if (filter.after && typeof filter.after === "function") {
afterFilters.push(filter.after.bind(filter));
}
}// end-of-for-loop
// add the request sink
beforeFilters.push(self.requestSink.bind(self));
pipeline = beforeFilters.concat(afterFilters);
} else {
pipeline.push(self.requestSink.bind(self));
}
const requestFun: RequestFunction = (request: WebResource): Promise<HttpOperationResponse> => {
if (!request.headers) request.headers = {};
return utils.executePromisesSequentially(pipeline, request);
};
return requestFun;
}
requestSink(options: WebResource): Promise<HttpOperationResponse> {
if (this.requestOptions.method) delete this.requestOptions.method;
return utils.dispatchRequest(options);
}
}

20
lib/restError.ts Normal file
Просмотреть файл

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { WebResource } from "./webResource";
export class RestError extends Error {
code?: string;
statusCode?: number;
request?: WebResource;
response?: Response;
body?: any;
constructor(message: string, code?: string, statusCode?: number, request?: WebResource, response?: Response, body?: any) {
super(message);
this.code = code;
this.statusCode = statusCode;
this.request = request;
this.response = response;
this.body = body;
}
}

759
lib/serializer.ts Normal file
Просмотреть файл

@ -0,0 +1,759 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as utils from "./util/utils";
import { duration, isDuration } from "moment";
const isBuffer = require("is-buffer");
import * as isStream from "is-stream";
export class Serializer {
modelMappers?: { [key: string]: any };
constructor(mappers?: { [key: string]: any }) {
this.modelMappers = mappers;
}
validateConstraints(mapper: Mapper, value: any, objectName: string): void {
if (mapper.constraints && (value !== null || value !== undefined)) {
Object.keys(mapper.constraints).forEach((constraintType) => {
if (constraintType.match(/^ExclusiveMaximum$/ig) !== null) {
if (value >= ((mapper.constraints as MapperConstraints).ExclusiveMaximum as number)) {
throw new Error(`"${objectName}" with value "${value}" should satify the constraint "ExclusiveMaximum": ${((mapper.constraints as MapperConstraints).ExclusiveMaximum as number)}.`);
}
} else if (constraintType.match(/^ExclusiveMinimum$/ig) !== null) {
if (value <= ((mapper.constraints as MapperConstraints).ExclusiveMinimum as number)) {
throw new Error(`${objectName} " with value "${value} " should satify the constraint "ExclusiveMinimum": ${((mapper.constraints as MapperConstraints).ExclusiveMinimum as number)}.`);
}
} else if (constraintType.match(/^InclusiveMaximum$/ig) !== null) {
if (value > ((mapper.constraints as MapperConstraints).InclusiveMaximum as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "InclusiveMaximum": ${((mapper.constraints as MapperConstraints).InclusiveMaximum as number)}.`);
}
} else if (constraintType.match(/^InclusiveMinimum$/ig) !== null) {
if (value < ((mapper.constraints as MapperConstraints).InclusiveMinimum as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "InclusiveMinimum": ${((mapper.constraints as MapperConstraints).InclusiveMinimum as number)}.`);
}
} else if (constraintType.match(/^MaxItems$/ig) !== null) {
if (value.length > ((mapper.constraints as MapperConstraints).MaxItems as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MaxItems": ${((mapper.constraints as MapperConstraints).MaxItems as number)}.`);
}
} else if (constraintType.match(/^MaxLength$/ig) !== null) {
if (value.length > ((mapper.constraints as MapperConstraints).MaxLength as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MaxLength": ${((mapper.constraints as MapperConstraints).MaxLength as number)}.`);
}
} else if (constraintType.match(/^MinItems$/ig) !== null) {
if (value.length < ((mapper.constraints as MapperConstraints).MinItems as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MinItems": ${((mapper.constraints as MapperConstraints).MinItems as number)}.`);
}
} else if (constraintType.match(/^MinLength$/ig) !== null) {
if (value.length < ((mapper.constraints as MapperConstraints).MinLength as number)) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MinLength": ${((mapper.constraints as MapperConstraints).MinLength as number)}.`);
}
} else if (constraintType.match(/^MultipleOf$/ig) !== null) {
if (value.length % ((mapper.constraints as MapperConstraints).MultipleOf as number) !== 0) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "MultipleOf": ${((mapper.constraints as MapperConstraints).MultipleOf as number)}.`);
}
} else if (constraintType.match(/^Pattern$/ig) !== null) {
if (value.match(((mapper.constraints as MapperConstraints).Pattern as string).split("/").join("\/")) === null) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "Pattern": ${((mapper.constraints as MapperConstraints).Pattern as string)}.`);
}
} else if (constraintType.match(/^UniqueItems/ig) !== null) {
if (((mapper.constraints as MapperConstraints).UniqueItems as boolean)) {
if (value.length !== value.filter((item: any, i: number, ar: Array<any>) => { { return ar.indexOf(item) === i; } }).length) {
throw new Error(`${objectName}" with value "${value}" should satify the constraint "UniqueItems": ${((mapper.constraints as MapperConstraints).UniqueItems as boolean)}`);
}
}
}
});
}
}
private trimEnd(str: string, ch: string) {
let len = str.length;
while ((len - 1) >= 0 && str[len - 1] === ch) {
--len;
}
return str.substr(0, len);
}
private bufferToBase64Url(buffer: any): string | undefined {
if (!buffer) {
return undefined;
}
if (!isBuffer(buffer)) {
throw new Error(`Please provide an input of type Buffer for converting to Base64Url.`);
}
// Buffer to Base64.
const str = buffer.toString("base64");
// Base64 to Base64Url.
return this.trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_");
}
private base64UrlToBuffer(str: string): any {
if (!str) {
return undefined;
}
if (str && typeof str.valueOf() !== "string") {
throw new Error("Please provide an input of type string for converting to Buffer");
}
// Base64Url to Base64.
str = str.replace(/\-/g, "+").replace(/\_/g, "/");
// Base64 to Buffer.
return Buffer.from(str, "base64");
}
private splitSerializeName(prop: string): Array<string> {
const classes: Array<string> = [];
let partialclass = "";
const subwords = prop.split(".");
subwords.forEach((item) => {
if (item.charAt(item.length - 1) === "\\") {
partialclass += item.substr(0, item.length - 1) + ".";
} else {
partialclass += item;
classes.push(partialclass);
partialclass = "";
}
});
return classes;
}
private dateToUnixTime(d: string | Date): number | undefined {
if (!d) {
return undefined;
}
if (typeof d.valueOf() === "string") {
d = new Date(d as string);
}
return Math.floor((d as Date).getTime() / 1000);
}
private unixTimeToDate(n: number): Date | undefined {
if (!n) {
return undefined;
}
return new Date(n * 1000);
}
private serializeBasicTypes(typeName: string, objectName: string, value: any): any {
if (value !== null && value !== undefined) {
if (typeName.match(/^Number$/ig) !== null) {
if (typeof value !== "number") {
throw new Error(`${objectName} with value ${value} must be of type number.`);
}
} else if (typeName.match(/^String$/ig) !== null) {
if (typeof value.valueOf() !== "string") {
throw new Error(`${objectName} with value "${value}" must be of type string.`);
}
} else if (typeName.match(/^Uuid$/ig) !== null) {
if (!(typeof value.valueOf() === "string" && utils.isValidUuid(value))) {
throw new Error(`${objectName} with value "${value}" must be of type string and a valid uuid.`);
}
} else if (typeName.match(/^Boolean$/ig) !== null) {
if (typeof value !== "boolean") {
throw new Error(`${objectName} with value ${value} must be of type boolean.`);
}
} else if (typeName.match(/^Object$/ig) !== null) {
if (typeof value !== "object") {
throw new Error(`${objectName} must be of type object.`);
}
} else if (typeName.match(/^Stream$/ig) !== null) {
if (!isStream(value)) {
throw new Error(`${objectName} must be of type stream.`);
}
}
}
return value;
}
private serializeEnumType(objectName: string, allowedValues: Array<any>, value: any): any {
if (!allowedValues) {
throw new Error(`Please provide a set of allowedValues to validate ${objectName} as an Enum Type.`);
}
const isPresent = allowedValues.some((item) => {
if (typeof item.valueOf() === "string") {
return item.toLowerCase() === value.toLowerCase();
}
return item === value;
});
if (!isPresent) {
throw new Error(`${value} is not a valid value for ${objectName}. The valid values are: ${JSON.stringify(allowedValues)}.`);
}
return value;
}
private serializeBufferType(objectName: string, value: any): any {
if (value !== null && value !== undefined) {
if (!isBuffer(value)) {
throw new Error(`${objectName} must be of type Buffer.`);
}
value = value.toString("base64");
}
return value;
}
private serializeBase64UrlType(objectName: string, value: any): any {
if (value !== null && value !== undefined) {
if (!isBuffer(value)) {
throw new Error(`${objectName} must be of type Buffer.`);
}
value = this.bufferToBase64Url(value);
}
return value;
}
private serializeDateTypes(typeName: string, value: any, objectName: string) {
if (value !== null && value !== undefined) {
if (typeName.match(/^Date$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`);
}
value = (value instanceof Date) ? value.toISOString().substring(0, 10) : new Date(value).toISOString().substring(0, 10);
} else if (typeName.match(/^DateTime$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`);
}
value = (value instanceof Date) ? value.toISOString() : new Date(value).toISOString();
} else if (typeName.match(/^DateTimeRfc1123$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123 format.`);
}
value = (value instanceof Date) ? value.toUTCString() : new Date(value).toUTCString();
} else if (typeName.match(/^UnixTime$/ig) !== null) {
if (!(value instanceof Date ||
(typeof value.valueOf() === "string" && !isNaN(Date.parse(value))))) {
throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123/ISO8601 format ` +
`for it to be serialized in UnixTime/Epoch format.`);
}
value = this.dateToUnixTime(value);
} else if (typeName.match(/^TimeSpan$/ig) !== null) {
if (!isDuration(value)) {
throw new Error(`${objectName} must be a TimeSpan/Duration.`);
}
value = value.toISOString();
}
}
return value;
}
private serializeSequenceType(mapper: SequenceMapper, object: any, objectName: string) {
if (!Array.isArray(object)) {
throw new Error(`${objectName} must be of type Array.`);
}
if (!mapper.type.element || typeof mapper.type.element !== "object") {
throw new Error(`element" metadata for an Array must be defined in the ` +
`mapper and it must of type "object" in ${objectName}.`);
}
const tempArray = [];
for (let i = 0; i < object.length; i++) {
tempArray[i] = this.serialize(mapper.type.element, object[i], objectName);
}
return tempArray;
}
private serializeDictionaryType(mapper: DictionaryMapper, object: any, objectName: string) {
if (typeof object !== "object") {
throw new Error(`${objectName} must be of type object.`);
}
if (!mapper.type.value || typeof mapper.type.value !== "object") {
throw new Error(`"value" metadata for a Dictionary must be defined in the ` +
`mapper and it must of type "object" in ${objectName}.`);
}
const tempDictionary: { [key: string]: any } = {};
for (const key in object) {
if (object.hasOwnProperty(key)) {
tempDictionary[key] = this.serialize(mapper.type.value, object[key], objectName);
}
}
return tempDictionary;
}
private serializeCompositeType(mapper: CompositeMapper, object: any, objectName: string) {
// check for polymorphic discriminator
if (mapper.type.polymorphicDiscriminator) {
mapper = this.getPolymorphicMapper(mapper, object, objectName, "serialize");
}
const payload: any = {};
let modelMapper: CompositeMapper = {
required: false,
serializedName: "serializedName",
type: {
name: "Composite",
className: "className",
modelProperties: {}
}
};
if (object !== null && object !== undefined) {
let modelProps = mapper.type.modelProperties;
if (!modelProps) {
if (!mapper.type.className) {
throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper, undefined, 2)}".`);
}
// get the mapper if modelProperties of the CompositeType is not present and
// then get the modelProperties from it.
modelMapper = (this.modelMappers as { [key: string]: any })[mapper.type.className];
if (!modelMapper) {
throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}".`);
}
modelProps = modelMapper.type.modelProperties;
if (!modelProps) {
throw new Error(`modelProperties cannot be null or undefined in the ` +
`mapper "${JSON.stringify(modelMapper)}" of type "${mapper.type.className}" for object "${objectName}".`);
}
}
for (const key in modelProps) {
if (modelProps.hasOwnProperty(key)) {
const paths = this.splitSerializeName(modelProps[key].serializedName);
const propName = paths.pop();
let parentObject: any = payload;
paths.forEach((pathName: string) => {
const childObject = parentObject[pathName];
if ((childObject === null || childObject === undefined) && (object[key] !== null && object[key] !== undefined)) {
parentObject[pathName] = {};
}
parentObject = parentObject[pathName];
});
// make sure required properties of the CompositeType are present
if (modelProps[key].required && !modelProps[key].isConstant) {
if (object[key] === null || object[key] === undefined) {
throw new Error(`${key}" cannot be null or undefined in "${objectName}".`);
}
}
// make sure that readOnly properties are not sent on the wire
if (modelProps[key].readOnly) {
continue;
}
// serialize the property if it is present in the provided object instance
if (((parentObject !== null && parentObject !== undefined) && (modelProps[key].defaultValue !== null && modelProps[key].defaultValue !== undefined)) ||
(object[key] !== null && object[key] !== undefined)) {
let propertyObjectName = objectName;
if (modelProps[key].serializedName !== "") propertyObjectName = objectName + "." + modelProps[key].serializedName;
const propertyMapper = modelProps[key];
const serializedValue = this.serialize(propertyMapper, object[key], propertyObjectName);
if (propName !== null && propName !== undefined) parentObject[propName] = serializedValue;
}
}
}
return payload;
}
return object;
}
/**
* Serialize the given object based on its metadata defined in the mapper
*
* @param {Mapper} mapper The mapper which defines the metadata of the serializable object
*
* @param {object|string|Array|number|boolean|Date|stream} object A valid Javascript object to be serialized
*
* @param {string} objectName Name of the serialized object
*
* @returns {object|string|Array|number|boolean|Date|stream} A valid serialized Javascript object
*/
serialize(mapper: Mapper, object: any, objectName: string): any {
let payload: any = {};
const mapperType = mapper.type.name as string;
if (!objectName) objectName = mapper.serializedName;
if (mapperType.match(/^Sequence$/ig) !== null) payload = [];
// Throw if required and object is null or undefined
if (mapper.required && (object === null || object === undefined) && !mapper.isConstant) {
throw new Error(`${objectName} cannot be null or undefined.`);
}
// Set Defaults
if ((mapper.defaultValue !== null && mapper.defaultValue !== undefined) &&
(object === null || object === undefined)) {
object = mapper.defaultValue;
}
if (mapper.isConstant) object = mapper.defaultValue;
// Validate Constraints if any
this.validateConstraints(mapper, object, objectName);
if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/ig) !== null) {
payload = this.serializeBasicTypes(mapperType, objectName, object);
} else if (mapperType.match(/^Enum$/ig) !== null) {
const enumMapper: EnumMapper = mapper as EnumMapper;
payload = this.serializeEnumType(objectName, enumMapper.type.allowedValues, object);
} else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/ig) !== null) {
payload = this.serializeDateTypes(mapperType, object, objectName);
} else if (mapperType.match(/^ByteArray$/ig) !== null) {
payload = this.serializeBufferType(objectName, object);
} else if (mapperType.match(/^Base64Url$/ig) !== null) {
payload = this.serializeBase64UrlType(objectName, object);
} else if (mapperType.match(/^Sequence$/ig) !== null) {
payload = this.serializeSequenceType(mapper as SequenceMapper, object, objectName);
} else if (mapperType.match(/^Dictionary$/ig) !== null) {
payload = this.serializeDictionaryType(mapper as DictionaryMapper, object, objectName);
} else if (mapperType.match(/^Composite$/ig) !== null) {
payload = this.serializeCompositeType(mapper as CompositeMapper, object, objectName);
}
return payload;
}
private deserializeCompositeType(mapper: CompositeMapper, responseBody: any, objectName: string): any {
/*jshint validthis: true */
// check for polymorphic discriminator
if (mapper.type.polymorphicDiscriminator) {
mapper = this.getPolymorphicMapper(mapper, responseBody, objectName, "deserialize");
}
let instance: { [key: string]: any } = {};
let modelMapper: Mapper = {
required: false,
serializedName: "serializedName",
type: {
name: "Composite"
}
};
if (responseBody !== null && responseBody !== undefined) {
let modelProps = mapper.type.modelProperties;
if (!modelProps) {
if (!mapper.type.className) {
throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper)}"`);
}
// get the mapper if modelProperties of the CompositeType is not present and
// then get the modelProperties from it.
modelMapper = (this.modelMappers as { [key: string]: any })[mapper.type.className];
if (!modelMapper) {
throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}"`);
}
modelProps = (modelMapper as CompositeMapper).type.modelProperties;
if (!modelProps) {
throw new Error(`modelProperties cannot be null or undefined in the ` +
`mapper "${JSON.stringify(modelMapper)}" of type "${mapper.type.className}" for responseBody "${objectName}".`);
}
}
for (const key in modelProps) {
if (modelProps.hasOwnProperty(key)) {
const jpath = ["responseBody"];
const paths = this.splitSerializeName(modelProps[key].serializedName);
paths.forEach((item) => {
jpath.push(`["${item}"]`);
});
// deserialize the property if it is present in the provided responseBody instance
let propertyInstance;
try {
/*jslint evil: true */
propertyInstance = eval(jpath.join(""));
} catch (err) {
continue;
}
let propertyObjectName = objectName;
if (modelProps[key].serializedName !== "") propertyObjectName = objectName + "." + modelProps[key].serializedName;
const propertyMapper = modelProps[key];
let serializedValue;
// paging
if (Array.isArray(responseBody[key]) && modelProps[key].serializedName === "") {
propertyInstance = responseBody[key];
instance = this.deserialize(propertyMapper, propertyInstance, propertyObjectName);
} else if (propertyInstance !== null && propertyInstance !== undefined) {
serializedValue = this.deserialize(propertyMapper, propertyInstance, propertyObjectName);
instance[key] = serializedValue;
}
}
}
return instance;
}
return responseBody;
}
private deserializeDictionaryType(mapper: DictionaryMapper, responseBody: any, objectName: string): any {
/*jshint validthis: true */
if (!mapper.type.value || typeof mapper.type.value !== "object") {
throw new Error(`"value" metadata for a Dictionary must be defined in the ` +
`mapper and it must of type "object" in ${objectName}`);
}
if (responseBody) {
const tempDictionary: { [key: string]: any } = {};
for (const key in responseBody) {
if (responseBody.hasOwnProperty(key)) {
tempDictionary[key] = this.deserialize(mapper.type.value, responseBody[key], objectName);
}
}
return tempDictionary;
}
return responseBody;
}
private deserializeSequenceType(mapper: SequenceMapper, responseBody: any, objectName: string): any {
/*jshint validthis: true */
if (!mapper.type.element || typeof mapper.type.element !== "object") {
throw new Error(`element" metadata for an Array must be defined in the ` +
`mapper and it must of type "object" in ${objectName}`);
}
if (responseBody) {
const tempArray = [];
for (let i = 0; i < responseBody.length; i++) {
tempArray[i] = this.deserialize(mapper.type.element, responseBody[i], objectName);
}
return tempArray;
}
return responseBody;
}
/**
* Deserialize the given object based on its metadata defined in the mapper
*
* @param {object} mapper The mapper which defines the metadata of the serializable object
*
* @param {object|string|Array|number|boolean|Date|stream} responseBody A valid Javascript entity to be deserialized
*
* @param {string} objectName Name of the deserialized object
*
* @returns {object|string|Array|number|boolean|Date|stream} A valid deserialized Javascript object
*/
deserialize(mapper: Mapper, responseBody: any, objectName: string): any {
if (responseBody === null || responseBody === undefined) return responseBody;
let payload: any;
const mapperType = mapper.type.name;
if (!objectName) objectName = mapper.serializedName;
if (mapperType.match(/^Sequence$/ig) !== null) payload = [];
if (mapperType.match(/^(Number|String|Boolean|Enum|Object|Stream|Uuid)$/ig) !== null) {
payload = responseBody;
} else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/ig) !== null) {
payload = new Date(responseBody);
} else if (mapperType.match(/^TimeSpan$/ig) !== null) {
payload = duration(responseBody);
} else if (mapperType.match(/^UnixTime$/ig) !== null) {
payload = this.unixTimeToDate(responseBody);
} else if (mapperType.match(/^ByteArray$/ig) !== null) {
payload = Buffer.from(responseBody, "base64");
} else if (mapperType.match(/^Base64Url$/ig) !== null) {
payload = this.base64UrlToBuffer(responseBody);
} else if (mapperType.match(/^Sequence$/ig) !== null) {
payload = this.deserializeSequenceType(mapper as SequenceMapper, responseBody, objectName);
} else if (mapperType.match(/^Dictionary$/ig) !== null) {
payload = this.deserializeDictionaryType(mapper as DictionaryMapper, responseBody, objectName);
} else if (mapperType.match(/^Composite$/ig) !== null) {
payload = this.deserializeCompositeType(mapper as CompositeMapper, responseBody, objectName);
}
if (mapper.isConstant) payload = mapper.defaultValue;
return payload;
}
private getPolymorphicMapper(mapper: CompositeMapper, object: any, objectName: string, mode: string): CompositeMapper {
// check for polymorphic discriminator
// Until version 1.15.1, "polymorphicDiscriminator" in the mapper was a string. This method was not effective when the
// polymorphicDiscriminator property had a dot in it"s name. So we have comeup with a desgin where polymorphicDiscriminator
// will be an object that contains the clientName (normalized property name, ex: "odatatype") and
// the serializedName (ex: "odata.type") (We do not escape the dots with double backslash in this case as it is not required)
// Thus when serializing, the user will give us an object which will contain the normalizedProperty hence we will lookup
// the clientName of the polmorphicDiscriminator in the mapper and during deserialization from the responseBody we will
// lookup the serializedName of the polmorphicDiscriminator in the mapper. This will help us in selecting the correct mapper
// for the model that needs to be serializes or deserialized.
// We need this routing for backwards compatibility. This will absorb the breaking change in the mapper and allow new versions
// of the runtime to work seamlessly with older version (>= 0.17.0-Nightly20161008) of Autorest generated node.js clients.
if (mapper.type.polymorphicDiscriminator) {
if (typeof mapper.type.polymorphicDiscriminator.valueOf() === "string") {
return this.getPolymorphicMapperStringVersion(mapper, object, objectName);
} else if (mapper.type.polymorphicDiscriminator instanceof Object) {
return this.getPolymorphicMapperObjectVersion(mapper, object, objectName, mode);
} else {
throw new Error(`The polymorphicDiscriminator for "${objectName}" is neither a string nor an object.`);
}
}
return mapper;
}
// processes new version of the polymorphicDiscriminator in the mapper.
private getPolymorphicMapperObjectVersion(mapper: CompositeMapper, object: any, objectName: string, mode: string): CompositeMapper {
// check for polymorphic discriminator
let polymorphicPropertyName = "";
if (mode === "serialize") {
polymorphicPropertyName = "clientName";
} else if (mode === "deserialize") {
polymorphicPropertyName = "serializedName";
} else {
throw new Error(`The given mode "${mode}" for getting the polymorphic mapper for "${objectName}" is inavlid.`);
}
const discriminatorAsObject: PolymorphicDiscriminator = mapper.type.polymorphicDiscriminator as PolymorphicDiscriminator;
if (discriminatorAsObject &&
discriminatorAsObject[polymorphicPropertyName] !== null &&
discriminatorAsObject[polymorphicPropertyName] !== undefined) {
if (object === null || object === undefined) {
throw new Error(`${objectName}" cannot be null or undefined. ` +
`"${discriminatorAsObject[polymorphicPropertyName]}" is the ` +
`polmorphicDiscriminator and is a required property.`);
}
if (object[discriminatorAsObject[polymorphicPropertyName]] === null ||
object[discriminatorAsObject[polymorphicPropertyName]] === undefined) {
throw new Error(`No discriminator field "${discriminatorAsObject[polymorphicPropertyName]}" was found in "${objectName}".`);
}
let indexDiscriminator = undefined;
if (object[discriminatorAsObject[polymorphicPropertyName]] === mapper.type.uberParent) {
indexDiscriminator = object[discriminatorAsObject[polymorphicPropertyName]];
} else {
indexDiscriminator = mapper.type.uberParent + "." + object[discriminatorAsObject[polymorphicPropertyName]];
}
if (!(this.modelMappers as { [key: string]: any }).discriminators[indexDiscriminator]) {
throw new Error(`${discriminatorAsObject[polymorphicPropertyName]}": ` +
`"${object[discriminatorAsObject[polymorphicPropertyName]]}" in "${objectName}" is not a valid ` +
`discriminator as a corresponding model class for the disciminator "${indexDiscriminator}" ` +
`was not found in this.modelMappers.discriminators object.`);
}
mapper = (this.modelMappers as { [key: string]: any }).discriminators[indexDiscriminator];
}
return mapper;
}
// processes old version of the polymorphicDiscriminator in the mapper.
private getPolymorphicMapperStringVersion(mapper: CompositeMapper, object: any, objectName: string): CompositeMapper {
// check for polymorphic discriminator
const discriminatorAsString: string = mapper.type.polymorphicDiscriminator as string;
if (discriminatorAsString !== null && discriminatorAsString !== undefined) {
if (object === null || object === undefined) {
throw new Error(`${objectName}" cannot be null or undefined. "${discriminatorAsString}" is the ` +
`polmorphicDiscriminator and is a required property.`);
}
if (object[discriminatorAsString] === null || object[discriminatorAsString] === undefined) {
throw new Error(`No discriminator field "${discriminatorAsString}" was found in "${objectName}".`);
}
let indexDiscriminator = undefined;
if (object[discriminatorAsString] === mapper.type.uberParent) {
indexDiscriminator = object[discriminatorAsString];
} else {
indexDiscriminator = mapper.type.uberParent + "." + object[discriminatorAsString];
}
if (!(this.modelMappers as { [key: string]: any }).discriminators[indexDiscriminator]) {
throw new Error(`${discriminatorAsString}": ` +
`"${object[discriminatorAsString]}" in "${objectName}" is not a valid ` +
`discriminator as a corresponding model class for the disciminator "${indexDiscriminator}" ` +
`was not found in this.models.discriminators object.`);
}
mapper = (this.modelMappers as { [key: string]: any }).discriminators[indexDiscriminator];
}
return mapper;
}
}
export interface MapperConstraints {
InclusiveMaximum?: number;
ExclusiveMaximum?: number;
InclusiveMinimum?: number;
ExclusiveMinimum?: number;
MaxLength?: number;
MinLength?: number;
Pattern?: string;
MaxItems?: number;
MinItems?: number;
UniqueItems?: true;
MultipleOf?: number;
}
export interface BaseMapperType {
name: string;
[key: string]: any;
}
export interface Mapper {
readOnly?: boolean;
isConstant?: boolean;
required: boolean;
serializedName: string;
type: BaseMapperType;
defaultValue?: any;
constraints?: MapperConstraints;
}
export interface PolymorphicDiscriminator {
serializedName: string;
clientName: string;
[key: string]: string;
}
export interface CompositeMapper extends Mapper {
type: {
name: "Composite";
className: string;
modelProperties?: { [propertyName: string]: Mapper };
uberParent?: string;
polymorphicDiscriminator?: string | PolymorphicDiscriminator;
};
}
export interface SequenceMapper extends Mapper {
type: {
name: "Sequence";
element: Mapper;
};
}
export interface DictionaryMapper extends Mapper {
type: {
name: "Dictionary";
value: Mapper;
};
}
export interface EnumMapper extends Mapper {
type: {
name: "Enum";
allowedValues: Array<any>;
};
}
export interface UrlParameterValue {
value: string;
skipUrlEncoding: boolean;
}
export function serializeObject(toSerialize: any): any {
if (toSerialize === null || toSerialize === undefined) return undefined;
if (isBuffer(toSerialize)) {
toSerialize = toSerialize.toString("base64");
return toSerialize;
}
else if (toSerialize instanceof Date) {
return toSerialize.toISOString();
}
else if (Array.isArray(toSerialize)) {
const array = [];
for (let i = 0; i < toSerialize.length; i++) {
array.push(serializeObject(toSerialize[i]));
}
return array;
} else if (typeof toSerialize === "object") {
const dictionary: { [key: string]: any } = {};
for (const property in toSerialize) {
dictionary[property] = serializeObject(toSerialize[property]);
}
return dictionary;
}
return toSerialize;
}
export const MapperType = utils.strEnum([
"Base64Url",
"Boolean",
"ByteArray",
"Composite",
"Date",
"DateTime",
"DateTimeRfc1123",
"Dictionary",
"Enum",
"Number",
"Object",
"Sequence",
"String",
"Stream",
"TimeSpan",
"UnixTime"
]);

147
lib/serviceClient.ts Normal file
Просмотреть файл

@ -0,0 +1,147 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { RequestPipeline } from "./requestPipeline";
import { ServiceClientCredentials } from "./credentials/serviceClientCredentials";
import { BaseFilter } from "./filters/baseFilter";
import { ExponentialRetryPolicyFilter } from "./filters/exponentialRetryPolicyFilter";
import { SystemErrorRetryPolicyFilter } from "./filters/systemErrorRetryPolicyFilter";
import { RedirectFilter } from "./filters/redirectFilter";
import { SigningFilter } from "./filters/signingFilter";
import { RPRegistrationFilter } from "./filters/rpRegistrationFilter";
import { MsRestUserAgentFilter } from "./filters/msRestUserAgentFilter";
import { WebResource, RequestPrepareOptions } from "./webResource";
import { Constants } from "./util/constants";
import { HttpOperationResponse } from "./httpOperationResponse";
/**
* Options to be provided while creating the client.
*/
export interface ServiceClientOptions {
/**
* @property {RequestInit} [requestOptions] The request options. Detailed info can be found
* here https://github.github.io/fetch/#Request
*/
requestOptions?: RequestInit;
/**
* @property {Array<BaseFilter>} [filters] An array of filters/interceptors that will
* be processed in the request pipeline (before and after) sending the request on the wire.
*/
filters?: BaseFilter[];
/**
* @property {bool} [noRetryPolicy] - If set to true, turn off the default retry policy.
*/
noRetryPolicy?: boolean;
/**
* @property {number} [rpRegistrationRetryTimeout] - Gets or sets the retry timeout
* in seconds for AutomaticRPRegistration. Default value is 30.
*/
rpRegistrationRetryTimeout?: number;
}
/**
* @class
* Initializes a new instance of the ServiceClient.
*/
export class ServiceClient {
/**
* The string to be appended to the User-Agent header while sending the request.
* This will be applicable only for node.js environment as the fetch library in browser does not allow setting custom UA.
* @property {Array<string>} value - An array of string that need to be appended to the User-Agent request header.
*/
userAgentInfo: { value: Array<string> };
/**
* The request pipeline that provides hooks for adding custom filters.
* The before filters get executed before sending the request and the after filters get executed after receiving the response.
*/
pipeline: Function;
/**
* The ServiceClient constructor
* @constructor
* @param {ServiceClientCredentials }[credentials] - BasicAuthenticationCredentials or
* TokenCredentials object used for authentication.
* @param { ServiceClientOptions } [options] The service client options that govern the behavior of the client.
*/
constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) {
if (!options) {
options = {};
}
if (!options.requestOptions) {
options.requestOptions = {};
}
if (!options.filters) {
options.filters = [];
}
this.userAgentInfo = { value: [] };
if (credentials && !credentials.signRequest) {
throw new Error("credentials argument needs to implement signRequest method");
}
try {
const moduleName = "ms-rest-js";
const moduleVersion = Constants.msRestVersion;
this.addUserAgentInfo(`${moduleName}/${moduleVersion}`);
} catch (err) {
// do nothing
}
if (credentials) {
options.filters.push(new SigningFilter(credentials));
}
options.filters.push(new MsRestUserAgentFilter(this.userAgentInfo.value));
options.filters.push(new RedirectFilter());
options.filters.push(new RPRegistrationFilter(options.rpRegistrationRetryTimeout));
if (!options.noRetryPolicy) {
options.filters.push(new ExponentialRetryPolicyFilter());
options.filters.push(new SystemErrorRetryPolicyFilter());
}
this.pipeline = new RequestPipeline(options.filters, options.requestOptions).create();
}
/**
* Adds custom information to user agent header
* @param {any} additionalUserAgentInfo - information to be added to user agent header, as string.
*/
addUserAgentInfo(additionalUserAgentInfo: string): void {
if (this.userAgentInfo.value.indexOf(additionalUserAgentInfo) === -1) {
this.userAgentInfo.value.push(additionalUserAgentInfo);
}
return;
}
async sendRequest(options: RequestPrepareOptions | WebResource): Promise<HttpOperationResponse> {
if (options === null || options === undefined || typeof options !== "object") {
throw new Error("options cannot be null or undefined and it must be of type object.");
}
let httpRequest: WebResource;
try {
if (options instanceof WebResource) {
options.validateRequestProperties();
httpRequest = options;
} else {
httpRequest = new WebResource();
httpRequest = httpRequest.prepare(options);
}
} catch (error) {
return Promise.reject(error);
}
// send request
let operationResponse: HttpOperationResponse;
try {
operationResponse = await this.pipeline(httpRequest);
} catch (err) {
return Promise.reject(err);
}
return Promise.resolve(operationResponse);
}
}

85
lib/util/constants.ts Normal file
Просмотреть файл

@ -0,0 +1,85 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
export const Constants = {
/**
* The ms-rest version
* @const
* @type {string}
*/
msRestVersion: "0.1.0",
/**
* Specifies HTTP.
*
* @const
* @type {string}
*/
HTTP: "http:",
/**
* Specifies HTTPS.
*
* @const
* @type {string}
*/
HTTPS: "https:",
/**
* Specifies HTTP Proxy.
*
* @const
* @type {string}
*/
HTTP_PROXY: "HTTP_PROXY",
/**
* Specifies HTTPS Proxy.
*
* @const
* @type {string}
*/
HTTPS_PROXY: "HTTPS_PROXY",
HttpConstants: {
/**
* Http Verbs
*
* @const
* @enum {string}
*/
HttpVerbs: {
PUT: "PUT",
GET: "GET",
DELETE: "DELETE",
POST: "POST",
MERGE: "MERGE",
HEAD: "HEAD",
PATCH: "PATCH"
},
},
/**
* Defines constants for use with HTTP headers.
*/
HeaderConstants: {
/**
* The Authorization header.
*
* @const
* @type {string}
*/
AUTHORIZATION: "authorization",
AUTHORIZATION_SCHEME: "Bearer",
/**
* The UserAgent header.
*
* @const
* @type {string}
*/
USER_AGENT: "User-Agent"
}
};

323
lib/util/utils.ts Normal file
Просмотреть файл

@ -0,0 +1,323 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as uuid from "uuid";
import * as FormData from "form-data";
import { WebResource } from "../webResource";
import { Constants } from "./constants";
import { RestError } from "../restError";
import { HttpOperationResponse } from "../httpOperationResponse";
/**
* Provides the fetch() method based on the environment.
* @returns {fetch} fetch - The fetch() method available in the environment to make requests
*/
export function getFetch(): Function {
// using window.Fetch in Edge gives a TypeMismatchError
// (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8546263/).
// Hence we will be using the fetch-ponyfill for Edge.
if (typeof window !== "undefined" && window.fetch && window.navigator &&
window.navigator.userAgent && window.navigator.userAgent.indexOf("Edge/") === -1) {
return window.fetch.bind(window);
}
return require("fetch-ponyfill")({ useCookie: true }).fetch;
}
/**
* A constant that provides the fetch() method based on the environment.
*/
export const myFetch = getFetch();
/**
* Checks if a parsed URL is HTTPS
*
* @param {object} urlToCheck The url to check
* @return {boolean} True if the URL is HTTPS; false otherwise.
*/
export function urlIsHTTPS(urlToCheck: { protocol: string }): boolean {
return urlToCheck.protocol.toLowerCase() === Constants.HTTPS;
}
/**
* Checks if a value is null or undefined.
*
* @param {object} value The value to check for null or undefined.
* @return {boolean} True if the value is null or undefined, false otherwise.
*/
// TODO: Audit the usages of this and remove them.
// Read: https://medium.com/@basarat/null-vs-undefined-in-typescript-land-dc0c7a5f240a
// https://github.com/Microsoft/TypeScript/issues/7426
export function objectIsNull(value: any): boolean {
return value === null || value === undefined;
}
/**
* Encodes an URI.
*
* @param {string} uri The URI to be encoded.
* @return {string} The encoded URI.
*/
export function encodeUri(uri: string) {
return encodeURIComponent(uri)
.replace(/!/g, "%21")
.replace(/"/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29")
.replace(/\*/g, "%2A");
}
/**
* Returns a stripped version of the Http Response which only contains body,
* headers and the status.
*
* @param {nodeFetch.Response} response - The Http Response
*
* @return {object} strippedResponse - The stripped version of Http Response.
*/
export function stripResponse(response: Response) {
const strippedResponse: any = {};
strippedResponse.body = response.body;
strippedResponse.headers = response.headers;
strippedResponse.status = response.status;
return strippedResponse;
}
/**
* Returns a stripped version of the Http Request that does not contain the
* Authorization header.
*
* @param {object} request - The Http Request object
*
* @return {object} strippedRequest - The stripped version of Http Request.
*/
export function stripRequest(request: WebResource): WebResource {
let strippedRequest = new WebResource();
try {
strippedRequest = JSON.parse(JSON.stringify(request));
if (strippedRequest.headers && strippedRequest.headers.Authorization) {
delete strippedRequest.headers.Authorization;
} else if (strippedRequest.headers && strippedRequest.headers.authorization) {
delete strippedRequest.headers.authorization;
}
} catch (err) {
const errMsg = err.message;
err.message = `Error - "${errMsg}" occured while creating a stripped version of the request object - "${request}".`;
return err;
}
return strippedRequest;
}
/**
* Validates the given uuid as a string
*
* @param {string} uuid - The uuid as a string that needs to be validated
*
* @return {boolean} result - True if the uuid is valid; false otherwise.
*/
export function isValidUuid(uuid: string): boolean {
const validUuidRegex = new RegExp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", "ig");
return validUuidRegex.test(uuid);
}
/**
* Provides an array of values of an object. For example
* for a given object { "a": "foo", "b": "bar" }, the method returns ["foo", "bar"].
*
* @param {object} obj - An object whose properties need to be enumerated so that it"s values can be provided as an array
*
* @return {array} result - An array of values of the given object.
*/
export function objectValues(obj: { [key: string]: any; }): any[] {
const result: any[] = [];
if (obj && obj instanceof Object) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result.push((<any>obj)[key]);
}
}
} else {
throw new Error(`The provided object ${JSON.stringify(obj, undefined, 2)} is not a valid object that can be ` +
`enumerated to provide its values as an array.`);
}
return result;
}
/**
* Generated UUID
*
* @return {string} RFC4122 v4 UUID.
*/
export function generateUuid(): string {
return uuid.v4();
}
/*
* Executes an array of promises sequentially. Inspiration of this method is here:
* https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html. An awesome blog on promises!
*
* @param {Array} promiseFactories An array of promise factories(A function that return a promise)
*
* @param {any} [kickstart] Input to the first promise that is used to kickstart the promise chain.
* If not provided then the promise chain starts with undefined.
*
* @return A chain of resolved or rejected promises
*/
export function executePromisesSequentially(promiseFactories: Array<any>, kickstart: any) {
let result = Promise.resolve(kickstart);
promiseFactories.forEach((promiseFactory) => {
result = result.then(promiseFactory);
});
return result;
}
/*
* Merges source object into the target object
* @param {object} source The object that needs to be merged
*
* @param {object} target The object to be merged into
*
* @returns {object} target - Returns the merged target object.
*/
export function mergeObjects(source: { [key: string]: any; }, target: { [key: string]: any; }) {
Object.keys(source).forEach((key) => {
target[key] = source[key];
});
return target;
}
/**
* A wrapper for setTimeout that resolves a promise after t milliseconds.
* @param {number} t - The number of milliseconds to be delayed.
* @param {T} value - The value to be resolved with after a timeout of t milliseconds.
* @returns {Promise<T>} - Resolved promise
*/
export function delay<T>(t: number, value?: T): Promise<T> {
return new Promise((resolve) => setTimeout(() => resolve(value), t));
}
/**
* Utility function to create a K:V from a list of strings
*/
export function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
return o.reduce((res, key: string) => {
res[key] = key;
return res;
}, Object.create(null));
}
/**
* Service callback that is returned for REST requests initiated by the service client.
*
* @property {Error|RestError} err - The error occurred if any, while executing the request; otherwise null
* @property {TResult} result - The deserialized response body if an error did not occur.
* @property {WebResource} request - The raw/actual request sent to the server if an error did not occur.
* @property {Response} response - The raw/actual response from the server if an error did not occur.
*/
export interface ServiceCallback<TResult> { (err: Error | RestError, result?: TResult, request?: WebResource, response?: Response): void; }
/**
* Converts a Promise to a callback.
* @param {Promise<any>} promise - The Promise to be converted to a callback
* @returns {Function} fn - A function that takes the callback (cb: Function): void
*/
export function promiseToCallback(promise: Promise<any>): Function {
if (typeof promise.then !== "function") {
throw new Error("The provided input is not a Promise.");
}
return (cb: Function): void => {
promise.then((data: any) => {
process.nextTick(cb, undefined, data);
}, (err: Error) => {
process.nextTick(cb, err);
});
};
}
/**
* Converts a Promise to a service callback.
* @param {Promise<HttpOperationResponse>} promise - The Promise of HttpOperationResponse to be converted to a service callback
* @returns {Function} fn - A function that takes the service callback (cb: ServiceCallback<T>): void
*/
export function promiseToServiceCallback<T>(promise: Promise<HttpOperationResponse>): Function {
if (typeof promise.then !== "function") {
throw new Error("The provided input is not a Promise.");
}
return (cb: ServiceCallback<T>): void => {
promise.then((data: HttpOperationResponse) => {
process.nextTick(cb, undefined, data.bodyAsJson as T, data.request, data.response);
}, (err: Error) => {
process.nextTick(cb, err);
});
};
}
/**
* Sends the request and returns the received response.
* @param {WebResource} options - The request to be sent.
* @returns {Promise<HttpOperationResponse} operationResponse - The response object.
*/
export async function dispatchRequest(options: WebResource): Promise<HttpOperationResponse> {
if (!options) {
return Promise.reject(new Error("options (WebResource) cannot be null or undefined and must be of type object."));
}
if (options.formData) {
const formData: any = options.formData;
const requestForm = new FormData();
const appendFormValue = (key: string, value: any) => {
if (value && value.hasOwnProperty("value") && value.hasOwnProperty("options")) {
requestForm.append(key, value.value, value.options);
} else {
requestForm.append(key, value);
}
};
for (const formKey in formData) {
if (formData.hasOwnProperty(formKey)) {
const formValue = formData[formKey];
if (formValue instanceof Array) {
for (let j = 0; j < formValue.length; j++) {
appendFormValue(formKey, formValue[j]);
}
} else {
appendFormValue(formKey, formValue);
}
}
}
options.body = requestForm;
options.formData = undefined;
if (options.headers && options.headers["Content-Type"] &&
options.headers["Content-Type"].indexOf("multipart/form-data") > -1 && typeof requestForm.getBoundary === "function") {
options.headers["Content-Type"] = `multipart/form-data; boundary=${requestForm.getBoundary()}`;
}
}
let res: Response;
try {
res = await myFetch(options.url, options);
} catch (err) {
return Promise.reject(err);
}
const operationResponse = new HttpOperationResponse(options, res, res.body);
if (!options.rawResponse) {
try {
operationResponse.bodyAsText = await res.text();
} catch (err) {
const msg = `Error "${err}" occured while converting the raw response body into string.`;
const errCode = err.code || "RAWTEXT_CONVERSION_ERROR";
const e = new RestError(msg, errCode, res.status, options, res, res.body);
return Promise.reject(e);
}
try {
if (operationResponse.bodyAsText) {
operationResponse.bodyAsJson = JSON.parse(operationResponse.bodyAsText);
}
} catch (err) {
const msg = `Error "${err}" occured while executing JSON.parse on the response body - ${operationResponse.bodyAsText}.`;
const errCode = err.code || "JSON_PARSE_ERROR";
const e = new RestError(msg, errCode, res.status, options, res, operationResponse.bodyAsText);
return Promise.reject(e);
}
}
return Promise.resolve(operationResponse);
}

307
lib/webResource.ts Normal file
Просмотреть файл

@ -0,0 +1,307 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { generateUuid } from "./util/utils";
import { Serializer, Mapper } from "./serializer";
export type HttpMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "TRACE";
/**
* Creates a new WebResource object.
*
* This class provides an abstraction over a REST call by being library / implementation agnostic and wrapping the necessary
* properties to initiate a request.
*
* @constructor
*/
export class WebResource {
url: string;
method: HttpMethods;
body?: any;
headers: { [key: string]: any; } = {};
rawResponse?: boolean;
formData?: any;
query?: { [key: string]: any; };
constructor(url?: string, method?: HttpMethods, body?: any, query?: { [key: string]: any; }, headers: { [key: string]: any; } = {}, rawResponse = false) {
this.rawResponse = rawResponse;
this.url = url || "";
this.method = method || "GET";
this.headers = headers || {};
this.body = body;
this.query = query;
this.formData = undefined;
}
/**
* Validates that the required properties such as method, url, headers["Content-Type"],
* headers["accept-language"] are defined. It will throw an error if one of the above
* mentioned properties are not defined.
*/
validateRequestProperties(): void {
if (!this.method || !this.url || !this.headers["Content-Type"] || !this.headers["accept-language"]) {
throw new Error("method, url, headers[\"Content-Type\"], headers[\"accept-language\"] are " +
"required properties before making a request. Either provide them or use WebResource.prepare() method.");
}
return;
}
/**
* Prepares the request.
* @param {RequestPrepareOptions} options - Options to provide for preparing the request.
* @returns {object} WebResource Returns the prepared WebResource (HTTP Request) object that needs to be given to the request pipeline.
*/
prepare(options: RequestPrepareOptions) {
if (options === null || options === undefined || typeof options !== "object") {
throw new Error("options cannot be null or undefined and must be of type object");
}
if (options.method === null || options.method === undefined || typeof options.method.valueOf() !== "string") {
throw new Error("options.method cannot be null or undefined and it must be of type string.");
}
if (options.url && options.pathTemplate) {
throw new Error("options.url and options.pathTemplate are mutually exclusive. Please provide either of them.");
}
if ((options.pathTemplate === null || options.pathTemplate === undefined || typeof options.pathTemplate.valueOf() !== "string") && (options.url === null || options.url === undefined || typeof options.url.valueOf() !== "string")) {
throw new Error("Please provide either options.pathTemplate or options.url. Currently none of them were provided.");
}
// set the url if it is provided.
if (options.url) {
if (typeof options.url !== "string") {
throw new Error("options.url must be of type \"string\".");
}
this.url = options.url;
}
// set the method
if (options.method) {
const validMethods = ["GET", "PUT", "HEAD", "DELETE", "OPTIONS", "POST", "PATCH", "TRACE"];
if (validMethods.indexOf(options.method.toUpperCase()) === -1) {
throw new Error("The provided method \"" + options.method + "\" is invalid. Supported HTTP methods are: " + JSON.stringify(validMethods));
}
}
this.method = (options.method.toUpperCase() as HttpMethods);
// construct the url if path template is provided
if (options.pathTemplate) {
if (typeof options.pathTemplate !== "string") {
throw new Error("options.pathTemplate must be of type \"string\".");
}
if (!options.baseUrl) {
options.baseUrl = "https://management.azure.com";
}
const baseUrl = options.baseUrl;
let url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + (options.pathTemplate.startsWith("/") ? options.pathTemplate.slice(1) : options.pathTemplate);
const segments = url.match(/({\w*\s*\w*})/ig);
if (segments && segments.length) {
if (options.pathParameters === null || options.pathParameters === undefined || typeof options.pathParameters !== "object") {
throw new Error(`pathTemplate: ${options.pathTemplate} has been provided. Hence, options.pathParameters ` +
`cannot be null or undefined and must be of type "object".`);
}
segments.forEach(function (item) {
const pathParamName = item.slice(1, -1);
const pathParam = (options.pathParameters as { [key: string]: any })[pathParamName];
if (pathParam === null || pathParam === undefined || !(typeof pathParam === "string" || typeof pathParam === "object")) {
throw new Error(`pathTemplate: ${options.pathTemplate} contains the path parameter ${pathParamName}` +
` however, it is not present in ${options.pathParameters} - ${JSON.stringify(options.pathParameters, undefined, 2)}.` +
`The value of the path parameter can either be a "string" of the form { ${pathParamName}: "some sample value" } or ` +
`it can be an "object" of the form { "${pathParamName}": { value: "some sample value", skipUrlEncoding: true } }.`);
}
if (typeof pathParam.valueOf() === "string") {
url = url.replace(item, encodeURIComponent(pathParam));
}
if (typeof pathParam.valueOf() === "object") {
if (!pathParam.value) {
throw new Error(`options.pathParameters[${pathParamName}] is of type "object" but it does not contain a "value" property.`);
}
if (pathParam.skipUrlEncoding) {
url = url.replace(item, pathParam.value);
} else {
url = url.replace(item, encodeURIComponent(pathParam.value));
}
}
});
}
this.url = url;
}
// append query parameters to the url if they are provided. They can be provided with pathTemplate or url option.
if (options.queryParameters) {
if (typeof options.queryParameters !== "object") {
throw new Error(`options.queryParameters must be of type object. It should be a JSON object ` +
`of "query-parameter-name" as the key and the "query-parameter-value" as the value. ` +
`The "query-parameter-value" may be fo type "string" or an "object" of the form { value: "query-parameter-value", skipUrlEncoding: true }.`);
}
// append question mark if it is not present in the url
if (this.url && this.url.indexOf("?") === -1) {
this.url += "?";
}
// construct queryString
const queryParams = [];
const queryParameters = options.queryParameters;
// We need to populate this.query as a dictionary if the request is being used for Sway's validateRequest().
this.query = {};
for (const queryParamName in queryParameters) {
const queryParam: any = queryParameters[queryParamName];
if (queryParam) {
if (typeof queryParam === "string") {
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam));
this.query[queryParamName] = encodeURIComponent(queryParam);
}
else if (typeof queryParam === "object") {
if (!queryParam.value) {
throw new Error(`options.queryParameters[${queryParamName}] is of type "object" but it does not contain a "value" property.`);
}
if (queryParam.skipUrlEncoding) {
queryParams.push(queryParamName + "=" + queryParam.value);
this.query[queryParamName] = queryParam.value;
} else {
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam.value));
this.query[queryParamName] = encodeURIComponent(queryParam.value);
}
}
}
}// end-of-for
// append the queryString
this.url += queryParams.join("&");
}
// add headers to the request if they are provided
if (options.headers) {
const headers = options.headers;
for (const headerName in headers) {
if (headers.hasOwnProperty(headerName)) {
this.headers[headerName] = headers[headerName];
}
}
}
// ensure accept-language is set correctly
if (!this.headers["accept-language"]) {
this.headers["accept-language"] = "en-US";
}
// ensure the request-id is set correctly
if (!this.headers["x-ms-client-request-id"] && !options.disableClientRequestId) {
this.headers["x-ms-client-request-id"] = generateUuid();
}
// default
if (!this.headers["Content-Type"]) {
this.headers["Content-Type"] = "application/json; charset=utf-8";
}
// set the request body. request.js automatically sets the Content-Length request header, so we need not set it explicilty
this.body = undefined;
if (options.body !== null && options.body !== undefined) {
// body as a stream special case. set the body as-is and check for some special request headers specific to sending a stream.
if (options.bodyIsStream) {
this.body = options.body;
if (!this.headers["Transfer-Encoding"]) {
this.headers["Transfer-Encoding"] = "chunked";
}
if (this.headers["Content-Type"] !== "application/octet-stream") {
this.headers["Content-Type"] = "application/octet-stream";
}
} else {
let serializedBody = undefined;
if (options.serializationMapper) {
serializedBody = new Serializer(options.mappers).serialize(options.serializationMapper, options.body, "requestBody");
}
if (options.disableJsonStringifyOnBody) {
this.body = serializedBody || options.body;
} else {
this.body = serializedBody ? JSON.stringify(serializedBody) : JSON.stringify(options.body);
}
}
}
return this;
}
}
/**
* Prepares the request.
* @param {object} options The request options that should be provided to send a request successfully
* @param {string} options.method The HTTP request method. Valid values are "GET", "PUT", "HEAD", "DELETE", "OPTIONS", "POST", "PATCH".
* @param {string} [options.url] The request url. It may or may not have query parameters in it.
* Either provide the "url" or provide the "pathTemplate" in the options object. Both the options are mutually exclusive.
* @param {object} [options.queryParameters] A dictionary of query parameters to be appended to the url, where
* the "key" is the "query-parameter-name" and the "value" is the "query-parameter-value".
* The "query-parameter-value" can be of type "string" or it can be of type "object".
* The "object" format should be used when you want to skip url encoding. While using the object format,
* the object must have a property named value which provides the "query-parameter-value".
* Example:
* - query-parameter-value in "object" format: { "query-parameter-name": { value: "query-parameter-value", skipUrlEncoding: true } }
* - query-parameter-value in "string" format: { "query-parameter-name": "query-parameter-value"}.
* Note: "If options.url already has some query parameters, then the value provided in options.queryParameters will be appended to the url.
* @param {string} [options.pathTemplate] The path template of the request url. Either provide the "url" or provide the "pathTemplate"
* in the options object. Both the options are mutually exclusive.
* Example: "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}"
* @param {string} [options.baseUrl] The base url of the request. Default value is: "https://management.azure.com". This is applicable only with
* options.pathTemplate. If you are providing options.url then it is expected that you provide the complete url.
* @param {object} [options.pathParameters] A dictionary of path parameters that need to be replaced with actual values in the pathTemplate.
* Here the key is the "path-parameter-name" and the value is the "path-parameter-value".
* The "path-parameter-value" can be of type "string" or it can be of type "object".
* The "object" format should be used when you want to skip url encoding. While using the object format,
* the object must have a property named value which provides the "path-parameter-value".
* Example:
* - path-parameter-value in "object" format: { "path-parameter-name": { value: "path-parameter-value", skipUrlEncoding: true } }
* - path-parameter-value in "string" format: { "path-parameter-name": "path-parameter-value" }.
* @param {object} [options.headers] A dictionary of request headers that need to be applied to the request.
* Here the key is the "header-name" and the value is the "header-value". The header-value MUST be of type string.
* - ContentType must be provided with the key name as "Content-Type". Default value "application/json; charset=utf-8".
* - "Transfer-Encoding" is set to "chunked" by default if "options.bodyIsStream" is set to true.
* - "Content-Type" is set to "application/octet-stream" by default if "options.bodyIsStream" is set to true.
* - "accept-language" by default is set to "en-US"
* - "x-ms-client-request-id" by default is set to a new Guid. To not generate a guid for the request, please set options.disableClientRequestId to true
* @param {boolean} [options.disableClientRequestId] When set to true, instructs the client to not set "x-ms-client-request-id" header to a new Guid().
* @param {object|string|boolean|array|number|null|undefined} [options.body] - The request body. It can be of any type. This method will JSON.stringify() the request body.
* @param {object} [options.serializationMapper] - Provides information on how to serialize the request body.
* @param {object} [options.mappers] - A dictionary of mappers that may be used while [de]serialization.
* @param {object} [options.deserializationMapper] - Provides information on how to deserialize the response body.
* @param {boolean} [options.disableJsonStringifyOnBody] - Indicates whether this method should JSON.stringify() the request body. Default value: false.
* @param {boolean} [options.bodyIsStream] - Indicates whether the request body is a stream (useful for file upload scenarios).
* @returns {object} WebResource Returns the prepared WebResource (HTTP Request) object that needs to be given to the request pipeline.
*/
export interface RequestPrepareOptions {
method: HttpMethods;
url?: string;
queryParameters?: { [key: string]: any } | ParameterValue;
pathTemplate?: string;
baseUrl?: string;
pathParameters?: { [key: string]: any } | ParameterValue;
headers?: { [key: string]: any };
disableClientRequestId?: boolean;
body?: any;
serializationMapper?: Mapper;
mappers?: { [x: string]: any };
deserializationMapper?: object;
disableJsonStringifyOnBody?: boolean;
bodyIsStream?: boolean;
}
/**
* The Parameter value provided for path or query parameters in RequestPrepareOptions
*/
export interface ParameterValue {
value: any;
skipUrlEncoding: boolean;
[key: string]: any;
}
/**
* Describes the base structure of the options object that will be used in every operation.
*/
export interface RequestOptionsBase {
/**
* @property {object} [customHeaders] - User defined custom request headers that
* will be applied before the request is sent.
*/
customHeaders?: { [key: string]: string };
[key: string]: any;
}

4090
msRestBundle.js Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1
msRestBundle.js.map Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1
msRestBundle.min.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1
msRestBundle.min.js.map Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

3783
package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

67
package.json Normal file
Просмотреть файл

@ -0,0 +1,67 @@
{
"name": "ms-rest-js",
"author": {
"name": "Microsoft Corporation",
"email": "azsdkteam@microsoft.com",
"url": "https://github.com/Azure/azure-sdk-for-node"
},
"version": "0.1.0",
"description": "Client Runtime for Node.js client libraries generated using AutoRest",
"tags": [
"node",
"microsoft",
"autorest",
"clientruntime"
],
"keywords": [
"node",
"microsoft",
"autorest",
"clientruntime"
],
"main": "./dist/lib/msRest.js",
"types": "./typings/lib/msRest.d.ts",
"license": "MIT",
"dependencies": {
"@types/form-data": "^2.2.0",
"@types/node": "^8.0.28",
"@types/node-fetch": "^1.6.7",
"@types/uuid": "^3.4.1",
"@types/is-stream": "^1.1.0",
"fetch-cookie": "^0.6.0",
"form-data": "^2.3.1",
"is-stream": "^1.1.0",
"url-parse": "^1.1.9",
"moment": "^2.18.1",
"is-buffer": "^1.1.5",
"uuid": "^3.1.0",
"detect-node": "^2.0.3",
"fetch-ponyfill": "amarzavery/fetch-ponyfill#master"
},
"devDependencies": {
"@types/mocha": "^2.2.40",
"@types/should": "^8.1.30",
"mocha": "^3.2.0",
"should": "5.2.0",
"ts-loader": "^2.3.7",
"tslint": "^5.7.0",
"typescript": "^2.5.2",
"webpack": "^3.5.6",
"uglify-es": "^3.1.0"
},
"homepage": "https://github.com/Azure/azure-sdk-for-node/runtime/ms-rest",
"repository": {
"type": "git",
"url": "git@github.com:Azure/azure-sdk-for-node.git"
},
"bugs": {
"url": "http://github.com/Azure/azure-sdk-for-node/issues"
},
"scripts": {
"tsc": "tsc -p tsconfig.json",
"test": "npm install && npm -s run-script unit",
"unit": "mocha -t 50000 dist/test",
"uglify": "node node_modules/uglify-es/bin/uglifyjs --source-map -c -m -o msRestBundle.min.js msRestBundle.js",
"build": "npm -s run-script tsc && webpack && npm -s run-script uglify"
}
}

25
samples/index.html Normal file
Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Todos</title>
<script type="text/javascript" src="../msRestBundle.js"></script>
<script type="text/javascript">
document.write('hello world');
const msRest = className;
const subscriptionId = "00977cdb-163f-435f-9c32-39ec8ae61f4d";
const token = "token";
const creds = new msRest.TokenCredentials(token);
const client = new msRest.ServiceClient(creds);
const req = {
url: `https://management.azure.com/subscriptions/${subscriptionId}/providers/Microsoft.Storage/storageAccounts?api-version=2015-06-15`,
method: "GET"
};
client.sendRequest(req).then((res) => { document.write(res.bodyAsText); }).catch((err) => { console.log(err); });
</script>
</head>
<body>
</body>
</html>

26
samples/node-sample.js Normal file
Просмотреть файл

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const msRest = require("../lib/msRest");
const clientOptions = {
filters: [new msRest.LogFilter()]
};
const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "subscriptionId";
// An easy way to get the token
// 1. Go to this test drive link https://azure.github.io/projects/apis and authenticate by clicking on Authorize. Check the user impersoantion checkbox in the popup.
// 1.1 select a subscription of your choice
// 1.2 select the storage-2015-06-15 option from the first drop down list
// 1.3 expand the url to list storage accounts in a subscription
// 1.4 click on try it out button.
// 1.5 in the curl tab you will see the actual curl request that has the bearer token in it
// 1.6 copy paste that token here. That token is valid for 1 hour
const token = process.env["ACCESS_TOKEN"] || "token";
const creds = new msRest.TokenCredentials(token);
const client = new msRest.ServiceClient(creds, clientOptions);
const req = {
url: `https://management.azure.com/subscriptions/${subscriptionId}/providers/Microsoft.Storage/storageAccounts?api-version=2015-06-15`,
method: 'GET'
};
client.sendRequest(req).then(function (res) {
console.log(res.bodyAsText);
});
//# sourceMappingURL=node-sample.js.map

Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"node-sample.js","sourceRoot":"","sources":["../../samples/node-sample.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,wCAAwC;AACxC,MAAM,aAAa,GAAgC;IACjD,OAAO,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,gBAAgB,CAAC;AAChF,+BAA+B;AAC/B,qKAAqK;AACrK,2CAA2C;AAC3C,yEAAyE;AACzE,gEAAgE;AAChE,kCAAkC;AAClC,2FAA2F;AAC3F,iEAAiE;AACjE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC;AACrD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC9D,MAAM,GAAG,GAAiC;IACxC,GAAG,EAAE,8CAA8C,cAAc,qEAAqE;IACtI,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,GAAiC;IACtE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC"}

28
samples/node-sample.ts Normal file
Просмотреть файл

@ -0,0 +1,28 @@
"use strict";
import * as msRest from "../lib/msRest";
const clientOptions: msRest.ServiceClientOptions = {
filters: [new msRest.LogFilter()]
};
const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "subscriptionId";
// An easy way to get the token
// 1. Go to this test drive link https://azure.github.io/projects/apis and authenticate by clicking on Authorize. Check the user impersoantion checkbox in the popup.
// 1.1 select a subscription of your choice
// 1.2 select the storage-2015-06-15 option from the first drop down list
// 1.3 expand the url to list storage accounts in a subscription
// 1.4 click on try it out button.
// 1.5 in the curl tab you will see the actual curl request that has the bearer token in it
// 1.6 copy paste that token here. That token is valid for 1 hour
const token = process.env["ACCESS_TOKEN"] || "token";
const creds = new msRest.TokenCredentials(token);
const client = new msRest.ServiceClient(creds, clientOptions);
const req: msRest.RequestPrepareOptions = {
url: `https://management.azure.com/subscriptions/${subscriptionId}/providers/Microsoft.Storage/storageAccounts?api-version=2015-06-15`,
method: 'GET'
};
client.sendRequest(req).then(function (res: msRest.HttpOperationResponse) {
console.log(res.bodyAsText);
});

109
test/credentialTests.ts Normal file
Просмотреть файл

@ -0,0 +1,109 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as msRest from "../lib/msRest";
const should = require("should");
const TokenCredentials = msRest.TokenCredentials;
const BasicAuthenticationCredentials = msRest.BasicAuthenticationCredentials;
const dummyToken = "A-dummy-access-token";
const fakeScheme = "fake-auth-scheme";
const dummyuserName = "dummy@mummy.com";
const dummyPassword = "IL0veDummies";
describe("Token credentials", () => {
describe("usage", () => {
it("should set auth header with bearer scheme in request", (done) => {
const creds = new TokenCredentials(dummyToken);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest: msRest.WebResource) => {
should.exist(signedRequest.headers["authorization"]);
signedRequest.headers["authorization"].should.match(new RegExp("^Bearer\\s+" + dummyToken + "$"));
done();
});
});
it("should set auth header with custom scheme in request", (done) => {
const creds = new TokenCredentials(dummyToken, fakeScheme);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest: msRest.WebResource) => {
should.exist(signedRequest.headers["authorization"]);
signedRequest.headers["authorization"].should.match(new RegExp("^" + fakeScheme + "\\s+" + dummyToken + "$"));
done();
});
});
});
describe("construction", () => {
it("should succeed with token", () => {
(() => {
new TokenCredentials(dummyToken);
}).should.not.throw();
});
// it("should fail without credentials", () => {
// (() => {
// new TokenCredentials();
// }).should.throw();
// });
// it("should fail without token", () => {
// (() => {
// new TokenCredentials(null, fakeScheme);
// }).should.throw();
// });
});
});
describe("Basic Authentication credentials", () => {
const encodedCredentials = Buffer.from(dummyuserName + ":" + dummyPassword).toString("base64");
describe("usage", () => {
it("should base64 encode the username and password and set auth header with baisc scheme in request", (done) => {
const creds = new BasicAuthenticationCredentials(dummyuserName, dummyPassword);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest: msRest.WebResource) => {
signedRequest.headers.should.have.property("authorization");
signedRequest.headers["authorization"].should.match(new RegExp("^Basic\\s+" + encodedCredentials + "$"));
done();
});
});
it("should base64 encode the username and password and set auth header with custom scheme in request", (done) => {
const creds = new BasicAuthenticationCredentials(dummyuserName, dummyPassword, fakeScheme);
const request = new msRest.WebResource();
request.headers = {};
creds.signRequest(request).then((signedRequest: msRest.WebResource) => {
signedRequest.headers.should.have.property("authorization");
signedRequest.headers["authorization"].should.match(new RegExp("^" + fakeScheme + "\\s+" + encodedCredentials + "$"));
done();
});
});
});
describe("construction", () => {
it("should succeed with userName and password", () => {
(() => {
new BasicAuthenticationCredentials(dummyuserName, dummyPassword);
}).should.not.throw();
});
// it("should fail without credentials", () => {
// (() => {
// new BasicAuthenticationCredentials(null, null);
// }).should.throw();
// });
// it("should fail without userName and password", () => {
// (() => {
// new BasicAuthenticationCredentials(null, null, fakeScheme);
// }).should.throw();
// });
});
});

Просмотреть файл

@ -0,0 +1,592 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
*/
let internalMappers: any = {};
internalMappers.Cat = {
required: false,
serializedName: "cat",
type: {
name: "Composite",
className: "Cat",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
},
color: {
required: false,
serializedName: "color",
type: {
name: "String"
}
},
hates: {
required: false,
serializedName: "hates",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "DogElementType",
type: {
name: "Composite",
className: "Dog"
}
}
}
}
}
}
};
internalMappers.Dog = {
required: false,
serializedName: "dog",
type: {
name: "Composite",
className: "Dog",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
},
food: {
required: false,
serializedName: "food",
type: {
name: "String"
}
}
}
}
};
internalMappers.Fish = {
required: false,
serializedName: "Fish",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
}
}
}
};
internalMappers.Invoice = {
required: false,
serializedName: "Invoice",
type: {
name: "Composite",
className: "Invoice",
modelProperties: {
invId: {
serializedName: "invoiceId",
required: true,
type: {
name: "Number"
}
},
invDate: {
serializedName: "invDate",
required: false,
type: {
name: "Date"
}
},
invProducts: {
serializedName: "invProducts",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Dictionary",
value: {
type: {
name: "Composite",
className: "Product"
}
}
}
}
}
}
}
}
};
internalMappers.Pet = {
required: false,
serializedName: "pet",
type: {
name: "Composite",
className: "Pet",
polymorphicDiscriminator: "pet.type",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pettype: {
required: true,
serializedName: "pet\\.type",
type: {
name: "String"
}
}
}
}
};
internalMappers.PetGallery = {
required: false,
serializedName: "PetGallery",
type: {
name: "Composite",
className: "PetGallery",
modelProperties: {
id: {
required: false,
serializedName: "id",
type: {
name: "Number"
}
},
name: {
required: false,
serializedName: "name",
type: {
name: "String"
}
},
pets: {
required: false,
serializedName: "pets",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "petElementType",
type: {
name: "Composite",
polymorphicDiscriminator: "pet.type",
uberParent: "Pet",
className: "Pet"
}
}
}
}
}
}
};
internalMappers.Product = {
required: false,
serializedName: "Product",
type: {
name: "Composite",
className: "Product",
modelProperties: {
id: {
serializedName: "id",
constraints: {
},
required: true,
type: {
name: "Number"
}
},
name: {
serializedName: "name",
required: true,
type: {
name: "String"
}
},
provisioningState: {
serializedName: "properties.provisioningState",
required: false,
type: {
name: "Enum",
allowedValues: ["Creating", "Failed", "Succeeded"]
}
},
tags: {
serializedName: "tags",
required: false,
type: {
name: "Dictionary",
value: {
type: {
name: "String"
}
}
}
},
dispatchTime: {
serializedName: "dispatchTime",
required: false,
type: {
name: "DateTime"
}
},
invoiceInfo: {
serializedName: "invoiceInfo",
required: false,
type: {
name: "Composite",
className: "Invoice"
}
},
subProducts: {
serializedName: "subProducts",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "SubProduct"
}
}
}
}
}
}
};
internalMappers.ProductListResult = {
required: false,
serializedName: "ProductListResult",
type: {
name: "Composite",
className: "ProductListResult",
modelProperties: {
value: {
serializedName: "",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "Product"
}
}
}
}
}
}
};
internalMappers.ProductListResultNextLink = {
required: false,
serializedName: "ProductListResultNextLink",
type: {
name: "Composite",
className: "ProductListResultNextLink",
modelProperties: {
value: {
serializedName: "",
required: false,
type: {
name: "Sequence",
element: {
type: {
name: "Composite",
className: "Product"
}
}
}
},
nextLink: {
serializedName: "nextLink",
required: false,
type: {
name: "String"
}
}
}
}
};
internalMappers.SawShark = {
required: false,
serializedName: "sawshark",
type: {
name: "Composite",
className: "Sawshark",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
},
age: {
required: false,
serializedName: "age",
type: {
name: "Number"
}
},
birthday: {
required: true,
serializedName: "birthday",
type: {
name: "DateTime"
}
},
picture: {
required: false,
serializedName: "picture",
type: {
name: "ByteArray"
}
}
}
}
};
internalMappers.Shark = {
required: false,
serializedName: "shark",
type: {
name: "Composite",
className: "Shark",
modelProperties: {
species: {
required: false,
serializedName: "species",
type: {
name: "String"
}
},
length: {
required: true,
serializedName: "length",
type: {
name: "Number"
}
},
siblings: {
required: false,
serializedName: "siblings",
type: {
name: "Sequence",
element: {
required: false,
serializedName: "FishElementType",
type: {
name: "Composite",
polymorphicDiscriminator: {
serializedName: "fish.type",
clientName: "fishtype"
},
uberParent: "Fish",
className: "Fish"
}
}
}
},
fishtype: {
required: true,
serializedName: "fish\\.type",
type: {
name: "String"
}
},
age: {
required: false,
serializedName: "age",
type: {
name: "Number"
}
},
birthday: {
required: true,
serializedName: "birthday",
type: {
name: "DateTime"
}
}
}
}
};
internalMappers.SubProduct = {
required: false,
serializedName: "SubProduct",
type: {
name: "Composite",
className: "SubProduct",
modelProperties: {
subId: {
serializedName: "subId",
required: true,
type: {
name: "Number"
}
},
subName: {
serializedName: "subName",
required: true,
type: {
name: "String"
}
},
provisioningState: {
serializedName: "provisioningState",
required: false,
type: {
name: "Enum",
allowedValues: ["Creating", "Failed", "Succeeded"]
}
},
makeTime: {
serializedName: "makeTime",
required: false,
type: {
name: "DateTime"
}
},
invoiceInfo: {
serializedName: "invoiceInfo",
required: false,
type: {
name: "Composite",
className: "Invoice"
}
}
}
}
};
internalMappers.discriminators = {
"Fish": internalMappers.Fish,
"Fish.shark": internalMappers.Shark,
"Fish.sawshark": internalMappers.SawShark,
"Pet": internalMappers.Pet,
"Pet.Cat": internalMappers.Cat,
"Pet.Dog": internalMappers.Dog
};
export const Mappers = internalMappers;

Просмотреть файл

@ -0,0 +1,57 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
*
* Code generated by Microsoft (R) AutoRest Code Generator 0.14.0.0
* Changes may cause incorrect behavior and will be lost if the code is
* regenerated.
*/
/* jshint latedef:false */
/* jshint forin:false */
/* jshint noempty:false */
'use strict';
import * as msRest from '../../../../lib/msRest';
import { Mappers } from './models/mappers';
/**
* @class
* Initializes a new instance of the TestClient class.
* @constructor
*
* @param {string} [baseUri] - The base URI of the service.
*
* @param {object} [options] - The parameter options
*
* @param {Array} [options.filters] - Filters to be added to the request pipeline
*
* @param {object} [options.requestOptions] - Options for the underlying request object
* {@link https://github.com/request/request#requestoptions-callback Options doc}
*
* @param {bool} [options.noRetryPolicy] - If set to true, turn off default retry policy
*/
class TestClient extends msRest.ServiceClient {
baseUri?: string;
acceptLanguage?: string;
models?: any;
serializer: msRest.Serializer;
constructor(baseUri: string, options?: msRest.ServiceClientOptions) {
if (!options) options = {};
super(undefined, options);
this.baseUri = baseUri;
if (!this.baseUri) {
this.baseUri = 'https://management.azure.com';
}
if (!this.acceptLanguage) {
this.acceptLanguage = 'en-US';
}
this.serializer = new msRest.Serializer(Mappers);
}
}
export { TestClient };

43
test/logFilterTests.ts Normal file
Просмотреть файл

@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as assert from "assert";
import { WebResource } from "../lib/webResource";
import { HttpOperationResponse } from "../lib/httpOperationResponse";
import { LogFilter } from "../lib/filters/logFilter";
import { Response } from "node-fetch";
describe("Log filter", () => {
it("should log messages when a logger object is provided", (done) => {
const expected = `>> Request: {
"headers": {},
"rawResponse": false,
"url": "https://foo.com",
"method": "PUT",
"body": {
"a": 1
}
}
>> Response status code: 200
>> Body: null
`;
let output = "";
const logger: Function = (message: string): void => { output += message + "\n"; };
const lf = new LogFilter(logger);
const req = new WebResource("https://foo.com", "PUT", { "a": 1 });
const res = new Response();
const opRes = new HttpOperationResponse(req, res as any, res.body as any);
lf.after(opRes).then(() => {
//console.dir(output, { depth: null });
//console.log(">>>>>>>");
//console.dir(expected);
assert.deepEqual(output, expected);
done();
}).catch((err: Error) => {
done(err);
});
});
});

753
test/serializationTests.ts Normal file
Просмотреть файл

@ -0,0 +1,753 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as assert from "assert";
import * as moment from "moment";
import * as msRest from "../lib/msRest";
const should = require("should");
import { TestClient } from "./data/TestClient/lib/testClient";
import { Mappers } from "./data/Testclient/lib/models/mappers";
let Serializer = new msRest.Serializer({});
let valid_uuid = "ceaafd1e-f936-429f-bbfc-82ee75dddc33";
describe("msrest", function () {
describe("serializeObject", function () {
it("should correctly serialize a Date Object", function (done) {
let dateObj = new Date("2015-01-01");
let dateISO = "2015-01-01T00:00:00.000Z";
msRest.serializeObject(dateObj).should.equal(dateISO);
done();
});
it("should correctly serialize a Date object with max value", function (done) {
let serializedDateString = msRest.serializeObject(new Date("9999-12-31T23:59:59-12:00"));
serializedDateString.should.equal("+010000-01-01T11:59:59.000Z");
done();
});
it("should correctly serialize a Buffer Object", function (done) {
let bufferObj = new Buffer("Javascript");
let base64str = "SmF2YXNjcmlwdA==";
msRest.serializeObject(bufferObj).should.equal(base64str);
done();
});
it("should correctly serialize Primitive types", function (done) {
msRest.serializeObject(true).should.equal(true);
msRest.serializeObject(false).should.equal(false);
msRest.serializeObject("true").should.equal("true");
msRest.serializeObject(1).should.equal(1);
msRest.serializeObject(100.0123).should.equal(100.0123);
assert.equal(msRest.serializeObject(null), null);
done();
});
it("should correctly serialize an empty array and an empty dictionary", function (done) {
assert.deepEqual(msRest.serializeObject([]), []);
assert.deepEqual(msRest.serializeObject({}), {});
done();
});
it("should correctly serialize a complex JSON object", function (done) {
let o1: any = {
"p1": "value1",
"p2": "value2",
"top-buf": new Buffer("top string", "utf-8"),
"top-date": new Date("2014"),
"top-dates": [new Date("1900"), new Date("1901")],
"insider": {
"insider-buf": new Buffer("insider string", "utf-8"),
"insider-date": new Date("2015"),
"insider-dates": [new Date("2100"), new Date("2101")],
"insider-dictionary": {
"k1": new Date("2015"),
"k2": new Date("2016"),
"k3": new Date("2017")
},
"top-complex": {
"id": 1,
"name": "Joey",
"age": 23.36,
"male": true,
"birthday": "1992-01-01T00:00:00.000Z",
"anniversary": new Date("2013-12-08"),
"memory": new Buffer("Yadadadada")
}
}
};
let o2: any = {
p1: "value1",
p2: "value2",
"top-buf": "dG9wIHN0cmluZw==",
"top-date": "2014-01-01T00:00:00.000Z",
"top-dates": [
"1900-01-01T00:00:00.000Z",
"1901-01-01T00:00:00.000Z"
],
insider: {
"insider-buf": "aW5zaWRlciBzdHJpbmc=",
"insider-date": "2015-01-01T00:00:00.000Z",
"insider-dates": [
"2100-01-01T00:00:00.000Z",
"2101-01-01T00:00:00.000Z"
],
"insider-dictionary": {
k1: "2015-01-01T00:00:00.000Z",
k2: "2016-01-01T00:00:00.000Z",
k3: "2017-01-01T00:00:00.000Z"
},
"top-complex": {
id: 1,
name: "Joey",
age: 23.36,
male: true,
birthday: "1992-01-01T00:00:00.000Z",
anniversary: "2013-12-08T00:00:00.000Z",
memory: "WWFkYWRhZGFkYQ=="
}
}
};
assert.deepEqual(msRest.serializeObject(o1), o2);
done();
});
});
describe("serialize", function () {
let invalid_uuid = "abcd-efgd90-90890jkh";
it("should correctly serialize a string", function (done) {
let mapper: msRest.Mapper = { type: { name: "String" }, required: false, serializedName: "string" };
let serializedObject = Serializer.serialize(mapper, "foo", "stringBody");
serializedObject.should.equal("foo");
done();
});
it("should correctly serialize a uuid", function (done) {
let mapper: msRest.Mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
let serializedObject = Serializer.serialize(mapper, valid_uuid, "uuidBody");
serializedObject.should.equal(valid_uuid);
done();
});
it("should throw an error if the value is not a valid Uuid", function (done) {
let mapper: msRest.Mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
try {
Serializer.serialize(mapper, invalid_uuid, "uuidBody");
} catch (error) {
error.message.should.match(/.*with value.*must be of type string and a valid uuid/ig);
done();
}
});
it("should correctly serialize a number", function (done) {
let mapper: msRest.Mapper = { type: { name: "Number" }, required: false, serializedName: "Number" };
let serializedObject = Serializer.serialize(mapper, 1.506, "stringBody");
serializedObject.should.equal(1.506);
done();
});
it("should correctly serialize a boolean", function (done) {
let mapper: msRest.Mapper = { type: { name: "Boolean" }, required: false, serializedName: "Boolean" };
let serializedObject = Serializer.serialize(mapper, false, "stringBody");
serializedObject.should.equal(false);
done();
});
it("should correctly serialize an Enum", function (done) {
let mapper: msRest.EnumMapper = { type: { name: "Enum", allowedValues: [1, 2, 3, 4] }, required: false, serializedName: "Enum" };
let serializedObject = Serializer.serialize(mapper, 1, "enumBody");
serializedObject.should.equal(1);
done();
});
it("should throw an error if the value is not valid for an Enum", function (done) {
let mapper: msRest.EnumMapper = { type: { name: "Enum", allowedValues: [1, 2, 3, 4] }, required: false, serializedName: "Enum" };
try {
Serializer.serialize(mapper, 6, "enumBody");
} catch (error) {
error.message.should.match(/6 is not a valid value for enumBody\. The valid values are: \[1,2,3,4\]/ig);
done();
}
});
it("should correctly serialize a Buffer Object", function (done) {
let mapper: msRest.Mapper = { type: { name: "ByteArray" }, required: false, serializedName: "ByteArray" };
let bufferObj = new Buffer("Javascript");
let base64str = "SmF2YXNjcmlwdA==";
let serializedObject = Serializer.serialize(mapper, bufferObj, "stringBody");
serializedObject.should.equal(base64str);
done();
});
it("should correctly serialize a Date Object", function (done) {
let dateObj = new Date("2015-01-01");
let dateISO = "2015-01-01";
let mapper: msRest.Mapper = { type: { name: "Date" }, required: false, serializedName: "Date" };
Serializer.serialize(mapper, dateObj, "dateObj").should.equal(dateISO);
done();
});
it("should correctly serialize a Date object with max value", function (done) {
let mapper: msRest.Mapper = { type: { name: "DateTime" }, required: false, serializedName: "DateTime" };
let serializedDateString = Serializer.serialize(mapper, new Date("9999-12-31T23:59:59-12:00"), "dateTimeObj");
should.equal(serializedDateString, "+010000-01-01T11:59:59.000Z");
done();
});
it("should correctly serialize a Date object with max value and format UnixTime", function (done) {
let mapper: msRest.Mapper = { type: { name: "UnixTime" }, required: false, serializedName: "UnixTime" };
let serializedDate = Serializer.serialize(mapper, new Date("9999-12-31T23:59:59-12:00"), "dateTimeObj");
serializedDate.should.equal(253402343999);
done();
});
it("should correctly serialize a string in DateTimeRfc1123", function (done) {
let mapper: msRest.Mapper = { type: { name: "DateTimeRfc1123" }, required: false, serializedName: "DateTimeRfc1123" };
let rfc = new Date("Mon, 01 Jan 0001 00:00:00 GMT");
let serializedDateString = Serializer.serialize(mapper, rfc, "dateTimeObj");
serializedDateString.should.equal("Mon, 01 Jan 2001 00:00:00 GMT");
done();
});
it("should correctly serialize a duration object", function (done) {
let mapper: msRest.Mapper = { type: { name: "TimeSpan" }, required: false, serializedName: "TimeSpan" };
let duration = moment.duration({ days: 123, hours: 22, minutes: 14, seconds: 12, milliseconds: 11 });
let serializedDateString = Serializer.serialize(mapper, duration, "dateTimeObj");
serializedDateString.should.equal("P123DT22H14M12.010999999998603S");
done();
});
it("should correctly serialize an array of primitives", function (done) {
let mapper: msRest.SequenceMapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
type: { name: "String" },
required: true,
serializedName: "sequenceElement"
}
}
};
let array = ["One", "Two", "three"];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize an array of array of primitives", function (done) {
let mapper: msRest.SequenceMapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Number"
}
}
}
}
}
};
let array = [[1], [2], [1, 2, 3]];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize an array of dictionary of primitives", function (done) {
let mapper: msRest.SequenceMapper = {
required: false,
serializedName: "Sequence",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Boolean"
}
}
}
}
}
};
let array = [{ 1: true }, { 2: false }, { 1: true, 2: false, 3: true }];
let serializedArray = Serializer.serialize(mapper, array, "arrayObj");
assert.deepEqual(array, serializedArray);
done();
});
it("should correctly serialize a dictionary of primitives", function (done) {
let mapper: msRest.DictionaryMapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "String"
}
}
}
};
let dict = { 1: "One", 2: "Two", 3: "three" };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a dictionary of array of primitives", function (done) {
let mapper: msRest.DictionaryMapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Sequence",
element: {
required: true,
serializedName: "sequenceElement",
type: {
name: "Number"
}
}
}
}
}
};
let dict = { "One": [1], "Two": [1, 2], "three": [1, 2, 3] };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a dictionary of dictionary of primitives", function (done) {
let mapper: msRest.DictionaryMapper = {
required: false,
serializedName: "Dictionary",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Dictionary",
value: {
required: true,
serializedName: "valueElement",
type: {
name: "Boolean"
}
}
}
}
}
};
let dict = { 1: { "One": true }, 2: { "Two": false }, 3: { "three": true } };
let serializedDictionary = Serializer.serialize(mapper, dict, "dictObj");
assert.deepEqual(dict, serializedDictionary);
done();
});
it("should correctly serialize a composite type", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.Product;
let productObj = {
id: 101,
name: "TestProduct",
provisioningState: "Succeeded",
tags: {
tag1: "value1",
tag2: "value2"
},
dispatchTime: new Date("2015-01-01T12:35:36.009Z"),
invoiceInfo: {
invId: 1002,
invDate: "2015-12-25",
invProducts: [
{
"Product1": {
id: 101,
name: "TestProduct"
}
},
{
"Product2": {
id: 104,
name: "TestProduct1"
}
}
]
},
subProducts: [
{
subId: 102,
subName: "SubProduct1",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invId: 1002,
invDate: "2015-12-25"
}
},
{
subId: 103,
subName: "SubProduct2",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invId: 1003,
invDate: "2015-12-25"
}
}
]
};
let serializedProduct = client.serializer.serialize(mapper, productObj, "productObject");
for (let prop in serializedProduct) {
if (prop === "properties") {
serializedProduct[prop].provisioningState.should.equal(productObj.provisioningState);
} else if (prop === "id") {
serializedProduct[prop].should.equal(productObj.id);
} else if (prop === "name") {
serializedProduct[prop].should.equal(productObj.name);
} else if (prop === "tags") {
JSON.stringify(serializedProduct[prop]).should.equal(JSON.stringify(productObj.tags));
} else if (prop === "dispatchTime") {
JSON.stringify(serializedProduct[prop]).should.equal(JSON.stringify(productObj.dispatchTime));
} else if (prop === "invoiceInfo") {
(JSON.stringify(serializedProduct[prop]).length - JSON.stringify(productObj.invoiceInfo).length).should.equal(4);
} else if (prop === "subProducts") {
(JSON.stringify(serializedProduct[prop]).length - JSON.stringify(productObj.subProducts).length).should.equal(8);
}
}
done();
});
it("should correctly serialize object version of polymorphic discriminator", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.SawShark;
let sawshark = {
"fishtype": "sawshark",
"age": 22,
"birthday": new Date("2012-01-05T01:00:00Z"),
"species": "king",
"length": 1.0,
"picture": new Buffer([255, 255, 255, 255, 254]),
"siblings": [
{
"fishtype": "shark",
"age": 6,
"birthday": new Date("2012-01-05T01:00:00Z"),
"length": 20.0,
"species": "predator"
},
{
"fishtype": "sawshark",
"age": 105,
"birthday": new Date("1900-01-05T01:00:00Z"),
"length": 10.0,
"picture": new Buffer([255, 255, 255, 255, 254]),
"species": "dangerous"
}
]
};
let serializedSawshark = client.serializer.serialize(mapper, sawshark, "result");
serializedSawshark.age.should.equal(22);
serializedSawshark["fish.type"].should.equal("sawshark");
serializedSawshark.siblings.length.should.equal(2);
serializedSawshark.siblings[0]["fish.type"].should.equal("shark");
serializedSawshark.siblings[0].age.should.equal(6);
serializedSawshark.siblings[0].birthday.should.equal(new Date("2012-01-05T01:00:00Z").toISOString());
serializedSawshark.siblings[1]["fish.type"].should.equal("sawshark");
serializedSawshark.siblings[1].age.should.equal(105);
serializedSawshark.siblings[1].birthday.should.equal(new Date("1900-01-05T01:00:00Z").toISOString());
serializedSawshark.siblings[1].picture.should.equal("//////4=");
serializedSawshark.picture.should.equal("//////4=");
done();
});
it("should correctly serialize string version of polymorphic discriminator", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.PetGallery;
let petgallery = {
"id": 1,
"name": "Fav pet gallery",
"pets": [
{
"id": 2,
"name": "moti",
"food": "buiscuit",
"pet.type": "Dog",
"pettype": "Dog"
},
{
"id": 3,
"name": "billa",
"color": "red",
"pet.type": "Cat",
"pettype": "Cat" // In string version the user has to pass the actual property with dot and the normalized one.
}
]
};
let serializedPetGallery = client.serializer.serialize(mapper, petgallery, "result");
serializedPetGallery.id.should.equal(1);
serializedPetGallery.name.should.equal("Fav pet gallery");
serializedPetGallery.pets.length.should.equal(2);
serializedPetGallery.pets[0]["pet.type"].should.equal("Dog");
serializedPetGallery.pets[0].id.should.equal(2);
serializedPetGallery.pets[0].name.should.equal("moti");
serializedPetGallery.pets[0].food.should.equal("buiscuit");
serializedPetGallery.pets[1]["pet.type"].should.equal("Cat");
serializedPetGallery.pets[1].id.should.equal(3);
serializedPetGallery.pets[1].name.should.equal("billa");
serializedPetGallery.pets[1].color.should.equal("red");
done();
});
});
describe("deserialize", function () {
it("should correctly deserialize a uuid", function (done) {
let mapper: msRest.Mapper = { type: { name: "Uuid" }, required: false, serializedName: "Uuid" };
let serializedObject = Serializer.deserialize(mapper, valid_uuid, "uuidBody");
serializedObject.should.equal(valid_uuid);
done();
});
it("should correctly deserialize a composite type", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.Product;
let responseBody = {
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
},
tags: {
tag1: "value1",
tag2: "value2"
},
dispatchTime: new Date("2015-01-01T12:35:36.009Z"),
invoiceInfo: {
invoiceId: 1002,
invDate: "2015-12-25",
invProducts: [
{
"Product1": {
id: 101,
name: "TestProduct"
}
},
{
"Product2": {
id: 104,
name: "TestProduct1"
}
}
]
},
subProducts: [
{
subId: 102,
subName: "SubProduct1",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invoiceId: 1002,
invDate: "2015-12-25"
}
},
{
subId: 103,
subName: "SubProduct2",
makeTime: new Date("2015-12-21T01:01:01"),
invoiceInfo: {
invoiceId: 1003,
invDate: "2015-12-25"
}
}
]
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
for (let prop in deserializedProduct) {
if (prop === "provisioningState") {
deserializedProduct.provisioningState.should.equal(responseBody.properties.provisioningState);
} else if (prop === "id") {
deserializedProduct[prop].should.equal(responseBody.id);
} else if (prop === "name") {
deserializedProduct[prop].should.equal(responseBody.name);
} else if (prop === "tags") {
JSON.stringify(deserializedProduct[prop]).should.equal(JSON.stringify(responseBody.tags));
} else if (prop === "dispatchTime") {
JSON.stringify(deserializedProduct[prop]).should.equal(JSON.stringify(responseBody.dispatchTime));
} else if (prop === "invoiceInfo") {
(JSON.stringify(deserializedProduct[prop]).length - JSON.stringify(responseBody.invoiceInfo).length).should.equal(10);
} else if (prop === "subProducts") {
(JSON.stringify(deserializedProduct[prop]).length - JSON.stringify(responseBody.subProducts).length).should.equal(20);
}
}
done();
});
it("should correctly deserialize a pageable type without nextLink", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.ProductListResult;
let responseBody = {
value: [
{
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
}
},
{
id: 104,
name: "TestProduct1",
properties: {
provisioningState: "Failed"
}
}
]
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
(Array.isArray(deserializedProduct)).should.be.true;
deserializedProduct.length.should.equal(2);
for (let i = 0; i < deserializedProduct.length; i++) {
if (i === 0) {
deserializedProduct[i].id.should.equal(101);
deserializedProduct[i].name.should.equal("TestProduct");
deserializedProduct[i].provisioningState.should.equal("Succeeded");
} else if (i === 1) {
deserializedProduct[i].id.should.equal(104);
deserializedProduct[i].name.should.equal("TestProduct1");
deserializedProduct[i].provisioningState.should.equal("Failed");
}
}
done();
});
it("should correctly deserialize a pageable type with nextLink", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.ProductListResultNextLink;
let responseBody = {
value: [
{
id: 101,
name: "TestProduct",
properties: {
provisioningState: "Succeeded"
}
},
{
id: 104,
name: "TestProduct1",
properties: {
provisioningState: "Failed"
}
}
],
nextLink: "https://helloworld.com"
};
let deserializedProduct = client.serializer.deserialize(mapper, responseBody, "responseBody");
(Array.isArray(deserializedProduct)).should.be.true;
deserializedProduct.length.should.equal(2);
deserializedProduct.nextLink.should.equal("https://helloworld.com");
for (let i = 0; i < deserializedProduct.length; i++) {
if (i === 0) {
deserializedProduct[i].id.should.equal(101);
deserializedProduct[i].name.should.equal("TestProduct");
deserializedProduct[i].provisioningState.should.equal("Succeeded");
} else if (i === 1) {
deserializedProduct[i].id.should.equal(104);
deserializedProduct[i].name.should.equal("TestProduct1");
deserializedProduct[i].provisioningState.should.equal("Failed");
}
}
done();
});
it("should correctly deserialize object version of polymorphic discriminator", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.Fish;
let responseBody = {
"fish.type": "sawshark",
"age": 22,
"birthday": new Date("2012-01-05T01:00:00Z").toISOString(),
"species": "king",
"length": 1.0,
"picture": new Buffer([255, 255, 255, 255, 254]).toString(),
"siblings": [
{
"fish.type": "shark",
"age": 6,
"birthday": new Date("2012-01-05T01:00:00Z"),
"length": 20.0,
"species": "predator"
},
{
"fish.type": "sawshark",
"age": 105,
"birthday": new Date("1900-01-05T01:00:00Z").toISOString(),
"length": 10.0,
"picture": new Buffer([255, 255, 255, 255, 254]).toString(),
"species": "dangerous"
}
]
};
let deserializedSawshark = client.serializer.deserialize(mapper, responseBody, "responseBody");
deserializedSawshark.age.should.equal(22);
deserializedSawshark.fishtype.should.equal("sawshark");
deserializedSawshark.siblings.length.should.equal(2);
deserializedSawshark.siblings[0].fishtype.should.equal("shark");
deserializedSawshark.siblings[0].age.should.equal(6);
deserializedSawshark.siblings[0].birthday.toISOString().should.equal("2012-01-05T01:00:00.000Z");
deserializedSawshark.siblings[1].fishtype.should.equal("sawshark");
deserializedSawshark.siblings[1].age.should.equal(105);
deserializedSawshark.siblings[1].birthday.toISOString().should.equal("1900-01-05T01:00:00.000Z");
done();
});
it("should correctly deserialize string version of polymorphic discriminator", function (done) {
let client = new TestClient("http://localhost:9090");
let mapper = Mappers.PetGallery;
let petgallery = {
"id": 1,
"name": "Fav pet gallery",
"pets": [
{
"id": 2,
"name": "moti",
"food": "buiscuit",
"pet.type": "Dog",
},
{
"id": 3,
"name": "billa",
"color": "red",
"pet.type": "Cat",
}
]
};
let deserializedPetGallery = client.serializer.deserialize(mapper, petgallery, "result");
deserializedPetGallery.id.should.equal(1);
deserializedPetGallery.name.should.equal("Fav pet gallery");
deserializedPetGallery.pets.length.should.equal(2);
deserializedPetGallery.pets[0]["pettype"].should.equal("Dog");
deserializedPetGallery.pets[0].id.should.equal(2);
deserializedPetGallery.pets[0].name.should.equal("moti");
deserializedPetGallery.pets[0].food.should.equal("buiscuit");
deserializedPetGallery.pets[1]["pettype"].should.equal("Cat");
deserializedPetGallery.pets[1].id.should.equal(3);
deserializedPetGallery.pets[1].name.should.equal("billa");
deserializedPetGallery.pets[1].color.should.equal("red");
done();
});
});
});

Просмотреть файл

@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as assert from "assert";
import { WebResource } from "../lib/webResource";
import { MsRestUserAgentFilter } from "../lib/filters/msRestUserAgentFilter";
import { Constants } from "../lib/util/constants";
const should = require("should");
const userAgentHeader = Constants.HeaderConstants.USER_AGENT;
describe("ms-rest user agent filter", () => {
it("should construct user agent header when supplied empty array", (done) => {
const userAgentArray: Array<string> = [];
const userAgentFilter = new MsRestUserAgentFilter(userAgentArray);
const resource = new WebResource();
resource.headers = {};
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
resource.headers[userAgentHeader].should.containEql("Node");
resource.headers[userAgentHeader].should.containEql("Azure-SDK-For-Node");
done();
}).catch((err) => { done(err); });
});
it("should not modify user agent header if already present", (done) => {
const genericRuntime = "ms-rest";
const azureRuntime = "ms-rest-azure";
const azureSDK = "Azure-SDK-For-Node";
const userAgentArray = [`${genericRuntime}/v1.0.0`, `${azureRuntime}/v1.0.0`];
const userAgentFilter = new MsRestUserAgentFilter(userAgentArray);
const customUA = "my custom user agent";
const resource = new WebResource();
resource.headers = {};
resource.headers[userAgentHeader] = customUA;
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
const actualUA = resource.headers[userAgentHeader];
actualUA.should.not.containEql("Node");
actualUA.should.not.containEql(azureSDK);
actualUA.should.not.containEql(azureRuntime);
actualUA.should.containEql(customUA);
done();
}).catch((err) => { done(err); });
});
it("should insert azure-sdk-for-node at right position", (done) => {
const genericRuntime = "ms-rest";
const azureRuntime = "ms-rest-azure";
const azureSDK = "Azure-SDK-For-Node";
const userAgentArray = [`${genericRuntime}/v1.0.0`, `${azureRuntime}/v1.0.0`];
const userAgentFilter = new MsRestUserAgentFilter(userAgentArray);
const resource = new WebResource();
resource.headers = {};
userAgentFilter.before(resource).then((resource) => {
should.ok(resource);
const deconstructedUserAgent = resource.headers[userAgentHeader].split(" ");
should.ok(deconstructedUserAgent);
const indexOfAzureRuntime = deconstructedUserAgent.findIndex((e: string) => e.startsWith(azureRuntime));
assert.notEqual(indexOfAzureRuntime, -1, `did not find ${azureRuntime} in user agent`);
const indexOfAzureSDK = deconstructedUserAgent.indexOf(azureSDK);
assert.notEqual(indexOfAzureSDK, -1, `did not find ${azureSDK} in user agent`);
assert.equal(indexOfAzureSDK, 1 + indexOfAzureRuntime, `${azureSDK} is not in the right place in user agent string`);
done();
}).catch((err) => { done(err); });
});
});

40
tsconfig.json Normal file
Просмотреть файл

@ -0,0 +1,40 @@
{
"compilerOptions": {
"alwaysStrict": true,
"module": "commonjs",
"noImplicitAny": true,
"preserveConstEnums": true,
"sourceMap": true,
"newLine": "LF",
"target": "es6",
"moduleResolution": "node",
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "dist",
"allowJs": false,
"strict": true,
"strictNullChecks": true,
"declaration": true,
"declarationDir": "./typings",
"lib": [
"dom",
"dom.iterable",
"es5",
"es6",
"es7",
"esnext",
"esnext.asynciterable",
"es2015.iterable"
]
},
"compileOnSave": true,
"exclude": [
"node_modules"
],
"include": [
"./lib/**/*.ts",
"./test/**/*.ts"
]
}

55
tslint.json Normal file
Просмотреть файл

@ -0,0 +1,55 @@
{
"rules": {
"class-name": true,
"comment-format": [true,
"check-space"
],
"indent": [true,
"spaces"
],
"linebreak-style": [true, "LF"],
"one-line": [true,
"check-open-brace",
"check-whitespace"
],
"no-var-keyword": true,
"quotemark": [true,
"double",
"avoid-escape"
],
"semicolon": [true, "always", "ignore-bound-class-methods"],
"whitespace": [true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-inferrable-types": [true],
"no-null-keyword": true,
"prefer-const": true,
"no-switch-case-fall-through": true,
"triple-equals": true,
"jsdoc-format": true
}
}

23
typings/lib/credentials/basicAuthenticationCredentials.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
import { WebResource } from "../webResource";
import { ServiceClientCredentials } from "./serviceClientCredentials";
/**
* Creates a new BasicAuthenticationCredentials object.
*
* @constructor
* @param {string} userName User name.
* @param {string} password Password.
* @param {string} [authorizationScheme] The authorization scheme.
*/
export declare class BasicAuthenticationCredentials implements ServiceClientCredentials {
userName: string;
password: string;
authorizationScheme: string;
constructor(userName: string, password: string, authorizationScheme?: string);
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @returns {Promise<WebResource>} - The signed request object.
*/
signRequest(webResource: WebResource): Promise<WebResource>;
}

10
typings/lib/credentials/serviceClientCredentials.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
import { WebResource } from "../webResource";
export interface ServiceClientCredentials {
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} webResource The WebResource/request to be signed.
* @returns {Promise<WebResource>} The signed request object;
*/
signRequest(webResource: WebResource): Promise<WebResource>;
}

21
typings/lib/credentials/tokenCredentials.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
import { WebResource } from "../webResource";
import { ServiceClientCredentials } from "./serviceClientCredentials";
/**
* Creates a new TokenCredentials object.
*
* @constructor
* @param {string} token The token.
* @param {string} authorizationScheme The authorization scheme.
*/
export declare class TokenCredentials implements ServiceClientCredentials {
token: string;
authorizationScheme: string;
constructor(token: string, authorizationScheme?: string);
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} The WebResource to be signed.
* @return {Promise<WebResource>} The signed request object.
*/
signRequest(webResource: WebResource): Promise<WebResource>;
}

7
typings/lib/filters/baseFilter.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
import { WebResource } from "../webResource";
import { HttpOperationResponse } from "../httpOperationResponse";
export declare class BaseFilter {
constructor();
before(request: WebResource): Promise<WebResource>;
after(response: HttpOperationResponse): Promise<HttpOperationResponse>;
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше