diff --git a/.github/workflows/check-dist.yml b/.github/workflows/check-dist.yml
index ec05c3e..f476ceb 100644
--- a/.github/workflows/check-dist.yml
+++ b/.github/workflows/check-dist.yml
@@ -23,10 +23,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name: Set Node.js 16.x
+ - name: Set Node.js 20
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 20.x
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 64ef4f2..a2537fa 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -33,7 +33,5 @@ jobs:
- name: Live Test
uses: ./
with:
- subscriptionId: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- resourceGroup: ${{ vars.AZURE_RESOURCE_GROUP }}
- templateFile: test/scenarios/static-error/main.bicep
- parametersFile: test/scenarios/static-error/main.bicepparam
+ action: validate
+ config: test/live/config.json
\ No newline at end of file
diff --git a/action.yml b/action.yml
index 96ed49b..174aaa8 100644
--- a/action.yml
+++ b/action.yml
@@ -1,27 +1,17 @@
name: 'Bicep Action'
-description: 'Testing with Bicep Action'
+description: 'Runs various Bicep deployment scenarios'
author: 'Anthony Martin'
inputs:
repo-token:
description: "A GitHub token for API access. Defaults to {{ github.token }}."
default: "${{ github.token }}"
required: true
- subscriptionId:
+ config:
+ description: "Path to the JSON configuration file"
required: true
- description: 'Subscription Id'
- resourceGroup:
+ action:
+ description: "The action to perform"
required: true
- description: 'Resource Group'
- templateFile:
- required: true
- description: 'Template File'
- parametersFile:
- required: true
- description: 'Parameters File'
- whatIf:
- required: false
- description: 'Run what-if'
- default: false
runs:
- using: 'node16'
+ using: 'node20'
main: 'dist/index.js'
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
index 5e641e4..21301d5 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,156 +1,114 @@
require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
-/***/ 446:
-/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
-
-"use strict";
-
-var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- 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) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.whatif = exports.validate = exports.AzCli = void 0;
-const io_1 = __nccwpck_require__(436);
-const exec_1 = __nccwpck_require__(514);
-class AzCli {
- execute(parameters) {
- return __awaiter(this, void 0, void 0, function* () {
- const azPath = yield (0, io_1.which)("az");
- return yield (0, exec_1.getExecOutput)(azPath, parameters, {
- silent: true,
- failOnStdErr: false,
- ignoreReturnCode: true
- });
- });
- }
-}
-exports.AzCli = AzCli;
-function validate(wrapper, params) {
- return __awaiter(this, void 0, void 0, function* () {
- const parameters = [
- "deployment",
- "group",
- "validate",
- ...(params.managementGroup
- ? ["--management-group", params.managementGroup]
- : []),
- ...(params.subscriptionId ? ["--subscription", params.subscriptionId] : []),
- ...(params.resourceGroup ? ["--resource-group", params.resourceGroup] : []),
- ...(params.deploymentName ? ["--name", params.deploymentName] : []),
- ...["--template-file", params.templateFile],
- ...(params.parametersFile ? ["--parameters", params.parametersFile] : []),
- ...["--output", "json"],
- ...["--only-show-errors"]
- ];
- return yield wrapper.execute(parameters);
- });
-}
-exports.validate = validate;
-function whatif(wrapper, params) {
- return __awaiter(this, void 0, void 0, function* () {
- const parameters = [
- "deployment",
- "group",
- "what-if",
- ...(params.managementGroup
- ? ["--management-group", params.managementGroup]
- : []),
- ...(params.subscriptionId ? ["--subscription", params.subscriptionId] : []),
- ...(params.resourceGroup ? ["--resource-group", params.resourceGroup] : []),
- ...(params.deploymentName ? ["--name", params.deploymentName] : []),
- ...["--template-file", params.templateFile],
- ...(params.parametersFile ? ["--parameters", params.parametersFile] : []),
- ...["--output", "json"],
- ...["--only-show-errors"],
- ...["--no-pretty-print"]
- ];
- return yield wrapper.execute(parameters);
- });
-}
-exports.whatif = whatif;
-
-
-/***/ }),
-
-/***/ 180:
-/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+/***/ 4690:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
-var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- 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) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getInputs = void 0;
-const core_1 = __nccwpck_require__(186);
-function getInputs() {
- return __awaiter(this, void 0, void 0, function* () {
- const subscriptionId = (0, core_1.getInput)("subscriptionId", { required: true });
- const resourceGroup = (0, core_1.getInput)("resourceGroup", { required: true });
- const templateFile = (0, core_1.getInput)("templateFile", { required: true });
- const parametersFile = (0, core_1.getInput)("parametersFile", { required: true });
- const runWhatIf = (0, core_1.getBooleanInput)('whatIf', { required: false });
- return {
- subscriptionId,
- resourceGroup,
- templateFile,
- parametersFile,
- runWhatIf,
- };
- });
+const core_1 = __nccwpck_require__(2186);
+async function getInputs() {
+ const action = (0, core_1.getInput)("action", { required: true });
+ const config = (0, core_1.getInput)("config", { required: true });
+ return {
+ action,
+ config
+ };
}
exports.getInputs = getInputs;
-
+//# sourceMappingURL=inputs.js.map
/***/ }),
-/***/ 109:
+/***/ 9496:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
-var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- 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) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-const core_1 = __nccwpck_require__(186);
-const azcli_1 = __nccwpck_require__(446);
-const run_1 = __nccwpck_require__(884);
-const inputs_1 = __nccwpck_require__(180);
-function run() {
- return __awaiter(this, void 0, void 0, function* () {
- const inputs = yield (0, inputs_1.getInputs)();
- const markdown = inputs.runWhatIf ?
- yield (0, run_1.whatIfAndGetMarkdown)(new azcli_1.AzCli(), inputs) :
- yield (0, run_1.validateAndGetMarkdown)(new azcli_1.AzCli(), inputs);
+const core_1 = __nccwpck_require__(2186);
+const exec_1 = __nccwpck_require__(1514);
+const inputs_1 = __nccwpck_require__(4690);
+const promises_1 = __nccwpck_require__(3292);
+const bicep_node_1 = __nccwpck_require__(837);
+const os_1 = __importDefault(__nccwpck_require__(2037));
+const core_rest_pipeline_1 = __nccwpck_require__(8121);
+const arm_resources_1 = __nccwpck_require__(4280);
+const identity_1 = __nccwpck_require__(3084);
+const markdown_1 = __nccwpck_require__(8794);
+const path_1 = __importDefault(__nccwpck_require__(1017));
+async function run() {
+ const inputs = await (0, inputs_1.getInputs)();
+ const configPath = path_1.default.normalize(inputs.config);
+ const config = JSON.parse(await (0, promises_1.readFile)(configPath, "utf8"));
+ const bicepParamsPath = path_1.default.join(path_1.default.dirname(configPath), config.bicepParamsFile);
+ if (inputs.action !== "validate") {
+ throw `Unsupported action: ${inputs.action}`;
+ }
+ const bicepPath = await bicep_node_1.Bicep.install(os_1.default.tmpdir(), config.bicepVersion);
+ //export BICEP_PARAMETERS_OVERRIDES='{"env": "dev"}'
+ const result = await (0, exec_1.getExecOutput)(bicepPath, [
+ "build-params",
+ "--stdout",
+ bicepParamsPath
+ ]);
+ if (result.exitCode !== 0) {
+ throw result.stderr;
+ }
+ const buildParamsOutput = JSON.parse(result.stdout);
+ if (!buildParamsOutput.templateJson) {
+ throw "Template JSON not found in build-params output";
+ }
+ const client = new arm_resources_1.ResourceManagementClient(new identity_1.AzureCliCredential(), config.subscriptionId);
+ const template = JSON.parse(buildParamsOutput.templateJson);
+ const { parameters } = JSON.parse(buildParamsOutput.parametersJson);
+ const scope = `/subscriptions/${config.subscriptionId}/resourceGroups/${config.resourceGroup}`;
+ let error;
+ try {
+ const poller = await client.deployments.beginValidateAtScope(scope, config.name, {
+ properties: {
+ template,
+ parameters,
+ mode: "Incremental"
+ }
+ });
+ const validateResult = await poller.pollUntilDone();
+ error = validateResult.error;
+ }
+ catch (e) {
+ error = parseError(e);
+ }
+ if (error === null || error === void 0 ? void 0 : error.details) {
+ const markdown = (0, markdown_1.combine)([
+ (0, markdown_1.getResultHeading)("Validate Results", false),
+ (0, markdown_1.convertTableToString)((0, markdown_1.getErrorTable)(error.details))
+ ]);
core_1.summary.addRaw(markdown).write();
- });
+ }
+ else {
+ const markdown = (0, markdown_1.getResultHeading)("Validate Results", true);
+ core_1.summary.addRaw(markdown).write();
+ }
+}
+function parseError(error) {
+ if (error instanceof core_rest_pipeline_1.RestError) {
+ return error.details.error;
+ }
+ return {
+ message: `${error}`,
+ };
}
run();
-
+//# sourceMappingURL=main.js.map
/***/ }),
-/***/ 821:
+/***/ 8794:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
@@ -210,83 +168,11 @@ function convertTableToString(rows) {
return mdRows.join("\n");
}
exports.convertTableToString = convertTableToString;
-
-
-/***/ }),
-
-/***/ 884:
-/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
-
-"use strict";
-
-var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- 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) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.whatIfAndGetMarkdown = exports.validateAndGetMarkdown = void 0;
-const azcli_1 = __nccwpck_require__(446);
-const markdown_1 = __nccwpck_require__(821);
-function validateAndGetMarkdown(azCli, parameters) {
- return __awaiter(this, void 0, void 0, function* () {
- const heading = "Validate Results";
- const result = yield (0, azcli_1.validate)(azCli, parameters);
- if (result.exitCode !== 0) {
- const errors = parseErrors(result.stderr);
- return (0, markdown_1.combine)([(0, markdown_1.getResultHeading)(heading, false), (0, markdown_1.convertTableToString)((0, markdown_1.getErrorTable)(errors))]);
- }
- else {
- return (0, markdown_1.combine)([(0, markdown_1.getResultHeading)(heading, true)]);
- }
- });
-}
-exports.validateAndGetMarkdown = validateAndGetMarkdown;
-function whatIfAndGetMarkdown(azCli, parameters) {
- var _a;
- return __awaiter(this, void 0, void 0, function* () {
- const heading = "What-If Results";
- const result = yield (0, azcli_1.whatif)(azCli, parameters);
- let resultHeading, body;
- if (result.exitCode !== 0) {
- resultHeading = (0, markdown_1.getResultHeading)(heading, false);
- const errors = parseErrors(result.stderr);
- body = (0, markdown_1.getErrorTable)(errors);
- }
- else {
- resultHeading = (0, markdown_1.getResultHeading)(heading, true);
- const response = JSON.parse(result.stdout);
- body = (0, markdown_1.getWhatIfTable)((_a = response.changes) !== null && _a !== void 0 ? _a : []);
- }
- return (0, markdown_1.combine)([resultHeading, (0, markdown_1.convertTableToString)(body)]);
- });
-}
-exports.whatIfAndGetMarkdown = whatIfAndGetMarkdown;
-function parseErrors(stderr) {
- if (stderr.startsWith("ERROR: ")) {
- stderr = stderr.substring("ERROR: ".length);
- }
- const errors = [];
- const split = stderr.split(/\r?\n/);
- for (const line of split) {
- if (line.startsWith("{")) {
- errors.push(JSON.parse(line));
- }
- else if (/^(.+)\((\d+),(\d+)\)\s:\s(Error|Warning|Info)\s(.+):\s(.+)$/.test(line)) {
- errors.push({ code: "BicepBuildError", message: line });
- }
- }
- return errors;
-}
-
+//# sourceMappingURL=markdown.js.map
/***/ }),
-/***/ 351:
+/***/ 7351:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -312,8 +198,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.issue = exports.issueCommand = void 0;
-const os = __importStar(__nccwpck_require__(37));
-const utils_1 = __nccwpck_require__(278);
+const os = __importStar(__nccwpck_require__(2037));
+const utils_1 = __nccwpck_require__(5278);
/**
* Commands
*
@@ -385,7 +271,7 @@ function escapeProperty(s) {
/***/ }),
-/***/ 186:
+/***/ 2186:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -420,12 +306,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;
-const command_1 = __nccwpck_require__(351);
+const command_1 = __nccwpck_require__(7351);
const file_command_1 = __nccwpck_require__(717);
-const utils_1 = __nccwpck_require__(278);
-const os = __importStar(__nccwpck_require__(37));
-const path = __importStar(__nccwpck_require__(17));
-const oidc_utils_1 = __nccwpck_require__(41);
+const utils_1 = __nccwpck_require__(5278);
+const os = __importStar(__nccwpck_require__(2037));
+const path = __importStar(__nccwpck_require__(1017));
+const oidc_utils_1 = __nccwpck_require__(8041);
/**
* The code to exit an action
*/
@@ -710,17 +596,17 @@ exports.getIDToken = getIDToken;
/**
* Summary exports
*/
-var summary_1 = __nccwpck_require__(327);
+var summary_1 = __nccwpck_require__(1327);
Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } }));
/**
* @deprecated use core.summary
*/
-var summary_2 = __nccwpck_require__(327);
+var summary_2 = __nccwpck_require__(1327);
Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } }));
/**
* Path exports
*/
-var path_utils_1 = __nccwpck_require__(981);
+var path_utils_1 = __nccwpck_require__(2981);
Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } }));
Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } }));
Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }));
@@ -757,10 +643,10 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
-const fs = __importStar(__nccwpck_require__(147));
-const os = __importStar(__nccwpck_require__(37));
-const uuid_1 = __nccwpck_require__(840);
-const utils_1 = __nccwpck_require__(278);
+const fs = __importStar(__nccwpck_require__(7147));
+const os = __importStar(__nccwpck_require__(2037));
+const uuid_1 = __nccwpck_require__(5840);
+const utils_1 = __nccwpck_require__(5278);
function issueFileCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`];
if (!filePath) {
@@ -793,7 +679,7 @@ exports.prepareKeyValueMessage = prepareKeyValueMessage;
/***/ }),
-/***/ 41:
+/***/ 8041:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -809,9 +695,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OidcClient = void 0;
-const http_client_1 = __nccwpck_require__(255);
-const auth_1 = __nccwpck_require__(526);
-const core_1 = __nccwpck_require__(186);
+const http_client_1 = __nccwpck_require__(6255);
+const auth_1 = __nccwpck_require__(5526);
+const core_1 = __nccwpck_require__(2186);
class OidcClient {
static createHttpClient(allowRetry = true, maxRetry = 10) {
const requestOptions = {
@@ -877,7 +763,7 @@ exports.OidcClient = OidcClient;
/***/ }),
-/***/ 981:
+/***/ 2981:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -903,7 +789,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;
-const path = __importStar(__nccwpck_require__(17));
+const path = __importStar(__nccwpck_require__(1017));
/**
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
* replaced with /.
@@ -942,7 +828,7 @@ exports.toPlatformPath = toPlatformPath;
/***/ }),
-/***/ 327:
+/***/ 1327:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -958,8 +844,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0;
-const os_1 = __nccwpck_require__(37);
-const fs_1 = __nccwpck_require__(147);
+const os_1 = __nccwpck_require__(2037);
+const fs_1 = __nccwpck_require__(7147);
const { access, appendFile, writeFile } = fs_1.promises;
exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';
exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';
@@ -1232,7 +1118,7 @@ exports.summary = _summary;
/***/ }),
-/***/ 278:
+/***/ 5278:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
@@ -1279,7 +1165,7 @@ exports.toCommandProperties = toCommandProperties;
/***/ }),
-/***/ 514:
+/***/ 1514:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -1314,8 +1200,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getExecOutput = exports.exec = void 0;
-const string_decoder_1 = __nccwpck_require__(576);
-const tr = __importStar(__nccwpck_require__(159));
+const string_decoder_1 = __nccwpck_require__(1576);
+const tr = __importStar(__nccwpck_require__(8159));
/**
* Exec a command.
* Output will be streamed to the live console.
@@ -1389,7 +1275,7 @@ exports.getExecOutput = getExecOutput;
/***/ }),
-/***/ 159:
+/***/ 8159:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -1424,13 +1310,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.argStringToArray = exports.ToolRunner = void 0;
-const os = __importStar(__nccwpck_require__(37));
-const events = __importStar(__nccwpck_require__(361));
-const child = __importStar(__nccwpck_require__(81));
-const path = __importStar(__nccwpck_require__(17));
-const io = __importStar(__nccwpck_require__(436));
-const ioUtil = __importStar(__nccwpck_require__(962));
-const timers_1 = __nccwpck_require__(512);
+const os = __importStar(__nccwpck_require__(2037));
+const events = __importStar(__nccwpck_require__(2361));
+const child = __importStar(__nccwpck_require__(2081));
+const path = __importStar(__nccwpck_require__(1017));
+const io = __importStar(__nccwpck_require__(7436));
+const ioUtil = __importStar(__nccwpck_require__(1962));
+const timers_1 = __nccwpck_require__(9512);
/* eslint-disable @typescript-eslint/unbound-method */
const IS_WINDOWS = process.platform === 'win32';
/*
@@ -2014,7 +1900,7 @@ class ExecState extends events.EventEmitter {
/***/ }),
-/***/ 526:
+/***/ 5526:
/***/ (function(__unused_webpack_module, exports) {
"use strict";
@@ -2102,7 +1988,7 @@ exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHand
/***/ }),
-/***/ 255:
+/***/ 6255:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -2138,10 +2024,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;
-const http = __importStar(__nccwpck_require__(685));
-const https = __importStar(__nccwpck_require__(687));
-const pm = __importStar(__nccwpck_require__(835));
-const tunnel = __importStar(__nccwpck_require__(294));
+const http = __importStar(__nccwpck_require__(3685));
+const https = __importStar(__nccwpck_require__(5687));
+const pm = __importStar(__nccwpck_require__(9835));
+const tunnel = __importStar(__nccwpck_require__(4294));
var HttpCodes;
(function (HttpCodes) {
HttpCodes[HttpCodes["OK"] = 200] = "OK";
@@ -2727,7 +2613,7 @@ const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCa
/***/ }),
-/***/ 835:
+/***/ 9835:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
@@ -2816,7 +2702,7 @@ function isLoopbackAddress(host) {
/***/ }),
-/***/ 962:
+/***/ 1962:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -2852,8 +2738,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
-const fs = __importStar(__nccwpck_require__(147));
-const path = __importStar(__nccwpck_require__(17));
+const fs = __importStar(__nccwpck_require__(7147));
+const path = __importStar(__nccwpck_require__(1017));
_a = fs.promises
// export const {open} = 'fs'
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
@@ -3006,7 +2892,7 @@ exports.getCmdPath = getCmdPath;
/***/ }),
-/***/ 436:
+/***/ 7436:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -3041,9 +2927,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
-const assert_1 = __nccwpck_require__(491);
-const path = __importStar(__nccwpck_require__(17));
-const ioUtil = __importStar(__nccwpck_require__(962));
+const assert_1 = __nccwpck_require__(9491);
+const path = __importStar(__nccwpck_require__(1017));
+const ioUtil = __importStar(__nccwpck_require__(1962));
/**
* Copies a file or folder.
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
@@ -3312,75 +3198,61031 @@ function copyFile(srcFile, destFile, force) {
/***/ }),
-/***/ 294:
-/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+/***/ 2557:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+///
+const listenersMap = new WeakMap();
+const abortedMap = new WeakMap();
+/**
+ * An aborter instance implements AbortSignal interface, can abort HTTP requests.
+ *
+ * - Call AbortSignal.none to create a new AbortSignal instance that cannot be cancelled.
+ * Use `AbortSignal.none` when you are required to pass a cancellation token but the operation
+ * cannot or will not ever be cancelled.
+ *
+ * @example
+ * Abort without timeout
+ * ```ts
+ * await doAsyncWork(AbortSignal.none);
+ * ```
+ */
+class AbortSignal {
+ constructor() {
+ /**
+ * onabort event listener.
+ */
+ this.onabort = null;
+ listenersMap.set(this, []);
+ abortedMap.set(this, false);
+ }
+ /**
+ * Status of whether aborted or not.
+ *
+ * @readonly
+ */
+ get aborted() {
+ if (!abortedMap.has(this)) {
+ throw new TypeError("Expected `this` to be an instance of AbortSignal.");
+ }
+ return abortedMap.get(this);
+ }
+ /**
+ * Creates a new AbortSignal instance that will never be aborted.
+ *
+ * @readonly
+ */
+ static get none() {
+ return new AbortSignal();
+ }
+ /**
+ * Added new "abort" event listener, only support "abort" event.
+ *
+ * @param _type - Only support "abort" event
+ * @param listener - The listener to be added
+ */
+ addEventListener(
+ // tslint:disable-next-line:variable-name
+ _type, listener) {
+ if (!listenersMap.has(this)) {
+ throw new TypeError("Expected `this` to be an instance of AbortSignal.");
+ }
+ const listeners = listenersMap.get(this);
+ listeners.push(listener);
+ }
+ /**
+ * Remove "abort" event listener, only support "abort" event.
+ *
+ * @param _type - Only support "abort" event
+ * @param listener - The listener to be removed
+ */
+ removeEventListener(
+ // tslint:disable-next-line:variable-name
+ _type, listener) {
+ if (!listenersMap.has(this)) {
+ throw new TypeError("Expected `this` to be an instance of AbortSignal.");
+ }
+ const listeners = listenersMap.get(this);
+ const index = listeners.indexOf(listener);
+ if (index > -1) {
+ listeners.splice(index, 1);
+ }
+ }
+ /**
+ * Dispatches a synthetic event to the AbortSignal.
+ */
+ dispatchEvent(_event) {
+ throw new Error("This is a stub dispatchEvent implementation that should not be used. It only exists for type-checking purposes.");
+ }
+}
+/**
+ * Helper to trigger an abort event immediately, the onabort and all abort event listeners will be triggered.
+ * Will try to trigger abort event for all linked AbortSignal nodes.
+ *
+ * - If there is a timeout, the timer will be cancelled.
+ * - If aborted is true, nothing will happen.
+ *
+ * @internal
+ */
+// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters
+function abortSignal(signal) {
+ if (signal.aborted) {
+ return;
+ }
+ if (signal.onabort) {
+ signal.onabort.call(signal);
+ }
+ const listeners = listenersMap.get(signal);
+ if (listeners) {
+ // Create a copy of listeners so mutations to the array
+ // (e.g. via removeListener calls) don't affect the listeners
+ // we invoke.
+ listeners.slice().forEach((listener) => {
+ listener.call(signal, { type: "abort" });
+ });
+ }
+ abortedMap.set(signal, true);
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * This error is thrown when an asynchronous operation has been aborted.
+ * Check for this error by testing the `name` that the name property of the
+ * error matches `"AbortError"`.
+ *
+ * @example
+ * ```ts
+ * const controller = new AbortController();
+ * controller.abort();
+ * try {
+ * doAsyncWork(controller.signal)
+ * } catch (e) {
+ * if (e.name === 'AbortError') {
+ * // handle abort error here.
+ * }
+ * }
+ * ```
+ */
+class AbortError extends Error {
+ constructor(message) {
+ super(message);
+ this.name = "AbortError";
+ }
+}
+/**
+ * An AbortController provides an AbortSignal and the associated controls to signal
+ * that an asynchronous operation should be aborted.
+ *
+ * @example
+ * Abort an operation when another event fires
+ * ```ts
+ * const controller = new AbortController();
+ * const signal = controller.signal;
+ * doAsyncWork(signal);
+ * button.addEventListener('click', () => controller.abort());
+ * ```
+ *
+ * @example
+ * Share aborter cross multiple operations in 30s
+ * ```ts
+ * // Upload the same data to 2 different data centers at the same time,
+ * // abort another when any of them is finished
+ * const controller = AbortController.withTimeout(30 * 1000);
+ * doAsyncWork(controller.signal).then(controller.abort);
+ * doAsyncWork(controller.signal).then(controller.abort);
+ *```
+ *
+ * @example
+ * Cascaded aborting
+ * ```ts
+ * // All operations can't take more than 30 seconds
+ * const aborter = Aborter.timeout(30 * 1000);
+ *
+ * // Following 2 operations can't take more than 25 seconds
+ * await doAsyncWork(aborter.withTimeout(25 * 1000));
+ * await doAsyncWork(aborter.withTimeout(25 * 1000));
+ * ```
+ */
+class AbortController {
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ constructor(parentSignals) {
+ this._signal = new AbortSignal();
+ if (!parentSignals) {
+ return;
+ }
+ // coerce parentSignals into an array
+ if (!Array.isArray(parentSignals)) {
+ // eslint-disable-next-line prefer-rest-params
+ parentSignals = arguments;
+ }
+ for (const parentSignal of parentSignals) {
+ // if the parent signal has already had abort() called,
+ // then call abort on this signal as well.
+ if (parentSignal.aborted) {
+ this.abort();
+ }
+ else {
+ // when the parent signal aborts, this signal should as well.
+ parentSignal.addEventListener("abort", () => {
+ this.abort();
+ });
+ }
+ }
+ }
+ /**
+ * The AbortSignal associated with this controller that will signal aborted
+ * when the abort method is called on this controller.
+ *
+ * @readonly
+ */
+ get signal() {
+ return this._signal;
+ }
+ /**
+ * Signal that any operations passed this controller's associated abort signal
+ * to cancel any remaining work and throw an `AbortError`.
+ */
+ abort() {
+ abortSignal(this._signal);
+ }
+ /**
+ * Creates a new AbortSignal instance that will abort after the provided ms.
+ * @param ms - Elapsed time in milliseconds to trigger an abort.
+ */
+ static timeout(ms) {
+ const signal = new AbortSignal();
+ const timer = setTimeout(abortSignal, ms, signal);
+ // Prevent the active Timer from keeping the Node.js event loop active.
+ if (typeof timer.unref === "function") {
+ timer.unref();
+ }
+ return signal;
+ }
+}
-module.exports = __nccwpck_require__(219);
+exports.AbortController = AbortController;
+exports.AbortError = AbortError;
+exports.AbortSignal = AbortSignal;
+//# sourceMappingURL=index.js.map
/***/ }),
-/***/ 219:
+/***/ 4280:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
-var net = __nccwpck_require__(808);
-var tls = __nccwpck_require__(404);
-var http = __nccwpck_require__(685);
-var https = __nccwpck_require__(687);
-var events = __nccwpck_require__(361);
-var assert = __nccwpck_require__(491);
-var util = __nccwpck_require__(837);
-
-
-exports.httpOverHttp = httpOverHttp;
-exports.httpsOverHttp = httpsOverHttp;
-exports.httpOverHttps = httpOverHttps;
-exports.httpsOverHttps = httpsOverHttps;
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+var tslib = __nccwpck_require__(4351);
+var coreClient = __nccwpck_require__(9729);
+var coreRestPipeline = __nccwpck_require__(8121);
+var coreLro = __nccwpck_require__(7094);
-function httpOverHttp(options) {
- var agent = new TunnelingAgent(options);
- agent.request = http.request;
- return agent;
+function _interopNamespace(e) {
+ if (e && e.__esModule) return e;
+ var n = Object.create(null);
+ if (e) {
+ Object.keys(e).forEach(function (k) {
+ if (k !== 'default') {
+ var d = Object.getOwnPropertyDescriptor(e, k);
+ Object.defineProperty(n, k, d.get ? d : {
+ enumerable: true,
+ get: function () { return e[k]; }
+ });
+ }
+ });
+ }
+ n["default"] = e;
+ return Object.freeze(n);
}
-function httpsOverHttp(options) {
- var agent = new TunnelingAgent(options);
- agent.request = http.request;
- agent.createSocket = createSecureSocket;
- agent.defaultPort = 443;
- return agent;
-}
+var coreClient__namespace = /*#__PURE__*/_interopNamespace(coreClient);
+var coreRestPipeline__namespace = /*#__PURE__*/_interopNamespace(coreRestPipeline);
-function httpOverHttps(options) {
- var agent = new TunnelingAgent(options);
- agent.request = https.request;
- return agent;
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+const pageMap = new WeakMap();
+/**
+ * Given the last `.value` produced by the `byPage` iterator,
+ * returns a continuation token that can be used to begin paging from
+ * that point later.
+ * @param page An object from accessing `value` on the IteratorResult from a `byPage` iterator.
+ * @returns The continuation token that can be passed into byPage() during future calls.
+ */
+function getContinuationToken(page) {
+ var _a;
+ if (typeof page !== "object" || page === null) {
+ return undefined;
+ }
+ return (_a = pageMap.get(page)) === null || _a === void 0 ? void 0 : _a.continuationToken;
}
-
-function httpsOverHttps(options) {
- var agent = new TunnelingAgent(options);
- agent.request = https.request;
- agent.createSocket = createSecureSocket;
- agent.defaultPort = 443;
- return agent;
+function setContinuationToken(page, continuationToken) {
+ var _a;
+ if (typeof page !== "object" || page === null || !continuationToken) {
+ return;
+ }
+ const pageInfo = (_a = pageMap.get(page)) !== null && _a !== void 0 ? _a : {};
+ pageInfo.continuationToken = continuationToken;
+ pageMap.set(page, pageInfo);
}
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+/** Known values of {@link ExpressionEvaluationOptionsScopeType} that the service accepts. */
+exports.KnownExpressionEvaluationOptionsScopeType = void 0;
+(function (KnownExpressionEvaluationOptionsScopeType) {
+ /** NotSpecified */
+ KnownExpressionEvaluationOptionsScopeType["NotSpecified"] = "NotSpecified";
+ /** Outer */
+ KnownExpressionEvaluationOptionsScopeType["Outer"] = "Outer";
+ /** Inner */
+ KnownExpressionEvaluationOptionsScopeType["Inner"] = "Inner";
+})(exports.KnownExpressionEvaluationOptionsScopeType || (exports.KnownExpressionEvaluationOptionsScopeType = {}));
+/** Known values of {@link ProvisioningState} that the service accepts. */
+exports.KnownProvisioningState = void 0;
+(function (KnownProvisioningState) {
+ /** NotSpecified */
+ KnownProvisioningState["NotSpecified"] = "NotSpecified";
+ /** Accepted */
+ KnownProvisioningState["Accepted"] = "Accepted";
+ /** Running */
+ KnownProvisioningState["Running"] = "Running";
+ /** Ready */
+ KnownProvisioningState["Ready"] = "Ready";
+ /** Creating */
+ KnownProvisioningState["Creating"] = "Creating";
+ /** Created */
+ KnownProvisioningState["Created"] = "Created";
+ /** Deleting */
+ KnownProvisioningState["Deleting"] = "Deleting";
+ /** Deleted */
+ KnownProvisioningState["Deleted"] = "Deleted";
+ /** Canceled */
+ KnownProvisioningState["Canceled"] = "Canceled";
+ /** Failed */
+ KnownProvisioningState["Failed"] = "Failed";
+ /** Succeeded */
+ KnownProvisioningState["Succeeded"] = "Succeeded";
+ /** Updating */
+ KnownProvisioningState["Updating"] = "Updating";
+})(exports.KnownProvisioningState || (exports.KnownProvisioningState = {}));
+/** Known values of {@link AliasPathTokenType} that the service accepts. */
+exports.KnownAliasPathTokenType = void 0;
+(function (KnownAliasPathTokenType) {
+ /** The token type is not specified. */
+ KnownAliasPathTokenType["NotSpecified"] = "NotSpecified";
+ /** The token type can be anything. */
+ KnownAliasPathTokenType["Any"] = "Any";
+ /** The token type is string. */
+ KnownAliasPathTokenType["String"] = "String";
+ /** The token type is object. */
+ KnownAliasPathTokenType["Object"] = "Object";
+ /** The token type is array. */
+ KnownAliasPathTokenType["Array"] = "Array";
+ /** The token type is integer. */
+ KnownAliasPathTokenType["Integer"] = "Integer";
+ /** The token type is number. */
+ KnownAliasPathTokenType["Number"] = "Number";
+ /** The token type is boolean. */
+ KnownAliasPathTokenType["Boolean"] = "Boolean";
+})(exports.KnownAliasPathTokenType || (exports.KnownAliasPathTokenType = {}));
+/** Known values of {@link AliasPathAttributes} that the service accepts. */
+exports.KnownAliasPathAttributes = void 0;
+(function (KnownAliasPathAttributes) {
+ /** The token that the alias path is referring to has no attributes. */
+ KnownAliasPathAttributes["None"] = "None";
+ /** The token that the alias path is referring to is modifiable by policies with 'modify' effect. */
+ KnownAliasPathAttributes["Modifiable"] = "Modifiable";
+})(exports.KnownAliasPathAttributes || (exports.KnownAliasPathAttributes = {}));
+/** Known values of {@link ProviderAuthorizationConsentState} that the service accepts. */
+exports.KnownProviderAuthorizationConsentState = void 0;
+(function (KnownProviderAuthorizationConsentState) {
+ /** NotSpecified */
+ KnownProviderAuthorizationConsentState["NotSpecified"] = "NotSpecified";
+ /** Required */
+ KnownProviderAuthorizationConsentState["Required"] = "Required";
+ /** NotRequired */
+ KnownProviderAuthorizationConsentState["NotRequired"] = "NotRequired";
+ /** Consented */
+ KnownProviderAuthorizationConsentState["Consented"] = "Consented";
+})(exports.KnownProviderAuthorizationConsentState || (exports.KnownProviderAuthorizationConsentState = {}));
+/** Known values of {@link ExtendedLocationType} that the service accepts. */
+exports.KnownExtendedLocationType = void 0;
+(function (KnownExtendedLocationType) {
+ /** EdgeZone */
+ KnownExtendedLocationType["EdgeZone"] = "EdgeZone";
+})(exports.KnownExtendedLocationType || (exports.KnownExtendedLocationType = {}));
+/** Known values of {@link TagsPatchOperation} that the service accepts. */
+exports.KnownTagsPatchOperation = void 0;
+(function (KnownTagsPatchOperation) {
+ /** The 'replace' option replaces the entire set of existing tags with a new set. */
+ KnownTagsPatchOperation["Replace"] = "Replace";
+ /** The 'merge' option allows adding tags with new names and updating the values of tags with existing names. */
+ KnownTagsPatchOperation["Merge"] = "Merge";
+ /** The 'delete' option allows selectively deleting tags based on given names or name\/value pairs. */
+ KnownTagsPatchOperation["Delete"] = "Delete";
+})(exports.KnownTagsPatchOperation || (exports.KnownTagsPatchOperation = {}));
-function TunnelingAgent(options) {
- var self = this;
- self.options = options || {};
- self.proxyOptions = self.options.proxy || {};
- self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
- self.requests = [];
- self.sockets = [];
-
- self.on('free', function onFree(socket, host, port, localAddress) {
- var options = toOptions(host, port, localAddress);
- for (var i = 0, len = self.requests.length; i < len; ++i) {
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+const OperationListResult = {
+ type: {
+ name: "Composite",
+ className: "OperationListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Operation"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const Operation = {
+ type: {
+ name: "Composite",
+ className: "Operation",
+ modelProperties: {
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ display: {
+ serializedName: "display",
+ type: {
+ name: "Composite",
+ className: "OperationDisplay"
+ }
+ }
+ }
+ }
+};
+const OperationDisplay = {
+ type: {
+ name: "Composite",
+ className: "OperationDisplay",
+ modelProperties: {
+ provider: {
+ serializedName: "provider",
+ type: {
+ name: "String"
+ }
+ },
+ resource: {
+ serializedName: "resource",
+ type: {
+ name: "String"
+ }
+ },
+ operation: {
+ serializedName: "operation",
+ type: {
+ name: "String"
+ }
+ },
+ description: {
+ serializedName: "description",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const CloudError = {
+ type: {
+ name: "Composite",
+ className: "CloudError",
+ modelProperties: {
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ }
+ }
+ }
+};
+const ErrorResponse = {
+ type: {
+ name: "Composite",
+ className: "ErrorResponse",
+ modelProperties: {
+ code: {
+ serializedName: "code",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ message: {
+ serializedName: "message",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ target: {
+ serializedName: "target",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ details: {
+ serializedName: "details",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ }
+ }
+ },
+ additionalInfo: {
+ serializedName: "additionalInfo",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ErrorAdditionalInfo"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const ErrorAdditionalInfo = {
+ type: {
+ name: "Composite",
+ className: "ErrorAdditionalInfo",
+ modelProperties: {
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ info: {
+ serializedName: "info",
+ readOnly: true,
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ }
+ }
+ }
+};
+const Deployment = {
+ type: {
+ name: "Composite",
+ className: "Deployment",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentProperties"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const DeploymentProperties = {
+ type: {
+ name: "Composite",
+ className: "DeploymentProperties",
+ modelProperties: {
+ template: {
+ serializedName: "template",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ templateLink: {
+ serializedName: "templateLink",
+ type: {
+ name: "Composite",
+ className: "TemplateLink"
+ }
+ },
+ parameters: {
+ serializedName: "parameters",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ parametersLink: {
+ serializedName: "parametersLink",
+ type: {
+ name: "Composite",
+ className: "ParametersLink"
+ }
+ },
+ mode: {
+ serializedName: "mode",
+ required: true,
+ type: {
+ name: "Enum",
+ allowedValues: ["Incremental", "Complete"]
+ }
+ },
+ debugSetting: {
+ serializedName: "debugSetting",
+ type: {
+ name: "Composite",
+ className: "DebugSetting"
+ }
+ },
+ onErrorDeployment: {
+ serializedName: "onErrorDeployment",
+ type: {
+ name: "Composite",
+ className: "OnErrorDeployment"
+ }
+ },
+ expressionEvaluationOptions: {
+ serializedName: "expressionEvaluationOptions",
+ type: {
+ name: "Composite",
+ className: "ExpressionEvaluationOptions"
+ }
+ }
+ }
+ }
+};
+const TemplateLink = {
+ type: {
+ name: "Composite",
+ className: "TemplateLink",
+ modelProperties: {
+ uri: {
+ serializedName: "uri",
+ type: {
+ name: "String"
+ }
+ },
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ },
+ relativePath: {
+ serializedName: "relativePath",
+ type: {
+ name: "String"
+ }
+ },
+ contentVersion: {
+ serializedName: "contentVersion",
+ type: {
+ name: "String"
+ }
+ },
+ queryString: {
+ serializedName: "queryString",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ParametersLink = {
+ type: {
+ name: "Composite",
+ className: "ParametersLink",
+ modelProperties: {
+ uri: {
+ serializedName: "uri",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ contentVersion: {
+ serializedName: "contentVersion",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DebugSetting = {
+ type: {
+ name: "Composite",
+ className: "DebugSetting",
+ modelProperties: {
+ detailLevel: {
+ serializedName: "detailLevel",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const OnErrorDeployment = {
+ type: {
+ name: "Composite",
+ className: "OnErrorDeployment",
+ modelProperties: {
+ type: {
+ serializedName: "type",
+ type: {
+ name: "Enum",
+ allowedValues: ["LastSuccessful", "SpecificDeployment"]
+ }
+ },
+ deploymentName: {
+ serializedName: "deploymentName",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ExpressionEvaluationOptions = {
+ type: {
+ name: "Composite",
+ className: "ExpressionEvaluationOptions",
+ modelProperties: {
+ scope: {
+ serializedName: "scope",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentExtended = {
+ type: {
+ name: "Composite",
+ className: "DeploymentExtended",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentPropertiesExtended"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const DeploymentPropertiesExtended = {
+ type: {
+ name: "Composite",
+ className: "DeploymentPropertiesExtended",
+ modelProperties: {
+ provisioningState: {
+ serializedName: "provisioningState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ correlationId: {
+ serializedName: "correlationId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ timestamp: {
+ serializedName: "timestamp",
+ readOnly: true,
+ type: {
+ name: "DateTime"
+ }
+ },
+ duration: {
+ serializedName: "duration",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ outputs: {
+ serializedName: "outputs",
+ readOnly: true,
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ providers: {
+ serializedName: "providers",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Provider"
+ }
+ }
+ }
+ },
+ dependencies: {
+ serializedName: "dependencies",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Dependency"
+ }
+ }
+ }
+ },
+ templateLink: {
+ serializedName: "templateLink",
+ type: {
+ name: "Composite",
+ className: "TemplateLink"
+ }
+ },
+ parameters: {
+ serializedName: "parameters",
+ readOnly: true,
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ parametersLink: {
+ serializedName: "parametersLink",
+ type: {
+ name: "Composite",
+ className: "ParametersLink"
+ }
+ },
+ mode: {
+ serializedName: "mode",
+ readOnly: true,
+ type: {
+ name: "Enum",
+ allowedValues: ["Incremental", "Complete"]
+ }
+ },
+ debugSetting: {
+ serializedName: "debugSetting",
+ type: {
+ name: "Composite",
+ className: "DebugSetting"
+ }
+ },
+ onErrorDeployment: {
+ serializedName: "onErrorDeployment",
+ type: {
+ name: "Composite",
+ className: "OnErrorDeploymentExtended"
+ }
+ },
+ templateHash: {
+ serializedName: "templateHash",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ outputResources: {
+ serializedName: "outputResources",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ResourceReference"
+ }
+ }
+ }
+ },
+ validatedResources: {
+ serializedName: "validatedResources",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ResourceReference"
+ }
+ }
+ }
+ },
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ }
+ }
+ }
+};
+const Provider = {
+ type: {
+ name: "Composite",
+ className: "Provider",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ namespace: {
+ serializedName: "namespace",
+ type: {
+ name: "String"
+ }
+ },
+ registrationState: {
+ serializedName: "registrationState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ registrationPolicy: {
+ serializedName: "registrationPolicy",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ resourceTypes: {
+ serializedName: "resourceTypes",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ProviderResourceType"
+ }
+ }
+ }
+ },
+ providerAuthorizationConsentState: {
+ serializedName: "providerAuthorizationConsentState",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ProviderResourceType = {
+ type: {
+ name: "Composite",
+ className: "ProviderResourceType",
+ modelProperties: {
+ resourceType: {
+ serializedName: "resourceType",
+ type: {
+ name: "String"
+ }
+ },
+ locations: {
+ serializedName: "locations",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ locationMappings: {
+ serializedName: "locationMappings",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ProviderExtendedLocation"
+ }
+ }
+ }
+ },
+ aliases: {
+ serializedName: "aliases",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Alias"
+ }
+ }
+ }
+ },
+ apiVersions: {
+ serializedName: "apiVersions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ defaultApiVersion: {
+ serializedName: "defaultApiVersion",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ zoneMappings: {
+ serializedName: "zoneMappings",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ZoneMapping"
+ }
+ }
+ }
+ },
+ apiProfiles: {
+ serializedName: "apiProfiles",
+ readOnly: true,
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ApiProfile"
+ }
+ }
+ }
+ },
+ capabilities: {
+ serializedName: "capabilities",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const ProviderExtendedLocation = {
+ type: {
+ name: "Composite",
+ className: "ProviderExtendedLocation",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ type: {
+ name: "String"
+ }
+ },
+ extendedLocations: {
+ serializedName: "extendedLocations",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const Alias = {
+ type: {
+ name: "Composite",
+ className: "Alias",
+ modelProperties: {
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ paths: {
+ serializedName: "paths",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "AliasPath"
+ }
+ }
+ }
+ },
+ type: {
+ serializedName: "type",
+ type: {
+ name: "Enum",
+ allowedValues: ["NotSpecified", "PlainText", "Mask"]
+ }
+ },
+ defaultPath: {
+ serializedName: "defaultPath",
+ type: {
+ name: "String"
+ }
+ },
+ defaultPattern: {
+ serializedName: "defaultPattern",
+ type: {
+ name: "Composite",
+ className: "AliasPattern"
+ }
+ },
+ defaultMetadata: {
+ serializedName: "defaultMetadata",
+ type: {
+ name: "Composite",
+ className: "AliasPathMetadata"
+ }
+ }
+ }
+ }
+};
+const AliasPath = {
+ type: {
+ name: "Composite",
+ className: "AliasPath",
+ modelProperties: {
+ path: {
+ serializedName: "path",
+ type: {
+ name: "String"
+ }
+ },
+ apiVersions: {
+ serializedName: "apiVersions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ pattern: {
+ serializedName: "pattern",
+ type: {
+ name: "Composite",
+ className: "AliasPattern"
+ }
+ },
+ metadata: {
+ serializedName: "metadata",
+ type: {
+ name: "Composite",
+ className: "AliasPathMetadata"
+ }
+ }
+ }
+ }
+};
+const AliasPattern = {
+ type: {
+ name: "Composite",
+ className: "AliasPattern",
+ modelProperties: {
+ phrase: {
+ serializedName: "phrase",
+ type: {
+ name: "String"
+ }
+ },
+ variable: {
+ serializedName: "variable",
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ type: {
+ name: "Enum",
+ allowedValues: ["NotSpecified", "Extract"]
+ }
+ }
+ }
+ }
+};
+const AliasPathMetadata = {
+ type: {
+ name: "Composite",
+ className: "AliasPathMetadata",
+ modelProperties: {
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ attributes: {
+ serializedName: "attributes",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ZoneMapping = {
+ type: {
+ name: "Composite",
+ className: "ZoneMapping",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ zones: {
+ serializedName: "zones",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const ApiProfile = {
+ type: {
+ name: "Composite",
+ className: "ApiProfile",
+ modelProperties: {
+ profileVersion: {
+ serializedName: "profileVersion",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ apiVersion: {
+ serializedName: "apiVersion",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const Dependency = {
+ type: {
+ name: "Composite",
+ className: "Dependency",
+ modelProperties: {
+ dependsOn: {
+ serializedName: "dependsOn",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "BasicDependency"
+ }
+ }
+ }
+ },
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ },
+ resourceType: {
+ serializedName: "resourceType",
+ type: {
+ name: "String"
+ }
+ },
+ resourceName: {
+ serializedName: "resourceName",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const BasicDependency = {
+ type: {
+ name: "Composite",
+ className: "BasicDependency",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ },
+ resourceType: {
+ serializedName: "resourceType",
+ type: {
+ name: "String"
+ }
+ },
+ resourceName: {
+ serializedName: "resourceName",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const OnErrorDeploymentExtended = {
+ type: {
+ name: "Composite",
+ className: "OnErrorDeploymentExtended",
+ modelProperties: {
+ provisioningState: {
+ serializedName: "provisioningState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ type: {
+ name: "Enum",
+ allowedValues: ["LastSuccessful", "SpecificDeployment"]
+ }
+ },
+ deploymentName: {
+ serializedName: "deploymentName",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceReference = {
+ type: {
+ name: "Composite",
+ className: "ResourceReference",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentValidateResult = {
+ type: {
+ name: "Composite",
+ className: "DeploymentValidateResult",
+ modelProperties: {
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentPropertiesExtended"
+ }
+ }
+ }
+ }
+};
+const DeploymentExportResult = {
+ type: {
+ name: "Composite",
+ className: "DeploymentExportResult",
+ modelProperties: {
+ template: {
+ serializedName: "template",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ }
+ }
+ }
+};
+const DeploymentListResult = {
+ type: {
+ name: "Composite",
+ className: "DeploymentListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "DeploymentExtended"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ScopedDeployment = {
+ type: {
+ name: "Composite",
+ className: "ScopedDeployment",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentProperties"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const ScopedDeploymentWhatIf = {
+ type: {
+ name: "Composite",
+ className: "ScopedDeploymentWhatIf",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIfProperties"
+ }
+ }
+ }
+ }
+};
+const DeploymentWhatIfSettings = {
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIfSettings",
+ modelProperties: {
+ resultFormat: {
+ serializedName: "resultFormat",
+ type: {
+ name: "Enum",
+ allowedValues: ["ResourceIdOnly", "FullResourcePayloads"]
+ }
+ }
+ }
+ }
+};
+const WhatIfOperationResult = {
+ type: {
+ name: "Composite",
+ className: "WhatIfOperationResult",
+ modelProperties: {
+ status: {
+ serializedName: "status",
+ type: {
+ name: "String"
+ }
+ },
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ },
+ changes: {
+ serializedName: "properties.changes",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "WhatIfChange"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const WhatIfChange = {
+ type: {
+ name: "Composite",
+ className: "WhatIfChange",
+ modelProperties: {
+ resourceId: {
+ serializedName: "resourceId",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ changeType: {
+ serializedName: "changeType",
+ required: true,
+ type: {
+ name: "Enum",
+ allowedValues: [
+ "Create",
+ "Delete",
+ "Ignore",
+ "Deploy",
+ "NoChange",
+ "Modify",
+ "Unsupported"
+ ]
+ }
+ },
+ unsupportedReason: {
+ serializedName: "unsupportedReason",
+ type: {
+ name: "String"
+ }
+ },
+ before: {
+ serializedName: "before",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ after: {
+ serializedName: "after",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ delta: {
+ serializedName: "delta",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "WhatIfPropertyChange"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const WhatIfPropertyChange = {
+ type: {
+ name: "Composite",
+ className: "WhatIfPropertyChange",
+ modelProperties: {
+ path: {
+ serializedName: "path",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ propertyChangeType: {
+ serializedName: "propertyChangeType",
+ required: true,
+ type: {
+ name: "Enum",
+ allowedValues: ["Create", "Delete", "Modify", "Array", "NoEffect"]
+ }
+ },
+ before: {
+ serializedName: "before",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ after: {
+ serializedName: "after",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ children: {
+ serializedName: "children",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "WhatIfPropertyChange"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const DeploymentWhatIf = {
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIf",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIfProperties"
+ }
+ }
+ }
+ }
+};
+const ProviderPermissionListResult = {
+ type: {
+ name: "Composite",
+ className: "ProviderPermissionListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ProviderPermission"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ProviderPermission = {
+ type: {
+ name: "Composite",
+ className: "ProviderPermission",
+ modelProperties: {
+ applicationId: {
+ serializedName: "applicationId",
+ type: {
+ name: "String"
+ }
+ },
+ roleDefinition: {
+ serializedName: "roleDefinition",
+ type: {
+ name: "Composite",
+ className: "RoleDefinition"
+ }
+ },
+ managedByRoleDefinition: {
+ serializedName: "managedByRoleDefinition",
+ type: {
+ name: "Composite",
+ className: "RoleDefinition"
+ }
+ },
+ providerAuthorizationConsentState: {
+ serializedName: "providerAuthorizationConsentState",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const RoleDefinition = {
+ type: {
+ name: "Composite",
+ className: "RoleDefinition",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ isServiceRole: {
+ serializedName: "isServiceRole",
+ type: {
+ name: "Boolean"
+ }
+ },
+ permissions: {
+ serializedName: "permissions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Permission"
+ }
+ }
+ }
+ },
+ scopes: {
+ serializedName: "scopes",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const Permission = {
+ type: {
+ name: "Composite",
+ className: "Permission",
+ modelProperties: {
+ actions: {
+ serializedName: "actions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ notActions: {
+ serializedName: "notActions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ dataActions: {
+ serializedName: "dataActions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ notDataActions: {
+ serializedName: "notDataActions",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const ProviderRegistrationRequest = {
+ type: {
+ name: "Composite",
+ className: "ProviderRegistrationRequest",
+ modelProperties: {
+ thirdPartyProviderConsent: {
+ serializedName: "thirdPartyProviderConsent",
+ type: {
+ name: "Composite",
+ className: "ProviderConsentDefinition"
+ }
+ }
+ }
+ }
+};
+const ProviderConsentDefinition = {
+ type: {
+ name: "Composite",
+ className: "ProviderConsentDefinition",
+ modelProperties: {
+ consentToAuthorization: {
+ serializedName: "consentToAuthorization",
+ type: {
+ name: "Boolean"
+ }
+ }
+ }
+ }
+};
+const ProviderListResult = {
+ type: {
+ name: "Composite",
+ className: "ProviderListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "Provider"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ProviderResourceTypeListResult = {
+ type: {
+ name: "Composite",
+ className: "ProviderResourceTypeListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ProviderResourceType"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceListResult = {
+ type: {
+ name: "Composite",
+ className: "ResourceListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "GenericResourceExpanded"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const Plan = {
+ type: {
+ name: "Composite",
+ className: "Plan",
+ modelProperties: {
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ publisher: {
+ serializedName: "publisher",
+ type: {
+ name: "String"
+ }
+ },
+ product: {
+ serializedName: "product",
+ type: {
+ name: "String"
+ }
+ },
+ promotionCode: {
+ serializedName: "promotionCode",
+ type: {
+ name: "String"
+ }
+ },
+ version: {
+ serializedName: "version",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const Sku = {
+ type: {
+ name: "Composite",
+ className: "Sku",
+ modelProperties: {
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ tier: {
+ serializedName: "tier",
+ type: {
+ name: "String"
+ }
+ },
+ size: {
+ serializedName: "size",
+ type: {
+ name: "String"
+ }
+ },
+ family: {
+ serializedName: "family",
+ type: {
+ name: "String"
+ }
+ },
+ model: {
+ serializedName: "model",
+ type: {
+ name: "String"
+ }
+ },
+ capacity: {
+ serializedName: "capacity",
+ type: {
+ name: "Number"
+ }
+ }
+ }
+ }
+};
+const Identity = {
+ type: {
+ name: "Composite",
+ className: "Identity",
+ modelProperties: {
+ principalId: {
+ serializedName: "principalId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ tenantId: {
+ serializedName: "tenantId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ type: {
+ name: "Enum",
+ allowedValues: [
+ "SystemAssigned",
+ "UserAssigned",
+ "SystemAssigned, UserAssigned",
+ "None"
+ ]
+ }
+ },
+ userAssignedIdentities: {
+ serializedName: "userAssignedIdentities",
+ type: {
+ name: "Dictionary",
+ value: {
+ type: {
+ name: "Composite",
+ className: "IdentityUserAssignedIdentitiesValue"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const IdentityUserAssignedIdentitiesValue = {
+ type: {
+ name: "Composite",
+ className: "IdentityUserAssignedIdentitiesValue",
+ modelProperties: {
+ principalId: {
+ serializedName: "principalId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ clientId: {
+ serializedName: "clientId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const Resource = {
+ type: {
+ name: "Composite",
+ className: "Resource",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ extendedLocation: {
+ serializedName: "extendedLocation",
+ type: {
+ name: "Composite",
+ className: "ExtendedLocation"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const ExtendedLocation = {
+ type: {
+ name: "Composite",
+ className: "ExtendedLocation",
+ modelProperties: {
+ type: {
+ serializedName: "type",
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceGroup = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroup",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "ResourceGroupProperties"
+ }
+ },
+ location: {
+ serializedName: "location",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ managedBy: {
+ serializedName: "managedBy",
+ type: {
+ name: "String"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const ResourceGroupProperties = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroupProperties",
+ modelProperties: {
+ provisioningState: {
+ serializedName: "provisioningState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceGroupPatchable = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroupPatchable",
+ modelProperties: {
+ name: {
+ serializedName: "name",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "ResourceGroupProperties"
+ }
+ },
+ managedBy: {
+ serializedName: "managedBy",
+ type: {
+ name: "String"
+ }
+ },
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const ExportTemplateRequest = {
+ type: {
+ name: "Composite",
+ className: "ExportTemplateRequest",
+ modelProperties: {
+ resources: {
+ serializedName: "resources",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ options: {
+ serializedName: "options",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceGroupExportResult = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroupExportResult",
+ modelProperties: {
+ template: {
+ serializedName: "template",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ },
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ }
+ }
+ }
+};
+const ResourceGroupListResult = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroupListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "ResourceGroup"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourcesMoveInfo = {
+ type: {
+ name: "Composite",
+ className: "ResourcesMoveInfo",
+ modelProperties: {
+ resources: {
+ serializedName: "resources",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "String"
+ }
+ }
+ }
+ },
+ targetResourceGroup: {
+ serializedName: "targetResourceGroup",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const TagValue = {
+ type: {
+ name: "Composite",
+ className: "TagValue",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ tagValue: {
+ serializedName: "tagValue",
+ type: {
+ name: "String"
+ }
+ },
+ count: {
+ serializedName: "count",
+ type: {
+ name: "Composite",
+ className: "TagCount"
+ }
+ }
+ }
+ }
+};
+const TagCount = {
+ type: {
+ name: "Composite",
+ className: "TagCount",
+ modelProperties: {
+ type: {
+ serializedName: "type",
+ type: {
+ name: "String"
+ }
+ },
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Number"
+ }
+ }
+ }
+ }
+};
+const TagDetails = {
+ type: {
+ name: "Composite",
+ className: "TagDetails",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ tagName: {
+ serializedName: "tagName",
+ type: {
+ name: "String"
+ }
+ },
+ count: {
+ serializedName: "count",
+ type: {
+ name: "Composite",
+ className: "TagCount"
+ }
+ },
+ values: {
+ serializedName: "values",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "TagValue"
+ }
+ }
+ }
+ }
+ }
+ }
+};
+const TagsListResult = {
+ type: {
+ name: "Composite",
+ className: "TagsListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "TagDetails"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentOperation = {
+ type: {
+ name: "Composite",
+ className: "DeploymentOperation",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ operationId: {
+ serializedName: "operationId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "DeploymentOperationProperties"
+ }
+ }
+ }
+ }
+};
+const DeploymentOperationProperties = {
+ type: {
+ name: "Composite",
+ className: "DeploymentOperationProperties",
+ modelProperties: {
+ provisioningOperation: {
+ serializedName: "provisioningOperation",
+ readOnly: true,
+ type: {
+ name: "Enum",
+ allowedValues: [
+ "NotSpecified",
+ "Create",
+ "Delete",
+ "Waiting",
+ "AzureAsyncOperationWaiting",
+ "ResourceCacheWaiting",
+ "Action",
+ "Read",
+ "EvaluateDeploymentOutput",
+ "DeploymentCleanup"
+ ]
+ }
+ },
+ provisioningState: {
+ serializedName: "provisioningState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ timestamp: {
+ serializedName: "timestamp",
+ readOnly: true,
+ type: {
+ name: "DateTime"
+ }
+ },
+ duration: {
+ serializedName: "duration",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ serviceRequestId: {
+ serializedName: "serviceRequestId",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ statusCode: {
+ serializedName: "statusCode",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ statusMessage: {
+ serializedName: "statusMessage",
+ type: {
+ name: "Composite",
+ className: "StatusMessage"
+ }
+ },
+ targetResource: {
+ serializedName: "targetResource",
+ type: {
+ name: "Composite",
+ className: "TargetResource"
+ }
+ },
+ request: {
+ serializedName: "request",
+ type: {
+ name: "Composite",
+ className: "HttpMessage"
+ }
+ },
+ response: {
+ serializedName: "response",
+ type: {
+ name: "Composite",
+ className: "HttpMessage"
+ }
+ }
+ }
+ }
+};
+const StatusMessage = {
+ type: {
+ name: "Composite",
+ className: "StatusMessage",
+ modelProperties: {
+ status: {
+ serializedName: "status",
+ type: {
+ name: "String"
+ }
+ },
+ error: {
+ serializedName: "error",
+ type: {
+ name: "Composite",
+ className: "ErrorResponse"
+ }
+ }
+ }
+ }
+};
+const TargetResource = {
+ type: {
+ name: "Composite",
+ className: "TargetResource",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ },
+ resourceName: {
+ serializedName: "resourceName",
+ type: {
+ name: "String"
+ }
+ },
+ resourceType: {
+ serializedName: "resourceType",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const HttpMessage = {
+ type: {
+ name: "Composite",
+ className: "HttpMessage",
+ modelProperties: {
+ content: {
+ serializedName: "content",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ }
+ }
+ }
+};
+const DeploymentOperationsListResult = {
+ type: {
+ name: "Composite",
+ className: "DeploymentOperationsListResult",
+ modelProperties: {
+ value: {
+ serializedName: "value",
+ type: {
+ name: "Sequence",
+ element: {
+ type: {
+ name: "Composite",
+ className: "DeploymentOperation"
+ }
+ }
+ }
+ },
+ nextLink: {
+ serializedName: "nextLink",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const TemplateHashResult = {
+ type: {
+ name: "Composite",
+ className: "TemplateHashResult",
+ modelProperties: {
+ minifiedTemplate: {
+ serializedName: "minifiedTemplate",
+ type: {
+ name: "String"
+ }
+ },
+ templateHash: {
+ serializedName: "templateHash",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const TagsResource = {
+ type: {
+ name: "Composite",
+ className: "TagsResource",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ name: {
+ serializedName: "name",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ type: {
+ serializedName: "type",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "Tags"
+ }
+ }
+ }
+ }
+};
+const Tags = {
+ type: {
+ name: "Composite",
+ className: "Tags",
+ modelProperties: {
+ tags: {
+ serializedName: "tags",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "String" } }
+ }
+ }
+ }
+ }
+};
+const TagsPatchResource = {
+ type: {
+ name: "Composite",
+ className: "TagsPatchResource",
+ modelProperties: {
+ operation: {
+ serializedName: "operation",
+ type: {
+ name: "String"
+ }
+ },
+ properties: {
+ serializedName: "properties",
+ type: {
+ name: "Composite",
+ className: "Tags"
+ }
+ }
+ }
+ }
+};
+const DeploymentExtendedFilter = {
+ type: {
+ name: "Composite",
+ className: "DeploymentExtendedFilter",
+ modelProperties: {
+ provisioningState: {
+ serializedName: "provisioningState",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const GenericResourceFilter = {
+ type: {
+ name: "Composite",
+ className: "GenericResourceFilter",
+ modelProperties: {
+ resourceType: {
+ serializedName: "resourceType",
+ type: {
+ name: "String"
+ }
+ },
+ tagname: {
+ serializedName: "tagname",
+ type: {
+ name: "String"
+ }
+ },
+ tagvalue: {
+ serializedName: "tagvalue",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceGroupFilter = {
+ type: {
+ name: "Composite",
+ className: "ResourceGroupFilter",
+ modelProperties: {
+ tagName: {
+ serializedName: "tagName",
+ type: {
+ name: "String"
+ }
+ },
+ tagValue: {
+ serializedName: "tagValue",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const ResourceProviderOperationDisplayProperties = {
+ type: {
+ name: "Composite",
+ className: "ResourceProviderOperationDisplayProperties",
+ modelProperties: {
+ publisher: {
+ serializedName: "publisher",
+ type: {
+ name: "String"
+ }
+ },
+ provider: {
+ serializedName: "provider",
+ type: {
+ name: "String"
+ }
+ },
+ resource: {
+ serializedName: "resource",
+ type: {
+ name: "String"
+ }
+ },
+ operation: {
+ serializedName: "operation",
+ type: {
+ name: "String"
+ }
+ },
+ description: {
+ serializedName: "description",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const SubResource = {
+ type: {
+ name: "Composite",
+ className: "SubResource",
+ modelProperties: {
+ id: {
+ serializedName: "id",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentWhatIfProperties = {
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIfProperties",
+ modelProperties: Object.assign(Object.assign({}, DeploymentProperties.type.modelProperties), { whatIfSettings: {
+ serializedName: "whatIfSettings",
+ type: {
+ name: "Composite",
+ className: "DeploymentWhatIfSettings"
+ }
+ } })
+ }
+};
+const GenericResource = {
+ type: {
+ name: "Composite",
+ className: "GenericResource",
+ modelProperties: Object.assign(Object.assign({}, Resource.type.modelProperties), { plan: {
+ serializedName: "plan",
+ type: {
+ name: "Composite",
+ className: "Plan"
+ }
+ }, properties: {
+ serializedName: "properties",
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ }, kind: {
+ constraints: {
+ Pattern: new RegExp("^[-\\w\\._,\\(\\)]+$")
+ },
+ serializedName: "kind",
+ type: {
+ name: "String"
+ }
+ }, managedBy: {
+ serializedName: "managedBy",
+ type: {
+ name: "String"
+ }
+ }, sku: {
+ serializedName: "sku",
+ type: {
+ name: "Composite",
+ className: "Sku"
+ }
+ }, identity: {
+ serializedName: "identity",
+ type: {
+ name: "Composite",
+ className: "Identity"
+ }
+ } })
+ }
+};
+const GenericResourceExpanded = {
+ type: {
+ name: "Composite",
+ className: "GenericResourceExpanded",
+ modelProperties: Object.assign(Object.assign({}, GenericResource.type.modelProperties), { createdTime: {
+ serializedName: "createdTime",
+ readOnly: true,
+ type: {
+ name: "DateTime"
+ }
+ }, changedTime: {
+ serializedName: "changedTime",
+ readOnly: true,
+ type: {
+ name: "DateTime"
+ }
+ }, provisioningState: {
+ serializedName: "provisioningState",
+ readOnly: true,
+ type: {
+ name: "String"
+ }
+ } })
+ }
+};
+const DeploymentsWhatIfAtTenantScopeHeaders = {
+ type: {
+ name: "Composite",
+ className: "DeploymentsWhatIfAtTenantScopeHeaders",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ retryAfter: {
+ serializedName: "retry-after",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentsWhatIfAtManagementGroupScopeHeaders = {
+ type: {
+ name: "Composite",
+ className: "DeploymentsWhatIfAtManagementGroupScopeHeaders",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ retryAfter: {
+ serializedName: "retry-after",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentsWhatIfAtSubscriptionScopeHeaders = {
+ type: {
+ name: "Composite",
+ className: "DeploymentsWhatIfAtSubscriptionScopeHeaders",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ retryAfter: {
+ serializedName: "retry-after",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+const DeploymentsWhatIfHeaders = {
+ type: {
+ name: "Composite",
+ className: "DeploymentsWhatIfHeaders",
+ modelProperties: {
+ location: {
+ serializedName: "location",
+ type: {
+ name: "String"
+ }
+ },
+ retryAfter: {
+ serializedName: "retry-after",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+
+var Mappers = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ OperationListResult: OperationListResult,
+ Operation: Operation,
+ OperationDisplay: OperationDisplay,
+ CloudError: CloudError,
+ ErrorResponse: ErrorResponse,
+ ErrorAdditionalInfo: ErrorAdditionalInfo,
+ Deployment: Deployment,
+ DeploymentProperties: DeploymentProperties,
+ TemplateLink: TemplateLink,
+ ParametersLink: ParametersLink,
+ DebugSetting: DebugSetting,
+ OnErrorDeployment: OnErrorDeployment,
+ ExpressionEvaluationOptions: ExpressionEvaluationOptions,
+ DeploymentExtended: DeploymentExtended,
+ DeploymentPropertiesExtended: DeploymentPropertiesExtended,
+ Provider: Provider,
+ ProviderResourceType: ProviderResourceType,
+ ProviderExtendedLocation: ProviderExtendedLocation,
+ Alias: Alias,
+ AliasPath: AliasPath,
+ AliasPattern: AliasPattern,
+ AliasPathMetadata: AliasPathMetadata,
+ ZoneMapping: ZoneMapping,
+ ApiProfile: ApiProfile,
+ Dependency: Dependency,
+ BasicDependency: BasicDependency,
+ OnErrorDeploymentExtended: OnErrorDeploymentExtended,
+ ResourceReference: ResourceReference,
+ DeploymentValidateResult: DeploymentValidateResult,
+ DeploymentExportResult: DeploymentExportResult,
+ DeploymentListResult: DeploymentListResult,
+ ScopedDeployment: ScopedDeployment,
+ ScopedDeploymentWhatIf: ScopedDeploymentWhatIf,
+ DeploymentWhatIfSettings: DeploymentWhatIfSettings,
+ WhatIfOperationResult: WhatIfOperationResult,
+ WhatIfChange: WhatIfChange,
+ WhatIfPropertyChange: WhatIfPropertyChange,
+ DeploymentWhatIf: DeploymentWhatIf,
+ ProviderPermissionListResult: ProviderPermissionListResult,
+ ProviderPermission: ProviderPermission,
+ RoleDefinition: RoleDefinition,
+ Permission: Permission,
+ ProviderRegistrationRequest: ProviderRegistrationRequest,
+ ProviderConsentDefinition: ProviderConsentDefinition,
+ ProviderListResult: ProviderListResult,
+ ProviderResourceTypeListResult: ProviderResourceTypeListResult,
+ ResourceListResult: ResourceListResult,
+ Plan: Plan,
+ Sku: Sku,
+ Identity: Identity,
+ IdentityUserAssignedIdentitiesValue: IdentityUserAssignedIdentitiesValue,
+ Resource: Resource,
+ ExtendedLocation: ExtendedLocation,
+ ResourceGroup: ResourceGroup,
+ ResourceGroupProperties: ResourceGroupProperties,
+ ResourceGroupPatchable: ResourceGroupPatchable,
+ ExportTemplateRequest: ExportTemplateRequest,
+ ResourceGroupExportResult: ResourceGroupExportResult,
+ ResourceGroupListResult: ResourceGroupListResult,
+ ResourcesMoveInfo: ResourcesMoveInfo,
+ TagValue: TagValue,
+ TagCount: TagCount,
+ TagDetails: TagDetails,
+ TagsListResult: TagsListResult,
+ DeploymentOperation: DeploymentOperation,
+ DeploymentOperationProperties: DeploymentOperationProperties,
+ StatusMessage: StatusMessage,
+ TargetResource: TargetResource,
+ HttpMessage: HttpMessage,
+ DeploymentOperationsListResult: DeploymentOperationsListResult,
+ TemplateHashResult: TemplateHashResult,
+ TagsResource: TagsResource,
+ Tags: Tags,
+ TagsPatchResource: TagsPatchResource,
+ DeploymentExtendedFilter: DeploymentExtendedFilter,
+ GenericResourceFilter: GenericResourceFilter,
+ ResourceGroupFilter: ResourceGroupFilter,
+ ResourceProviderOperationDisplayProperties: ResourceProviderOperationDisplayProperties,
+ SubResource: SubResource,
+ DeploymentWhatIfProperties: DeploymentWhatIfProperties,
+ GenericResource: GenericResource,
+ GenericResourceExpanded: GenericResourceExpanded,
+ DeploymentsWhatIfAtTenantScopeHeaders: DeploymentsWhatIfAtTenantScopeHeaders,
+ DeploymentsWhatIfAtManagementGroupScopeHeaders: DeploymentsWhatIfAtManagementGroupScopeHeaders,
+ DeploymentsWhatIfAtSubscriptionScopeHeaders: DeploymentsWhatIfAtSubscriptionScopeHeaders,
+ DeploymentsWhatIfHeaders: DeploymentsWhatIfHeaders
+});
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+const accept = {
+ parameterPath: "accept",
+ mapper: {
+ defaultValue: "application/json",
+ isConstant: true,
+ serializedName: "Accept",
+ type: {
+ name: "String"
+ }
+ }
+};
+const $host = {
+ parameterPath: "$host",
+ mapper: {
+ serializedName: "$host",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const apiVersion = {
+ parameterPath: "apiVersion",
+ mapper: {
+ defaultValue: "2021-04-01",
+ isConstant: true,
+ serializedName: "api-version",
+ type: {
+ name: "String"
+ }
+ }
+};
+const nextLink = {
+ parameterPath: "nextLink",
+ mapper: {
+ serializedName: "nextLink",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const scope = {
+ parameterPath: "scope",
+ mapper: {
+ serializedName: "scope",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const deploymentName = {
+ parameterPath: "deploymentName",
+ mapper: {
+ constraints: {
+ Pattern: new RegExp("^[-\\w\\._\\(\\)]+$"),
+ MaxLength: 64,
+ MinLength: 1
+ },
+ serializedName: "deploymentName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const contentType = {
+ parameterPath: ["options", "contentType"],
+ mapper: {
+ defaultValue: "application/json",
+ isConstant: true,
+ serializedName: "Content-Type",
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters = {
+ parameterPath: "parameters",
+ mapper: Deployment
+};
+const filter = {
+ parameterPath: ["options", "filter"],
+ mapper: {
+ serializedName: "$filter",
+ type: {
+ name: "String"
+ }
+ }
+};
+const top = {
+ parameterPath: ["options", "top"],
+ mapper: {
+ serializedName: "$top",
+ type: {
+ name: "Number"
+ }
+ }
+};
+const parameters1 = {
+ parameterPath: "parameters",
+ mapper: ScopedDeployment
+};
+const parameters2 = {
+ parameterPath: "parameters",
+ mapper: ScopedDeploymentWhatIf
+};
+const groupId = {
+ parameterPath: "groupId",
+ mapper: {
+ constraints: {
+ MaxLength: 90,
+ MinLength: 1
+ },
+ serializedName: "groupId",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const subscriptionId = {
+ parameterPath: "subscriptionId",
+ mapper: {
+ serializedName: "subscriptionId",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters3 = {
+ parameterPath: "parameters",
+ mapper: DeploymentWhatIf
+};
+const resourceGroupName = {
+ parameterPath: "resourceGroupName",
+ mapper: {
+ constraints: {
+ Pattern: new RegExp("^[-\\w\\._\\(\\)]+$"),
+ MaxLength: 90,
+ MinLength: 1
+ },
+ serializedName: "resourceGroupName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const template = {
+ parameterPath: "template",
+ mapper: {
+ serializedName: "template",
+ required: true,
+ type: {
+ name: "Dictionary",
+ value: { type: { name: "any" } }
+ }
+ }
+};
+const resourceProviderNamespace = {
+ parameterPath: "resourceProviderNamespace",
+ mapper: {
+ serializedName: "resourceProviderNamespace",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const properties = {
+ parameterPath: ["options", "properties"],
+ mapper: ProviderRegistrationRequest
+};
+const expand = {
+ parameterPath: ["options", "expand"],
+ mapper: {
+ serializedName: "$expand",
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters4 = {
+ parameterPath: "parameters",
+ mapper: ResourcesMoveInfo
+};
+const sourceResourceGroupName = {
+ parameterPath: "sourceResourceGroupName",
+ mapper: {
+ constraints: {
+ Pattern: new RegExp("^[-\\w\\._\\(\\)]+$"),
+ MaxLength: 90,
+ MinLength: 1
+ },
+ serializedName: "sourceResourceGroupName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const parentResourcePath = {
+ parameterPath: "parentResourcePath",
+ mapper: {
+ serializedName: "parentResourcePath",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const resourceType = {
+ parameterPath: "resourceType",
+ mapper: {
+ serializedName: "resourceType",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const resourceName = {
+ parameterPath: "resourceName",
+ mapper: {
+ serializedName: "resourceName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const apiVersion1 = {
+ parameterPath: "apiVersion",
+ mapper: {
+ serializedName: "api-version",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters5 = {
+ parameterPath: "parameters",
+ mapper: GenericResource
+};
+const resourceId = {
+ parameterPath: "resourceId",
+ mapper: {
+ serializedName: "resourceId",
+ required: true,
+ type: {
+ name: "String"
+ }
+ },
+ skipEncoding: true
+};
+const parameters6 = {
+ parameterPath: "parameters",
+ mapper: ResourceGroup
+};
+const forceDeletionTypes = {
+ parameterPath: ["options", "forceDeletionTypes"],
+ mapper: {
+ serializedName: "forceDeletionTypes",
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters7 = {
+ parameterPath: "parameters",
+ mapper: ResourceGroupPatchable
+};
+const parameters8 = {
+ parameterPath: "parameters",
+ mapper: ExportTemplateRequest
+};
+const resourceGroupName1 = {
+ parameterPath: "resourceGroupName",
+ mapper: {
+ constraints: {
+ MaxLength: 90,
+ MinLength: 1
+ },
+ serializedName: "resourceGroupName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const tagName = {
+ parameterPath: "tagName",
+ mapper: {
+ serializedName: "tagName",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const tagValue = {
+ parameterPath: "tagValue",
+ mapper: {
+ serializedName: "tagValue",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+const parameters9 = {
+ parameterPath: "parameters",
+ mapper: TagsResource
+};
+const parameters10 = {
+ parameterPath: "parameters",
+ mapper: TagsPatchResource
+};
+const operationId = {
+ parameterPath: "operationId",
+ mapper: {
+ serializedName: "operationId",
+ required: true,
+ type: {
+ name: "String"
+ }
+ }
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing Operations operations. */
+class OperationsImpl {
+ /**
+ * Initialize a new instance of the class Operations class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Lists all of the available Microsoft.Resources REST API operations.
+ * @param options The options parameters.
+ */
+ list(options) {
+ const iter = this.listPagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(options, settings);
+ }
+ };
+ }
+ listPagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Lists all of the available Microsoft.Resources REST API operations.
+ * @param options The options parameters.
+ */
+ _list(options) {
+ return this.client.sendOperationRequest({ options }, listOperationSpec$6);
+ }
+ /**
+ * ListNext
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listNextOperationSpec$5);
+ }
+}
+// Operation Specifications
+const serializer$7 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const listOperationSpec$6 = {
+ path: "/providers/Microsoft.Resources/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: OperationListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host],
+ headerParameters: [accept],
+ serializer: serializer$7
+};
+const listNextOperationSpec$5 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: OperationListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [$host, nextLink],
+ headerParameters: [accept],
+ serializer: serializer$7
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+function createLroSpec(inputs) {
+ const { args, spec, sendOperationFn } = inputs;
+ return {
+ requestMethod: spec.httpMethod,
+ requestPath: spec.path,
+ sendInitialRequest: () => sendOperationFn(args, spec),
+ sendPollRequest: (path, options) => {
+ const restSpec = tslib.__rest(spec, ["requestBody"]);
+ return sendOperationFn(args, Object.assign(Object.assign({}, restSpec), { httpMethod: "GET", path, abortSignal: options === null || options === void 0 ? void 0 : options.abortSignal }));
+ }
+ };
+}
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing Deployments operations. */
+class DeploymentsImpl {
+ /**
+ * Initialize a new instance of the class Deployments class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Get all the deployments at the given scope.
+ * @param scope The resource scope.
+ * @param options The options parameters.
+ */
+ listAtScope(scope, options) {
+ const iter = this.listAtScopePagingAll(scope, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtScopePagingPage(scope, options, settings);
+ }
+ };
+ }
+ listAtScopePagingPage(scope, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtScope(scope, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtScopeNext(scope, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtScopePagingAll(scope, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtScopePagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtScopePagingPage(scope, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Get all the deployments at the tenant scope.
+ * @param options The options parameters.
+ */
+ listAtTenantScope(options) {
+ const iter = this.listAtTenantScopePagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtTenantScopePagingPage(options, settings);
+ }
+ };
+ }
+ listAtTenantScopePagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScope(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScopeNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtTenantScopePagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingAll_1() {
+ var e_2, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtTenantScopePagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ });
+ }
+ /**
+ * Get all the deployments for a management group.
+ * @param groupId The management group ID.
+ * @param options The options parameters.
+ */
+ listAtManagementGroupScope(groupId, options) {
+ const iter = this.listAtManagementGroupScopePagingAll(groupId, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtManagementGroupScopePagingPage(groupId, options, settings);
+ }
+ };
+ }
+ listAtManagementGroupScopePagingPage(groupId, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtManagementGroupScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtManagementGroupScope(groupId, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtManagementGroupScopeNext(groupId, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtManagementGroupScopePagingAll(groupId, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtManagementGroupScopePagingAll_1() {
+ var e_3, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtManagementGroupScopePagingPage(groupId, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_3) throw e_3.error; }
+ }
+ });
+ }
+ /**
+ * Get all the deployments for a subscription.
+ * @param options The options parameters.
+ */
+ listAtSubscriptionScope(options) {
+ const iter = this.listAtSubscriptionScopePagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtSubscriptionScopePagingPage(options, settings);
+ }
+ };
+ }
+ listAtSubscriptionScopePagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtSubscriptionScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtSubscriptionScope(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtSubscriptionScopeNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtSubscriptionScopePagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtSubscriptionScopePagingAll_1() {
+ var e_4, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtSubscriptionScopePagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_4) throw e_4.error; }
+ }
+ });
+ }
+ /**
+ * Get all the deployments for a resource group.
+ * @param resourceGroupName The name of the resource group with the deployments to get. The name is
+ * case insensitive.
+ * @param options The options parameters.
+ */
+ listByResourceGroup(resourceGroupName, options) {
+ const iter = this.listByResourceGroupPagingAll(resourceGroupName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listByResourceGroupPagingPage(resourceGroupName, options, settings);
+ }
+ };
+ }
+ listByResourceGroupPagingPage(resourceGroupName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listByResourceGroupPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listByResourceGroup(resourceGroupName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listByResourceGroupNext(resourceGroupName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listByResourceGroupPagingAll(resourceGroupName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listByResourceGroupPagingAll_1() {
+ var e_5, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listByResourceGroupPagingPage(resourceGroupName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_5) throw e_5.error; }
+ }
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtScope(scope, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { scope, deploymentName, options },
+ spec: deleteAtScopeOperationSpec$1
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtScopeAndWait(scope, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDeleteAtScope(scope, deploymentName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Checks whether the deployment exists.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ checkExistenceAtScope(scope, deploymentName, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, options }, checkExistenceAtScopeOperationSpec);
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtScope(scope, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { scope, deploymentName, parameters, options },
+ spec: createOrUpdateAtScopeOperationSpec$1
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtScopeAndWait(scope, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdateAtScope(scope, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a deployment.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ getAtScope(scope, deploymentName, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, options }, getAtScopeOperationSpec$2);
+ }
+ /**
+ * You can cancel a deployment only if the provisioningState is Accepted or Running. After the
+ * deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment
+ * stops the currently running template deployment and leaves the resources partially deployed.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ cancelAtScope(scope, deploymentName, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, options }, cancelAtScopeOperationSpec);
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtScope(scope, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { scope, deploymentName, parameters, options },
+ spec: validateAtScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtScopeAndWait(scope, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidateAtScope(scope, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Exports the template used for specified deployment.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ exportTemplateAtScope(scope, deploymentName, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, options }, exportTemplateAtScopeOperationSpec);
+ }
+ /**
+ * Get all the deployments at the given scope.
+ * @param scope The resource scope.
+ * @param options The options parameters.
+ */
+ _listAtScope(scope, options) {
+ return this.client.sendOperationRequest({ scope, options }, listAtScopeOperationSpec$1);
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtTenantScope(deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, options },
+ spec: deleteAtTenantScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtTenantScopeAndWait(deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDeleteAtTenantScope(deploymentName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Checks whether the deployment exists.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ checkExistenceAtTenantScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, checkExistenceAtTenantScopeOperationSpec);
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtTenantScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: createOrUpdateAtTenantScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtTenantScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdateAtTenantScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ getAtTenantScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, getAtTenantScopeOperationSpec$2);
+ }
+ /**
+ * You can cancel a deployment only if the provisioningState is Accepted or Running. After the
+ * deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment
+ * stops the currently running template deployment and leaves the resources partially deployed.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ cancelAtTenantScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, cancelAtTenantScopeOperationSpec);
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtTenantScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: validateAtTenantScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtTenantScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidateAtTenantScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the tenant group.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtTenantScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: whatIfAtTenantScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs,
+ resourceLocationConfig: "location"
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the tenant group.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtTenantScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginWhatIfAtTenantScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Exports the template used for specified deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ exportTemplateAtTenantScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, exportTemplateAtTenantScopeOperationSpec);
+ }
+ /**
+ * Get all the deployments at the tenant scope.
+ * @param options The options parameters.
+ */
+ _listAtTenantScope(options) {
+ return this.client.sendOperationRequest({ options }, listAtTenantScopeOperationSpec$2);
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtManagementGroupScope(groupId, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { groupId, deploymentName, options },
+ spec: deleteAtManagementGroupScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtManagementGroupScopeAndWait(groupId, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDeleteAtManagementGroupScope(groupId, deploymentName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Checks whether the deployment exists.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ checkExistenceAtManagementGroupScope(groupId, deploymentName, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, options }, checkExistenceAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtManagementGroupScope(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { groupId, deploymentName, parameters, options },
+ spec: createOrUpdateAtManagementGroupScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtManagementGroupScopeAndWait(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdateAtManagementGroupScope(groupId, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a deployment.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ getAtManagementGroupScope(groupId, deploymentName, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, options }, getAtManagementGroupScopeOperationSpec$1);
+ }
+ /**
+ * You can cancel a deployment only if the provisioningState is Accepted or Running. After the
+ * deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment
+ * stops the currently running template deployment and leaves the resources partially deployed.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ cancelAtManagementGroupScope(groupId, deploymentName, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, options }, cancelAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtManagementGroupScope(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { groupId, deploymentName, parameters, options },
+ spec: validateAtManagementGroupScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtManagementGroupScopeAndWait(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidateAtManagementGroupScope(groupId, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the management
+ * group.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtManagementGroupScope(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { groupId, deploymentName, parameters, options },
+ spec: whatIfAtManagementGroupScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs,
+ resourceLocationConfig: "location"
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the management
+ * group.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtManagementGroupScopeAndWait(groupId, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginWhatIfAtManagementGroupScope(groupId, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Exports the template used for specified deployment.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ exportTemplateAtManagementGroupScope(groupId, deploymentName, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, options }, exportTemplateAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * Get all the deployments for a management group.
+ * @param groupId The management group ID.
+ * @param options The options parameters.
+ */
+ _listAtManagementGroupScope(groupId, options) {
+ return this.client.sendOperationRequest({ groupId, options }, listAtManagementGroupScopeOperationSpec$1);
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtSubscriptionScope(deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, options },
+ spec: deleteAtSubscriptionScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. This is an asynchronous operation that returns a
+ * status of 202 until the template deployment is successfully deleted. The Location response header
+ * contains the URI that is used to obtain the status of the process. While the process is running, a
+ * call to the URI in the Location header returns a status of 202. When the process finishes, the URI
+ * in the Location header returns a status of 204 on success. If the asynchronous request failed, the
+ * URI in the Location header returns an error-level status code.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAtSubscriptionScopeAndWait(deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDeleteAtSubscriptionScope(deploymentName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Checks whether the deployment exists.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ checkExistenceAtSubscriptionScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, checkExistenceAtSubscriptionScopeOperationSpec);
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtSubscriptionScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: createOrUpdateAtSubscriptionScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAtSubscriptionScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdateAtSubscriptionScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ getAtSubscriptionScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, getAtSubscriptionScopeOperationSpec$1);
+ }
+ /**
+ * You can cancel a deployment only if the provisioningState is Accepted or Running. After the
+ * deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment
+ * stops the currently running template deployment and leaves the resources partially deployed.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ cancelAtSubscriptionScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, cancelAtSubscriptionScopeOperationSpec);
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtSubscriptionScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: validateAtSubscriptionScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAtSubscriptionScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidateAtSubscriptionScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the subscription.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to What If.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtSubscriptionScope(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { deploymentName, parameters, options },
+ spec: whatIfAtSubscriptionScopeOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs,
+ resourceLocationConfig: "location"
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the subscription.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to What If.
+ * @param options The options parameters.
+ */
+ beginWhatIfAtSubscriptionScopeAndWait(deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginWhatIfAtSubscriptionScope(deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Exports the template used for specified deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ exportTemplateAtSubscriptionScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, exportTemplateAtSubscriptionScopeOperationSpec);
+ }
+ /**
+ * Get all the deployments for a subscription.
+ * @param options The options parameters.
+ */
+ _listAtSubscriptionScope(options) {
+ return this.client.sendOperationRequest({ options }, listAtSubscriptionScopeOperationSpec$1);
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. Deleting a template deployment does not affect the
+ * state of the resource group. This is an asynchronous operation that returns a status of 202 until
+ * the template deployment is successfully deleted. The Location response header contains the URI that
+ * is used to obtain the status of the process. While the process is running, a call to the URI in the
+ * Location header returns a status of 202. When the process finishes, the URI in the Location header
+ * returns a status of 204 on success. If the asynchronous request failed, the URI in the Location
+ * header returns an error-level status code.
+ * @param resourceGroupName The name of the resource group with the deployment to delete. The name is
+ * case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDelete(resourceGroupName, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, deploymentName, options },
+ spec: deleteOperationSpec$3
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * A template deployment that is currently running cannot be deleted. Deleting a template deployment
+ * removes the associated deployment operations. Deleting a template deployment does not affect the
+ * state of the resource group. This is an asynchronous operation that returns a status of 202 until
+ * the template deployment is successfully deleted. The Location response header contains the URI that
+ * is used to obtain the status of the process. While the process is running, a call to the URI in the
+ * Location header returns a status of 202. When the process finishes, the URI in the Location header
+ * returns a status of 204 on success. If the asynchronous request failed, the URI in the Location
+ * header returns an error-level status code.
+ * @param resourceGroupName The name of the resource group with the deployment to delete. The name is
+ * case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ beginDeleteAndWait(resourceGroupName, deploymentName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDelete(resourceGroupName, deploymentName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Checks whether the deployment exists.
+ * @param resourceGroupName The name of the resource group with the deployment to check. The name is
+ * case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ checkExistence(resourceGroupName, deploymentName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, options }, checkExistenceOperationSpec$2);
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param resourceGroupName The name of the resource group to deploy the resources to. The name is case
+ * insensitive. The resource group must already exist.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdate(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, deploymentName, parameters, options },
+ spec: createOrUpdateOperationSpec$3
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * You can provide the template and parameters directly in the request or link to JSON files.
+ * @param resourceGroupName The name of the resource group to deploy the resources to. The name is case
+ * insensitive. The resource group must already exist.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Additional parameters supplied to the operation.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAndWait(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdate(resourceGroupName, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a deployment.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ get(resourceGroupName, deploymentName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, options }, getOperationSpec$4);
+ }
+ /**
+ * You can cancel a deployment only if the provisioningState is Accepted or Running. After the
+ * deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment
+ * stops the currently running template deployment and leaves the resource group partially deployed.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ cancel(resourceGroupName, deploymentName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, options }, cancelOperationSpec);
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param resourceGroupName The name of the resource group the template will be deployed to. The name
+ * is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidate(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, deploymentName, parameters, options },
+ spec: validateOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Validates whether the specified template is syntactically correct and will be accepted by Azure
+ * Resource Manager..
+ * @param resourceGroupName The name of the resource group the template will be deployed to. The name
+ * is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginValidateAndWait(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidate(resourceGroupName, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the resource group.
+ * @param resourceGroupName The name of the resource group the template will be deployed to. The name
+ * is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIf(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, deploymentName, parameters, options },
+ spec: whatIfOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs,
+ resourceLocationConfig: "location"
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Returns changes that will be made by the deployment if executed at the scope of the resource group.
+ * @param resourceGroupName The name of the resource group the template will be deployed to. The name
+ * is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param parameters Parameters to validate.
+ * @param options The options parameters.
+ */
+ beginWhatIfAndWait(resourceGroupName, deploymentName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginWhatIf(resourceGroupName, deploymentName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Exports the template used for specified deployment.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ exportTemplate(resourceGroupName, deploymentName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, options }, exportTemplateOperationSpec$1);
+ }
+ /**
+ * Get all the deployments for a resource group.
+ * @param resourceGroupName The name of the resource group with the deployments to get. The name is
+ * case insensitive.
+ * @param options The options parameters.
+ */
+ _listByResourceGroup(resourceGroupName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, options }, listByResourceGroupOperationSpec$1);
+ }
+ /**
+ * Calculate the hash of the given template.
+ * @param template The template provided to calculate hash.
+ * @param options The options parameters.
+ */
+ calculateTemplateHash(template, options) {
+ return this.client.sendOperationRequest({ template, options }, calculateTemplateHashOperationSpec);
+ }
+ /**
+ * ListAtScopeNext
+ * @param scope The resource scope.
+ * @param nextLink The nextLink from the previous successful call to the ListAtScope method.
+ * @param options The options parameters.
+ */
+ _listAtScopeNext(scope, nextLink, options) {
+ return this.client.sendOperationRequest({ scope, nextLink, options }, listAtScopeNextOperationSpec$1);
+ }
+ /**
+ * ListAtTenantScopeNext
+ * @param nextLink The nextLink from the previous successful call to the ListAtTenantScope method.
+ * @param options The options parameters.
+ */
+ _listAtTenantScopeNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listAtTenantScopeNextOperationSpec$2);
+ }
+ /**
+ * ListAtManagementGroupScopeNext
+ * @param groupId The management group ID.
+ * @param nextLink The nextLink from the previous successful call to the ListAtManagementGroupScope
+ * method.
+ * @param options The options parameters.
+ */
+ _listAtManagementGroupScopeNext(groupId, nextLink, options) {
+ return this.client.sendOperationRequest({ groupId, nextLink, options }, listAtManagementGroupScopeNextOperationSpec$1);
+ }
+ /**
+ * ListAtSubscriptionScopeNext
+ * @param nextLink The nextLink from the previous successful call to the ListAtSubscriptionScope
+ * method.
+ * @param options The options parameters.
+ */
+ _listAtSubscriptionScopeNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listAtSubscriptionScopeNextOperationSpec$1);
+ }
+ /**
+ * ListByResourceGroupNext
+ * @param resourceGroupName The name of the resource group with the deployments to get. The name is
+ * case insensitive.
+ * @param nextLink The nextLink from the previous successful call to the ListByResourceGroup method.
+ * @param options The options parameters.
+ */
+ _listByResourceGroupNext(resourceGroupName, nextLink, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, nextLink, options }, listByResourceGroupNextOperationSpec$1);
+ }
+}
+// Operation Specifications
+const serializer$6 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const deleteAtScopeOperationSpec$1 = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const checkExistenceAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const createOrUpdateAtScopeOperationSpec$1 = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ 201: {
+ bodyMapper: DeploymentExtended
+ },
+ 202: {
+ bodyMapper: DeploymentExtended
+ },
+ 204: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const getAtScopeOperationSpec$2 = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const cancelAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel",
+ httpMethod: "POST",
+ responses: {
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const validateAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/validate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 201: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 202: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 204: {
+ bodyMapper: DeploymentValidateResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const exportTemplateAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtScopeOperationSpec$1 = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [$host, scope],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const deleteAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const checkExistenceAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const createOrUpdateAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ 201: {
+ bodyMapper: DeploymentExtended
+ },
+ 202: {
+ bodyMapper: DeploymentExtended
+ },
+ 204: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters1,
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const getAtTenantScopeOperationSpec$2 = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const cancelAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/cancel",
+ httpMethod: "POST",
+ responses: {
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const validateAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/validate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 201: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 202: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 204: {
+ bodyMapper: DeploymentValidateResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters1,
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const whatIfAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 201: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 202: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 204: {
+ bodyMapper: WhatIfOperationResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters2,
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const exportTemplateAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtTenantScopeOperationSpec$2 = {
+ path: "/providers/Microsoft.Resources/deployments/",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [$host],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const deleteAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const checkExistenceAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const createOrUpdateAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ 201: {
+ bodyMapper: DeploymentExtended
+ },
+ 202: {
+ bodyMapper: DeploymentExtended
+ },
+ 204: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters1,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const getAtManagementGroupScopeOperationSpec$1 = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const cancelAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel",
+ httpMethod: "POST",
+ responses: {
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const validateAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/validate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 201: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 202: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 204: {
+ bodyMapper: DeploymentValidateResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters1,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const whatIfAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 201: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 202: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 204: {
+ bodyMapper: WhatIfOperationResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters2,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const exportTemplateAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtManagementGroupScopeOperationSpec$1 = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [$host, groupId],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const deleteAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const checkExistenceAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const createOrUpdateAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ 201: {
+ bodyMapper: DeploymentExtended
+ },
+ 202: {
+ bodyMapper: DeploymentExtended
+ },
+ 204: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const getAtSubscriptionScopeOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const cancelAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel",
+ httpMethod: "POST",
+ responses: {
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const validateAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/validate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 201: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 202: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 204: {
+ bodyMapper: DeploymentValidateResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const whatIfAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 201: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 202: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 204: {
+ bodyMapper: WhatIfOperationResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters3,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const exportTemplateAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtSubscriptionScopeOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [$host, subscriptionId],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const deleteOperationSpec$3 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const checkExistenceOperationSpec$2 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const createOrUpdateOperationSpec$3 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ 201: {
+ bodyMapper: DeploymentExtended
+ },
+ 202: {
+ bodyMapper: DeploymentExtended
+ },
+ 204: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const getOperationSpec$4 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExtended
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const cancelOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel",
+ httpMethod: "POST",
+ responses: {
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const validateOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/validate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 201: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 202: {
+ bodyMapper: DeploymentValidateResult
+ },
+ 204: {
+ bodyMapper: DeploymentValidateResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const whatIfOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 201: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 202: {
+ bodyMapper: WhatIfOperationResult
+ },
+ 204: {
+ bodyMapper: WhatIfOperationResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters3,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const exportTemplateOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listByResourceGroupOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const calculateTemplateHashOperationSpec = {
+ path: "/providers/Microsoft.Resources/calculateTemplateHash",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: TemplateHashResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: template,
+ queryParameters: [apiVersion],
+ urlParameters: [$host],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$6
+};
+const listAtScopeNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [$host, nextLink, scope],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtTenantScopeNextOperationSpec$2 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [$host, nextLink],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtManagementGroupScopeNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [$host, nextLink, groupId],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listAtSubscriptionScopeNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+const listByResourceGroupNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$6
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing Providers operations. */
+class ProvidersImpl {
+ /**
+ * Initialize a new instance of the class Providers class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Gets all resource providers for a subscription.
+ * @param options The options parameters.
+ */
+ list(options) {
+ const iter = this.listPagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(options, settings);
+ }
+ };
+ }
+ listPagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Gets all resource providers for the tenant.
+ * @param options The options parameters.
+ */
+ listAtTenantScope(options) {
+ const iter = this.listAtTenantScopePagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtTenantScopePagingPage(options, settings);
+ }
+ };
+ }
+ listAtTenantScopePagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScope(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScopeNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtTenantScopePagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingAll_1() {
+ var e_2, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtTenantScopePagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ });
+ }
+ /**
+ * Unregisters a subscription from a resource provider.
+ * @param resourceProviderNamespace The namespace of the resource provider to unregister.
+ * @param options The options parameters.
+ */
+ unregister(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, unregisterOperationSpec);
+ }
+ /**
+ * Registers a management group with a resource provider.
+ * @param resourceProviderNamespace The namespace of the resource provider to register.
+ * @param groupId The management group ID.
+ * @param options The options parameters.
+ */
+ registerAtManagementGroupScope(resourceProviderNamespace, groupId, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, groupId, options }, registerAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * Get the provider permissions.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param options The options parameters.
+ */
+ providerPermissions(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, providerPermissionsOperationSpec);
+ }
+ /**
+ * Registers a subscription with a resource provider.
+ * @param resourceProviderNamespace The namespace of the resource provider to register.
+ * @param options The options parameters.
+ */
+ register(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, registerOperationSpec);
+ }
+ /**
+ * Gets all resource providers for a subscription.
+ * @param options The options parameters.
+ */
+ _list(options) {
+ return this.client.sendOperationRequest({ options }, listOperationSpec$5);
+ }
+ /**
+ * Gets all resource providers for the tenant.
+ * @param options The options parameters.
+ */
+ _listAtTenantScope(options) {
+ return this.client.sendOperationRequest({ options }, listAtTenantScopeOperationSpec$1);
+ }
+ /**
+ * Gets the specified resource provider.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param options The options parameters.
+ */
+ get(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, getOperationSpec$3);
+ }
+ /**
+ * Gets the specified resource provider at the tenant level.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param options The options parameters.
+ */
+ getAtTenantScope(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, getAtTenantScopeOperationSpec$1);
+ }
+ /**
+ * ListNext
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listNextOperationSpec$4);
+ }
+ /**
+ * ListAtTenantScopeNext
+ * @param nextLink The nextLink from the previous successful call to the ListAtTenantScope method.
+ * @param options The options parameters.
+ */
+ _listAtTenantScopeNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listAtTenantScopeNextOperationSpec$1);
+ }
+}
+// Operation Specifications
+const serializer$5 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const unregisterOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/unregister",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: Provider
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const registerAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/{resourceProviderNamespace}/register",
+ httpMethod: "POST",
+ responses: {
+ 200: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ groupId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const providerPermissionsOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/providerPermissions",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderPermissionListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const registerOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: Provider
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: properties,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$5
+};
+const listOperationSpec$5 = {
+ path: "/subscriptions/{subscriptionId}/providers",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, expand],
+ urlParameters: [$host, subscriptionId],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const listAtTenantScopeOperationSpec$1 = {
+ path: "/providers",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, expand],
+ urlParameters: [$host],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const getOperationSpec$3 = {
+ path: "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: Provider
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, expand],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const getAtTenantScopeOperationSpec$1 = {
+ path: "/providers/{resourceProviderNamespace}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: Provider
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, expand],
+ urlParameters: [$host, resourceProviderNamespace],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const listNextOperationSpec$4 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+const listAtTenantScopeNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [$host, nextLink],
+ headerParameters: [accept],
+ serializer: serializer$5
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+/** Class containing ProviderResourceTypes operations. */
+class ProviderResourceTypesImpl {
+ /**
+ * Initialize a new instance of the class ProviderResourceTypes class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * List the resource types for a specified resource provider.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param options The options parameters.
+ */
+ list(resourceProviderNamespace, options) {
+ return this.client.sendOperationRequest({ resourceProviderNamespace, options }, listOperationSpec$4);
+ }
+}
+// Operation Specifications
+const serializer$4 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const listOperationSpec$4 = {
+ path: "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/resourceTypes",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ProviderResourceTypeListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, expand],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceProviderNamespace
+ ],
+ headerParameters: [accept],
+ serializer: serializer$4
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing Resources operations. */
+class ResourcesImpl {
+ /**
+ * Initialize a new instance of the class Resources class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Get all the resources for a resource group.
+ * @param resourceGroupName The resource group with the resources to get.
+ * @param options The options parameters.
+ */
+ listByResourceGroup(resourceGroupName, options) {
+ const iter = this.listByResourceGroupPagingAll(resourceGroupName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listByResourceGroupPagingPage(resourceGroupName, options, settings);
+ }
+ };
+ }
+ listByResourceGroupPagingPage(resourceGroupName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listByResourceGroupPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listByResourceGroup(resourceGroupName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listByResourceGroupNext(resourceGroupName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listByResourceGroupPagingAll(resourceGroupName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listByResourceGroupPagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listByResourceGroupPagingPage(resourceGroupName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Get all the resources in a subscription.
+ * @param options The options parameters.
+ */
+ list(options) {
+ const iter = this.listPagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(options, settings);
+ }
+ };
+ }
+ listPagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_2, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ });
+ }
+ /**
+ * Get all the resources for a resource group.
+ * @param resourceGroupName The resource group with the resources to get.
+ * @param options The options parameters.
+ */
+ _listByResourceGroup(resourceGroupName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, options }, listByResourceGroupOperationSpec);
+ }
+ /**
+ * The resources to be moved must be in the same source resource group in the source subscription being
+ * used. The target resource group may be in a different subscription. When moving resources, both the
+ * source group and the target group are locked for the duration of the operation. Write and delete
+ * operations are blocked on the groups until the move completes.
+ * @param sourceResourceGroupName The name of the resource group from the source subscription
+ * containing the resources to be moved.
+ * @param parameters Parameters for moving resources.
+ * @param options The options parameters.
+ */
+ beginMoveResources(sourceResourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { sourceResourceGroupName, parameters, options },
+ spec: moveResourcesOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * The resources to be moved must be in the same source resource group in the source subscription being
+ * used. The target resource group may be in a different subscription. When moving resources, both the
+ * source group and the target group are locked for the duration of the operation. Write and delete
+ * operations are blocked on the groups until the move completes.
+ * @param sourceResourceGroupName The name of the resource group from the source subscription
+ * containing the resources to be moved.
+ * @param parameters Parameters for moving resources.
+ * @param options The options parameters.
+ */
+ beginMoveResourcesAndWait(sourceResourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginMoveResources(sourceResourceGroupName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * This operation checks whether the specified resources can be moved to the target. The resources to
+ * be moved must be in the same source resource group in the source subscription being used. The target
+ * resource group may be in a different subscription. If validation succeeds, it returns HTTP response
+ * code 204 (no content). If validation fails, it returns HTTP response code 409 (Conflict) with an
+ * error message. Retrieve the URL in the Location header value to check the result of the long-running
+ * operation.
+ * @param sourceResourceGroupName The name of the resource group from the source subscription
+ * containing the resources to be validated for move.
+ * @param parameters Parameters for moving resources.
+ * @param options The options parameters.
+ */
+ beginValidateMoveResources(sourceResourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { sourceResourceGroupName, parameters, options },
+ spec: validateMoveResourcesOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * This operation checks whether the specified resources can be moved to the target. The resources to
+ * be moved must be in the same source resource group in the source subscription being used. The target
+ * resource group may be in a different subscription. If validation succeeds, it returns HTTP response
+ * code 204 (no content). If validation fails, it returns HTTP response code 409 (Conflict) with an
+ * error message. Retrieve the URL in the Location header value to check the result of the long-running
+ * operation.
+ * @param sourceResourceGroupName The name of the resource group from the source subscription
+ * containing the resources to be validated for move.
+ * @param parameters Parameters for moving resources.
+ * @param options The options parameters.
+ */
+ beginValidateMoveResourcesAndWait(sourceResourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginValidateMoveResources(sourceResourceGroupName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Get all the resources in a subscription.
+ * @param options The options parameters.
+ */
+ _list(options) {
+ return this.client.sendOperationRequest({ options }, listOperationSpec$3);
+ }
+ /**
+ * Checks whether a resource exists.
+ * @param resourceGroupName The name of the resource group containing the resource to check. The name
+ * is case insensitive.
+ * @param resourceProviderNamespace The resource provider of the resource to check.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type.
+ * @param resourceName The name of the resource to check whether it exists.
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ checkExistence(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) {
+ return this.client.sendOperationRequest({
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName,
+ apiVersion,
+ options
+ }, checkExistenceOperationSpec$1);
+ }
+ /**
+ * Deletes a resource.
+ * @param resourceGroupName The name of the resource group that contains the resource to delete. The
+ * name is case insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type.
+ * @param resourceName The name of the resource to delete.
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ beginDelete(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: {
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName,
+ apiVersion,
+ options
+ },
+ spec: deleteOperationSpec$2
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Deletes a resource.
+ * @param resourceGroupName The name of the resource group that contains the resource to delete. The
+ * name is case insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type.
+ * @param resourceName The name of the resource to delete.
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ beginDeleteAndWait(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDelete(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Creates a resource.
+ * @param resourceGroupName The name of the resource group for the resource. The name is case
+ * insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type of the resource to create.
+ * @param resourceName The name of the resource to create.
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Parameters for creating or updating the resource.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdate(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: {
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName,
+ apiVersion,
+ parameters,
+ options
+ },
+ spec: createOrUpdateOperationSpec$2
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Creates a resource.
+ * @param resourceGroupName The name of the resource group for the resource. The name is case
+ * insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type of the resource to create.
+ * @param resourceName The name of the resource to create.
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Parameters for creating or updating the resource.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateAndWait(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdate(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Updates a resource.
+ * @param resourceGroupName The name of the resource group for the resource. The name is case
+ * insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type of the resource to update.
+ * @param resourceName The name of the resource to update.
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Parameters for updating the resource.
+ * @param options The options parameters.
+ */
+ beginUpdate(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: {
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName,
+ apiVersion,
+ parameters,
+ options
+ },
+ spec: updateOperationSpec$1
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Updates a resource.
+ * @param resourceGroupName The name of the resource group for the resource. The name is case
+ * insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type of the resource to update.
+ * @param resourceName The name of the resource to update.
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Parameters for updating the resource.
+ * @param options The options parameters.
+ */
+ beginUpdateAndWait(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginUpdate(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a resource.
+ * @param resourceGroupName The name of the resource group containing the resource to get. The name is
+ * case insensitive.
+ * @param resourceProviderNamespace The namespace of the resource provider.
+ * @param parentResourcePath The parent resource identity.
+ * @param resourceType The resource type of the resource.
+ * @param resourceName The name of the resource to get.
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ get(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) {
+ return this.client.sendOperationRequest({
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName,
+ apiVersion,
+ options
+ }, getOperationSpec$2);
+ }
+ /**
+ * Checks by ID whether a resource exists.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ checkExistenceById(resourceId, apiVersion, options) {
+ return this.client.sendOperationRequest({ resourceId, apiVersion, options }, checkExistenceByIdOperationSpec);
+ }
+ /**
+ * Deletes a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ beginDeleteById(resourceId, apiVersion, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceId, apiVersion, options },
+ spec: deleteByIdOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Deletes a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ beginDeleteByIdAndWait(resourceId, apiVersion, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDeleteById(resourceId, apiVersion, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Create a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Create or update resource parameters.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateById(resourceId, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceId, apiVersion, parameters, options },
+ spec: createOrUpdateByIdOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Create a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Create or update resource parameters.
+ * @param options The options parameters.
+ */
+ beginCreateOrUpdateByIdAndWait(resourceId, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginCreateOrUpdateById(resourceId, apiVersion, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Updates a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Update resource parameters.
+ * @param options The options parameters.
+ */
+ beginUpdateById(resourceId, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceId, apiVersion, parameters, options },
+ spec: updateByIdOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Updates a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param parameters Update resource parameters.
+ * @param options The options parameters.
+ */
+ beginUpdateByIdAndWait(resourceId, apiVersion, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginUpdateById(resourceId, apiVersion, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a resource by ID.
+ * @param resourceId The fully qualified ID of the resource, including the resource name and resource
+ * type. Use the format,
+ * /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
+ * @param apiVersion The API version to use for the operation.
+ * @param options The options parameters.
+ */
+ getById(resourceId, apiVersion, options) {
+ return this.client.sendOperationRequest({ resourceId, apiVersion, options }, getByIdOperationSpec);
+ }
+ /**
+ * ListByResourceGroupNext
+ * @param resourceGroupName The resource group with the resources to get.
+ * @param nextLink The nextLink from the previous successful call to the ListByResourceGroup method.
+ * @param options The options parameters.
+ */
+ _listByResourceGroupNext(resourceGroupName, nextLink, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, nextLink, options }, listByResourceGroupNextOperationSpec);
+ }
+ /**
+ * ListNext
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listNextOperationSpec$3);
+ }
+}
+// Operation Specifications
+const serializer$3 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const listByResourceGroupOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/resources",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [
+ apiVersion,
+ filter,
+ top,
+ expand
+ ],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const moveResourcesOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources",
+ httpMethod: "POST",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters4,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ sourceResourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const validateMoveResourcesOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/validateMoveResources",
+ httpMethod: "POST",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters4,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ sourceResourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const listOperationSpec$3 = {
+ path: "/subscriptions/{subscriptionId}/resources",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [
+ apiVersion,
+ filter,
+ top,
+ expand
+ ],
+ urlParameters: [$host, subscriptionId],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const checkExistenceOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const deleteOperationSpec$2 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const createOrUpdateOperationSpec$2 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ 201: {
+ bodyMapper: GenericResource
+ },
+ 202: {
+ bodyMapper: GenericResource
+ },
+ 204: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters5,
+ queryParameters: [apiVersion1],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const updateOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}",
+ httpMethod: "PATCH",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ 201: {
+ bodyMapper: GenericResource
+ },
+ 202: {
+ bodyMapper: GenericResource
+ },
+ 204: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters5,
+ queryParameters: [apiVersion1],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const getOperationSpec$2 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName,
+ resourceProviderNamespace,
+ parentResourcePath,
+ resourceType,
+ resourceName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const checkExistenceByIdOperationSpec = {
+ path: "/{resourceId}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [$host, resourceId],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const deleteByIdOperationSpec = {
+ path: "/{resourceId}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [$host, resourceId],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const createOrUpdateByIdOperationSpec = {
+ path: "/{resourceId}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ 201: {
+ bodyMapper: GenericResource
+ },
+ 202: {
+ bodyMapper: GenericResource
+ },
+ 204: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters5,
+ queryParameters: [apiVersion1],
+ urlParameters: [$host, resourceId],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const updateByIdOperationSpec = {
+ path: "/{resourceId}",
+ httpMethod: "PATCH",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ 201: {
+ bodyMapper: GenericResource
+ },
+ 202: {
+ bodyMapper: GenericResource
+ },
+ 204: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters5,
+ queryParameters: [apiVersion1],
+ urlParameters: [$host, resourceId],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$3
+};
+const getByIdOperationSpec = {
+ path: "/{resourceId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: GenericResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion1],
+ urlParameters: [$host, resourceId],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const listByResourceGroupNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+const listNextOperationSpec$3 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$3
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing ResourceGroups operations. */
+class ResourceGroupsImpl {
+ /**
+ * Initialize a new instance of the class ResourceGroups class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Gets all the resource groups for a subscription.
+ * @param options The options parameters.
+ */
+ list(options) {
+ const iter = this.listPagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(options, settings);
+ }
+ };
+ }
+ listPagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Checks whether a resource group exists.
+ * @param resourceGroupName The name of the resource group to check. The name is case insensitive.
+ * @param options The options parameters.
+ */
+ checkExistence(resourceGroupName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, options }, checkExistenceOperationSpec);
+ }
+ /**
+ * Creates or updates a resource group.
+ * @param resourceGroupName The name of the resource group to create or update. Can include
+ * alphanumeric, underscore, parentheses, hyphen, period (except at end), and Unicode characters that
+ * match the allowed characters.
+ * @param parameters Parameters supplied to the create or update a resource group.
+ * @param options The options parameters.
+ */
+ createOrUpdate(resourceGroupName, parameters, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, parameters, options }, createOrUpdateOperationSpec$1);
+ }
+ /**
+ * When you delete a resource group, all of its resources are also deleted. Deleting a resource group
+ * deletes all of its template deployments and currently stored operations.
+ * @param resourceGroupName The name of the resource group to delete. The name is case insensitive.
+ * @param options The options parameters.
+ */
+ beginDelete(resourceGroupName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, options },
+ spec: deleteOperationSpec$1
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * When you delete a resource group, all of its resources are also deleted. Deleting a resource group
+ * deletes all of its template deployments and currently stored operations.
+ * @param resourceGroupName The name of the resource group to delete. The name is case insensitive.
+ * @param options The options parameters.
+ */
+ beginDeleteAndWait(resourceGroupName, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginDelete(resourceGroupName, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets a resource group.
+ * @param resourceGroupName The name of the resource group to get. The name is case insensitive.
+ * @param options The options parameters.
+ */
+ get(resourceGroupName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, options }, getOperationSpec$1);
+ }
+ /**
+ * Resource groups can be updated through a simple PATCH operation to a group address. The format of
+ * the request is the same as that for creating a resource group. If a field is unspecified, the
+ * current value is retained.
+ * @param resourceGroupName The name of the resource group to update. The name is case insensitive.
+ * @param parameters Parameters supplied to update a resource group.
+ * @param options The options parameters.
+ */
+ update(resourceGroupName, parameters, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, parameters, options }, updateOperationSpec);
+ }
+ /**
+ * Captures the specified resource group as a template.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param parameters Parameters for exporting the template.
+ * @param options The options parameters.
+ */
+ beginExportTemplate(resourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const directSendOperation = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ return this.client.sendOperationRequest(args, spec);
+ });
+ const sendOperationFn = (args, spec) => tslib.__awaiter(this, void 0, void 0, function* () {
+ var _a;
+ let currentRawResponse = undefined;
+ const providedCallback = (_a = args.options) === null || _a === void 0 ? void 0 : _a.onResponse;
+ const callback = (rawResponse, flatResponse) => {
+ currentRawResponse = rawResponse;
+ providedCallback === null || providedCallback === void 0 ? void 0 : providedCallback(rawResponse, flatResponse);
+ };
+ const updatedArgs = Object.assign(Object.assign({}, args), { options: Object.assign(Object.assign({}, args.options), { onResponse: callback }) });
+ const flatResponse = yield directSendOperation(updatedArgs, spec);
+ return {
+ flatResponse,
+ rawResponse: {
+ statusCode: currentRawResponse.status,
+ body: currentRawResponse.parsedBody,
+ headers: currentRawResponse.headers.toJSON()
+ }
+ };
+ });
+ const lro = createLroSpec({
+ sendOperationFn,
+ args: { resourceGroupName, parameters, options },
+ spec: exportTemplateOperationSpec
+ });
+ const poller = yield coreLro.createHttpPoller(lro, {
+ restoreFrom: options === null || options === void 0 ? void 0 : options.resumeFrom,
+ intervalInMs: options === null || options === void 0 ? void 0 : options.updateIntervalInMs,
+ resourceLocationConfig: "location"
+ });
+ yield poller.poll();
+ return poller;
+ });
+ }
+ /**
+ * Captures the specified resource group as a template.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param parameters Parameters for exporting the template.
+ * @param options The options parameters.
+ */
+ beginExportTemplateAndWait(resourceGroupName, parameters, options) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const poller = yield this.beginExportTemplate(resourceGroupName, parameters, options);
+ return poller.pollUntilDone();
+ });
+ }
+ /**
+ * Gets all the resource groups for a subscription.
+ * @param options The options parameters.
+ */
+ _list(options) {
+ return this.client.sendOperationRequest({ options }, listOperationSpec$2);
+ }
+ /**
+ * ListNext
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listNextOperationSpec$2);
+ }
+}
+// Operation Specifications
+const serializer$2 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const checkExistenceOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}",
+ httpMethod: "HEAD",
+ responses: {
+ 204: {},
+ 404: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$2
+};
+const createOrUpdateOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroup
+ },
+ 201: {
+ bodyMapper: ResourceGroup
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters6,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$2
+};
+const deleteOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 201: {},
+ 202: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, forceDeletionTypes],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$2
+};
+const getOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroup
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$2
+};
+const updateOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}",
+ httpMethod: "PATCH",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroup
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters7,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$2
+};
+const exportTemplateOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/exportTemplate",
+ httpMethod: "POST",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroupExportResult
+ },
+ 201: {
+ bodyMapper: ResourceGroupExportResult
+ },
+ 202: {
+ bodyMapper: ResourceGroupExportResult
+ },
+ 204: {
+ bodyMapper: ResourceGroupExportResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters8,
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ resourceGroupName1
+ ],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$2
+};
+const listOperationSpec$2 = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroupListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, filter, top],
+ urlParameters: [$host, subscriptionId],
+ headerParameters: [accept],
+ serializer: serializer$2
+};
+const listNextOperationSpec$2 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: ResourceGroupListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$2
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing TagsOperations operations. */
+class TagsOperationsImpl {
+ /**
+ * Initialize a new instance of the class TagsOperations class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * This operation performs a union of predefined tags, resource tags, resource group tags and
+ * subscription tags, and returns a summary of usage for each tag name and value under the given
+ * subscription. In case of a large number of tags, this operation may return a previously cached
+ * result.
+ * @param options The options parameters.
+ */
+ list(options) {
+ const iter = this.listPagingAll(options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(options, settings);
+ }
+ };
+ }
+ listPagingPage(options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * This operation allows deleting a value from the list of predefined values for an existing predefined
+ * tag name. The value being deleted must not be in use as a tag value for the given tag name for any
+ * resource.
+ * @param tagName The name of the tag.
+ * @param tagValue The value of the tag to delete.
+ * @param options The options parameters.
+ */
+ deleteValue(tagName, tagValue, options) {
+ return this.client.sendOperationRequest({ tagName, tagValue, options }, deleteValueOperationSpec);
+ }
+ /**
+ * This operation allows adding a value to the list of predefined values for an existing predefined tag
+ * name. A tag value can have a maximum of 256 characters.
+ * @param tagName The name of the tag.
+ * @param tagValue The value of the tag to create.
+ * @param options The options parameters.
+ */
+ createOrUpdateValue(tagName, tagValue, options) {
+ return this.client.sendOperationRequest({ tagName, tagValue, options }, createOrUpdateValueOperationSpec);
+ }
+ /**
+ * This operation allows adding a name to the list of predefined tag names for the given subscription.
+ * A tag name can have a maximum of 512 characters and is case-insensitive. Tag names cannot have the
+ * following prefixes which are reserved for Azure use: 'microsoft', 'azure', 'windows'.
+ * @param tagName The name of the tag to create.
+ * @param options The options parameters.
+ */
+ createOrUpdate(tagName, options) {
+ return this.client.sendOperationRequest({ tagName, options }, createOrUpdateOperationSpec);
+ }
+ /**
+ * This operation allows deleting a name from the list of predefined tag names for the given
+ * subscription. The name being deleted must not be in use as a tag name for any resource. All
+ * predefined values for the given name must have already been deleted.
+ * @param tagName The name of the tag.
+ * @param options The options parameters.
+ */
+ delete(tagName, options) {
+ return this.client.sendOperationRequest({ tagName, options }, deleteOperationSpec);
+ }
+ /**
+ * This operation performs a union of predefined tags, resource tags, resource group tags and
+ * subscription tags, and returns a summary of usage for each tag name and value under the given
+ * subscription. In case of a large number of tags, this operation may return a previously cached
+ * result.
+ * @param options The options parameters.
+ */
+ _list(options) {
+ return this.client.sendOperationRequest({ options }, listOperationSpec$1);
+ }
+ /**
+ * This operation allows adding or replacing the entire set of tags on the specified resource or
+ * subscription. The specified entity can have a maximum of 50 tags.
+ * @param scope The resource scope.
+ * @param parameters Wrapper resource for tags API requests and responses.
+ * @param options The options parameters.
+ */
+ createOrUpdateAtScope(scope, parameters, options) {
+ return this.client.sendOperationRequest({ scope, parameters, options }, createOrUpdateAtScopeOperationSpec);
+ }
+ /**
+ * This operation allows replacing, merging or selectively deleting tags on the specified resource or
+ * subscription. The specified entity can have a maximum of 50 tags at the end of the operation. The
+ * 'replace' option replaces the entire set of existing tags with a new set. The 'merge' option allows
+ * adding tags with new names and updating the values of tags with existing names. The 'delete' option
+ * allows selectively deleting tags based on given names or name/value pairs.
+ * @param scope The resource scope.
+ * @param parameters Wrapper resource for tags patch API request only.
+ * @param options The options parameters.
+ */
+ updateAtScope(scope, parameters, options) {
+ return this.client.sendOperationRequest({ scope, parameters, options }, updateAtScopeOperationSpec);
+ }
+ /**
+ * Gets the entire set of tags on a resource or subscription.
+ * @param scope The resource scope.
+ * @param options The options parameters.
+ */
+ getAtScope(scope, options) {
+ return this.client.sendOperationRequest({ scope, options }, getAtScopeOperationSpec$1);
+ }
+ /**
+ * Deletes the entire set of tags on a resource or subscription.
+ * @param scope The resource scope.
+ * @param options The options parameters.
+ */
+ deleteAtScope(scope, options) {
+ return this.client.sendOperationRequest({ scope, options }, deleteAtScopeOperationSpec);
+ }
+ /**
+ * ListNext
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(nextLink, options) {
+ return this.client.sendOperationRequest({ nextLink, options }, listNextOperationSpec$1);
+ }
+}
+// Operation Specifications
+const serializer$1 = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const deleteValueOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ tagName,
+ tagValue
+ ],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const createOrUpdateValueOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: TagValue
+ },
+ 201: {
+ bodyMapper: TagValue
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ tagName,
+ tagValue
+ ],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const createOrUpdateOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/tagNames/{tagName}",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: TagDetails
+ },
+ 201: {
+ bodyMapper: TagDetails
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ tagName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const deleteOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/tagNames/{tagName}",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ 204: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ subscriptionId,
+ tagName
+ ],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const listOperationSpec$1 = {
+ path: "/subscriptions/{subscriptionId}/tagNames",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: TagsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, subscriptionId],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const createOrUpdateAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/tags/default",
+ httpMethod: "PUT",
+ responses: {
+ 200: {
+ bodyMapper: TagsResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters9,
+ queryParameters: [apiVersion],
+ urlParameters: [$host, scope],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$1
+};
+const updateAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/tags/default",
+ httpMethod: "PATCH",
+ responses: {
+ 200: {
+ bodyMapper: TagsResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ requestBody: parameters10,
+ queryParameters: [apiVersion],
+ urlParameters: [$host, scope],
+ headerParameters: [accept, contentType],
+ mediaType: "json",
+ serializer: serializer$1
+};
+const getAtScopeOperationSpec$1 = {
+ path: "/{scope}/providers/Microsoft.Resources/tags/default",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: TagsResource
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, scope],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const deleteAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/tags/default",
+ httpMethod: "DELETE",
+ responses: {
+ 200: {},
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [$host, scope],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+const listNextOperationSpec$1 = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: TagsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer: serializer$1
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+///
+/** Class containing DeploymentOperations operations. */
+class DeploymentOperationsImpl {
+ /**
+ * Initialize a new instance of the class DeploymentOperations class.
+ * @param client Reference to the service client
+ */
+ constructor(client) {
+ this.client = client;
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ listAtScope(scope, deploymentName, options) {
+ const iter = this.listAtScopePagingAll(scope, deploymentName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtScopePagingPage(scope, deploymentName, options, settings);
+ }
+ };
+ }
+ listAtScopePagingPage(scope, deploymentName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtScope(scope, deploymentName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtScopeNext(scope, deploymentName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtScopePagingAll(scope, deploymentName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtScopePagingAll_1() {
+ var e_1, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtScopePagingPage(scope, deploymentName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ });
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ listAtTenantScope(deploymentName, options) {
+ const iter = this.listAtTenantScopePagingAll(deploymentName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtTenantScopePagingPage(deploymentName, options, settings);
+ }
+ };
+ }
+ listAtTenantScopePagingPage(deploymentName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScope(deploymentName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtTenantScopeNext(deploymentName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtTenantScopePagingAll(deploymentName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtTenantScopePagingAll_1() {
+ var e_2, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtTenantScopePagingPage(deploymentName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ });
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ listAtManagementGroupScope(groupId, deploymentName, options) {
+ const iter = this.listAtManagementGroupScopePagingAll(groupId, deploymentName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtManagementGroupScopePagingPage(groupId, deploymentName, options, settings);
+ }
+ };
+ }
+ listAtManagementGroupScopePagingPage(groupId, deploymentName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtManagementGroupScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtManagementGroupScope(groupId, deploymentName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtManagementGroupScopeNext(groupId, deploymentName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtManagementGroupScopePagingAll(groupId, deploymentName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtManagementGroupScopePagingAll_1() {
+ var e_3, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtManagementGroupScopePagingPage(groupId, deploymentName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_3) throw e_3.error; }
+ }
+ });
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ listAtSubscriptionScope(deploymentName, options) {
+ const iter = this.listAtSubscriptionScopePagingAll(deploymentName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listAtSubscriptionScopePagingPage(deploymentName, options, settings);
+ }
+ };
+ }
+ listAtSubscriptionScopePagingPage(deploymentName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtSubscriptionScopePagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._listAtSubscriptionScope(deploymentName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listAtSubscriptionScopeNext(deploymentName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listAtSubscriptionScopePagingAll(deploymentName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listAtSubscriptionScopePagingAll_1() {
+ var e_4, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listAtSubscriptionScopePagingPage(deploymentName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_4) throw e_4.error; }
+ }
+ });
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ list(resourceGroupName, deploymentName, options) {
+ const iter = this.listPagingAll(resourceGroupName, deploymentName, options);
+ return {
+ next() {
+ return iter.next();
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ byPage: (settings) => {
+ if (settings === null || settings === void 0 ? void 0 : settings.maxPageSize) {
+ throw new Error("maxPageSize is not supported by this operation.");
+ }
+ return this.listPagingPage(resourceGroupName, deploymentName, options, settings);
+ }
+ };
+ }
+ listPagingPage(resourceGroupName, deploymentName, options, settings) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingPage_1() {
+ let result;
+ let continuationToken = settings === null || settings === void 0 ? void 0 : settings.continuationToken;
+ if (!continuationToken) {
+ result = yield tslib.__await(this._list(resourceGroupName, deploymentName, options));
+ let page = result.value || [];
+ continuationToken = result.nextLink;
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ while (continuationToken) {
+ result = yield tslib.__await(this._listNext(resourceGroupName, deploymentName, continuationToken, options));
+ continuationToken = result.nextLink;
+ let page = result.value || [];
+ setContinuationToken(page, continuationToken);
+ yield yield tslib.__await(page);
+ }
+ });
+ }
+ listPagingAll(resourceGroupName, deploymentName, options) {
+ return tslib.__asyncGenerator(this, arguments, function* listPagingAll_1() {
+ var e_5, _a;
+ try {
+ for (var _b = tslib.__asyncValues(this.listPagingPage(resourceGroupName, deploymentName, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
+ const page = _c.value;
+ yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
+ }
+ }
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
+ }
+ finally { if (e_5) throw e_5.error; }
+ }
+ });
+ }
+ /**
+ * Gets a deployments operation.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param operationId The ID of the operation to get.
+ * @param options The options parameters.
+ */
+ getAtScope(scope, deploymentName, operationId, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, operationId, options }, getAtScopeOperationSpec);
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ _listAtScope(scope, deploymentName, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, options }, listAtScopeOperationSpec);
+ }
+ /**
+ * Gets a deployments operation.
+ * @param deploymentName The name of the deployment.
+ * @param operationId The ID of the operation to get.
+ * @param options The options parameters.
+ */
+ getAtTenantScope(deploymentName, operationId, options) {
+ return this.client.sendOperationRequest({ deploymentName, operationId, options }, getAtTenantScopeOperationSpec);
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ _listAtTenantScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, listAtTenantScopeOperationSpec);
+ }
+ /**
+ * Gets a deployments operation.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param operationId The ID of the operation to get.
+ * @param options The options parameters.
+ */
+ getAtManagementGroupScope(groupId, deploymentName, operationId, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, operationId, options }, getAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ _listAtManagementGroupScope(groupId, deploymentName, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, options }, listAtManagementGroupScopeOperationSpec);
+ }
+ /**
+ * Gets a deployments operation.
+ * @param deploymentName The name of the deployment.
+ * @param operationId The ID of the operation to get.
+ * @param options The options parameters.
+ */
+ getAtSubscriptionScope(deploymentName, operationId, options) {
+ return this.client.sendOperationRequest({ deploymentName, operationId, options }, getAtSubscriptionScopeOperationSpec);
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ _listAtSubscriptionScope(deploymentName, options) {
+ return this.client.sendOperationRequest({ deploymentName, options }, listAtSubscriptionScopeOperationSpec);
+ }
+ /**
+ * Gets a deployments operation.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param operationId The ID of the operation to get.
+ * @param options The options parameters.
+ */
+ get(resourceGroupName, deploymentName, operationId, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, operationId, options }, getOperationSpec);
+ }
+ /**
+ * Gets all deployments operations for a deployment.
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param options The options parameters.
+ */
+ _list(resourceGroupName, deploymentName, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, options }, listOperationSpec);
+ }
+ /**
+ * ListAtScopeNext
+ * @param scope The resource scope.
+ * @param deploymentName The name of the deployment.
+ * @param nextLink The nextLink from the previous successful call to the ListAtScope method.
+ * @param options The options parameters.
+ */
+ _listAtScopeNext(scope, deploymentName, nextLink, options) {
+ return this.client.sendOperationRequest({ scope, deploymentName, nextLink, options }, listAtScopeNextOperationSpec);
+ }
+ /**
+ * ListAtTenantScopeNext
+ * @param deploymentName The name of the deployment.
+ * @param nextLink The nextLink from the previous successful call to the ListAtTenantScope method.
+ * @param options The options parameters.
+ */
+ _listAtTenantScopeNext(deploymentName, nextLink, options) {
+ return this.client.sendOperationRequest({ deploymentName, nextLink, options }, listAtTenantScopeNextOperationSpec);
+ }
+ /**
+ * ListAtManagementGroupScopeNext
+ * @param groupId The management group ID.
+ * @param deploymentName The name of the deployment.
+ * @param nextLink The nextLink from the previous successful call to the ListAtManagementGroupScope
+ * method.
+ * @param options The options parameters.
+ */
+ _listAtManagementGroupScopeNext(groupId, deploymentName, nextLink, options) {
+ return this.client.sendOperationRequest({ groupId, deploymentName, nextLink, options }, listAtManagementGroupScopeNextOperationSpec);
+ }
+ /**
+ * ListAtSubscriptionScopeNext
+ * @param deploymentName The name of the deployment.
+ * @param nextLink The nextLink from the previous successful call to the ListAtSubscriptionScope
+ * method.
+ * @param options The options parameters.
+ */
+ _listAtSubscriptionScopeNext(deploymentName, nextLink, options) {
+ return this.client.sendOperationRequest({ deploymentName, nextLink, options }, listAtSubscriptionScopeNextOperationSpec);
+ }
+ /**
+ * ListNext
+ * @param resourceGroupName The name of the resource group. The name is case insensitive.
+ * @param deploymentName The name of the deployment.
+ * @param nextLink The nextLink from the previous successful call to the List method.
+ * @param options The options parameters.
+ */
+ _listNext(resourceGroupName, deploymentName, nextLink, options) {
+ return this.client.sendOperationRequest({ resourceGroupName, deploymentName, nextLink, options }, listNextOperationSpec);
+ }
+}
+// Operation Specifications
+const serializer = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
+const getAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperation
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName,
+ operationId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtScopeOperationSpec = {
+ path: "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, top],
+ urlParameters: [
+ $host,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const getAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperation
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ operationId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtTenantScopeOperationSpec = {
+ path: "/providers/Microsoft.Resources/deployments/{deploymentName}/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, top],
+ urlParameters: [$host, deploymentName],
+ headerParameters: [accept],
+ serializer
+};
+const getAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperation
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId,
+ operationId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtManagementGroupScopeOperationSpec = {
+ path: "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, top],
+ urlParameters: [
+ $host,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const getAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperation
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ operationId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtSubscriptionScopeOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, top],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const getOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations/{operationId}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperation
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName,
+ operationId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listOperationSpec = {
+ path: "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ queryParameters: [apiVersion, top],
+ urlParameters: [
+ $host,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtScopeNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ scope,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtTenantScopeNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ deploymentName
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtManagementGroupScopeNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ deploymentName,
+ groupId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listAtSubscriptionScopeNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ deploymentName,
+ subscriptionId
+ ],
+ headerParameters: [accept],
+ serializer
+};
+const listNextOperationSpec = {
+ path: "{nextLink}",
+ httpMethod: "GET",
+ responses: {
+ 200: {
+ bodyMapper: DeploymentOperationsListResult
+ },
+ default: {
+ bodyMapper: CloudError
+ }
+ },
+ urlParameters: [
+ $host,
+ nextLink,
+ deploymentName,
+ subscriptionId,
+ resourceGroupName
+ ],
+ headerParameters: [accept],
+ serializer
+};
+
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * Code generated by Microsoft (R) AutoRest Code Generator.
+ * Changes may cause incorrect behavior and will be lost if the code is regenerated.
+ */
+class ResourceManagementClient extends coreClient__namespace.ServiceClient {
+ /**
+ * Initializes a new instance of the ResourceManagementClient class.
+ * @param credentials Subscription credentials which uniquely identify client subscription.
+ * @param subscriptionId The Microsoft Azure subscription ID.
+ * @param options The parameter options
+ */
+ constructor(credentials, subscriptionId, options) {
+ var _a, _b, _c;
+ if (credentials === undefined) {
+ throw new Error("'credentials' cannot be null");
+ }
+ if (subscriptionId === undefined) {
+ throw new Error("'subscriptionId' cannot be null");
+ }
+ // Initializing default values for options
+ if (!options) {
+ options = {};
+ }
+ const defaults = {
+ requestContentType: "application/json; charset=utf-8",
+ credential: credentials
+ };
+ const packageDetails = `azsdk-js-arm-resources/5.2.0`;
+ const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
+ ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
+ : `${packageDetails}`;
+ const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
+ userAgentPrefix
+ }, endpoint: (_b = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri) !== null && _b !== void 0 ? _b : "https://management.azure.com" });
+ super(optionsWithDefaults);
+ let bearerTokenAuthenticationPolicyFound = false;
+ if ((options === null || options === void 0 ? void 0 : options.pipeline) && options.pipeline.getOrderedPolicies().length > 0) {
+ const pipelinePolicies = options.pipeline.getOrderedPolicies();
+ bearerTokenAuthenticationPolicyFound = pipelinePolicies.some((pipelinePolicy) => pipelinePolicy.name ===
+ coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName);
+ }
+ if (!options ||
+ !options.pipeline ||
+ options.pipeline.getOrderedPolicies().length == 0 ||
+ !bearerTokenAuthenticationPolicyFound) {
+ this.pipeline.removePolicy({
+ name: coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName
+ });
+ this.pipeline.addPolicy(coreRestPipeline__namespace.bearerTokenAuthenticationPolicy({
+ credential: credentials,
+ scopes: (_c = optionsWithDefaults.credentialScopes) !== null && _c !== void 0 ? _c : `${optionsWithDefaults.endpoint}/.default`,
+ challengeCallbacks: {
+ authorizeRequestOnChallenge: coreClient__namespace.authorizeRequestOnClaimChallenge
+ }
+ }));
+ }
+ // Parameter assignments
+ this.subscriptionId = subscriptionId;
+ // Assigning values to Constant parameters
+ this.$host = options.$host || "https://management.azure.com";
+ this.apiVersion = options.apiVersion || "2021-04-01";
+ this.operations = new OperationsImpl(this);
+ this.deployments = new DeploymentsImpl(this);
+ this.providers = new ProvidersImpl(this);
+ this.providerResourceTypes = new ProviderResourceTypesImpl(this);
+ this.resources = new ResourcesImpl(this);
+ this.resourceGroups = new ResourceGroupsImpl(this);
+ this.tagsOperations = new TagsOperationsImpl(this);
+ this.deploymentOperations = new DeploymentOperationsImpl(this);
+ this.addCustomApiVersionPolicy(options.apiVersion);
+ }
+ /** A function that adds a policy that sets the api-version (or equivalent) to reflect the library version. */
+ addCustomApiVersionPolicy(apiVersion) {
+ if (!apiVersion) {
+ return;
+ }
+ const apiVersionPolicy = {
+ name: "CustomApiVersionPolicy",
+ sendRequest(request, next) {
+ return tslib.__awaiter(this, void 0, void 0, function* () {
+ const param = request.url.split("?");
+ if (param.length > 1) {
+ const newParams = param[1].split("&").map((item) => {
+ if (item.indexOf("api-version") > -1) {
+ return "api-version=" + apiVersion;
+ }
+ else {
+ return item;
+ }
+ });
+ request.url = param[0] + "?" + newParams.join("&");
+ }
+ return next(request);
+ });
+ }
+ };
+ this.pipeline.addPolicy(apiVersionPolicy);
+ }
+}
+
+exports.ResourceManagementClient = ResourceManagementClient;
+exports.getContinuationToken = getContinuationToken;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 9729:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var coreRestPipeline = __nccwpck_require__(8121);
+var logger$1 = __nccwpck_require__(3233);
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Encodes a byte array in base64 format.
+ * @param value - the Uint8Aray to encode
+ * @internal
+ */
+function encodeByteArray(value) {
+ // Buffer.from accepts | -- the TypeScript definition is off here
+ // https://nodejs.org/api/buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length
+ const bufferValue = value instanceof Buffer ? value : Buffer.from(value.buffer);
+ return bufferValue.toString("base64");
+}
+/**
+ * Decodes a base64 string into a byte array.
+ * @param value - the base64 string to decode
+ * @internal
+ */
+function decodeString(value) {
+ return Buffer.from(value, "base64");
+}
+/**
+ * Decodes a base64 string into a string.
+ * @param value - the base64 string to decode
+ * @internal
+ */
+function decodeStringToString(value) {
+ return Buffer.from(value, "base64").toString();
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Default key used to access the XML attributes.
+ */
+const XML_ATTRKEY = "$";
+/**
+ * Default key used to access the XML value content.
+ */
+const XML_CHARKEY = "_";
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * A type guard for a primitive response body.
+ * @param value - Value to test
+ *
+ * @internal
+ */
+function isPrimitiveBody(value, mapperTypeName) {
+ return (mapperTypeName !== "Composite" &&
+ mapperTypeName !== "Dictionary" &&
+ (typeof value === "string" ||
+ typeof value === "number" ||
+ typeof value === "boolean" ||
+ (mapperTypeName === null || mapperTypeName === void 0 ? void 0 : mapperTypeName.match(/^(Date|DateTime|DateTimeRfc1123|UnixTime|ByteArray|Base64Url)$/i)) !==
+ null ||
+ value === undefined ||
+ value === null));
+}
+const validateISODuration = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
+/**
+ * Returns true if the given string is in ISO 8601 format.
+ * @param value - The value to be validated for ISO 8601 duration format.
+ * @internal
+ */
+function isDuration(value) {
+ return validateISODuration.test(value);
+}
+const validUuidRegex = /^[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}$/i;
+/**
+ * Returns true if the provided uuid is valid.
+ *
+ * @param uuid - The uuid that needs to be validated.
+ *
+ * @internal
+ */
+function isValidUuid(uuid) {
+ return validUuidRegex.test(uuid);
+}
+/**
+ * Maps the response as follows:
+ * - wraps the response body if needed (typically if its type is primitive).
+ * - returns null if the combination of the headers and the body is empty.
+ * - otherwise, returns the combination of the headers and the body.
+ *
+ * @param responseObject - a representation of the parsed response
+ * @returns the response that will be returned to the user which can be null and/or wrapped
+ *
+ * @internal
+ */
+function handleNullableResponseAndWrappableBody(responseObject) {
+ const combinedHeadersAndBody = Object.assign(Object.assign({}, responseObject.headers), responseObject.body);
+ if (responseObject.hasNullableType &&
+ Object.getOwnPropertyNames(combinedHeadersAndBody).length === 0) {
+ return responseObject.shouldWrapBody ? { body: null } : null;
+ }
+ else {
+ return responseObject.shouldWrapBody
+ ? Object.assign(Object.assign({}, responseObject.headers), { body: responseObject.body }) : combinedHeadersAndBody;
+ }
+}
+/**
+ * Take a `FullOperationResponse` and turn it into a flat
+ * response object to hand back to the consumer.
+ * @param fullResponse - The processed response from the operation request
+ * @param responseSpec - The response map from the OperationSpec
+ *
+ * @internal
+ */
+function flattenResponse(fullResponse, responseSpec) {
+ var _a, _b;
+ const parsedHeaders = fullResponse.parsedHeaders;
+ // head methods never have a body, but we return a boolean set to body property
+ // to indicate presence/absence of the resource
+ if (fullResponse.request.method === "HEAD") {
+ return Object.assign(Object.assign({}, parsedHeaders), { body: fullResponse.parsedBody });
+ }
+ const bodyMapper = responseSpec && responseSpec.bodyMapper;
+ const isNullable = Boolean(bodyMapper === null || bodyMapper === void 0 ? void 0 : bodyMapper.nullable);
+ const expectedBodyTypeName = bodyMapper === null || bodyMapper === void 0 ? void 0 : bodyMapper.type.name;
+ /** If the body is asked for, we look at the expected body type to handle it */
+ if (expectedBodyTypeName === "Stream") {
+ return Object.assign(Object.assign({}, parsedHeaders), { blobBody: fullResponse.blobBody, readableStreamBody: fullResponse.readableStreamBody });
+ }
+ const modelProperties = (expectedBodyTypeName === "Composite" &&
+ bodyMapper.type.modelProperties) ||
+ {};
+ const isPageableResponse = Object.keys(modelProperties).some((k) => modelProperties[k].serializedName === "");
+ if (expectedBodyTypeName === "Sequence" || isPageableResponse) {
+ const arrayResponse = (_a = fullResponse.parsedBody) !== null && _a !== void 0 ? _a : [];
+ for (const key of Object.keys(modelProperties)) {
+ if (modelProperties[key].serializedName) {
+ arrayResponse[key] = (_b = fullResponse.parsedBody) === null || _b === void 0 ? void 0 : _b[key];
+ }
+ }
+ if (parsedHeaders) {
+ for (const key of Object.keys(parsedHeaders)) {
+ arrayResponse[key] = parsedHeaders[key];
+ }
+ }
+ return isNullable &&
+ !fullResponse.parsedBody &&
+ !parsedHeaders &&
+ Object.getOwnPropertyNames(modelProperties).length === 0
+ ? null
+ : arrayResponse;
+ }
+ return handleNullableResponseAndWrappableBody({
+ body: fullResponse.parsedBody,
+ headers: parsedHeaders,
+ hasNullableType: isNullable,
+ shouldWrapBody: isPrimitiveBody(fullResponse.parsedBody, expectedBodyTypeName),
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+class SerializerImpl {
+ constructor(modelMappers = {}, isXML = false) {
+ this.modelMappers = modelMappers;
+ this.isXML = isXML;
+ }
+ /**
+ * @deprecated Removing the constraints validation on client side.
+ */
+ validateConstraints(mapper, value, objectName) {
+ const failValidation = (constraintName, constraintValue) => {
+ throw new Error(`"${objectName}" with value "${value}" should satisfy the constraint "${constraintName}": ${constraintValue}.`);
+ };
+ if (mapper.constraints && value !== undefined && value !== null) {
+ const { ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems, } = mapper.constraints;
+ if (ExclusiveMaximum !== undefined && value >= ExclusiveMaximum) {
+ failValidation("ExclusiveMaximum", ExclusiveMaximum);
+ }
+ if (ExclusiveMinimum !== undefined && value <= ExclusiveMinimum) {
+ failValidation("ExclusiveMinimum", ExclusiveMinimum);
+ }
+ if (InclusiveMaximum !== undefined && value > InclusiveMaximum) {
+ failValidation("InclusiveMaximum", InclusiveMaximum);
+ }
+ if (InclusiveMinimum !== undefined && value < InclusiveMinimum) {
+ failValidation("InclusiveMinimum", InclusiveMinimum);
+ }
+ if (MaxItems !== undefined && value.length > MaxItems) {
+ failValidation("MaxItems", MaxItems);
+ }
+ if (MaxLength !== undefined && value.length > MaxLength) {
+ failValidation("MaxLength", MaxLength);
+ }
+ if (MinItems !== undefined && value.length < MinItems) {
+ failValidation("MinItems", MinItems);
+ }
+ if (MinLength !== undefined && value.length < MinLength) {
+ failValidation("MinLength", MinLength);
+ }
+ if (MultipleOf !== undefined && value % MultipleOf !== 0) {
+ failValidation("MultipleOf", MultipleOf);
+ }
+ if (Pattern) {
+ const pattern = typeof Pattern === "string" ? new RegExp(Pattern) : Pattern;
+ if (typeof value !== "string" || value.match(pattern) === null) {
+ failValidation("Pattern", Pattern);
+ }
+ }
+ if (UniqueItems &&
+ value.some((item, i, ar) => ar.indexOf(item) !== i)) {
+ failValidation("UniqueItems", UniqueItems);
+ }
+ }
+ }
+ /**
+ * Serialize the given object based on its metadata defined in the mapper
+ *
+ * @param mapper - The mapper which defines the metadata of the serializable object
+ *
+ * @param object - A valid Javascript object to be serialized
+ *
+ * @param objectName - Name of the serialized object
+ *
+ * @param options - additional options to serialization
+ *
+ * @returns A valid serialized Javascript object
+ */
+ serialize(mapper, object, objectName, options = { xml: {} }) {
+ var _a, _b, _c;
+ const updatedOptions = {
+ xml: {
+ rootName: (_a = options.xml.rootName) !== null && _a !== void 0 ? _a : "",
+ includeRoot: (_b = options.xml.includeRoot) !== null && _b !== void 0 ? _b : false,
+ xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY,
+ },
+ };
+ let payload = {};
+ const mapperType = mapper.type.name;
+ if (!objectName) {
+ objectName = mapper.serializedName;
+ }
+ if (mapperType.match(/^Sequence$/i) !== null) {
+ payload = [];
+ }
+ if (mapper.isConstant) {
+ object = mapper.defaultValue;
+ }
+ // This table of allowed values should help explain
+ // the mapper.required and mapper.nullable properties.
+ // X means "neither undefined or null are allowed".
+ // || required
+ // || true | false
+ // nullable || ==========================
+ // true || null | undefined/null
+ // false || X | undefined
+ // undefined || X | undefined/null
+ const { required, nullable } = mapper;
+ if (required && nullable && object === undefined) {
+ throw new Error(`${objectName} cannot be undefined.`);
+ }
+ if (required && !nullable && (object === undefined || object === null)) {
+ throw new Error(`${objectName} cannot be null or undefined.`);
+ }
+ if (!required && nullable === false && object === null) {
+ throw new Error(`${objectName} cannot be null.`);
+ }
+ if (object === undefined || object === null) {
+ payload = object;
+ }
+ else {
+ if (mapperType.match(/^any$/i) !== null) {
+ payload = object;
+ }
+ else if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/i) !== null) {
+ payload = serializeBasicTypes(mapperType, objectName, object);
+ }
+ else if (mapperType.match(/^Enum$/i) !== null) {
+ const enumMapper = mapper;
+ payload = serializeEnumType(objectName, enumMapper.type.allowedValues, object);
+ }
+ else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/i) !== null) {
+ payload = serializeDateTypes(mapperType, object, objectName);
+ }
+ else if (mapperType.match(/^ByteArray$/i) !== null) {
+ payload = serializeByteArrayType(objectName, object);
+ }
+ else if (mapperType.match(/^Base64Url$/i) !== null) {
+ payload = serializeBase64UrlType(objectName, object);
+ }
+ else if (mapperType.match(/^Sequence$/i) !== null) {
+ payload = serializeSequenceType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions);
+ }
+ else if (mapperType.match(/^Dictionary$/i) !== null) {
+ payload = serializeDictionaryType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions);
+ }
+ else if (mapperType.match(/^Composite$/i) !== null) {
+ payload = serializeCompositeType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions);
+ }
+ }
+ return payload;
+ }
+ /**
+ * Deserialize the given object based on its metadata defined in the mapper
+ *
+ * @param mapper - The mapper which defines the metadata of the serializable object
+ *
+ * @param responseBody - A valid Javascript entity to be deserialized
+ *
+ * @param objectName - Name of the deserialized object
+ *
+ * @param options - Controls behavior of XML parser and builder.
+ *
+ * @returns A valid deserialized Javascript object
+ */
+ deserialize(mapper, responseBody, objectName, options = { xml: {} }) {
+ var _a, _b, _c, _d;
+ const updatedOptions = {
+ xml: {
+ rootName: (_a = options.xml.rootName) !== null && _a !== void 0 ? _a : "",
+ includeRoot: (_b = options.xml.includeRoot) !== null && _b !== void 0 ? _b : false,
+ xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY,
+ },
+ ignoreUnknownProperties: (_d = options.ignoreUnknownProperties) !== null && _d !== void 0 ? _d : false,
+ };
+ if (responseBody === undefined || responseBody === null) {
+ if (this.isXML && mapper.type.name === "Sequence" && !mapper.xmlIsWrapped) {
+ // Edge case for empty XML non-wrapped lists. xml2js can't distinguish
+ // between the list being empty versus being missing,
+ // so let's do the more user-friendly thing and return an empty list.
+ responseBody = [];
+ }
+ // specifically check for undefined as default value can be a falsey value `0, "", false, null`
+ if (mapper.defaultValue !== undefined) {
+ responseBody = mapper.defaultValue;
+ }
+ return responseBody;
+ }
+ let payload;
+ const mapperType = mapper.type.name;
+ if (!objectName) {
+ objectName = mapper.serializedName;
+ }
+ if (mapperType.match(/^Composite$/i) !== null) {
+ payload = deserializeCompositeType(this, mapper, responseBody, objectName, updatedOptions);
+ }
+ else {
+ if (this.isXML) {
+ const xmlCharKey = updatedOptions.xml.xmlCharKey;
+ /**
+ * If the mapper specifies this as a non-composite type value but the responseBody contains
+ * both header ("$" i.e., XML_ATTRKEY) and body ("#" i.e., XML_CHARKEY) properties,
+ * then just reduce the responseBody value to the body ("#" i.e., XML_CHARKEY) property.
+ */
+ if (responseBody[XML_ATTRKEY] !== undefined && responseBody[xmlCharKey] !== undefined) {
+ responseBody = responseBody[xmlCharKey];
+ }
+ }
+ if (mapperType.match(/^Number$/i) !== null) {
+ payload = parseFloat(responseBody);
+ if (isNaN(payload)) {
+ payload = responseBody;
+ }
+ }
+ else if (mapperType.match(/^Boolean$/i) !== null) {
+ if (responseBody === "true") {
+ payload = true;
+ }
+ else if (responseBody === "false") {
+ payload = false;
+ }
+ else {
+ payload = responseBody;
+ }
+ }
+ else if (mapperType.match(/^(String|Enum|Object|Stream|Uuid|TimeSpan|any)$/i) !== null) {
+ payload = responseBody;
+ }
+ else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/i) !== null) {
+ payload = new Date(responseBody);
+ }
+ else if (mapperType.match(/^UnixTime$/i) !== null) {
+ payload = unixTimeToDate(responseBody);
+ }
+ else if (mapperType.match(/^ByteArray$/i) !== null) {
+ payload = decodeString(responseBody);
+ }
+ else if (mapperType.match(/^Base64Url$/i) !== null) {
+ payload = base64UrlToByteArray(responseBody);
+ }
+ else if (mapperType.match(/^Sequence$/i) !== null) {
+ payload = deserializeSequenceType(this, mapper, responseBody, objectName, updatedOptions);
+ }
+ else if (mapperType.match(/^Dictionary$/i) !== null) {
+ payload = deserializeDictionaryType(this, mapper, responseBody, objectName, updatedOptions);
+ }
+ }
+ if (mapper.isConstant) {
+ payload = mapper.defaultValue;
+ }
+ return payload;
+ }
+}
+/**
+ * Method that creates and returns a Serializer.
+ * @param modelMappers - Known models to map
+ * @param isXML - If XML should be supported
+ */
+function createSerializer(modelMappers = {}, isXML = false) {
+ return new SerializerImpl(modelMappers, isXML);
+}
+function trimEnd(str, ch) {
+ let len = str.length;
+ while (len - 1 >= 0 && str[len - 1] === ch) {
+ --len;
+ }
+ return str.substr(0, len);
+}
+function bufferToBase64Url(buffer) {
+ if (!buffer) {
+ return undefined;
+ }
+ if (!(buffer instanceof Uint8Array)) {
+ throw new Error(`Please provide an input of type Uint8Array for converting to Base64Url.`);
+ }
+ // Uint8Array to Base64.
+ const str = encodeByteArray(buffer);
+ // Base64 to Base64Url.
+ return trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_");
+}
+function base64UrlToByteArray(str) {
+ if (!str) {
+ return undefined;
+ }
+ if (str && typeof str.valueOf() !== "string") {
+ throw new Error("Please provide an input of type string for converting to Uint8Array");
+ }
+ // Base64Url to Base64.
+ str = str.replace(/-/g, "+").replace(/_/g, "/");
+ // Base64 to Uint8Array.
+ return decodeString(str);
+}
+function splitSerializeName(prop) {
+ const classes = [];
+ let partialclass = "";
+ if (prop) {
+ const subwords = prop.split(".");
+ for (const item of subwords) {
+ if (item.charAt(item.length - 1) === "\\") {
+ partialclass += item.substr(0, item.length - 1) + ".";
+ }
+ else {
+ partialclass += item;
+ classes.push(partialclass);
+ partialclass = "";
+ }
+ }
+ }
+ return classes;
+}
+function dateToUnixTime(d) {
+ if (!d) {
+ return undefined;
+ }
+ if (typeof d.valueOf() === "string") {
+ d = new Date(d);
+ }
+ return Math.floor(d.getTime() / 1000);
+}
+function unixTimeToDate(n) {
+ if (!n) {
+ return undefined;
+ }
+ return new Date(n * 1000);
+}
+function serializeBasicTypes(typeName, objectName, value) {
+ if (value !== null && value !== undefined) {
+ if (typeName.match(/^Number$/i) !== null) {
+ if (typeof value !== "number") {
+ throw new Error(`${objectName} with value ${value} must be of type number.`);
+ }
+ }
+ else if (typeName.match(/^String$/i) !== null) {
+ if (typeof value.valueOf() !== "string") {
+ throw new Error(`${objectName} with value "${value}" must be of type string.`);
+ }
+ }
+ else if (typeName.match(/^Uuid$/i) !== null) {
+ if (!(typeof value.valueOf() === "string" && isValidUuid(value))) {
+ throw new Error(`${objectName} with value "${value}" must be of type string and a valid uuid.`);
+ }
+ }
+ else if (typeName.match(/^Boolean$/i) !== null) {
+ if (typeof value !== "boolean") {
+ throw new Error(`${objectName} with value ${value} must be of type boolean.`);
+ }
+ }
+ else if (typeName.match(/^Stream$/i) !== null) {
+ const objectType = typeof value;
+ if (objectType !== "string" &&
+ typeof value.pipe !== "function" &&
+ !(value instanceof ArrayBuffer) &&
+ !ArrayBuffer.isView(value) &&
+ // File objects count as a type of Blob, so we want to use instanceof explicitly
+ !((typeof Blob === "function" || typeof Blob === "object") && value instanceof Blob) &&
+ objectType !== "function") {
+ throw new Error(`${objectName} must be a string, Blob, ArrayBuffer, ArrayBufferView, NodeJS.ReadableStream, or () => NodeJS.ReadableStream.`);
+ }
+ }
+ }
+ return value;
+}
+function 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;
+}
+function serializeByteArrayType(objectName, value) {
+ if (value !== undefined && value !== null) {
+ if (!(value instanceof Uint8Array)) {
+ throw new Error(`${objectName} must be of type Uint8Array.`);
+ }
+ value = encodeByteArray(value);
+ }
+ return value;
+}
+function serializeBase64UrlType(objectName, value) {
+ if (value !== undefined && value !== null) {
+ if (!(value instanceof Uint8Array)) {
+ throw new Error(`${objectName} must be of type Uint8Array.`);
+ }
+ value = bufferToBase64Url(value);
+ }
+ return value;
+}
+function serializeDateTypes(typeName, value, objectName) {
+ if (value !== undefined && value !== null) {
+ if (typeName.match(/^Date$/i) !== 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$/i) !== 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$/i) !== 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$/i) !== 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 = dateToUnixTime(value);
+ }
+ else if (typeName.match(/^TimeSpan$/i) !== null) {
+ if (!isDuration(value)) {
+ throw new Error(`${objectName} must be a string in ISO 8601 format. Instead was "${value}".`);
+ }
+ }
+ }
+ return value;
+}
+function serializeSequenceType(serializer, mapper, object, objectName, isXml, options) {
+ var _a;
+ if (!Array.isArray(object)) {
+ throw new Error(`${objectName} must be of type Array.`);
+ }
+ let elementType = mapper.type.element;
+ if (!elementType || typeof elementType !== "object") {
+ throw new Error(`element" metadata for an Array must be defined in the ` +
+ `mapper and it must of type "object" in ${objectName}.`);
+ }
+ // Quirk: Composite mappers referenced by `element` might
+ // not have *all* properties declared (like uberParent),
+ // so let's try to look up the full definition by name.
+ if (elementType.type.name === "Composite" && elementType.type.className) {
+ elementType = (_a = serializer.modelMappers[elementType.type.className]) !== null && _a !== void 0 ? _a : elementType;
+ }
+ const tempArray = [];
+ for (let i = 0; i < object.length; i++) {
+ const serializedValue = serializer.serialize(elementType, object[i], objectName, options);
+ if (isXml && elementType.xmlNamespace) {
+ const xmlnsKey = elementType.xmlNamespacePrefix
+ ? `xmlns:${elementType.xmlNamespacePrefix}`
+ : "xmlns";
+ if (elementType.type.name === "Composite") {
+ tempArray[i] = Object.assign({}, serializedValue);
+ tempArray[i][XML_ATTRKEY] = { [xmlnsKey]: elementType.xmlNamespace };
+ }
+ else {
+ tempArray[i] = {};
+ tempArray[i][options.xml.xmlCharKey] = serializedValue;
+ tempArray[i][XML_ATTRKEY] = { [xmlnsKey]: elementType.xmlNamespace };
+ }
+ }
+ else {
+ tempArray[i] = serializedValue;
+ }
+ }
+ return tempArray;
+}
+function serializeDictionaryType(serializer, mapper, object, objectName, isXml, options) {
+ if (typeof object !== "object") {
+ throw new Error(`${objectName} must be of type object.`);
+ }
+ const valueType = mapper.type.value;
+ if (!valueType || typeof valueType !== "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 of Object.keys(object)) {
+ const serializedValue = serializer.serialize(valueType, object[key], objectName, options);
+ // If the element needs an XML namespace we need to add it within the $ property
+ tempDictionary[key] = getXmlObjectValue(valueType, serializedValue, isXml, options);
+ }
+ // Add the namespace to the root element if needed
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix ? `xmlns:${mapper.xmlNamespacePrefix}` : "xmlns";
+ const result = tempDictionary;
+ result[XML_ATTRKEY] = { [xmlnsKey]: mapper.xmlNamespace };
+ return result;
+ }
+ return tempDictionary;
+}
+/**
+ * Resolves the additionalProperties property from a referenced mapper
+ * @param serializer - the serializer containing the entire set of mappers
+ * @param mapper - the composite mapper to resolve
+ * @param objectName - name of the object being serialized
+ */
+function resolveAdditionalProperties(serializer, mapper, objectName) {
+ const additionalProperties = mapper.type.additionalProperties;
+ if (!additionalProperties && mapper.type.className) {
+ const modelMapper = resolveReferencedMapper(serializer, mapper, objectName);
+ return modelMapper === null || modelMapper === void 0 ? void 0 : modelMapper.type.additionalProperties;
+ }
+ return additionalProperties;
+}
+/**
+ * Finds the mapper referenced by className
+ * @param serializer - the serializer containing the entire set of mappers
+ * @param mapper - the composite mapper to resolve
+ * @param objectName - name of the object being serialized
+ */
+function resolveReferencedMapper(serializer, mapper, objectName) {
+ const className = mapper.type.className;
+ if (!className) {
+ throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper, undefined, 2)}".`);
+ }
+ return serializer.modelMappers[className];
+}
+/**
+ * Resolves a composite mapper's modelProperties.
+ * @param serializer - the serializer containing the entire set of mappers
+ * @param mapper - the composite mapper to resolve
+ */
+function resolveModelProperties(serializer, mapper, objectName) {
+ let modelProps = mapper.type.modelProperties;
+ if (!modelProps) {
+ const modelMapper = resolveReferencedMapper(serializer, mapper, objectName);
+ if (!modelMapper) {
+ throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}".`);
+ }
+ modelProps = modelMapper === null || modelMapper === void 0 ? void 0 : 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}".`);
+ }
+ }
+ return modelProps;
+}
+function serializeCompositeType(serializer, mapper, object, objectName, isXml, options) {
+ if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
+ mapper = getPolymorphicMapper(serializer, mapper, object, "clientName");
+ }
+ if (object !== undefined && object !== null) {
+ const payload = {};
+ const modelProps = resolveModelProperties(serializer, mapper, objectName);
+ for (const key of Object.keys(modelProps)) {
+ const propertyMapper = modelProps[key];
+ if (propertyMapper.readOnly) {
+ continue;
+ }
+ let propName;
+ let parentObject = payload;
+ if (serializer.isXML) {
+ if (propertyMapper.xmlIsWrapped) {
+ propName = propertyMapper.xmlName;
+ }
+ else {
+ propName = propertyMapper.xmlElementName || propertyMapper.xmlName;
+ }
+ }
+ else {
+ const paths = splitSerializeName(propertyMapper.serializedName);
+ propName = paths.pop();
+ for (const pathName of paths) {
+ const childObject = parentObject[pathName];
+ if ((childObject === undefined || childObject === null) &&
+ ((object[key] !== undefined && object[key] !== null) ||
+ propertyMapper.defaultValue !== undefined)) {
+ parentObject[pathName] = {};
+ }
+ parentObject = parentObject[pathName];
+ }
+ }
+ if (parentObject !== undefined && parentObject !== null) {
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix
+ ? `xmlns:${mapper.xmlNamespacePrefix}`
+ : "xmlns";
+ parentObject[XML_ATTRKEY] = Object.assign(Object.assign({}, parentObject[XML_ATTRKEY]), { [xmlnsKey]: mapper.xmlNamespace });
+ }
+ const propertyObjectName = propertyMapper.serializedName !== ""
+ ? objectName + "." + propertyMapper.serializedName
+ : objectName;
+ let toSerialize = object[key];
+ const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
+ if (polymorphicDiscriminator &&
+ polymorphicDiscriminator.clientName === key &&
+ (toSerialize === undefined || toSerialize === null)) {
+ toSerialize = mapper.serializedName;
+ }
+ const serializedValue = serializer.serialize(propertyMapper, toSerialize, propertyObjectName, options);
+ if (serializedValue !== undefined && propName !== undefined && propName !== null) {
+ const value = getXmlObjectValue(propertyMapper, serializedValue, isXml, options);
+ if (isXml && propertyMapper.xmlIsAttribute) {
+ // XML_ATTRKEY, i.e., $ is the key attributes are kept under in xml2js.
+ // This keeps things simple while preventing name collision
+ // with names in user documents.
+ parentObject[XML_ATTRKEY] = parentObject[XML_ATTRKEY] || {};
+ parentObject[XML_ATTRKEY][propName] = serializedValue;
+ }
+ else if (isXml && propertyMapper.xmlIsWrapped) {
+ parentObject[propName] = { [propertyMapper.xmlElementName]: value };
+ }
+ else {
+ parentObject[propName] = value;
+ }
+ }
+ }
+ }
+ const additionalPropertiesMapper = resolveAdditionalProperties(serializer, mapper, objectName);
+ if (additionalPropertiesMapper) {
+ const propNames = Object.keys(modelProps);
+ for (const clientPropName in object) {
+ const isAdditionalProperty = propNames.every((pn) => pn !== clientPropName);
+ if (isAdditionalProperty) {
+ payload[clientPropName] = serializer.serialize(additionalPropertiesMapper, object[clientPropName], objectName + '["' + clientPropName + '"]', options);
+ }
+ }
+ }
+ return payload;
+ }
+ return object;
+}
+function getXmlObjectValue(propertyMapper, serializedValue, isXml, options) {
+ if (!isXml || !propertyMapper.xmlNamespace) {
+ return serializedValue;
+ }
+ const xmlnsKey = propertyMapper.xmlNamespacePrefix
+ ? `xmlns:${propertyMapper.xmlNamespacePrefix}`
+ : "xmlns";
+ const xmlNamespace = { [xmlnsKey]: propertyMapper.xmlNamespace };
+ if (["Composite"].includes(propertyMapper.type.name)) {
+ if (serializedValue[XML_ATTRKEY]) {
+ return serializedValue;
+ }
+ else {
+ const result = Object.assign({}, serializedValue);
+ result[XML_ATTRKEY] = xmlNamespace;
+ return result;
+ }
+ }
+ const result = {};
+ result[options.xml.xmlCharKey] = serializedValue;
+ result[XML_ATTRKEY] = xmlNamespace;
+ return result;
+}
+function isSpecialXmlProperty(propertyName, options) {
+ return [XML_ATTRKEY, options.xml.xmlCharKey].includes(propertyName);
+}
+function deserializeCompositeType(serializer, mapper, responseBody, objectName, options) {
+ var _a, _b;
+ const xmlCharKey = (_a = options.xml.xmlCharKey) !== null && _a !== void 0 ? _a : XML_CHARKEY;
+ if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
+ mapper = getPolymorphicMapper(serializer, mapper, responseBody, "serializedName");
+ }
+ const modelProps = resolveModelProperties(serializer, mapper, objectName);
+ let instance = {};
+ const handledPropertyNames = [];
+ for (const key of Object.keys(modelProps)) {
+ const propertyMapper = modelProps[key];
+ const paths = splitSerializeName(modelProps[key].serializedName);
+ handledPropertyNames.push(paths[0]);
+ const { serializedName, xmlName, xmlElementName } = propertyMapper;
+ let propertyObjectName = objectName;
+ if (serializedName !== "" && serializedName !== undefined) {
+ propertyObjectName = objectName + "." + serializedName;
+ }
+ const headerCollectionPrefix = propertyMapper.headerCollectionPrefix;
+ if (headerCollectionPrefix) {
+ const dictionary = {};
+ for (const headerKey of Object.keys(responseBody)) {
+ if (headerKey.startsWith(headerCollectionPrefix)) {
+ dictionary[headerKey.substring(headerCollectionPrefix.length)] = serializer.deserialize(propertyMapper.type.value, responseBody[headerKey], propertyObjectName, options);
+ }
+ handledPropertyNames.push(headerKey);
+ }
+ instance[key] = dictionary;
+ }
+ else if (serializer.isXML) {
+ if (propertyMapper.xmlIsAttribute && responseBody[XML_ATTRKEY]) {
+ instance[key] = serializer.deserialize(propertyMapper, responseBody[XML_ATTRKEY][xmlName], propertyObjectName, options);
+ }
+ else if (propertyMapper.xmlIsMsText) {
+ if (responseBody[xmlCharKey] !== undefined) {
+ instance[key] = responseBody[xmlCharKey];
+ }
+ else if (typeof responseBody === "string") {
+ // The special case where xml parser parses "content" into JSON of
+ // `{ name: "content"}` instead of `{ name: { "_": "content" }}`
+ instance[key] = responseBody;
+ }
+ }
+ else {
+ const propertyName = xmlElementName || xmlName || serializedName;
+ if (propertyMapper.xmlIsWrapped) {
+ /* a list of wrapped by
+ For the xml example below
+
+ ...
+ ...
+
+ the responseBody has
+ {
+ Cors: {
+ CorsRule: [{...}, {...}]
+ }
+ }
+ xmlName is "Cors" and xmlElementName is"CorsRule".
+ */
+ const wrapped = responseBody[xmlName];
+ const elementList = (_b = wrapped === null || wrapped === void 0 ? void 0 : wrapped[xmlElementName]) !== null && _b !== void 0 ? _b : [];
+ instance[key] = serializer.deserialize(propertyMapper, elementList, propertyObjectName, options);
+ handledPropertyNames.push(xmlName);
+ }
+ else {
+ const property = responseBody[propertyName];
+ instance[key] = serializer.deserialize(propertyMapper, property, propertyObjectName, options);
+ handledPropertyNames.push(propertyName);
+ }
+ }
+ }
+ else {
+ // deserialize the property if it is present in the provided responseBody instance
+ let propertyInstance;
+ let res = responseBody;
+ // traversing the object step by step.
+ let steps = 0;
+ for (const item of paths) {
+ if (!res)
+ break;
+ steps++;
+ res = res[item];
+ }
+ // only accept null when reaching the last position of object otherwise it would be undefined
+ if (res === null && steps < paths.length) {
+ res = undefined;
+ }
+ propertyInstance = res;
+ const polymorphicDiscriminator = mapper.type.polymorphicDiscriminator;
+ // checking that the model property name (key)(ex: "fishtype") and the
+ // clientName of the polymorphicDiscriminator {metadata} (ex: "fishtype")
+ // instead of the serializedName of the polymorphicDiscriminator (ex: "fish.type")
+ // is a better approach. The generator is not consistent with escaping '\.' in the
+ // serializedName of the property (ex: "fish\.type") that is marked as polymorphic discriminator
+ // and the serializedName of the metadata polymorphicDiscriminator (ex: "fish.type"). However,
+ // the clientName transformation of the polymorphicDiscriminator (ex: "fishtype") and
+ // the transformation of model property name (ex: "fishtype") is done consistently.
+ // Hence, it is a safer bet to rely on the clientName of the polymorphicDiscriminator.
+ if (polymorphicDiscriminator &&
+ key === polymorphicDiscriminator.clientName &&
+ (propertyInstance === undefined || propertyInstance === null)) {
+ propertyInstance = mapper.serializedName;
+ }
+ let serializedValue;
+ // paging
+ if (Array.isArray(responseBody[key]) && modelProps[key].serializedName === "") {
+ propertyInstance = responseBody[key];
+ const arrayInstance = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName, options);
+ // Copy over any properties that have already been added into the instance, where they do
+ // not exist on the newly de-serialized array
+ for (const [k, v] of Object.entries(instance)) {
+ if (!Object.prototype.hasOwnProperty.call(arrayInstance, k)) {
+ arrayInstance[k] = v;
+ }
+ }
+ instance = arrayInstance;
+ }
+ else if (propertyInstance !== undefined || propertyMapper.defaultValue !== undefined) {
+ serializedValue = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName, options);
+ instance[key] = serializedValue;
+ }
+ }
+ }
+ const additionalPropertiesMapper = mapper.type.additionalProperties;
+ if (additionalPropertiesMapper) {
+ const isAdditionalProperty = (responsePropName) => {
+ for (const clientPropName in modelProps) {
+ const paths = splitSerializeName(modelProps[clientPropName].serializedName);
+ if (paths[0] === responsePropName) {
+ return false;
+ }
+ }
+ return true;
+ };
+ for (const responsePropName in responseBody) {
+ if (isAdditionalProperty(responsePropName)) {
+ instance[responsePropName] = serializer.deserialize(additionalPropertiesMapper, responseBody[responsePropName], objectName + '["' + responsePropName + '"]', options);
+ }
+ }
+ }
+ else if (responseBody && !options.ignoreUnknownProperties) {
+ for (const key of Object.keys(responseBody)) {
+ if (instance[key] === undefined &&
+ !handledPropertyNames.includes(key) &&
+ !isSpecialXmlProperty(key, options)) {
+ instance[key] = responseBody[key];
+ }
+ }
+ }
+ return instance;
+}
+function deserializeDictionaryType(serializer, mapper, responseBody, objectName, options) {
+ /* jshint validthis: true */
+ const value = mapper.type.value;
+ if (!value || typeof 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 of Object.keys(responseBody)) {
+ tempDictionary[key] = serializer.deserialize(value, responseBody[key], objectName, options);
+ }
+ return tempDictionary;
+ }
+ return responseBody;
+}
+function deserializeSequenceType(serializer, mapper, responseBody, objectName, options) {
+ var _a;
+ let element = mapper.type.element;
+ if (!element || typeof 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) {
+ if (!Array.isArray(responseBody)) {
+ // xml2js will interpret a single element array as just the element, so force it to be an array
+ responseBody = [responseBody];
+ }
+ // Quirk: Composite mappers referenced by `element` might
+ // not have *all* properties declared (like uberParent),
+ // so let's try to look up the full definition by name.
+ if (element.type.name === "Composite" && element.type.className) {
+ element = (_a = serializer.modelMappers[element.type.className]) !== null && _a !== void 0 ? _a : element;
+ }
+ const tempArray = [];
+ for (let i = 0; i < responseBody.length; i++) {
+ tempArray[i] = serializer.deserialize(element, responseBody[i], `${objectName}[${i}]`, options);
+ }
+ return tempArray;
+ }
+ return responseBody;
+}
+function getIndexDiscriminator(discriminators, discriminatorValue, typeName) {
+ const typeNamesToCheck = [typeName];
+ while (typeNamesToCheck.length) {
+ const currentName = typeNamesToCheck.shift();
+ const indexDiscriminator = discriminatorValue === currentName
+ ? discriminatorValue
+ : currentName + "." + discriminatorValue;
+ if (Object.prototype.hasOwnProperty.call(discriminators, indexDiscriminator)) {
+ return discriminators[indexDiscriminator];
+ }
+ else {
+ for (const [name, mapper] of Object.entries(discriminators)) {
+ if (name.startsWith(currentName + ".") &&
+ mapper.type.uberParent === currentName &&
+ mapper.type.className) {
+ typeNamesToCheck.push(mapper.type.className);
+ }
+ }
+ }
+ }
+ return undefined;
+}
+function getPolymorphicMapper(serializer, mapper, object, polymorphicPropertyName) {
+ var _a;
+ const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
+ if (polymorphicDiscriminator) {
+ let discriminatorName = polymorphicDiscriminator[polymorphicPropertyName];
+ if (discriminatorName) {
+ // The serializedName might have \\, which we just want to ignore
+ if (polymorphicPropertyName === "serializedName") {
+ discriminatorName = discriminatorName.replace(/\\/gi, "");
+ }
+ const discriminatorValue = object[discriminatorName];
+ const typeName = (_a = mapper.type.uberParent) !== null && _a !== void 0 ? _a : mapper.type.className;
+ if (typeof discriminatorValue === "string" && typeName) {
+ const polymorphicMapper = getIndexDiscriminator(serializer.modelMappers.discriminators, discriminatorValue, typeName);
+ if (polymorphicMapper) {
+ mapper = polymorphicMapper;
+ }
+ }
+ }
+ }
+ return mapper;
+}
+function getPolymorphicDiscriminatorRecursively(serializer, mapper) {
+ return (mapper.type.polymorphicDiscriminator ||
+ getPolymorphicDiscriminatorSafely(serializer, mapper.type.uberParent) ||
+ getPolymorphicDiscriminatorSafely(serializer, mapper.type.className));
+}
+function getPolymorphicDiscriminatorSafely(serializer, typeName) {
+ return (typeName &&
+ serializer.modelMappers[typeName] &&
+ serializer.modelMappers[typeName].type.polymorphicDiscriminator);
+}
+/**
+ * Known types of Mappers
+ */
+const MapperTypeNames = {
+ Base64Url: "Base64Url",
+ Boolean: "Boolean",
+ ByteArray: "ByteArray",
+ Composite: "Composite",
+ Date: "Date",
+ DateTime: "DateTime",
+ DateTimeRfc1123: "DateTimeRfc1123",
+ Dictionary: "Dictionary",
+ Enum: "Enum",
+ Number: "Number",
+ Object: "Object",
+ Sequence: "Sequence",
+ String: "String",
+ Stream: "Stream",
+ TimeSpan: "TimeSpan",
+ UnixTime: "UnixTime",
+};
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * @internal
+ * Retrieves the value to use for a given operation argument
+ * @param operationArguments - The arguments passed from the generated client
+ * @param parameter - The parameter description
+ * @param fallbackObject - If something isn't found in the arguments bag, look here.
+ * Generally used to look at the service client properties.
+ */
+function getOperationArgumentValueFromParameter(operationArguments, parameter, fallbackObject) {
+ let parameterPath = parameter.parameterPath;
+ const parameterMapper = parameter.mapper;
+ let value;
+ if (typeof parameterPath === "string") {
+ parameterPath = [parameterPath];
+ }
+ if (Array.isArray(parameterPath)) {
+ if (parameterPath.length > 0) {
+ if (parameterMapper.isConstant) {
+ value = parameterMapper.defaultValue;
+ }
+ else {
+ let propertySearchResult = getPropertyFromParameterPath(operationArguments, parameterPath);
+ if (!propertySearchResult.propertyFound && fallbackObject) {
+ propertySearchResult = getPropertyFromParameterPath(fallbackObject, parameterPath);
+ }
+ let useDefaultValue = false;
+ if (!propertySearchResult.propertyFound) {
+ useDefaultValue =
+ parameterMapper.required ||
+ (parameterPath[0] === "options" && parameterPath.length === 2);
+ }
+ value = useDefaultValue ? parameterMapper.defaultValue : propertySearchResult.propertyValue;
+ }
+ }
+ }
+ else {
+ if (parameterMapper.required) {
+ value = {};
+ }
+ for (const propertyName in parameterPath) {
+ const propertyMapper = parameterMapper.type.modelProperties[propertyName];
+ const propertyPath = parameterPath[propertyName];
+ const propertyValue = getOperationArgumentValueFromParameter(operationArguments, {
+ parameterPath: propertyPath,
+ mapper: propertyMapper,
+ }, fallbackObject);
+ if (propertyValue !== undefined) {
+ if (!value) {
+ value = {};
+ }
+ value[propertyName] = propertyValue;
+ }
+ }
+ }
+ return value;
+}
+function getPropertyFromParameterPath(parent, parameterPath) {
+ const result = { propertyFound: false };
+ let i = 0;
+ for (; i < parameterPath.length; ++i) {
+ const parameterPathPart = parameterPath[i];
+ // Make sure to check inherited properties too, so don't use hasOwnProperty().
+ if (parent && parameterPathPart in parent) {
+ parent = parent[parameterPathPart];
+ }
+ else {
+ break;
+ }
+ }
+ if (i === parameterPath.length) {
+ result.propertyValue = parent;
+ result.propertyFound = true;
+ }
+ return result;
+}
+const operationRequestMap = new WeakMap();
+const originalRequestSymbol = Symbol.for("@azure/core-client original request");
+function hasOriginalRequest(request) {
+ return originalRequestSymbol in request;
+}
+function getOperationRequestInfo(request) {
+ if (hasOriginalRequest(request)) {
+ return getOperationRequestInfo(request[originalRequestSymbol]);
+ }
+ let info = operationRequestMap.get(request);
+ if (!info) {
+ info = {};
+ operationRequestMap.set(request, info);
+ }
+ return info;
+}
+
+// Copyright (c) Microsoft Corporation.
+const defaultJsonContentTypes = ["application/json", "text/json"];
+const defaultXmlContentTypes = ["application/xml", "application/atom+xml"];
+/**
+ * The programmatic identifier of the deserializationPolicy.
+ */
+const deserializationPolicyName = "deserializationPolicy";
+/**
+ * This policy handles parsing out responses according to OperationSpecs on the request.
+ */
+function deserializationPolicy(options = {}) {
+ var _a, _b, _c, _d, _e, _f, _g;
+ const jsonContentTypes = (_b = (_a = options.expectedContentTypes) === null || _a === void 0 ? void 0 : _a.json) !== null && _b !== void 0 ? _b : defaultJsonContentTypes;
+ const xmlContentTypes = (_d = (_c = options.expectedContentTypes) === null || _c === void 0 ? void 0 : _c.xml) !== null && _d !== void 0 ? _d : defaultXmlContentTypes;
+ const parseXML = options.parseXML;
+ const serializerOptions = options.serializerOptions;
+ const updatedOptions = {
+ xml: {
+ rootName: (_e = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.rootName) !== null && _e !== void 0 ? _e : "",
+ includeRoot: (_f = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.includeRoot) !== null && _f !== void 0 ? _f : false,
+ xmlCharKey: (_g = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _g !== void 0 ? _g : XML_CHARKEY,
+ },
+ };
+ return {
+ name: deserializationPolicyName,
+ async sendRequest(request, next) {
+ const response = await next(request);
+ return deserializeResponseBody(jsonContentTypes, xmlContentTypes, response, updatedOptions, parseXML);
+ },
+ };
+}
+function getOperationResponseMap(parsedResponse) {
+ let result;
+ const request = parsedResponse.request;
+ const operationInfo = getOperationRequestInfo(request);
+ const operationSpec = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationSpec;
+ if (operationSpec) {
+ if (!(operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationResponseGetter)) {
+ result = operationSpec.responses[parsedResponse.status];
+ }
+ else {
+ result = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationResponseGetter(operationSpec, parsedResponse);
+ }
+ }
+ return result;
+}
+function shouldDeserializeResponse(parsedResponse) {
+ const request = parsedResponse.request;
+ const operationInfo = getOperationRequestInfo(request);
+ const shouldDeserialize = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.shouldDeserialize;
+ let result;
+ if (shouldDeserialize === undefined) {
+ result = true;
+ }
+ else if (typeof shouldDeserialize === "boolean") {
+ result = shouldDeserialize;
+ }
+ else {
+ result = shouldDeserialize(parsedResponse);
+ }
+ return result;
+}
+async function deserializeResponseBody(jsonContentTypes, xmlContentTypes, response, options, parseXML) {
+ const parsedResponse = await parse(jsonContentTypes, xmlContentTypes, response, options, parseXML);
+ if (!shouldDeserializeResponse(parsedResponse)) {
+ return parsedResponse;
+ }
+ const operationInfo = getOperationRequestInfo(parsedResponse.request);
+ const operationSpec = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationSpec;
+ if (!operationSpec || !operationSpec.responses) {
+ return parsedResponse;
+ }
+ const responseSpec = getOperationResponseMap(parsedResponse);
+ const { error, shouldReturnResponse } = handleErrorResponse(parsedResponse, operationSpec, responseSpec, options);
+ if (error) {
+ throw error;
+ }
+ else if (shouldReturnResponse) {
+ return parsedResponse;
+ }
+ // An operation response spec does exist for current status code, so
+ // use it to deserialize the response.
+ if (responseSpec) {
+ if (responseSpec.bodyMapper) {
+ let valueToDeserialize = parsedResponse.parsedBody;
+ if (operationSpec.isXML && responseSpec.bodyMapper.type.name === MapperTypeNames.Sequence) {
+ valueToDeserialize =
+ typeof valueToDeserialize === "object"
+ ? valueToDeserialize[responseSpec.bodyMapper.xmlElementName]
+ : [];
+ }
+ try {
+ parsedResponse.parsedBody = operationSpec.serializer.deserialize(responseSpec.bodyMapper, valueToDeserialize, "operationRes.parsedBody", options);
+ }
+ catch (deserializeError) {
+ const restError = new coreRestPipeline.RestError(`Error ${deserializeError} occurred in deserializing the responseBody - ${parsedResponse.bodyAsText}`, {
+ statusCode: parsedResponse.status,
+ request: parsedResponse.request,
+ response: parsedResponse,
+ });
+ throw restError;
+ }
+ }
+ else if (operationSpec.httpMethod === "HEAD") {
+ // head methods never have a body, but we return a boolean to indicate presence/absence of the resource
+ parsedResponse.parsedBody = response.status >= 200 && response.status < 300;
+ }
+ if (responseSpec.headersMapper) {
+ parsedResponse.parsedHeaders = operationSpec.serializer.deserialize(responseSpec.headersMapper, parsedResponse.headers.toJSON(), "operationRes.parsedHeaders", { xml: {}, ignoreUnknownProperties: true });
+ }
+ }
+ return parsedResponse;
+}
+function isOperationSpecEmpty(operationSpec) {
+ const expectedStatusCodes = Object.keys(operationSpec.responses);
+ return (expectedStatusCodes.length === 0 ||
+ (expectedStatusCodes.length === 1 && expectedStatusCodes[0] === "default"));
+}
+function handleErrorResponse(parsedResponse, operationSpec, responseSpec, options) {
+ var _a;
+ const isSuccessByStatus = 200 <= parsedResponse.status && parsedResponse.status < 300;
+ const isExpectedStatusCode = isOperationSpecEmpty(operationSpec)
+ ? isSuccessByStatus
+ : !!responseSpec;
+ if (isExpectedStatusCode) {
+ if (responseSpec) {
+ if (!responseSpec.isError) {
+ return { error: null, shouldReturnResponse: false };
+ }
+ }
+ else {
+ return { error: null, shouldReturnResponse: false };
+ }
+ }
+ const errorResponseSpec = responseSpec !== null && responseSpec !== void 0 ? responseSpec : operationSpec.responses.default;
+ const initialErrorMessage = ((_a = parsedResponse.request.streamResponseStatusCodes) === null || _a === void 0 ? void 0 : _a.has(parsedResponse.status))
+ ? `Unexpected status code: ${parsedResponse.status}`
+ : parsedResponse.bodyAsText;
+ const error = new coreRestPipeline.RestError(initialErrorMessage, {
+ statusCode: parsedResponse.status,
+ request: parsedResponse.request,
+ response: parsedResponse,
+ });
+ // If the item failed but there's no error spec or default spec to deserialize the error,
+ // we should fail so we just throw the parsed response
+ if (!errorResponseSpec) {
+ throw error;
+ }
+ const defaultBodyMapper = errorResponseSpec.bodyMapper;
+ const defaultHeadersMapper = errorResponseSpec.headersMapper;
+ try {
+ // If error response has a body, try to deserialize it using default body mapper.
+ // Then try to extract error code & message from it
+ if (parsedResponse.parsedBody) {
+ const parsedBody = parsedResponse.parsedBody;
+ let deserializedError;
+ if (defaultBodyMapper) {
+ let valueToDeserialize = parsedBody;
+ if (operationSpec.isXML && defaultBodyMapper.type.name === MapperTypeNames.Sequence) {
+ valueToDeserialize = [];
+ const elementName = defaultBodyMapper.xmlElementName;
+ if (typeof parsedBody === "object" && elementName) {
+ valueToDeserialize = parsedBody[elementName];
+ }
+ }
+ deserializedError = operationSpec.serializer.deserialize(defaultBodyMapper, valueToDeserialize, "error.response.parsedBody", options);
+ }
+ const internalError = parsedBody.error || deserializedError || parsedBody;
+ error.code = internalError.code;
+ if (internalError.message) {
+ error.message = internalError.message;
+ }
+ if (defaultBodyMapper) {
+ error.response.parsedBody = deserializedError;
+ }
+ }
+ // If error response has headers, try to deserialize it using default header mapper
+ if (parsedResponse.headers && defaultHeadersMapper) {
+ error.response.parsedHeaders =
+ operationSpec.serializer.deserialize(defaultHeadersMapper, parsedResponse.headers.toJSON(), "operationRes.parsedHeaders");
+ }
+ }
+ catch (defaultError) {
+ error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody - "${parsedResponse.bodyAsText}" for the default response.`;
+ }
+ return { error, shouldReturnResponse: false };
+}
+async function parse(jsonContentTypes, xmlContentTypes, operationResponse, opts, parseXML) {
+ var _a;
+ if (!((_a = operationResponse.request.streamResponseStatusCodes) === null || _a === void 0 ? void 0 : _a.has(operationResponse.status)) &&
+ operationResponse.bodyAsText) {
+ const text = operationResponse.bodyAsText;
+ const contentType = operationResponse.headers.get("Content-Type") || "";
+ const contentComponents = !contentType
+ ? []
+ : contentType.split(";").map((component) => component.toLowerCase());
+ try {
+ if (contentComponents.length === 0 ||
+ contentComponents.some((component) => jsonContentTypes.indexOf(component) !== -1)) {
+ operationResponse.parsedBody = JSON.parse(text);
+ return operationResponse;
+ }
+ else if (contentComponents.some((component) => xmlContentTypes.indexOf(component) !== -1)) {
+ if (!parseXML) {
+ throw new Error("Parsing XML not supported.");
+ }
+ const body = await parseXML(text, opts.xml);
+ operationResponse.parsedBody = body;
+ return operationResponse;
+ }
+ }
+ catch (err) {
+ const msg = `Error "${err}" occurred while parsing the response body - ${operationResponse.bodyAsText}.`;
+ const errCode = err.code || coreRestPipeline.RestError.PARSE_ERROR;
+ const e = new coreRestPipeline.RestError(msg, {
+ code: errCode,
+ statusCode: operationResponse.status,
+ request: operationResponse.request,
+ response: operationResponse,
+ });
+ throw e;
+ }
+ }
+ return operationResponse;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Gets the list of status codes for streaming responses.
+ * @internal
+ */
+function getStreamingResponseStatusCodes(operationSpec) {
+ const result = new Set();
+ for (const statusCode in operationSpec.responses) {
+ const operationResponse = operationSpec.responses[statusCode];
+ if (operationResponse.bodyMapper &&
+ operationResponse.bodyMapper.type.name === MapperTypeNames.Stream) {
+ result.add(Number(statusCode));
+ }
+ }
+ return result;
+}
+/**
+ * Get the path to this parameter's value as a dotted string (a.b.c).
+ * @param parameter - The parameter to get the path string for.
+ * @returns The path to this parameter's value as a dotted string.
+ * @internal
+ */
+function getPathStringFromParameter(parameter) {
+ const { parameterPath, mapper } = parameter;
+ let result;
+ if (typeof parameterPath === "string") {
+ result = parameterPath;
+ }
+ else if (Array.isArray(parameterPath)) {
+ result = parameterPath.join(".");
+ }
+ else {
+ result = mapper.serializedName;
+ }
+ return result;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the serializationPolicy.
+ */
+const serializationPolicyName = "serializationPolicy";
+/**
+ * This policy handles assembling the request body and headers using
+ * an OperationSpec and OperationArguments on the request.
+ */
+function serializationPolicy(options = {}) {
+ const stringifyXML = options.stringifyXML;
+ return {
+ name: serializationPolicyName,
+ async sendRequest(request, next) {
+ const operationInfo = getOperationRequestInfo(request);
+ const operationSpec = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationSpec;
+ const operationArguments = operationInfo === null || operationInfo === void 0 ? void 0 : operationInfo.operationArguments;
+ if (operationSpec && operationArguments) {
+ serializeHeaders(request, operationArguments, operationSpec);
+ serializeRequestBody(request, operationArguments, operationSpec, stringifyXML);
+ }
+ return next(request);
+ },
+ };
+}
+/**
+ * @internal
+ */
+function serializeHeaders(request, operationArguments, operationSpec) {
+ var _a, _b;
+ if (operationSpec.headerParameters) {
+ for (const headerParameter of operationSpec.headerParameters) {
+ let headerValue = getOperationArgumentValueFromParameter(operationArguments, headerParameter);
+ if ((headerValue !== null && headerValue !== undefined) || headerParameter.mapper.required) {
+ headerValue = operationSpec.serializer.serialize(headerParameter.mapper, headerValue, getPathStringFromParameter(headerParameter));
+ const headerCollectionPrefix = headerParameter.mapper
+ .headerCollectionPrefix;
+ if (headerCollectionPrefix) {
+ for (const key of Object.keys(headerValue)) {
+ request.headers.set(headerCollectionPrefix + key, headerValue[key]);
+ }
+ }
+ else {
+ request.headers.set(headerParameter.mapper.serializedName || getPathStringFromParameter(headerParameter), headerValue);
+ }
+ }
+ }
+ }
+ const customHeaders = (_b = (_a = operationArguments.options) === null || _a === void 0 ? void 0 : _a.requestOptions) === null || _b === void 0 ? void 0 : _b.customHeaders;
+ if (customHeaders) {
+ for (const customHeaderName of Object.keys(customHeaders)) {
+ request.headers.set(customHeaderName, customHeaders[customHeaderName]);
+ }
+ }
+}
+/**
+ * @internal
+ */
+function serializeRequestBody(request, operationArguments, operationSpec, stringifyXML = function () {
+ throw new Error("XML serialization unsupported!");
+}) {
+ var _a, _b, _c, _d, _e;
+ const serializerOptions = (_a = operationArguments.options) === null || _a === void 0 ? void 0 : _a.serializerOptions;
+ const updatedOptions = {
+ xml: {
+ rootName: (_b = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.rootName) !== null && _b !== void 0 ? _b : "",
+ includeRoot: (_c = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.includeRoot) !== null && _c !== void 0 ? _c : false,
+ xmlCharKey: (_d = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _d !== void 0 ? _d : XML_CHARKEY,
+ },
+ };
+ const xmlCharKey = updatedOptions.xml.xmlCharKey;
+ if (operationSpec.requestBody && operationSpec.requestBody.mapper) {
+ request.body = getOperationArgumentValueFromParameter(operationArguments, operationSpec.requestBody);
+ const bodyMapper = operationSpec.requestBody.mapper;
+ const { required, serializedName, xmlName, xmlElementName, xmlNamespace, xmlNamespacePrefix, nullable, } = bodyMapper;
+ const typeName = bodyMapper.type.name;
+ try {
+ if ((request.body !== undefined && request.body !== null) ||
+ (nullable && request.body === null) ||
+ required) {
+ const requestBodyParameterPathString = getPathStringFromParameter(operationSpec.requestBody);
+ request.body = operationSpec.serializer.serialize(bodyMapper, request.body, requestBodyParameterPathString, updatedOptions);
+ const isStream = typeName === MapperTypeNames.Stream;
+ if (operationSpec.isXML) {
+ const xmlnsKey = xmlNamespacePrefix ? `xmlns:${xmlNamespacePrefix}` : "xmlns";
+ const value = getXmlValueWithNamespace(xmlNamespace, xmlnsKey, typeName, request.body, updatedOptions);
+ if (typeName === MapperTypeNames.Sequence) {
+ request.body = stringifyXML(prepareXMLRootList(value, xmlElementName || xmlName || serializedName, xmlnsKey, xmlNamespace), { rootName: xmlName || serializedName, xmlCharKey });
+ }
+ else if (!isStream) {
+ request.body = stringifyXML(value, {
+ rootName: xmlName || serializedName,
+ xmlCharKey,
+ });
+ }
+ }
+ else if (typeName === MapperTypeNames.String &&
+ (((_e = operationSpec.contentType) === null || _e === void 0 ? void 0 : _e.match("text/plain")) || operationSpec.mediaType === "text")) {
+ // the String serializer has validated that request body is a string
+ // so just send the string.
+ return;
+ }
+ else if (!isStream) {
+ request.body = JSON.stringify(request.body);
+ }
+ }
+ }
+ catch (error) {
+ throw new Error(`Error "${error.message}" occurred in serializing the payload - ${JSON.stringify(serializedName, undefined, " ")}.`);
+ }
+ }
+ else if (operationSpec.formDataParameters && operationSpec.formDataParameters.length > 0) {
+ request.formData = {};
+ for (const formDataParameter of operationSpec.formDataParameters) {
+ const formDataParameterValue = getOperationArgumentValueFromParameter(operationArguments, formDataParameter);
+ if (formDataParameterValue !== undefined && formDataParameterValue !== null) {
+ const formDataParameterPropertyName = formDataParameter.mapper.serializedName || getPathStringFromParameter(formDataParameter);
+ request.formData[formDataParameterPropertyName] = operationSpec.serializer.serialize(formDataParameter.mapper, formDataParameterValue, getPathStringFromParameter(formDataParameter), updatedOptions);
+ }
+ }
+ }
+}
+/**
+ * Adds an xml namespace to the xml serialized object if needed, otherwise it just returns the value itself
+ */
+function getXmlValueWithNamespace(xmlNamespace, xmlnsKey, typeName, serializedValue, options) {
+ // Composite and Sequence schemas already got their root namespace set during serialization
+ // We just need to add xmlns to the other schema types
+ if (xmlNamespace && !["Composite", "Sequence", "Dictionary"].includes(typeName)) {
+ const result = {};
+ result[options.xml.xmlCharKey] = serializedValue;
+ result[XML_ATTRKEY] = { [xmlnsKey]: xmlNamespace };
+ return result;
+ }
+ return serializedValue;
+}
+function prepareXMLRootList(obj, elementName, xmlNamespaceKey, xmlNamespace) {
+ if (!Array.isArray(obj)) {
+ obj = [obj];
+ }
+ if (!xmlNamespaceKey || !xmlNamespace) {
+ return { [elementName]: obj };
+ }
+ const result = { [elementName]: obj };
+ result[XML_ATTRKEY] = { [xmlNamespaceKey]: xmlNamespace };
+ return result;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Creates a new Pipeline for use with a Service Client.
+ * Adds in deserializationPolicy by default.
+ * Also adds in bearerTokenAuthenticationPolicy if passed a TokenCredential.
+ * @param options - Options to customize the created pipeline.
+ */
+function createClientPipeline(options = {}) {
+ const pipeline = coreRestPipeline.createPipelineFromOptions(options !== null && options !== void 0 ? options : {});
+ if (options.credentialOptions) {
+ pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
+ credential: options.credentialOptions.credential,
+ scopes: options.credentialOptions.credentialScopes,
+ }));
+ }
+ pipeline.addPolicy(serializationPolicy(options.serializationOptions), { phase: "Serialize" });
+ pipeline.addPolicy(deserializationPolicy(options.deserializationOptions), {
+ phase: "Deserialize",
+ });
+ return pipeline;
+}
+
+// Copyright (c) Microsoft Corporation.
+let cachedHttpClient;
+function getCachedDefaultHttpClient() {
+ if (!cachedHttpClient) {
+ cachedHttpClient = coreRestPipeline.createDefaultHttpClient();
+ }
+ return cachedHttpClient;
+}
+
+// Copyright (c) Microsoft Corporation.
+const CollectionFormatToDelimiterMap = {
+ CSV: ",",
+ SSV: " ",
+ Multi: "Multi",
+ TSV: "\t",
+ Pipes: "|",
+};
+function getRequestUrl(baseUri, operationSpec, operationArguments, fallbackObject) {
+ const urlReplacements = calculateUrlReplacements(operationSpec, operationArguments, fallbackObject);
+ let isAbsolutePath = false;
+ let requestUrl = replaceAll(baseUri, urlReplacements);
+ if (operationSpec.path) {
+ let path = replaceAll(operationSpec.path, urlReplacements);
+ // QUIRK: sometimes we get a path component like /{nextLink}
+ // which may be a fully formed URL with a leading /. In that case, we should
+ // remove the leading /
+ if (operationSpec.path === "/{nextLink}" && path.startsWith("/")) {
+ path = path.substring(1);
+ }
+ // QUIRK: sometimes we get a path component like {nextLink}
+ // which may be a fully formed URL. In that case, we should
+ // ignore the baseUri.
+ if (isAbsoluteUrl(path)) {
+ requestUrl = path;
+ isAbsolutePath = true;
+ }
+ else {
+ requestUrl = appendPath(requestUrl, path);
+ }
+ }
+ const { queryParams, sequenceParams } = calculateQueryParameters(operationSpec, operationArguments, fallbackObject);
+ /**
+ * Notice that this call sets the `noOverwrite` parameter to true if the `requestUrl`
+ * is an absolute path. This ensures that existing query parameter values in `requestUrl`
+ * do not get overwritten. On the other hand when `requestUrl` is not absolute path, it
+ * is still being built so there is nothing to overwrite.
+ */
+ requestUrl = appendQueryParams(requestUrl, queryParams, sequenceParams, isAbsolutePath);
+ return requestUrl;
+}
+function replaceAll(input, replacements) {
+ let result = input;
+ for (const [searchValue, replaceValue] of replacements) {
+ result = result.split(searchValue).join(replaceValue);
+ }
+ return result;
+}
+function calculateUrlReplacements(operationSpec, operationArguments, fallbackObject) {
+ var _a;
+ const result = new Map();
+ if ((_a = operationSpec.urlParameters) === null || _a === void 0 ? void 0 : _a.length) {
+ for (const urlParameter of operationSpec.urlParameters) {
+ let urlParameterValue = getOperationArgumentValueFromParameter(operationArguments, urlParameter, fallbackObject);
+ const parameterPathString = getPathStringFromParameter(urlParameter);
+ urlParameterValue = operationSpec.serializer.serialize(urlParameter.mapper, urlParameterValue, parameterPathString);
+ if (!urlParameter.skipEncoding) {
+ urlParameterValue = encodeURIComponent(urlParameterValue);
+ }
+ result.set(`{${urlParameter.mapper.serializedName || parameterPathString}}`, urlParameterValue);
+ }
+ }
+ return result;
+}
+function isAbsoluteUrl(url) {
+ return url.includes("://");
+}
+function appendPath(url, pathToAppend) {
+ if (!pathToAppend) {
+ return url;
+ }
+ const parsedUrl = new URL(url);
+ let newPath = parsedUrl.pathname;
+ if (!newPath.endsWith("/")) {
+ newPath = `${newPath}/`;
+ }
+ if (pathToAppend.startsWith("/")) {
+ pathToAppend = pathToAppend.substring(1);
+ }
+ const searchStart = pathToAppend.indexOf("?");
+ if (searchStart !== -1) {
+ const path = pathToAppend.substring(0, searchStart);
+ const search = pathToAppend.substring(searchStart + 1);
+ newPath = newPath + path;
+ if (search) {
+ parsedUrl.search = parsedUrl.search ? `${parsedUrl.search}&${search}` : search;
+ }
+ }
+ else {
+ newPath = newPath + pathToAppend;
+ }
+ parsedUrl.pathname = newPath;
+ return parsedUrl.toString();
+}
+function calculateQueryParameters(operationSpec, operationArguments, fallbackObject) {
+ var _a;
+ const result = new Map();
+ const sequenceParams = new Set();
+ if ((_a = operationSpec.queryParameters) === null || _a === void 0 ? void 0 : _a.length) {
+ for (const queryParameter of operationSpec.queryParameters) {
+ if (queryParameter.mapper.type.name === "Sequence" && queryParameter.mapper.serializedName) {
+ sequenceParams.add(queryParameter.mapper.serializedName);
+ }
+ let queryParameterValue = getOperationArgumentValueFromParameter(operationArguments, queryParameter, fallbackObject);
+ if ((queryParameterValue !== undefined && queryParameterValue !== null) ||
+ queryParameter.mapper.required) {
+ queryParameterValue = operationSpec.serializer.serialize(queryParameter.mapper, queryParameterValue, getPathStringFromParameter(queryParameter));
+ const delimiter = queryParameter.collectionFormat
+ ? CollectionFormatToDelimiterMap[queryParameter.collectionFormat]
+ : "";
+ if (Array.isArray(queryParameterValue)) {
+ // replace null and undefined
+ queryParameterValue = queryParameterValue.map((item) => {
+ if (item === null || item === undefined) {
+ return "";
+ }
+ return item;
+ });
+ }
+ if (queryParameter.collectionFormat === "Multi" && queryParameterValue.length === 0) {
+ continue;
+ }
+ else if (Array.isArray(queryParameterValue) &&
+ (queryParameter.collectionFormat === "SSV" || queryParameter.collectionFormat === "TSV")) {
+ queryParameterValue = queryParameterValue.join(delimiter);
+ }
+ if (!queryParameter.skipEncoding) {
+ if (Array.isArray(queryParameterValue)) {
+ queryParameterValue = queryParameterValue.map((item) => {
+ return encodeURIComponent(item);
+ });
+ }
+ else {
+ queryParameterValue = encodeURIComponent(queryParameterValue);
+ }
+ }
+ // Join pipes and CSV *after* encoding, or the server will be upset.
+ if (Array.isArray(queryParameterValue) &&
+ (queryParameter.collectionFormat === "CSV" || queryParameter.collectionFormat === "Pipes")) {
+ queryParameterValue = queryParameterValue.join(delimiter);
+ }
+ result.set(queryParameter.mapper.serializedName || getPathStringFromParameter(queryParameter), queryParameterValue);
+ }
+ }
+ }
+ return {
+ queryParams: result,
+ sequenceParams,
+ };
+}
+function simpleParseQueryParams(queryString) {
+ const result = new Map();
+ if (!queryString || queryString[0] !== "?") {
+ return result;
+ }
+ // remove the leading ?
+ queryString = queryString.slice(1);
+ const pairs = queryString.split("&");
+ for (const pair of pairs) {
+ const [name, value] = pair.split("=", 2);
+ const existingValue = result.get(name);
+ if (existingValue) {
+ if (Array.isArray(existingValue)) {
+ existingValue.push(value);
+ }
+ else {
+ result.set(name, [existingValue, value]);
+ }
+ }
+ else {
+ result.set(name, value);
+ }
+ }
+ return result;
+}
+/** @internal */
+function appendQueryParams(url, queryParams, sequenceParams, noOverwrite = false) {
+ if (queryParams.size === 0) {
+ return url;
+ }
+ const parsedUrl = new URL(url);
+ // QUIRK: parsedUrl.searchParams will have their name/value pairs decoded, which
+ // can change their meaning to the server, such as in the case of a SAS signature.
+ // To avoid accidentally un-encoding a query param, we parse the key/values ourselves
+ const combinedParams = simpleParseQueryParams(parsedUrl.search);
+ for (const [name, value] of queryParams) {
+ const existingValue = combinedParams.get(name);
+ if (Array.isArray(existingValue)) {
+ if (Array.isArray(value)) {
+ existingValue.push(...value);
+ const valueSet = new Set(existingValue);
+ combinedParams.set(name, Array.from(valueSet));
+ }
+ else {
+ existingValue.push(value);
+ }
+ }
+ else if (existingValue) {
+ if (Array.isArray(value)) {
+ value.unshift(existingValue);
+ }
+ else if (sequenceParams.has(name)) {
+ combinedParams.set(name, [existingValue, value]);
+ }
+ if (!noOverwrite) {
+ combinedParams.set(name, value);
+ }
+ }
+ else {
+ combinedParams.set(name, value);
+ }
+ }
+ const searchPieces = [];
+ for (const [name, value] of combinedParams) {
+ if (typeof value === "string") {
+ searchPieces.push(`${name}=${value}`);
+ }
+ else if (Array.isArray(value)) {
+ // QUIRK: If we get an array of values, include multiple key/value pairs
+ for (const subValue of value) {
+ searchPieces.push(`${name}=${subValue}`);
+ }
+ }
+ else {
+ searchPieces.push(`${name}=${value}`);
+ }
+ }
+ // QUIRK: we have to set search manually as searchParams will encode comma when it shouldn't.
+ parsedUrl.search = searchPieces.length ? `?${searchPieces.join("&")}` : "";
+ return parsedUrl.toString();
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger = logger$1.createClientLogger("core-client");
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Initializes a new instance of the ServiceClient.
+ */
+class ServiceClient {
+ /**
+ * The ServiceClient constructor
+ * @param credential - The credentials used for authentication with the service.
+ * @param options - The service client options that govern the behavior of the client.
+ */
+ constructor(options = {}) {
+ var _a, _b;
+ this._requestContentType = options.requestContentType;
+ this._endpoint = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri;
+ if (options.baseUri) {
+ logger.warning("The baseUri option for SDK Clients has been deprecated, please use endpoint instead.");
+ }
+ this._allowInsecureConnection = options.allowInsecureConnection;
+ this._httpClient = options.httpClient || getCachedDefaultHttpClient();
+ this.pipeline = options.pipeline || createDefaultPipeline(options);
+ if ((_b = options.additionalPolicies) === null || _b === void 0 ? void 0 : _b.length) {
+ for (const { policy, position } of options.additionalPolicies) {
+ // Sign happens after Retry and is commonly needed to occur
+ // before policies that intercept post-retry.
+ const afterPhase = position === "perRetry" ? "Sign" : undefined;
+ this.pipeline.addPolicy(policy, {
+ afterPhase,
+ });
+ }
+ }
+ }
+ /**
+ * Send the provided httpRequest.
+ */
+ async sendRequest(request) {
+ return this.pipeline.sendRequest(this._httpClient, request);
+ }
+ /**
+ * Send an HTTP request that is populated using the provided OperationSpec.
+ * @typeParam T - The typed result of the request, based on the OperationSpec.
+ * @param operationArguments - The arguments that the HTTP request's templated values will be populated from.
+ * @param operationSpec - The OperationSpec to use to populate the httpRequest.
+ */
+ async sendOperationRequest(operationArguments, operationSpec) {
+ const endpoint = operationSpec.baseUrl || this._endpoint;
+ if (!endpoint) {
+ throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a endpoint string property that contains the base URL to use.");
+ }
+ // Templatized URLs sometimes reference properties on the ServiceClient child class,
+ // so we have to pass `this` below in order to search these properties if they're
+ // not part of OperationArguments
+ const url = getRequestUrl(endpoint, operationSpec, operationArguments, this);
+ const request = coreRestPipeline.createPipelineRequest({
+ url,
+ });
+ request.method = operationSpec.httpMethod;
+ const operationInfo = getOperationRequestInfo(request);
+ operationInfo.operationSpec = operationSpec;
+ operationInfo.operationArguments = operationArguments;
+ const contentType = operationSpec.contentType || this._requestContentType;
+ if (contentType && operationSpec.requestBody) {
+ request.headers.set("Content-Type", contentType);
+ }
+ const options = operationArguments.options;
+ if (options) {
+ const requestOptions = options.requestOptions;
+ if (requestOptions) {
+ if (requestOptions.timeout) {
+ request.timeout = requestOptions.timeout;
+ }
+ if (requestOptions.onUploadProgress) {
+ request.onUploadProgress = requestOptions.onUploadProgress;
+ }
+ if (requestOptions.onDownloadProgress) {
+ request.onDownloadProgress = requestOptions.onDownloadProgress;
+ }
+ if (requestOptions.shouldDeserialize !== undefined) {
+ operationInfo.shouldDeserialize = requestOptions.shouldDeserialize;
+ }
+ if (requestOptions.allowInsecureConnection) {
+ request.allowInsecureConnection = true;
+ }
+ }
+ if (options.abortSignal) {
+ request.abortSignal = options.abortSignal;
+ }
+ if (options.tracingOptions) {
+ request.tracingOptions = options.tracingOptions;
+ }
+ }
+ if (this._allowInsecureConnection) {
+ request.allowInsecureConnection = true;
+ }
+ if (request.streamResponseStatusCodes === undefined) {
+ request.streamResponseStatusCodes = getStreamingResponseStatusCodes(operationSpec);
+ }
+ try {
+ const rawResponse = await this.sendRequest(request);
+ const flatResponse = flattenResponse(rawResponse, operationSpec.responses[rawResponse.status]);
+ if (options === null || options === void 0 ? void 0 : options.onResponse) {
+ options.onResponse(rawResponse, flatResponse);
+ }
+ return flatResponse;
+ }
+ catch (error) {
+ if (typeof error === "object" && (error === null || error === void 0 ? void 0 : error.response)) {
+ const rawResponse = error.response;
+ const flatResponse = flattenResponse(rawResponse, operationSpec.responses[error.statusCode] || operationSpec.responses["default"]);
+ error.details = flatResponse;
+ if (options === null || options === void 0 ? void 0 : options.onResponse) {
+ options.onResponse(rawResponse, flatResponse, error);
+ }
+ }
+ throw error;
+ }
+ }
+}
+function createDefaultPipeline(options) {
+ const credentialScopes = getCredentialScopes(options);
+ const credentialOptions = options.credential && credentialScopes
+ ? { credentialScopes, credential: options.credential }
+ : undefined;
+ return createClientPipeline(Object.assign(Object.assign({}, options), { credentialOptions }));
+}
+function getCredentialScopes(options) {
+ if (options.credentialScopes) {
+ return options.credentialScopes;
+ }
+ if (options.endpoint) {
+ return `${options.endpoint}/.default`;
+ }
+ if (options.baseUri) {
+ return `${options.baseUri}/.default`;
+ }
+ if (options.credential && !options.credentialScopes) {
+ throw new Error(`When using credentials, the ServiceClientOptions must contain either a endpoint or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`);
+ }
+ return undefined;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Converts: `Bearer a="b", c="d", Bearer d="e", f="g"`.
+ * Into: `[ { a: 'b', c: 'd' }, { d: 'e', f: 'g' } ]`.
+ *
+ * @internal
+ */
+function parseCAEChallenge(challenges) {
+ const bearerChallenges = `, ${challenges.trim()}`.split(", Bearer ").filter((x) => x);
+ return bearerChallenges.map((challenge) => {
+ const challengeParts = `${challenge.trim()}, `.split('", ').filter((x) => x);
+ const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split('="')));
+ // Key-value pairs to plain object:
+ return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
+ });
+}
+/**
+ * This function can be used as a callback for the `bearerTokenAuthenticationPolicy` of `@azure/core-rest-pipeline`, to support CAE challenges:
+ * [Continuous Access Evaluation](https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation).
+ *
+ * Call the `bearerTokenAuthenticationPolicy` with the following options:
+ *
+ * ```ts
+ * import { bearerTokenAuthenticationPolicy } from "@azure/core-rest-pipeline";
+ * import { authorizeRequestOnClaimChallenge } from "@azure/core-client";
+ *
+ * const bearerTokenAuthenticationPolicy = bearerTokenAuthenticationPolicy({
+ * authorizeRequestOnChallenge: authorizeRequestOnClaimChallenge
+ * });
+ * ```
+ *
+ * Once provided, the `bearerTokenAuthenticationPolicy` policy will internally handle Continuous Access Evaluation (CAE) challenges.
+ * When it can't complete a challenge it will return the 401 (unauthorized) response from ARM.
+ *
+ * Example challenge with claims:
+ *
+ * ```
+ * Bearer authorization_uri="https://login.windows-ppe.net/", error="invalid_token",
+ * error_description="User session has been revoked",
+ * claims="eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTYwMzc0MjgwMCJ9fX0="
+ * ```
+ */
+async function authorizeRequestOnClaimChallenge(onChallengeOptions) {
+ const { scopes, response } = onChallengeOptions;
+ const logger$1 = onChallengeOptions.logger || logger;
+ const challenge = response.headers.get("WWW-Authenticate");
+ if (!challenge) {
+ logger$1.info(`The WWW-Authenticate header was missing. Failed to perform the Continuous Access Evaluation authentication flow.`);
+ return false;
+ }
+ const challenges = parseCAEChallenge(challenge) || [];
+ const parsedChallenge = challenges.find((x) => x.claims);
+ if (!parsedChallenge) {
+ logger$1.info(`The WWW-Authenticate header was missing the necessary "claims" to perform the Continuous Access Evaluation authentication flow.`);
+ return false;
+ }
+ const accessToken = await onChallengeOptions.getAccessToken(parsedChallenge.scope ? [parsedChallenge.scope] : scopes, {
+ claims: decodeStringToString(parsedChallenge.claims),
+ });
+ if (!accessToken) {
+ return false;
+ }
+ onChallengeOptions.request.headers.set("Authorization", `Bearer ${accessToken.token}`);
+ return true;
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * A set of constants used internally when processing requests.
+ */
+const Constants = {
+ DefaultScope: "/.default",
+ /**
+ * Defines constants for use with HTTP headers.
+ */
+ HeaderConstants: {
+ /**
+ * The Authorization header.
+ */
+ AUTHORIZATION: "authorization",
+ },
+};
+/**
+ * Defines a callback to handle auth challenge for Storage APIs.
+ * This implements the bearer challenge process described here: https://docs.microsoft.com/rest/api/storageservices/authorize-with-azure-active-directory#bearer-challenge
+ * Handling has specific features for storage that departs to the general AAD challenge docs.
+ **/
+const authorizeRequestOnTenantChallenge = async (challengeOptions) => {
+ const requestOptions = requestToOptions(challengeOptions.request);
+ const challenge = getChallenge(challengeOptions.response);
+ if (challenge) {
+ const challengeInfo = parseChallenge(challenge);
+ const challengeScopes = buildScopes(challengeOptions, challengeInfo);
+ const tenantId = extractTenantId(challengeInfo);
+ const accessToken = await challengeOptions.getAccessToken(challengeScopes, Object.assign(Object.assign({}, requestOptions), { tenantId }));
+ if (!accessToken) {
+ return false;
+ }
+ challengeOptions.request.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${accessToken.token}`);
+ return true;
+ }
+ return false;
+};
+/**
+ * Extracts the tenant id from the challenge information
+ * The tenant id is contained in the authorization_uri as the first
+ * path part.
+ */
+function extractTenantId(challengeInfo) {
+ const parsedAuthUri = new URL(challengeInfo.authorization_uri);
+ const pathSegments = parsedAuthUri.pathname.split("/");
+ const tenantId = pathSegments[1];
+ return tenantId;
+}
+/**
+ * Builds the authentication scopes based on the information that comes in the
+ * challenge information. Scopes url is present in the resource_id, if it is empty
+ * we keep using the original scopes.
+ */
+function buildScopes(challengeOptions, challengeInfo) {
+ if (!challengeInfo.resource_uri) {
+ return challengeOptions.scopes;
+ }
+ const challengeScopes = new URL(challengeInfo.resource_uri);
+ challengeScopes.pathname = Constants.DefaultScope;
+ return [challengeScopes.toString()];
+}
+/**
+ * We will retrieve the challenge only if the response status code was 401,
+ * and if the response contained the header "WWW-Authenticate" with a non-empty value.
+ */
+function getChallenge(response) {
+ const challenge = response.headers.get("WWW-Authenticate");
+ if (response.status === 401 && challenge) {
+ return challenge;
+ }
+ return;
+}
+/**
+ * Converts: `Bearer a="b" c="d"`.
+ * Into: `[ { a: 'b', c: 'd' }]`.
+ *
+ * @internal
+ */
+function parseChallenge(challenge) {
+ const bearerChallenge = challenge.slice("Bearer ".length);
+ const challengeParts = `${bearerChallenge.trim()} `.split(" ").filter((x) => x);
+ const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split("=")));
+ // Key-value pairs to plain object:
+ return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
+}
+/**
+ * Extracts the options form a Pipeline Request for later re-use
+ */
+function requestToOptions(request) {
+ return {
+ abortSignal: request.abortSignal,
+ requestOptions: {
+ timeout: request.timeout,
+ },
+ tracingOptions: request.tracingOptions,
+ };
+}
+
+exports.MapperTypeNames = MapperTypeNames;
+exports.ServiceClient = ServiceClient;
+exports.XML_ATTRKEY = XML_ATTRKEY;
+exports.XML_CHARKEY = XML_CHARKEY;
+exports.authorizeRequestOnClaimChallenge = authorizeRequestOnClaimChallenge;
+exports.authorizeRequestOnTenantChallenge = authorizeRequestOnTenantChallenge;
+exports.createClientPipeline = createClientPipeline;
+exports.createSerializer = createSerializer;
+exports.deserializationPolicy = deserializationPolicy;
+exports.deserializationPolicyName = deserializationPolicyName;
+exports.serializationPolicy = serializationPolicy;
+exports.serializationPolicyName = serializationPolicyName;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 7094:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var logger$1 = __nccwpck_require__(3233);
+var abortController = __nccwpck_require__(2557);
+var coreUtil = __nccwpck_require__(1333);
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The `@azure/logger` configuration for this package.
+ * @internal
+ */
+const logger = logger$1.createClientLogger("core-lro");
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The default time interval to wait before sending the next polling request.
+ */
+const POLL_INTERVAL_IN_MS = 2000;
+/**
+ * The closed set of terminal states.
+ */
+const terminalStates = ["succeeded", "canceled", "failed"];
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Deserializes the state
+ */
+function deserializeState(serializedState) {
+ try {
+ return JSON.parse(serializedState).state;
+ }
+ catch (e) {
+ throw new Error(`Unable to deserialize input state: ${serializedState}`);
+ }
+}
+function setStateError(inputs) {
+ const { state, stateProxy, isOperationError } = inputs;
+ return (error) => {
+ if (isOperationError(error)) {
+ stateProxy.setError(state, error);
+ stateProxy.setFailed(state);
+ }
+ throw error;
+ };
+}
+function appendReadableErrorMessage(currentMessage, innerMessage) {
+ let message = currentMessage;
+ if (message.slice(-1) !== ".") {
+ message = message + ".";
+ }
+ return message + " " + innerMessage;
+}
+function simplifyError(err) {
+ let message = err.message;
+ let code = err.code;
+ let curErr = err;
+ while (curErr.innererror) {
+ curErr = curErr.innererror;
+ code = curErr.code;
+ message = appendReadableErrorMessage(message, curErr.message);
+ }
+ return {
+ code,
+ message,
+ };
+}
+function processOperationStatus(result) {
+ const { state, stateProxy, status, isDone, processResult, getError, response, setErrorAsResult } = result;
+ switch (status) {
+ case "succeeded": {
+ stateProxy.setSucceeded(state);
+ break;
+ }
+ case "failed": {
+ const err = getError === null || getError === void 0 ? void 0 : getError(response);
+ let postfix = "";
+ if (err) {
+ const { code, message } = simplifyError(err);
+ postfix = `. ${code}. ${message}`;
+ }
+ const errStr = `The long-running operation has failed${postfix}`;
+ stateProxy.setError(state, new Error(errStr));
+ stateProxy.setFailed(state);
+ logger.warning(errStr);
+ break;
+ }
+ case "canceled": {
+ stateProxy.setCanceled(state);
+ break;
+ }
+ }
+ if ((isDone === null || isDone === void 0 ? void 0 : isDone(response, state)) ||
+ (isDone === undefined &&
+ ["succeeded", "canceled"].concat(setErrorAsResult ? [] : ["failed"]).includes(status))) {
+ stateProxy.setResult(state, buildResult({
+ response,
+ state,
+ processResult,
+ }));
+ }
+}
+function buildResult(inputs) {
+ const { processResult, response, state } = inputs;
+ return processResult ? processResult(response, state) : response;
+}
+/**
+ * Initiates the long-running operation.
+ */
+async function initOperation(inputs) {
+ const { init, stateProxy, processResult, getOperationStatus, withOperationLocation, setErrorAsResult, } = inputs;
+ const { operationLocation, resourceLocation, metadata, response } = await init();
+ if (operationLocation)
+ withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(operationLocation, false);
+ const config = {
+ metadata,
+ operationLocation,
+ resourceLocation,
+ };
+ logger.verbose(`LRO: Operation description:`, config);
+ const state = stateProxy.initState(config);
+ const status = getOperationStatus({ response, state, operationLocation });
+ processOperationStatus({ state, status, stateProxy, response, setErrorAsResult, processResult });
+ return state;
+}
+async function pollOperationHelper(inputs) {
+ const { poll, state, stateProxy, operationLocation, getOperationStatus, getResourceLocation, isOperationError, options, } = inputs;
+ const response = await poll(operationLocation, options).catch(setStateError({
+ state,
+ stateProxy,
+ isOperationError,
+ }));
+ const status = getOperationStatus(response, state);
+ logger.verbose(`LRO: Status:\n\tPolling from: ${state.config.operationLocation}\n\tOperation status: ${status}\n\tPolling status: ${terminalStates.includes(status) ? "Stopped" : "Running"}`);
+ if (status === "succeeded") {
+ const resourceLocation = getResourceLocation(response, state);
+ if (resourceLocation !== undefined) {
+ return {
+ response: await poll(resourceLocation).catch(setStateError({ state, stateProxy, isOperationError })),
+ status,
+ };
+ }
+ }
+ return { response, status };
+}
+/** Polls the long-running operation. */
+async function pollOperation(inputs) {
+ const { poll, state, stateProxy, options, getOperationStatus, getResourceLocation, getOperationLocation, isOperationError, withOperationLocation, getPollingInterval, processResult, getError, updateState, setDelay, isDone, setErrorAsResult, } = inputs;
+ const { operationLocation } = state.config;
+ if (operationLocation !== undefined) {
+ const { response, status } = await pollOperationHelper({
+ poll,
+ getOperationStatus,
+ state,
+ stateProxy,
+ operationLocation,
+ getResourceLocation,
+ isOperationError,
+ options,
+ });
+ processOperationStatus({
+ status,
+ response,
+ state,
+ stateProxy,
+ isDone,
+ processResult,
+ getError,
+ setErrorAsResult,
+ });
+ if (!terminalStates.includes(status)) {
+ const intervalInMs = getPollingInterval === null || getPollingInterval === void 0 ? void 0 : getPollingInterval(response);
+ if (intervalInMs)
+ setDelay(intervalInMs);
+ const location = getOperationLocation === null || getOperationLocation === void 0 ? void 0 : getOperationLocation(response, state);
+ if (location !== undefined) {
+ const isUpdated = operationLocation !== location;
+ state.config.operationLocation = location;
+ withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(location, isUpdated);
+ }
+ else
+ withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(operationLocation, false);
+ }
+ updateState === null || updateState === void 0 ? void 0 : updateState(state, response);
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+function getOperationLocationPollingUrl(inputs) {
+ const { azureAsyncOperation, operationLocation } = inputs;
+ return operationLocation !== null && operationLocation !== void 0 ? operationLocation : azureAsyncOperation;
+}
+function getLocationHeader(rawResponse) {
+ return rawResponse.headers["location"];
+}
+function getOperationLocationHeader(rawResponse) {
+ return rawResponse.headers["operation-location"];
+}
+function getAzureAsyncOperationHeader(rawResponse) {
+ return rawResponse.headers["azure-asyncoperation"];
+}
+function findResourceLocation(inputs) {
+ var _a;
+ const { location, requestMethod, requestPath, resourceLocationConfig } = inputs;
+ switch (requestMethod) {
+ case "PUT": {
+ return requestPath;
+ }
+ case "DELETE": {
+ return undefined;
+ }
+ case "PATCH": {
+ return (_a = getDefault()) !== null && _a !== void 0 ? _a : requestPath;
+ }
+ default: {
+ return getDefault();
+ }
+ }
+ function getDefault() {
+ switch (resourceLocationConfig) {
+ case "azure-async-operation": {
+ return undefined;
+ }
+ case "original-uri": {
+ return requestPath;
+ }
+ case "location":
+ default: {
+ return location;
+ }
+ }
+ }
+}
+function inferLroMode(inputs) {
+ const { rawResponse, requestMethod, requestPath, resourceLocationConfig } = inputs;
+ const operationLocation = getOperationLocationHeader(rawResponse);
+ const azureAsyncOperation = getAzureAsyncOperationHeader(rawResponse);
+ const pollingUrl = getOperationLocationPollingUrl({ operationLocation, azureAsyncOperation });
+ const location = getLocationHeader(rawResponse);
+ const normalizedRequestMethod = requestMethod === null || requestMethod === void 0 ? void 0 : requestMethod.toLocaleUpperCase();
+ if (pollingUrl !== undefined) {
+ return {
+ mode: "OperationLocation",
+ operationLocation: pollingUrl,
+ resourceLocation: findResourceLocation({
+ requestMethod: normalizedRequestMethod,
+ location,
+ requestPath,
+ resourceLocationConfig,
+ }),
+ };
+ }
+ else if (location !== undefined) {
+ return {
+ mode: "ResourceLocation",
+ operationLocation: location,
+ };
+ }
+ else if (normalizedRequestMethod === "PUT" && requestPath) {
+ return {
+ mode: "Body",
+ operationLocation: requestPath,
+ };
+ }
+ else {
+ return undefined;
+ }
+}
+function transformStatus(inputs) {
+ const { status, statusCode } = inputs;
+ if (typeof status !== "string" && status !== undefined) {
+ throw new Error(`Polling was unsuccessful. Expected status to have a string value or no value but it has instead: ${status}. This doesn't necessarily indicate the operation has failed. Check your Azure subscription or resource status for more information.`);
+ }
+ switch (status === null || status === void 0 ? void 0 : status.toLocaleLowerCase()) {
+ case undefined:
+ return toOperationStatus(statusCode);
+ case "succeeded":
+ return "succeeded";
+ case "failed":
+ return "failed";
+ case "running":
+ case "accepted":
+ case "started":
+ case "canceling":
+ case "cancelling":
+ return "running";
+ case "canceled":
+ case "cancelled":
+ return "canceled";
+ default: {
+ logger.verbose(`LRO: unrecognized operation status: ${status}`);
+ return status;
+ }
+ }
+}
+function getStatus(rawResponse) {
+ var _a;
+ const { status } = (_a = rawResponse.body) !== null && _a !== void 0 ? _a : {};
+ return transformStatus({ status, statusCode: rawResponse.statusCode });
+}
+function getProvisioningState(rawResponse) {
+ var _a, _b;
+ const { properties, provisioningState } = (_a = rawResponse.body) !== null && _a !== void 0 ? _a : {};
+ const status = (_b = properties === null || properties === void 0 ? void 0 : properties.provisioningState) !== null && _b !== void 0 ? _b : provisioningState;
+ return transformStatus({ status, statusCode: rawResponse.statusCode });
+}
+function toOperationStatus(statusCode) {
+ if (statusCode === 202) {
+ return "running";
+ }
+ else if (statusCode < 300) {
+ return "succeeded";
+ }
+ else {
+ return "failed";
+ }
+}
+function parseRetryAfter({ rawResponse }) {
+ const retryAfter = rawResponse.headers["retry-after"];
+ if (retryAfter !== undefined) {
+ // Retry-After header value is either in HTTP date format, or in seconds
+ const retryAfterInSeconds = parseInt(retryAfter);
+ return isNaN(retryAfterInSeconds)
+ ? calculatePollingIntervalFromDate(new Date(retryAfter))
+ : retryAfterInSeconds * 1000;
+ }
+ return undefined;
+}
+function getErrorFromResponse(response) {
+ const error = response.flatResponse.error;
+ if (!error) {
+ logger.warning(`The long-running operation failed but there is no error property in the response's body`);
+ return;
+ }
+ if (!error.code || !error.message) {
+ logger.warning(`The long-running operation failed but the error property in the response's body doesn't contain code or message`);
+ return;
+ }
+ return error;
+}
+function calculatePollingIntervalFromDate(retryAfterDate) {
+ const timeNow = Math.floor(new Date().getTime());
+ const retryAfterTime = retryAfterDate.getTime();
+ if (timeNow < retryAfterTime) {
+ return retryAfterTime - timeNow;
+ }
+ return undefined;
+}
+function getStatusFromInitialResponse(inputs) {
+ const { response, state, operationLocation } = inputs;
+ function helper() {
+ var _a;
+ const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
+ switch (mode) {
+ case undefined:
+ return toOperationStatus(response.rawResponse.statusCode);
+ case "Body":
+ return getOperationStatus(response, state);
+ default:
+ return "running";
+ }
+ }
+ const status = helper();
+ return status === "running" && operationLocation === undefined ? "succeeded" : status;
+}
+/**
+ * Initiates the long-running operation.
+ */
+async function initHttpOperation(inputs) {
+ const { stateProxy, resourceLocationConfig, processResult, lro, setErrorAsResult } = inputs;
+ return initOperation({
+ init: async () => {
+ const response = await lro.sendInitialRequest();
+ const config = inferLroMode({
+ rawResponse: response.rawResponse,
+ requestPath: lro.requestPath,
+ requestMethod: lro.requestMethod,
+ resourceLocationConfig,
+ });
+ return Object.assign({ response, operationLocation: config === null || config === void 0 ? void 0 : config.operationLocation, resourceLocation: config === null || config === void 0 ? void 0 : config.resourceLocation }, ((config === null || config === void 0 ? void 0 : config.mode) ? { metadata: { mode: config.mode } } : {}));
+ },
+ stateProxy,
+ processResult: processResult
+ ? ({ flatResponse }, state) => processResult(flatResponse, state)
+ : ({ flatResponse }) => flatResponse,
+ getOperationStatus: getStatusFromInitialResponse,
+ setErrorAsResult,
+ });
+}
+function getOperationLocation({ rawResponse }, state) {
+ var _a;
+ const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
+ switch (mode) {
+ case "OperationLocation": {
+ return getOperationLocationPollingUrl({
+ operationLocation: getOperationLocationHeader(rawResponse),
+ azureAsyncOperation: getAzureAsyncOperationHeader(rawResponse),
+ });
+ }
+ case "ResourceLocation": {
+ return getLocationHeader(rawResponse);
+ }
+ case "Body":
+ default: {
+ return undefined;
+ }
+ }
+}
+function getOperationStatus({ rawResponse }, state) {
+ var _a;
+ const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
+ switch (mode) {
+ case "OperationLocation": {
+ return getStatus(rawResponse);
+ }
+ case "ResourceLocation": {
+ return toOperationStatus(rawResponse.statusCode);
+ }
+ case "Body": {
+ return getProvisioningState(rawResponse);
+ }
+ default:
+ throw new Error(`Internal error: Unexpected operation mode: ${mode}`);
+ }
+}
+function getResourceLocation({ flatResponse }, state) {
+ if (typeof flatResponse === "object") {
+ const resourceLocation = flatResponse.resourceLocation;
+ if (resourceLocation !== undefined) {
+ state.config.resourceLocation = resourceLocation;
+ }
+ }
+ return state.config.resourceLocation;
+}
+function isOperationError(e) {
+ return e.name === "RestError";
+}
+/** Polls the long-running operation. */
+async function pollHttpOperation(inputs) {
+ const { lro, stateProxy, options, processResult, updateState, setDelay, state, setErrorAsResult, } = inputs;
+ return pollOperation({
+ state,
+ stateProxy,
+ setDelay,
+ processResult: processResult
+ ? ({ flatResponse }, inputState) => processResult(flatResponse, inputState)
+ : ({ flatResponse }) => flatResponse,
+ getError: getErrorFromResponse,
+ updateState,
+ getPollingInterval: parseRetryAfter,
+ getOperationLocation,
+ getOperationStatus,
+ isOperationError,
+ getResourceLocation,
+ options,
+ /**
+ * The expansion here is intentional because `lro` could be an object that
+ * references an inner this, so we need to preserve a reference to it.
+ */
+ poll: async (location, inputOptions) => lro.sendPollRequest(location, inputOptions),
+ setErrorAsResult,
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+const createStateProxy$1 = () => ({
+ /**
+ * The state at this point is created to be of type OperationState.
+ * It will be updated later to be of type TState when the
+ * customer-provided callback, `updateState`, is called during polling.
+ */
+ initState: (config) => ({ status: "running", config }),
+ setCanceled: (state) => (state.status = "canceled"),
+ setError: (state, error) => (state.error = error),
+ setResult: (state, result) => (state.result = result),
+ setRunning: (state) => (state.status = "running"),
+ setSucceeded: (state) => (state.status = "succeeded"),
+ setFailed: (state) => (state.status = "failed"),
+ getError: (state) => state.error,
+ getResult: (state) => state.result,
+ isCanceled: (state) => state.status === "canceled",
+ isFailed: (state) => state.status === "failed",
+ isRunning: (state) => state.status === "running",
+ isSucceeded: (state) => state.status === "succeeded",
+});
+/**
+ * Returns a poller factory.
+ */
+function buildCreatePoller(inputs) {
+ const { getOperationLocation, getStatusFromInitialResponse, getStatusFromPollResponse, isOperationError, getResourceLocation, getPollingInterval, getError, resolveOnUnsuccessful, } = inputs;
+ return async ({ init, poll }, options) => {
+ const { processResult, updateState, withOperationLocation: withOperationLocationCallback, intervalInMs = POLL_INTERVAL_IN_MS, restoreFrom, } = options || {};
+ const stateProxy = createStateProxy$1();
+ const withOperationLocation = withOperationLocationCallback
+ ? (() => {
+ let called = false;
+ return (operationLocation, isUpdated) => {
+ if (isUpdated)
+ withOperationLocationCallback(operationLocation);
+ else if (!called)
+ withOperationLocationCallback(operationLocation);
+ called = true;
+ };
+ })()
+ : undefined;
+ const state = restoreFrom
+ ? deserializeState(restoreFrom)
+ : await initOperation({
+ init,
+ stateProxy,
+ processResult,
+ getOperationStatus: getStatusFromInitialResponse,
+ withOperationLocation,
+ setErrorAsResult: !resolveOnUnsuccessful,
+ });
+ let resultPromise;
+ const abortController$1 = new abortController.AbortController();
+ const handlers = new Map();
+ const handleProgressEvents = async () => handlers.forEach((h) => h(state));
+ const cancelErrMsg = "Operation was canceled";
+ let currentPollIntervalInMs = intervalInMs;
+ const poller = {
+ getOperationState: () => state,
+ getResult: () => state.result,
+ isDone: () => ["succeeded", "failed", "canceled"].includes(state.status),
+ isStopped: () => resultPromise === undefined,
+ stopPolling: () => {
+ abortController$1.abort();
+ },
+ toString: () => JSON.stringify({
+ state,
+ }),
+ onProgress: (callback) => {
+ const s = Symbol();
+ handlers.set(s, callback);
+ return () => handlers.delete(s);
+ },
+ pollUntilDone: (pollOptions) => (resultPromise !== null && resultPromise !== void 0 ? resultPromise : (resultPromise = (async () => {
+ const { abortSignal: inputAbortSignal } = pollOptions || {};
+ const { signal: abortSignal } = inputAbortSignal
+ ? new abortController.AbortController([inputAbortSignal, abortController$1.signal])
+ : abortController$1;
+ if (!poller.isDone()) {
+ await poller.poll({ abortSignal });
+ while (!poller.isDone()) {
+ await coreUtil.delay(currentPollIntervalInMs, { abortSignal });
+ await poller.poll({ abortSignal });
+ }
+ }
+ if (resolveOnUnsuccessful) {
+ return poller.getResult();
+ }
+ else {
+ switch (state.status) {
+ case "succeeded":
+ return poller.getResult();
+ case "canceled":
+ throw new Error(cancelErrMsg);
+ case "failed":
+ throw state.error;
+ case "notStarted":
+ case "running":
+ throw new Error(`Polling completed without succeeding or failing`);
+ }
+ }
+ })().finally(() => {
+ resultPromise = undefined;
+ }))),
+ async poll(pollOptions) {
+ if (resolveOnUnsuccessful) {
+ if (poller.isDone())
+ return;
+ }
+ else {
+ switch (state.status) {
+ case "succeeded":
+ return;
+ case "canceled":
+ throw new Error(cancelErrMsg);
+ case "failed":
+ throw state.error;
+ }
+ }
+ await pollOperation({
+ poll,
+ state,
+ stateProxy,
+ getOperationLocation,
+ isOperationError,
+ withOperationLocation,
+ getPollingInterval,
+ getOperationStatus: getStatusFromPollResponse,
+ getResourceLocation,
+ processResult,
+ getError,
+ updateState,
+ options: pollOptions,
+ setDelay: (pollIntervalInMs) => {
+ currentPollIntervalInMs = pollIntervalInMs;
+ },
+ setErrorAsResult: !resolveOnUnsuccessful,
+ });
+ await handleProgressEvents();
+ if (!resolveOnUnsuccessful) {
+ switch (state.status) {
+ case "canceled":
+ throw new Error(cancelErrMsg);
+ case "failed":
+ throw state.error;
+ }
+ }
+ },
+ };
+ return poller;
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Creates a poller that can be used to poll a long-running operation.
+ * @param lro - Description of the long-running operation
+ * @param options - options to configure the poller
+ * @returns an initialized poller
+ */
+async function createHttpPoller(lro, options) {
+ const { resourceLocationConfig, intervalInMs, processResult, restoreFrom, updateState, withOperationLocation, resolveOnUnsuccessful = false, } = options || {};
+ return buildCreatePoller({
+ getStatusFromInitialResponse,
+ getStatusFromPollResponse: getOperationStatus,
+ isOperationError,
+ getOperationLocation,
+ getResourceLocation,
+ getPollingInterval: parseRetryAfter,
+ getError: getErrorFromResponse,
+ resolveOnUnsuccessful,
+ })({
+ init: async () => {
+ const response = await lro.sendInitialRequest();
+ const config = inferLroMode({
+ rawResponse: response.rawResponse,
+ requestPath: lro.requestPath,
+ requestMethod: lro.requestMethod,
+ resourceLocationConfig,
+ });
+ return Object.assign({ response, operationLocation: config === null || config === void 0 ? void 0 : config.operationLocation, resourceLocation: config === null || config === void 0 ? void 0 : config.resourceLocation }, ((config === null || config === void 0 ? void 0 : config.mode) ? { metadata: { mode: config.mode } } : {}));
+ },
+ poll: lro.sendPollRequest,
+ }, {
+ intervalInMs,
+ withOperationLocation,
+ restoreFrom,
+ updateState,
+ processResult: processResult
+ ? ({ flatResponse }, state) => processResult(flatResponse, state)
+ : ({ flatResponse }) => flatResponse,
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+const createStateProxy = () => ({
+ initState: (config) => ({ config, isStarted: true }),
+ setCanceled: (state) => (state.isCancelled = true),
+ setError: (state, error) => (state.error = error),
+ setResult: (state, result) => (state.result = result),
+ setRunning: (state) => (state.isStarted = true),
+ setSucceeded: (state) => (state.isCompleted = true),
+ setFailed: () => {
+ /** empty body */
+ },
+ getError: (state) => state.error,
+ getResult: (state) => state.result,
+ isCanceled: (state) => !!state.isCancelled,
+ isFailed: (state) => !!state.error,
+ isRunning: (state) => !!state.isStarted,
+ isSucceeded: (state) => Boolean(state.isCompleted && !state.isCancelled && !state.error),
+});
+class GenericPollOperation {
+ constructor(state, lro, setErrorAsResult, lroResourceLocationConfig, processResult, updateState, isDone) {
+ this.state = state;
+ this.lro = lro;
+ this.setErrorAsResult = setErrorAsResult;
+ this.lroResourceLocationConfig = lroResourceLocationConfig;
+ this.processResult = processResult;
+ this.updateState = updateState;
+ this.isDone = isDone;
+ }
+ setPollerConfig(pollerConfig) {
+ this.pollerConfig = pollerConfig;
+ }
+ async update(options) {
+ var _a;
+ const stateProxy = createStateProxy();
+ if (!this.state.isStarted) {
+ this.state = Object.assign(Object.assign({}, this.state), (await initHttpOperation({
+ lro: this.lro,
+ stateProxy,
+ resourceLocationConfig: this.lroResourceLocationConfig,
+ processResult: this.processResult,
+ setErrorAsResult: this.setErrorAsResult,
+ })));
+ }
+ const updateState = this.updateState;
+ const isDone = this.isDone;
+ if (!this.state.isCompleted && this.state.error === undefined) {
+ await pollHttpOperation({
+ lro: this.lro,
+ state: this.state,
+ stateProxy,
+ processResult: this.processResult,
+ updateState: updateState
+ ? (state, { rawResponse }) => updateState(state, rawResponse)
+ : undefined,
+ isDone: isDone
+ ? ({ flatResponse }, state) => isDone(flatResponse, state)
+ : undefined,
+ options,
+ setDelay: (intervalInMs) => {
+ this.pollerConfig.intervalInMs = intervalInMs;
+ },
+ setErrorAsResult: this.setErrorAsResult,
+ });
+ }
+ (_a = options === null || options === void 0 ? void 0 : options.fireProgress) === null || _a === void 0 ? void 0 : _a.call(options, this.state);
+ return this;
+ }
+ async cancel() {
+ logger.error("`cancelOperation` is deprecated because it wasn't implemented");
+ return this;
+ }
+ /**
+ * Serializes the Poller operation.
+ */
+ toString() {
+ return JSON.stringify({
+ state: this.state,
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * When a poller is manually stopped through the `stopPolling` method,
+ * the poller will be rejected with an instance of the PollerStoppedError.
+ */
+class PollerStoppedError extends Error {
+ constructor(message) {
+ super(message);
+ this.name = "PollerStoppedError";
+ Object.setPrototypeOf(this, PollerStoppedError.prototype);
+ }
+}
+/**
+ * When the operation is cancelled, the poller will be rejected with an instance
+ * of the PollerCancelledError.
+ */
+class PollerCancelledError extends Error {
+ constructor(message) {
+ super(message);
+ this.name = "PollerCancelledError";
+ Object.setPrototypeOf(this, PollerCancelledError.prototype);
+ }
+}
+/**
+ * A class that represents the definition of a program that polls through consecutive requests
+ * until it reaches a state of completion.
+ *
+ * A poller can be executed manually, by polling request by request by calling to the `poll()` method repeatedly, until its operation is completed.
+ * It also provides a way to wait until the operation completes, by calling `pollUntilDone()` and waiting until the operation finishes.
+ * Pollers can also request the cancellation of the ongoing process to whom is providing the underlying long running operation.
+ *
+ * ```ts
+ * const poller = new MyPoller();
+ *
+ * // Polling just once:
+ * await poller.poll();
+ *
+ * // We can try to cancel the request here, by calling:
+ * //
+ * // await poller.cancelOperation();
+ * //
+ *
+ * // Getting the final result:
+ * const result = await poller.pollUntilDone();
+ * ```
+ *
+ * The Poller is defined by two types, a type representing the state of the poller, which
+ * must include a basic set of properties from `PollOperationState`,
+ * and a return type defined by `TResult`, which can be anything.
+ *
+ * The Poller class implements the `PollerLike` interface, which allows poller implementations to avoid having
+ * to export the Poller's class directly, and instead only export the already instantiated poller with the PollerLike type.
+ *
+ * ```ts
+ * class Client {
+ * public async makePoller: PollerLike {
+ * const poller = new MyPoller({});
+ * // It might be preferred to return the poller after the first request is made,
+ * // so that some information can be obtained right away.
+ * await poller.poll();
+ * return poller;
+ * }
+ * }
+ *
+ * const poller: PollerLike = myClient.makePoller();
+ * ```
+ *
+ * A poller can be created through its constructor, then it can be polled until it's completed.
+ * At any point in time, the state of the poller can be obtained without delay through the getOperationState method.
+ * At any point in time, the intermediate forms of the result type can be requested without delay.
+ * Once the underlying operation is marked as completed, the poller will stop and the final value will be returned.
+ *
+ * ```ts
+ * const poller = myClient.makePoller();
+ * const state: MyOperationState = poller.getOperationState();
+ *
+ * // The intermediate result can be obtained at any time.
+ * const result: MyResult | undefined = poller.getResult();
+ *
+ * // The final result can only be obtained after the poller finishes.
+ * const result: MyResult = await poller.pollUntilDone();
+ * ```
+ *
+ */
+// eslint-disable-next-line no-use-before-define
+class Poller {
+ /**
+ * A poller needs to be initialized by passing in at least the basic properties of the `PollOperation`.
+ *
+ * When writing an implementation of a Poller, this implementation needs to deal with the initialization
+ * of any custom state beyond the basic definition of the poller. The basic poller assumes that the poller's
+ * operation has already been defined, at least its basic properties. The code below shows how to approach
+ * the definition of the constructor of a new custom poller.
+ *
+ * ```ts
+ * export class MyPoller extends Poller {
+ * constructor({
+ * // Anything you might need outside of the basics
+ * }) {
+ * let state: MyOperationState = {
+ * privateProperty: private,
+ * publicProperty: public,
+ * };
+ *
+ * const operation = {
+ * state,
+ * update,
+ * cancel,
+ * toString
+ * }
+ *
+ * // Sending the operation to the parent's constructor.
+ * super(operation);
+ *
+ * // You can assign more local properties here.
+ * }
+ * }
+ * ```
+ *
+ * Inside of this constructor, a new promise is created. This will be used to
+ * tell the user when the poller finishes (see `pollUntilDone()`). The promise's
+ * resolve and reject methods are also used internally to control when to resolve
+ * or reject anyone waiting for the poller to finish.
+ *
+ * The constructor of a custom implementation of a poller is where any serialized version of
+ * a previous poller's operation should be deserialized into the operation sent to the
+ * base constructor. For example:
+ *
+ * ```ts
+ * export class MyPoller extends Poller {
+ * constructor(
+ * baseOperation: string | undefined
+ * ) {
+ * let state: MyOperationState = {};
+ * if (baseOperation) {
+ * state = {
+ * ...JSON.parse(baseOperation).state,
+ * ...state
+ * };
+ * }
+ * const operation = {
+ * state,
+ * // ...
+ * }
+ * super(operation);
+ * }
+ * }
+ * ```
+ *
+ * @param operation - Must contain the basic properties of `PollOperation`.
+ */
+ constructor(operation) {
+ /** controls whether to throw an error if the operation failed or was canceled. */
+ this.resolveOnUnsuccessful = false;
+ this.stopped = true;
+ this.pollProgressCallbacks = [];
+ this.operation = operation;
+ this.promise = new Promise((resolve, reject) => {
+ this.resolve = resolve;
+ this.reject = reject;
+ });
+ // This prevents the UnhandledPromiseRejectionWarning in node.js from being thrown.
+ // The above warning would get thrown if `poller.poll` is called, it returns an error,
+ // and pullUntilDone did not have a .catch or await try/catch on it's return value.
+ this.promise.catch(() => {
+ /* intentionally blank */
+ });
+ }
+ /**
+ * Starts a loop that will break only if the poller is done
+ * or if the poller is stopped.
+ */
+ async startPolling(pollOptions = {}) {
+ if (this.stopped) {
+ this.stopped = false;
+ }
+ while (!this.isStopped() && !this.isDone()) {
+ await this.poll(pollOptions);
+ await this.delay();
+ }
+ }
+ /**
+ * pollOnce does one polling, by calling to the update method of the underlying
+ * poll operation to make any relevant change effective.
+ *
+ * It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
+ *
+ * @param options - Optional properties passed to the operation's update method.
+ */
+ async pollOnce(options = {}) {
+ if (!this.isDone()) {
+ this.operation = await this.operation.update({
+ abortSignal: options.abortSignal,
+ fireProgress: this.fireProgress.bind(this),
+ });
+ }
+ this.processUpdatedState();
+ }
+ /**
+ * fireProgress calls the functions passed in via onProgress the method of the poller.
+ *
+ * It loops over all of the callbacks received from onProgress, and executes them, sending them
+ * the current operation state.
+ *
+ * @param state - The current operation state.
+ */
+ fireProgress(state) {
+ for (const callback of this.pollProgressCallbacks) {
+ callback(state);
+ }
+ }
+ /**
+ * Invokes the underlying operation's cancel method.
+ */
+ async cancelOnce(options = {}) {
+ this.operation = await this.operation.cancel(options);
+ }
+ /**
+ * Returns a promise that will resolve once a single polling request finishes.
+ * It does this by calling the update method of the Poller's operation.
+ *
+ * It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
+ *
+ * @param options - Optional properties passed to the operation's update method.
+ */
+ poll(options = {}) {
+ if (!this.pollOncePromise) {
+ this.pollOncePromise = this.pollOnce(options);
+ const clearPollOncePromise = () => {
+ this.pollOncePromise = undefined;
+ };
+ this.pollOncePromise.then(clearPollOncePromise, clearPollOncePromise).catch(this.reject);
+ }
+ return this.pollOncePromise;
+ }
+ processUpdatedState() {
+ if (this.operation.state.error) {
+ this.stopped = true;
+ if (!this.resolveOnUnsuccessful) {
+ this.reject(this.operation.state.error);
+ throw this.operation.state.error;
+ }
+ }
+ if (this.operation.state.isCancelled) {
+ this.stopped = true;
+ if (!this.resolveOnUnsuccessful) {
+ const error = new PollerCancelledError("Operation was canceled");
+ this.reject(error);
+ throw error;
+ }
+ }
+ if (this.isDone() && this.resolve) {
+ // If the poller has finished polling, this means we now have a result.
+ // However, it can be the case that TResult is instantiated to void, so
+ // we are not expecting a result anyway. To assert that we might not
+ // have a result eventually after finishing polling, we cast the result
+ // to TResult.
+ this.resolve(this.getResult());
+ }
+ }
+ /**
+ * Returns a promise that will resolve once the underlying operation is completed.
+ */
+ async pollUntilDone(pollOptions = {}) {
+ if (this.stopped) {
+ this.startPolling(pollOptions).catch(this.reject);
+ }
+ // This is needed because the state could have been updated by
+ // `cancelOperation`, e.g. the operation is canceled or an error occurred.
+ this.processUpdatedState();
+ return this.promise;
+ }
+ /**
+ * Invokes the provided callback after each polling is completed,
+ * sending the current state of the poller's operation.
+ *
+ * It returns a method that can be used to stop receiving updates on the given callback function.
+ */
+ onProgress(callback) {
+ this.pollProgressCallbacks.push(callback);
+ return () => {
+ this.pollProgressCallbacks = this.pollProgressCallbacks.filter((c) => c !== callback);
+ };
+ }
+ /**
+ * Returns true if the poller has finished polling.
+ */
+ isDone() {
+ const state = this.operation.state;
+ return Boolean(state.isCompleted || state.isCancelled || state.error);
+ }
+ /**
+ * Stops the poller from continuing to poll.
+ */
+ stopPolling() {
+ if (!this.stopped) {
+ this.stopped = true;
+ if (this.reject) {
+ this.reject(new PollerStoppedError("This poller is already stopped"));
+ }
+ }
+ }
+ /**
+ * Returns true if the poller is stopped.
+ */
+ isStopped() {
+ return this.stopped;
+ }
+ /**
+ * Attempts to cancel the underlying operation.
+ *
+ * It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
+ *
+ * If it's called again before it finishes, it will throw an error.
+ *
+ * @param options - Optional properties passed to the operation's update method.
+ */
+ cancelOperation(options = {}) {
+ if (!this.cancelPromise) {
+ this.cancelPromise = this.cancelOnce(options);
+ }
+ else if (options.abortSignal) {
+ throw new Error("A cancel request is currently pending");
+ }
+ return this.cancelPromise;
+ }
+ /**
+ * Returns the state of the operation.
+ *
+ * Even though TState will be the same type inside any of the methods of any extension of the Poller class,
+ * implementations of the pollers can customize what's shared with the public by writing their own
+ * version of the `getOperationState` method, and by defining two types, one representing the internal state of the poller
+ * and a public type representing a safe to share subset of the properties of the internal state.
+ * Their definition of getOperationState can then return their public type.
+ *
+ * Example:
+ *
+ * ```ts
+ * // Let's say we have our poller's operation state defined as:
+ * interface MyOperationState extends PollOperationState {
+ * privateProperty?: string;
+ * publicProperty?: string;
+ * }
+ *
+ * // To allow us to have a true separation of public and private state, we have to define another interface:
+ * interface PublicState extends PollOperationState {
+ * publicProperty?: string;
+ * }
+ *
+ * // Then, we define our Poller as follows:
+ * export class MyPoller extends Poller {
+ * // ... More content is needed here ...
+ *
+ * public getOperationState(): PublicState {
+ * const state: PublicState = this.operation.state;
+ * return {
+ * // Properties from PollOperationState
+ * isStarted: state.isStarted,
+ * isCompleted: state.isCompleted,
+ * isCancelled: state.isCancelled,
+ * error: state.error,
+ * result: state.result,
+ *
+ * // The only other property needed by PublicState.
+ * publicProperty: state.publicProperty
+ * }
+ * }
+ * }
+ * ```
+ *
+ * You can see this in the tests of this repository, go to the file:
+ * `../test/utils/testPoller.ts`
+ * and look for the getOperationState implementation.
+ */
+ getOperationState() {
+ return this.operation.state;
+ }
+ /**
+ * Returns the result value of the operation,
+ * regardless of the state of the poller.
+ * It can return undefined or an incomplete form of the final TResult value
+ * depending on the implementation.
+ */
+ getResult() {
+ const state = this.operation.state;
+ return state.result;
+ }
+ /**
+ * Returns a serialized version of the poller's operation
+ * by invoking the operation's toString method.
+ */
+ toString() {
+ return this.operation.toString();
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The LRO Engine, a class that performs polling.
+ */
+class LroEngine extends Poller {
+ constructor(lro, options) {
+ const { intervalInMs = POLL_INTERVAL_IN_MS, resumeFrom, resolveOnUnsuccessful = false, isDone, lroResourceLocationConfig, processResult, updateState, } = options || {};
+ const state = resumeFrom
+ ? deserializeState(resumeFrom)
+ : {};
+ const operation = new GenericPollOperation(state, lro, !resolveOnUnsuccessful, lroResourceLocationConfig, processResult, updateState, isDone);
+ super(operation);
+ this.resolveOnUnsuccessful = resolveOnUnsuccessful;
+ this.config = { intervalInMs: intervalInMs };
+ operation.setPollerConfig(this.config);
+ }
+ /**
+ * The method used by the poller to wait before attempting to update its operation.
+ */
+ delay() {
+ return new Promise((resolve) => setTimeout(() => resolve(), this.config.intervalInMs));
+ }
+}
+
+exports.LroEngine = LroEngine;
+exports.Poller = Poller;
+exports.PollerCancelledError = PollerCancelledError;
+exports.PollerStoppedError = PollerStoppedError;
+exports.createHttpPoller = createHttpPoller;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 8121:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var logger$1 = __nccwpck_require__(3233);
+var coreUtil = __nccwpck_require__(1333);
+var os = __nccwpck_require__(2037);
+var abortController = __nccwpck_require__(2557);
+var FormData = __nccwpck_require__(4334);
+var httpsProxyAgent = __nccwpck_require__(7219);
+var httpProxyAgent = __nccwpck_require__(3764);
+var coreTracing = __nccwpck_require__(4175);
+var util = __nccwpck_require__(3837);
+var http = __nccwpck_require__(3685);
+var https = __nccwpck_require__(5687);
+var zlib = __nccwpck_require__(9796);
+var stream = __nccwpck_require__(2781);
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+function _interopNamespace(e) {
+ if (e && e.__esModule) return e;
+ var n = Object.create(null);
+ if (e) {
+ Object.keys(e).forEach(function (k) {
+ if (k !== 'default') {
+ var d = Object.getOwnPropertyDescriptor(e, k);
+ Object.defineProperty(n, k, d.get ? d : {
+ enumerable: true,
+ get: function () { return e[k]; }
+ });
+ }
+ });
+ }
+ n["default"] = e;
+ return Object.freeze(n);
+}
+
+var os__namespace = /*#__PURE__*/_interopNamespace(os);
+var FormData__default = /*#__PURE__*/_interopDefaultLegacy(FormData);
+var http__namespace = /*#__PURE__*/_interopNamespace(http);
+var https__namespace = /*#__PURE__*/_interopNamespace(https);
+var zlib__namespace = /*#__PURE__*/_interopNamespace(zlib);
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+const ValidPhaseNames = new Set(["Deserialize", "Serialize", "Retry", "Sign"]);
+/**
+ * A private implementation of Pipeline.
+ * Do not export this class from the package.
+ * @internal
+ */
+class HttpPipeline {
+ constructor(policies) {
+ var _a;
+ this._policies = [];
+ this._policies = (_a = policies === null || policies === void 0 ? void 0 : policies.slice(0)) !== null && _a !== void 0 ? _a : [];
+ this._orderedPolicies = undefined;
+ }
+ addPolicy(policy, options = {}) {
+ if (options.phase && options.afterPhase) {
+ throw new Error("Policies inside a phase cannot specify afterPhase.");
+ }
+ if (options.phase && !ValidPhaseNames.has(options.phase)) {
+ throw new Error(`Invalid phase name: ${options.phase}`);
+ }
+ if (options.afterPhase && !ValidPhaseNames.has(options.afterPhase)) {
+ throw new Error(`Invalid afterPhase name: ${options.afterPhase}`);
+ }
+ this._policies.push({
+ policy,
+ options,
+ });
+ this._orderedPolicies = undefined;
+ }
+ removePolicy(options) {
+ const removedPolicies = [];
+ this._policies = this._policies.filter((policyDescriptor) => {
+ if ((options.name && policyDescriptor.policy.name === options.name) ||
+ (options.phase && policyDescriptor.options.phase === options.phase)) {
+ removedPolicies.push(policyDescriptor.policy);
+ return false;
+ }
+ else {
+ return true;
+ }
+ });
+ this._orderedPolicies = undefined;
+ return removedPolicies;
+ }
+ sendRequest(httpClient, request) {
+ const policies = this.getOrderedPolicies();
+ const pipeline = policies.reduceRight((next, policy) => {
+ return (req) => {
+ return policy.sendRequest(req, next);
+ };
+ }, (req) => httpClient.sendRequest(req));
+ return pipeline(request);
+ }
+ getOrderedPolicies() {
+ if (!this._orderedPolicies) {
+ this._orderedPolicies = this.orderPolicies();
+ }
+ return this._orderedPolicies;
+ }
+ clone() {
+ return new HttpPipeline(this._policies);
+ }
+ static create() {
+ return new HttpPipeline();
+ }
+ orderPolicies() {
+ /**
+ * The goal of this method is to reliably order pipeline policies
+ * based on their declared requirements when they were added.
+ *
+ * Order is first determined by phase:
+ *
+ * 1. Serialize Phase
+ * 2. Policies not in a phase
+ * 3. Deserialize Phase
+ * 4. Retry Phase
+ * 5. Sign Phase
+ *
+ * Within each phase, policies are executed in the order
+ * they were added unless they were specified to execute
+ * before/after other policies or after a particular phase.
+ *
+ * To determine the final order, we will walk the policy list
+ * in phase order multiple times until all dependencies are
+ * satisfied.
+ *
+ * `afterPolicies` are the set of policies that must be
+ * executed before a given policy. This requirement is
+ * considered satisfied when each of the listed policies
+ * have been scheduled.
+ *
+ * `beforePolicies` are the set of policies that must be
+ * executed after a given policy. Since this dependency
+ * can be expressed by converting it into a equivalent
+ * `afterPolicies` declarations, they are normalized
+ * into that form for simplicity.
+ *
+ * An `afterPhase` dependency is considered satisfied when all
+ * policies in that phase have scheduled.
+ *
+ */
+ const result = [];
+ // Track all policies we know about.
+ const policyMap = new Map();
+ function createPhase(name) {
+ return {
+ name,
+ policies: new Set(),
+ hasRun: false,
+ hasAfterPolicies: false,
+ };
+ }
+ // Track policies for each phase.
+ const serializePhase = createPhase("Serialize");
+ const noPhase = createPhase("None");
+ const deserializePhase = createPhase("Deserialize");
+ const retryPhase = createPhase("Retry");
+ const signPhase = createPhase("Sign");
+ // a list of phases in order
+ const orderedPhases = [serializePhase, noPhase, deserializePhase, retryPhase, signPhase];
+ // Small helper function to map phase name to each Phase
+ function getPhase(phase) {
+ if (phase === "Retry") {
+ return retryPhase;
+ }
+ else if (phase === "Serialize") {
+ return serializePhase;
+ }
+ else if (phase === "Deserialize") {
+ return deserializePhase;
+ }
+ else if (phase === "Sign") {
+ return signPhase;
+ }
+ else {
+ return noPhase;
+ }
+ }
+ // First walk each policy and create a node to track metadata.
+ for (const descriptor of this._policies) {
+ const policy = descriptor.policy;
+ const options = descriptor.options;
+ const policyName = policy.name;
+ if (policyMap.has(policyName)) {
+ throw new Error("Duplicate policy names not allowed in pipeline");
+ }
+ const node = {
+ policy,
+ dependsOn: new Set(),
+ dependants: new Set(),
+ };
+ if (options.afterPhase) {
+ node.afterPhase = getPhase(options.afterPhase);
+ node.afterPhase.hasAfterPolicies = true;
+ }
+ policyMap.set(policyName, node);
+ const phase = getPhase(options.phase);
+ phase.policies.add(node);
+ }
+ // Now that each policy has a node, connect dependency references.
+ for (const descriptor of this._policies) {
+ const { policy, options } = descriptor;
+ const policyName = policy.name;
+ const node = policyMap.get(policyName);
+ if (!node) {
+ throw new Error(`Missing node for policy ${policyName}`);
+ }
+ if (options.afterPolicies) {
+ for (const afterPolicyName of options.afterPolicies) {
+ const afterNode = policyMap.get(afterPolicyName);
+ if (afterNode) {
+ // Linking in both directions helps later
+ // when we want to notify dependants.
+ node.dependsOn.add(afterNode);
+ afterNode.dependants.add(node);
+ }
+ }
+ }
+ if (options.beforePolicies) {
+ for (const beforePolicyName of options.beforePolicies) {
+ const beforeNode = policyMap.get(beforePolicyName);
+ if (beforeNode) {
+ // To execute before another node, make it
+ // depend on the current node.
+ beforeNode.dependsOn.add(node);
+ node.dependants.add(beforeNode);
+ }
+ }
+ }
+ }
+ function walkPhase(phase) {
+ phase.hasRun = true;
+ // Sets iterate in insertion order
+ for (const node of phase.policies) {
+ if (node.afterPhase && (!node.afterPhase.hasRun || node.afterPhase.policies.size)) {
+ // If this node is waiting on a phase to complete,
+ // we need to skip it for now.
+ // Even if the phase is empty, we should wait for it
+ // to be walked to avoid re-ordering policies.
+ continue;
+ }
+ if (node.dependsOn.size === 0) {
+ // If there's nothing else we're waiting for, we can
+ // add this policy to the result list.
+ result.push(node.policy);
+ // Notify anything that depends on this policy that
+ // the policy has been scheduled.
+ for (const dependant of node.dependants) {
+ dependant.dependsOn.delete(node);
+ }
+ policyMap.delete(node.policy.name);
+ phase.policies.delete(node);
+ }
+ }
+ }
+ function walkPhases() {
+ for (const phase of orderedPhases) {
+ walkPhase(phase);
+ // if the phase isn't complete
+ if (phase.policies.size > 0 && phase !== noPhase) {
+ if (!noPhase.hasRun) {
+ // Try running noPhase to see if that unblocks this phase next tick.
+ // This can happen if a phase that happens before noPhase
+ // is waiting on a noPhase policy to complete.
+ walkPhase(noPhase);
+ }
+ // Don't proceed to the next phase until this phase finishes.
+ return;
+ }
+ if (phase.hasAfterPolicies) {
+ // Run any policies unblocked by this phase
+ walkPhase(noPhase);
+ }
+ }
+ }
+ // Iterate until we've put every node in the result list.
+ let iteration = 0;
+ while (policyMap.size > 0) {
+ iteration++;
+ const initialResultLength = result.length;
+ // Keep walking each phase in order until we can order every node.
+ walkPhases();
+ // The result list *should* get at least one larger each time
+ // after the first full pass.
+ // Otherwise, we're going to loop forever.
+ if (result.length <= initialResultLength && iteration > 1) {
+ throw new Error("Cannot satisfy policy dependencies due to requirements cycle.");
+ }
+ }
+ return result;
+ }
+}
+/**
+ * Creates a totally empty pipeline.
+ * Useful for testing or creating a custom one.
+ */
+function createEmptyPipeline() {
+ return HttpPipeline.create();
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger = logger$1.createClientLogger("core-rest-pipeline");
+
+// Copyright (c) Microsoft Corporation.
+const RedactedString = "REDACTED";
+// Make sure this list is up-to-date with the one under core/logger/Readme#Keyconcepts
+const defaultAllowedHeaderNames = [
+ "x-ms-client-request-id",
+ "x-ms-return-client-request-id",
+ "x-ms-useragent",
+ "x-ms-correlation-request-id",
+ "x-ms-request-id",
+ "client-request-id",
+ "ms-cv",
+ "return-client-request-id",
+ "traceparent",
+ "Access-Control-Allow-Credentials",
+ "Access-Control-Allow-Headers",
+ "Access-Control-Allow-Methods",
+ "Access-Control-Allow-Origin",
+ "Access-Control-Expose-Headers",
+ "Access-Control-Max-Age",
+ "Access-Control-Request-Headers",
+ "Access-Control-Request-Method",
+ "Origin",
+ "Accept",
+ "Accept-Encoding",
+ "Cache-Control",
+ "Connection",
+ "Content-Length",
+ "Content-Type",
+ "Date",
+ "ETag",
+ "Expires",
+ "If-Match",
+ "If-Modified-Since",
+ "If-None-Match",
+ "If-Unmodified-Since",
+ "Last-Modified",
+ "Pragma",
+ "Request-Id",
+ "Retry-After",
+ "Server",
+ "Transfer-Encoding",
+ "User-Agent",
+ "WWW-Authenticate",
+];
+const defaultAllowedQueryParameters = ["api-version"];
+/**
+ * @internal
+ */
+class Sanitizer {
+ constructor({ additionalAllowedHeaderNames: allowedHeaderNames = [], additionalAllowedQueryParameters: allowedQueryParameters = [], } = {}) {
+ allowedHeaderNames = defaultAllowedHeaderNames.concat(allowedHeaderNames);
+ allowedQueryParameters = defaultAllowedQueryParameters.concat(allowedQueryParameters);
+ this.allowedHeaderNames = new Set(allowedHeaderNames.map((n) => n.toLowerCase()));
+ this.allowedQueryParameters = new Set(allowedQueryParameters.map((p) => p.toLowerCase()));
+ }
+ sanitize(obj) {
+ const seen = new Set();
+ return JSON.stringify(obj, (key, value) => {
+ // Ensure Errors include their interesting non-enumerable members
+ if (value instanceof Error) {
+ return Object.assign(Object.assign({}, value), { name: value.name, message: value.message });
+ }
+ if (key === "headers") {
+ return this.sanitizeHeaders(value);
+ }
+ else if (key === "url") {
+ return this.sanitizeUrl(value);
+ }
+ else if (key === "query") {
+ return this.sanitizeQuery(value);
+ }
+ else if (key === "body") {
+ // Don't log the request body
+ return undefined;
+ }
+ else if (key === "response") {
+ // Don't log response again
+ return undefined;
+ }
+ else if (key === "operationSpec") {
+ // When using sendOperationRequest, the request carries a massive
+ // field with the autorest spec. No need to log it.
+ return undefined;
+ }
+ else if (Array.isArray(value) || coreUtil.isObject(value)) {
+ if (seen.has(value)) {
+ return "[Circular]";
+ }
+ seen.add(value);
+ }
+ return value;
+ }, 2);
+ }
+ sanitizeHeaders(obj) {
+ const sanitized = {};
+ for (const key of Object.keys(obj)) {
+ if (this.allowedHeaderNames.has(key.toLowerCase())) {
+ sanitized[key] = obj[key];
+ }
+ else {
+ sanitized[key] = RedactedString;
+ }
+ }
+ return sanitized;
+ }
+ sanitizeQuery(value) {
+ if (typeof value !== "object" || value === null) {
+ return value;
+ }
+ const sanitized = {};
+ for (const k of Object.keys(value)) {
+ if (this.allowedQueryParameters.has(k.toLowerCase())) {
+ sanitized[k] = value[k];
+ }
+ else {
+ sanitized[k] = RedactedString;
+ }
+ }
+ return sanitized;
+ }
+ sanitizeUrl(value) {
+ if (typeof value !== "string" || value === null) {
+ return value;
+ }
+ const url = new URL(value);
+ if (!url.search) {
+ return value;
+ }
+ for (const [key] of url.searchParams) {
+ if (!this.allowedQueryParameters.has(key.toLowerCase())) {
+ url.searchParams.set(key, RedactedString);
+ }
+ }
+ return url.toString();
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the logPolicy.
+ */
+const logPolicyName = "logPolicy";
+/**
+ * A policy that logs all requests and responses.
+ * @param options - Options to configure logPolicy.
+ */
+function logPolicy(options = {}) {
+ var _a;
+ const logger$1 = (_a = options.logger) !== null && _a !== void 0 ? _a : logger.info;
+ const sanitizer = new Sanitizer({
+ additionalAllowedHeaderNames: options.additionalAllowedHeaderNames,
+ additionalAllowedQueryParameters: options.additionalAllowedQueryParameters,
+ });
+ return {
+ name: logPolicyName,
+ async sendRequest(request, next) {
+ if (!logger$1.enabled) {
+ return next(request);
+ }
+ logger$1(`Request: ${sanitizer.sanitize(request)}`);
+ const response = await next(request);
+ logger$1(`Response status code: ${response.status}`);
+ logger$1(`Headers: ${sanitizer.sanitize(response.headers)}`);
+ return response;
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The programmatic identifier of the redirectPolicy.
+ */
+const redirectPolicyName = "redirectPolicy";
+/**
+ * Methods that are allowed to follow redirects 301 and 302
+ */
+const allowedRedirect = ["GET", "HEAD"];
+/**
+ * A policy to follow Location headers from the server in order
+ * to support server-side redirection.
+ * In the browser, this policy is not used.
+ * @param options - Options to control policy behavior.
+ */
+function redirectPolicy(options = {}) {
+ const { maxRetries = 20 } = options;
+ return {
+ name: redirectPolicyName,
+ async sendRequest(request, next) {
+ const response = await next(request);
+ return handleRedirect(next, response, maxRetries);
+ },
+ };
+}
+async function handleRedirect(next, response, maxRetries, currentRetries = 0) {
+ const { request, status, headers } = response;
+ const locationHeader = headers.get("location");
+ if (locationHeader &&
+ (status === 300 ||
+ (status === 301 && allowedRedirect.includes(request.method)) ||
+ (status === 302 && allowedRedirect.includes(request.method)) ||
+ (status === 303 && request.method === "POST") ||
+ status === 307) &&
+ currentRetries < maxRetries) {
+ const url = new URL(locationHeader, request.url);
+ request.url = url.toString();
+ // 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 (status === 303) {
+ request.method = "GET";
+ request.headers.delete("Content-Length");
+ delete request.body;
+ }
+ request.headers.delete("Authorization");
+ const res = await next(request);
+ return handleRedirect(next, res, maxRetries, currentRetries + 1);
+ }
+ return response;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * @internal
+ */
+function getHeaderName() {
+ return "User-Agent";
+}
+/**
+ * @internal
+ */
+function setPlatformSpecificData(map) {
+ map.set("Node", process.version);
+ map.set("OS", `(${os__namespace.arch()}-${os__namespace.type()}-${os__namespace.release()})`);
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+const SDK_VERSION = "1.12.0";
+const DEFAULT_RETRY_POLICY_COUNT = 3;
+
+// Copyright (c) Microsoft Corporation.
+function getUserAgentString(telemetryInfo) {
+ const parts = [];
+ for (const [key, value] of telemetryInfo) {
+ const token = value ? `${key}/${value}` : key;
+ parts.push(token);
+ }
+ return parts.join(" ");
+}
+/**
+ * @internal
+ */
+function getUserAgentHeaderName() {
+ return getHeaderName();
+}
+/**
+ * @internal
+ */
+function getUserAgentValue(prefix) {
+ const runtimeInfo = new Map();
+ runtimeInfo.set("core-rest-pipeline", SDK_VERSION);
+ setPlatformSpecificData(runtimeInfo);
+ const defaultAgent = getUserAgentString(runtimeInfo);
+ const userAgentValue = prefix ? `${prefix} ${defaultAgent}` : defaultAgent;
+ return userAgentValue;
+}
+
+// Copyright (c) Microsoft Corporation.
+const UserAgentHeaderName = getUserAgentHeaderName();
+/**
+ * The programmatic identifier of the userAgentPolicy.
+ */
+const userAgentPolicyName = "userAgentPolicy";
+/**
+ * A policy that sets the User-Agent header (or equivalent) to reflect
+ * the library version.
+ * @param options - Options to customize the user agent value.
+ */
+function userAgentPolicy(options = {}) {
+ const userAgentValue = getUserAgentValue(options.userAgentPrefix);
+ return {
+ name: userAgentPolicyName,
+ async sendRequest(request, next) {
+ if (!request.headers.has(UserAgentHeaderName)) {
+ request.headers.set(UserAgentHeaderName, userAgentValue);
+ }
+ return next(request);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The programmatic identifier of the decompressResponsePolicy.
+ */
+const decompressResponsePolicyName = "decompressResponsePolicy";
+/**
+ * A policy to enable response decompression according to Accept-Encoding header
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding
+ */
+function decompressResponsePolicy() {
+ return {
+ name: decompressResponsePolicyName,
+ async sendRequest(request, next) {
+ // HEAD requests have no body
+ if (request.method !== "HEAD") {
+ request.headers.set("Accept-Encoding", "gzip,deflate");
+ }
+ return next(request);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+const StandardAbortMessage = "The operation was aborted.";
+/**
+ * A wrapper for setTimeout that resolves a promise after delayInMs milliseconds.
+ * @param delayInMs - The number of milliseconds to be delayed.
+ * @param value - The value to be resolved with after a timeout of t milliseconds.
+ * @param options - The options for delay - currently abort options
+ * - abortSignal - The abortSignal associated with containing operation.
+ * - abortErrorMsg - The abort error message associated with containing operation.
+ * @returns Resolved promise
+ */
+function delay(delayInMs, value, options) {
+ return new Promise((resolve, reject) => {
+ let timer = undefined;
+ let onAborted = undefined;
+ const rejectOnAbort = () => {
+ return reject(new abortController.AbortError((options === null || options === void 0 ? void 0 : options.abortErrorMsg) ? options === null || options === void 0 ? void 0 : options.abortErrorMsg : StandardAbortMessage));
+ };
+ const removeListeners = () => {
+ if ((options === null || options === void 0 ? void 0 : options.abortSignal) && onAborted) {
+ options.abortSignal.removeEventListener("abort", onAborted);
+ }
+ };
+ onAborted = () => {
+ if (timer) {
+ clearTimeout(timer);
+ }
+ removeListeners();
+ return rejectOnAbort();
+ };
+ if ((options === null || options === void 0 ? void 0 : options.abortSignal) && options.abortSignal.aborted) {
+ return rejectOnAbort();
+ }
+ timer = setTimeout(() => {
+ removeListeners();
+ resolve(value);
+ }, delayInMs);
+ if (options === null || options === void 0 ? void 0 : options.abortSignal) {
+ options.abortSignal.addEventListener("abort", onAborted);
+ }
+ });
+}
+/**
+ * @internal
+ * @returns the parsed value or undefined if the parsed value is invalid.
+ */
+function parseHeaderValueAsNumber(response, headerName) {
+ const value = response.headers.get(headerName);
+ if (!value)
+ return;
+ const valueAsNum = Number(value);
+ if (Number.isNaN(valueAsNum))
+ return;
+ return valueAsNum;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The header that comes back from Azure services representing
+ * the amount of time (minimum) to wait to retry (in seconds or timestamp after which we can retry).
+ */
+const RetryAfterHeader = "Retry-After";
+/**
+ * The headers that come back from Azure services representing
+ * the amount of time (minimum) to wait to retry.
+ *
+ * "retry-after-ms", "x-ms-retry-after-ms" : milliseconds
+ * "Retry-After" : seconds or timestamp
+ */
+const AllRetryAfterHeaders = ["retry-after-ms", "x-ms-retry-after-ms", RetryAfterHeader];
+/**
+ * A response is a throttling retry response if it has a throttling status code (429 or 503),
+ * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
+ *
+ * Returns the `retryAfterInMs` value if the response is a throttling retry response.
+ * If not throttling retry response, returns `undefined`.
+ *
+ * @internal
+ */
+function getRetryAfterInMs(response) {
+ if (!(response && [429, 503].includes(response.status)))
+ return undefined;
+ try {
+ // Headers: "retry-after-ms", "x-ms-retry-after-ms", "Retry-After"
+ for (const header of AllRetryAfterHeaders) {
+ const retryAfterValue = parseHeaderValueAsNumber(response, header);
+ if (retryAfterValue === 0 || retryAfterValue) {
+ // "Retry-After" header ==> seconds
+ // "retry-after-ms", "x-ms-retry-after-ms" headers ==> milli-seconds
+ const multiplyingFactor = header === RetryAfterHeader ? 1000 : 1;
+ return retryAfterValue * multiplyingFactor; // in milli-seconds
+ }
+ }
+ // RetryAfterHeader ("Retry-After") has a special case where it might be formatted as a date instead of a number of seconds
+ const retryAfterHeader = response.headers.get(RetryAfterHeader);
+ if (!retryAfterHeader)
+ return;
+ const date = Date.parse(retryAfterHeader);
+ const diff = date - Date.now();
+ // negative diff would mean a date in the past, so retry asap with 0 milliseconds
+ return Number.isFinite(diff) ? Math.max(0, diff) : undefined;
+ }
+ catch (e) {
+ return undefined;
+ }
+}
+/**
+ * A response is a retry response if it has a throttling status code (429 or 503),
+ * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
+ */
+function isThrottlingRetryResponse(response) {
+ return Number.isFinite(getRetryAfterInMs(response));
+}
+function throttlingRetryStrategy() {
+ return {
+ name: "throttlingRetryStrategy",
+ retry({ response }) {
+ const retryAfterInMs = getRetryAfterInMs(response);
+ if (!Number.isFinite(retryAfterInMs)) {
+ return { skipStrategy: true };
+ }
+ return {
+ retryAfterInMs,
+ };
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// intervals are in milliseconds
+const DEFAULT_CLIENT_RETRY_INTERVAL = 1000;
+const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
+/**
+ * A retry strategy that retries with an exponentially increasing delay in these two cases:
+ * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
+ * - Or otherwise if the outgoing request fails (408, greater or equal than 500, except for 501 and 505).
+ */
+function exponentialRetryStrategy(options = {}) {
+ var _a, _b;
+ const retryInterval = (_a = options.retryDelayInMs) !== null && _a !== void 0 ? _a : DEFAULT_CLIENT_RETRY_INTERVAL;
+ const maxRetryInterval = (_b = options.maxRetryDelayInMs) !== null && _b !== void 0 ? _b : DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
+ let retryAfterInMs = retryInterval;
+ return {
+ name: "exponentialRetryStrategy",
+ retry({ retryCount, response, responseError }) {
+ const matchedSystemError = isSystemError(responseError);
+ const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors;
+ const isExponential = isExponentialRetryResponse(response);
+ const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes;
+ const unknownResponse = response && (isThrottlingRetryResponse(response) || !isExponential);
+ if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) {
+ return { skipStrategy: true };
+ }
+ if (responseError && !matchedSystemError && !isExponential) {
+ return { errorToThrow: responseError };
+ }
+ // Exponentially increase the delay each time
+ const exponentialDelay = retryAfterInMs * Math.pow(2, retryCount);
+ // Don't let the delay exceed the maximum
+ const clampedExponentialDelay = Math.min(maxRetryInterval, exponentialDelay);
+ // Allow the final value to have some "jitter" (within 50% of the delay size) so
+ // that retries across multiple clients don't occur simultaneously.
+ retryAfterInMs =
+ clampedExponentialDelay / 2 + coreUtil.getRandomIntegerInclusive(0, clampedExponentialDelay / 2);
+ return { retryAfterInMs };
+ },
+ };
+}
+/**
+ * A response is a retry response if it has status codes:
+ * - 408, or
+ * - Greater or equal than 500, except for 501 and 505.
+ */
+function isExponentialRetryResponse(response) {
+ return Boolean(response &&
+ response.status !== undefined &&
+ (response.status >= 500 || response.status === 408) &&
+ response.status !== 501 &&
+ response.status !== 505);
+}
+/**
+ * Determines whether an error from a pipeline response was triggered in the network layer.
+ */
+function isSystemError(err) {
+ if (!err) {
+ return false;
+ }
+ return (err.code === "ETIMEDOUT" ||
+ err.code === "ESOCKETTIMEDOUT" ||
+ err.code === "ECONNREFUSED" ||
+ err.code === "ECONNRESET" ||
+ err.code === "ENOENT");
+}
+
+// Copyright (c) Microsoft Corporation.
+const retryPolicyLogger = logger$1.createClientLogger("core-rest-pipeline retryPolicy");
+/**
+ * The programmatic identifier of the retryPolicy.
+ */
+const retryPolicyName = "retryPolicy";
+/**
+ * retryPolicy is a generic policy to enable retrying requests when certain conditions are met
+ */
+function retryPolicy(strategies, options = { maxRetries: DEFAULT_RETRY_POLICY_COUNT }) {
+ const logger = options.logger || retryPolicyLogger;
+ return {
+ name: retryPolicyName,
+ async sendRequest(request, next) {
+ var _a, _b;
+ let response;
+ let responseError;
+ let retryCount = -1;
+ // eslint-disable-next-line no-constant-condition
+ retryRequest: while (true) {
+ retryCount += 1;
+ response = undefined;
+ responseError = undefined;
+ try {
+ logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId);
+ response = await next(request);
+ logger.info(`Retry ${retryCount}: Received a response from request`, request.requestId);
+ }
+ catch (e) {
+ logger.error(`Retry ${retryCount}: Received an error from request`, request.requestId);
+ // RestErrors are valid targets for the retry strategies.
+ // If none of the retry strategies can work with them, they will be thrown later in this policy.
+ // If the received error is not a RestError, it is immediately thrown.
+ responseError = e;
+ if (!e || responseError.name !== "RestError") {
+ throw e;
+ }
+ response = responseError.response;
+ }
+ if ((_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) {
+ logger.error(`Retry ${retryCount}: Request aborted.`);
+ const abortError = new abortController.AbortError();
+ throw abortError;
+ }
+ if (retryCount >= ((_b = options.maxRetries) !== null && _b !== void 0 ? _b : DEFAULT_RETRY_POLICY_COUNT)) {
+ logger.info(`Retry ${retryCount}: Maximum retries reached. Returning the last received response, or throwing the last received error.`);
+ if (responseError) {
+ throw responseError;
+ }
+ else if (response) {
+ return response;
+ }
+ else {
+ throw new Error("Maximum retries reached with no response or error to throw");
+ }
+ }
+ logger.info(`Retry ${retryCount}: Processing ${strategies.length} retry strategies.`);
+ strategiesLoop: for (const strategy of strategies) {
+ const strategyLogger = strategy.logger || retryPolicyLogger;
+ strategyLogger.info(`Retry ${retryCount}: Processing retry strategy ${strategy.name}.`);
+ const modifiers = strategy.retry({
+ retryCount,
+ response,
+ responseError,
+ });
+ if (modifiers.skipStrategy) {
+ strategyLogger.info(`Retry ${retryCount}: Skipped.`);
+ continue strategiesLoop;
+ }
+ const { errorToThrow, retryAfterInMs, redirectTo } = modifiers;
+ if (errorToThrow) {
+ strategyLogger.error(`Retry ${retryCount}: Retry strategy ${strategy.name} throws error:`, errorToThrow);
+ throw errorToThrow;
+ }
+ if (retryAfterInMs || retryAfterInMs === 0) {
+ strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} retries after ${retryAfterInMs}`);
+ await delay(retryAfterInMs, undefined, { abortSignal: request.abortSignal });
+ continue retryRequest;
+ }
+ if (redirectTo) {
+ strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} redirects to ${redirectTo}`);
+ request.url = redirectTo;
+ continue retryRequest;
+ }
+ }
+ if (responseError) {
+ logger.info(`None of the retry strategies could work with the received error. Throwing it.`);
+ throw responseError;
+ }
+ if (response) {
+ logger.info(`None of the retry strategies could work with the received response. Returning it.`);
+ return response;
+ }
+ // If all the retries skip and there's no response,
+ // we're still in the retry loop, so a new request will be sent
+ // until `maxRetries` is reached.
+ }
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Name of the {@link defaultRetryPolicy}
+ */
+const defaultRetryPolicyName = "defaultRetryPolicy";
+/**
+ * A policy that retries according to three strategies:
+ * - When the server sends a 429 response with a Retry-After header.
+ * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
+ * - Or otherwise if the outgoing request fails, it will retry with an exponentially increasing delay.
+ */
+function defaultRetryPolicy(options = {}) {
+ var _a;
+ return {
+ name: defaultRetryPolicyName,
+ sendRequest: retryPolicy([throttlingRetryStrategy(), exponentialRetryStrategy(options)], {
+ maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
+ }).sendRequest,
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the formDataPolicy.
+ */
+const formDataPolicyName = "formDataPolicy";
+/**
+ * A policy that encodes FormData on the request into the body.
+ */
+function formDataPolicy() {
+ return {
+ name: formDataPolicyName,
+ async sendRequest(request, next) {
+ if (request.formData) {
+ const contentType = request.headers.get("Content-Type");
+ if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) {
+ request.body = wwwFormUrlEncode(request.formData);
+ request.formData = undefined;
+ }
+ else {
+ await prepareFormData(request.formData, request);
+ }
+ }
+ return next(request);
+ },
+ };
+}
+function wwwFormUrlEncode(formData) {
+ const urlSearchParams = new URLSearchParams();
+ for (const [key, value] of Object.entries(formData)) {
+ if (Array.isArray(value)) {
+ for (const subValue of value) {
+ urlSearchParams.append(key, subValue.toString());
+ }
+ }
+ else {
+ urlSearchParams.append(key, value.toString());
+ }
+ }
+ return urlSearchParams.toString();
+}
+async function prepareFormData(formData, request) {
+ const requestForm = new FormData__default["default"]();
+ for (const formKey of Object.keys(formData)) {
+ const formValue = formData[formKey];
+ if (Array.isArray(formValue)) {
+ for (const subValue of formValue) {
+ requestForm.append(formKey, subValue);
+ }
+ }
+ else {
+ requestForm.append(formKey, formValue);
+ }
+ }
+ request.body = requestForm;
+ request.formData = undefined;
+ const contentType = request.headers.get("Content-Type");
+ if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
+ request.headers.set("Content-Type", `multipart/form-data; boundary=${requestForm.getBoundary()}`);
+ }
+ try {
+ const contentLength = await new Promise((resolve, reject) => {
+ requestForm.getLength((err, length) => {
+ if (err) {
+ reject(err);
+ }
+ else {
+ resolve(length);
+ }
+ });
+ });
+ request.headers.set("Content-Length", contentLength);
+ }
+ catch (e) {
+ // ignore setting the length if this fails
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const HTTPS_PROXY = "HTTPS_PROXY";
+const HTTP_PROXY = "HTTP_PROXY";
+const ALL_PROXY = "ALL_PROXY";
+const NO_PROXY = "NO_PROXY";
+/**
+ * The programmatic identifier of the proxyPolicy.
+ */
+const proxyPolicyName = "proxyPolicy";
+/**
+ * Stores the patterns specified in NO_PROXY environment variable.
+ * @internal
+ */
+const globalNoProxyList = [];
+let noProxyListLoaded = false;
+/** A cache of whether a host should bypass the proxy. */
+const globalBypassedMap = new Map();
+function getEnvironmentValue(name) {
+ if (process.env[name]) {
+ return process.env[name];
+ }
+ else if (process.env[name.toLowerCase()]) {
+ return process.env[name.toLowerCase()];
+ }
+ return undefined;
+}
+function loadEnvironmentProxyValue() {
+ if (!process) {
+ return undefined;
+ }
+ const httpsProxy = getEnvironmentValue(HTTPS_PROXY);
+ const allProxy = getEnvironmentValue(ALL_PROXY);
+ const httpProxy = getEnvironmentValue(HTTP_PROXY);
+ return httpsProxy || allProxy || httpProxy;
+}
+/**
+ * Check whether the host of a given `uri` matches any pattern in the no proxy list.
+ * If there's a match, any request sent to the same host shouldn't have the proxy settings set.
+ * This implementation is a port of https://github.com/Azure/azure-sdk-for-net/blob/8cca811371159e527159c7eb65602477898683e2/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs#L210
+ */
+function isBypassed(uri, noProxyList, bypassedMap) {
+ if (noProxyList.length === 0) {
+ return false;
+ }
+ const host = new URL(uri).hostname;
+ if (bypassedMap === null || bypassedMap === void 0 ? void 0 : bypassedMap.has(host)) {
+ return bypassedMap.get(host);
+ }
+ let isBypassedFlag = false;
+ for (const pattern of noProxyList) {
+ if (pattern[0] === ".") {
+ // This should match either domain it self or any subdomain or host
+ // .foo.com will match foo.com it self or *.foo.com
+ if (host.endsWith(pattern)) {
+ isBypassedFlag = true;
+ }
+ else {
+ if (host.length === pattern.length - 1 && host === pattern.slice(1)) {
+ isBypassedFlag = true;
+ }
+ }
+ }
+ else {
+ if (host === pattern) {
+ isBypassedFlag = true;
+ }
+ }
+ }
+ bypassedMap === null || bypassedMap === void 0 ? void 0 : bypassedMap.set(host, isBypassedFlag);
+ return isBypassedFlag;
+}
+function loadNoProxy() {
+ const noProxy = getEnvironmentValue(NO_PROXY);
+ noProxyListLoaded = true;
+ if (noProxy) {
+ return noProxy
+ .split(",")
+ .map((item) => item.trim())
+ .filter((item) => item.length);
+ }
+ return [];
+}
+/**
+ * This method converts a proxy url into `ProxySettings` for use with ProxyPolicy.
+ * If no argument is given, it attempts to parse a proxy URL from the environment
+ * variables `HTTPS_PROXY` or `HTTP_PROXY`.
+ * @param proxyUrl - The url of the proxy to use. May contain authentication information.
+ */
+function getDefaultProxySettings(proxyUrl) {
+ if (!proxyUrl) {
+ proxyUrl = loadEnvironmentProxyValue();
+ if (!proxyUrl) {
+ return undefined;
+ }
+ }
+ const parsedUrl = new URL(proxyUrl);
+ const schema = parsedUrl.protocol ? parsedUrl.protocol + "//" : "";
+ return {
+ host: schema + parsedUrl.hostname,
+ port: Number.parseInt(parsedUrl.port || "80"),
+ username: parsedUrl.username,
+ password: parsedUrl.password,
+ };
+}
+/**
+ * @internal
+ */
+function getProxyAgentOptions(proxySettings, { headers, tlsSettings }) {
+ let parsedProxyUrl;
+ try {
+ parsedProxyUrl = new URL(proxySettings.host);
+ }
+ catch (_error) {
+ throw new Error(`Expecting a valid host string in proxy settings, but found "${proxySettings.host}".`);
+ }
+ if (tlsSettings) {
+ logger.warning("TLS settings are not supported in combination with custom Proxy, certificates provided to the client will be ignored.");
+ }
+ const proxyAgentOptions = {
+ hostname: parsedProxyUrl.hostname,
+ port: proxySettings.port,
+ protocol: parsedProxyUrl.protocol,
+ headers: headers.toJSON(),
+ };
+ if (proxySettings.username && proxySettings.password) {
+ proxyAgentOptions.auth = `${proxySettings.username}:${proxySettings.password}`;
+ }
+ else if (proxySettings.username) {
+ proxyAgentOptions.auth = `${proxySettings.username}`;
+ }
+ return proxyAgentOptions;
+}
+function setProxyAgentOnRequest(request, cachedAgents) {
+ // Custom Agent should take precedence so if one is present
+ // we should skip to avoid overwriting it.
+ if (request.agent) {
+ return;
+ }
+ const url = new URL(request.url);
+ const isInsecure = url.protocol !== "https:";
+ const proxySettings = request.proxySettings;
+ if (proxySettings) {
+ if (isInsecure) {
+ if (!cachedAgents.httpProxyAgent) {
+ const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);
+ cachedAgents.httpProxyAgent = new httpProxyAgent.HttpProxyAgent(proxyAgentOptions);
+ }
+ request.agent = cachedAgents.httpProxyAgent;
+ }
+ else {
+ if (!cachedAgents.httpsProxyAgent) {
+ const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);
+ cachedAgents.httpsProxyAgent = new httpsProxyAgent.HttpsProxyAgent(proxyAgentOptions);
+ }
+ request.agent = cachedAgents.httpsProxyAgent;
+ }
+ }
+}
+/**
+ * A policy that allows one to apply proxy settings to all requests.
+ * If not passed static settings, they will be retrieved from the HTTPS_PROXY
+ * or HTTP_PROXY environment variables.
+ * @param proxySettings - ProxySettings to use on each request.
+ * @param options - additional settings, for example, custom NO_PROXY patterns
+ */
+function proxyPolicy(proxySettings = getDefaultProxySettings(), options) {
+ if (!noProxyListLoaded) {
+ globalNoProxyList.push(...loadNoProxy());
+ }
+ const cachedAgents = {};
+ return {
+ name: proxyPolicyName,
+ async sendRequest(request, next) {
+ var _a;
+ if (!request.proxySettings &&
+ !isBypassed(request.url, (_a = options === null || options === void 0 ? void 0 : options.customNoProxyList) !== null && _a !== void 0 ? _a : globalNoProxyList, (options === null || options === void 0 ? void 0 : options.customNoProxyList) ? undefined : globalBypassedMap)) {
+ request.proxySettings = proxySettings;
+ }
+ if (request.proxySettings) {
+ setProxyAgentOnRequest(request, cachedAgents);
+ }
+ return next(request);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The programmatic identifier of the setClientRequestIdPolicy.
+ */
+const setClientRequestIdPolicyName = "setClientRequestIdPolicy";
+/**
+ * Each PipelineRequest gets a unique id upon creation.
+ * This policy passes that unique id along via an HTTP header to enable better
+ * telemetry and tracing.
+ * @param requestIdHeaderName - The name of the header to pass the request ID to.
+ */
+function setClientRequestIdPolicy(requestIdHeaderName = "x-ms-client-request-id") {
+ return {
+ name: setClientRequestIdPolicyName,
+ async sendRequest(request, next) {
+ if (!request.headers.has(requestIdHeaderName)) {
+ request.headers.set(requestIdHeaderName, request.requestId);
+ }
+ return next(request);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Name of the TLS Policy
+ */
+const tlsPolicyName = "tlsPolicy";
+/**
+ * Gets a pipeline policy that adds the client certificate to the HttpClient agent for authentication.
+ */
+function tlsPolicy(tlsSettings) {
+ return {
+ name: tlsPolicyName,
+ sendRequest: async (req, next) => {
+ // Users may define a request tlsSettings, honor those over the client level one
+ if (!req.tlsSettings) {
+ req.tlsSettings = tlsSettings;
+ }
+ return next(req);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+const custom = util.inspect.custom;
+
+// Copyright (c) Microsoft Corporation.
+const errorSanitizer = new Sanitizer();
+/**
+ * A custom error type for failed pipeline requests.
+ */
+class RestError extends Error {
+ constructor(message, options = {}) {
+ super(message);
+ this.name = "RestError";
+ this.code = options.code;
+ this.statusCode = options.statusCode;
+ this.request = options.request;
+ this.response = options.response;
+ Object.setPrototypeOf(this, RestError.prototype);
+ }
+ /**
+ * Logging method for util.inspect in Node
+ */
+ [custom]() {
+ return `RestError: ${this.message} \n ${errorSanitizer.sanitize(this)}`;
+ }
+}
+/**
+ * Something went wrong when making the request.
+ * This means the actual request failed for some reason,
+ * such as a DNS issue or the connection being lost.
+ */
+RestError.REQUEST_SEND_ERROR = "REQUEST_SEND_ERROR";
+/**
+ * This means that parsing the response from the server failed.
+ * It may have been malformed.
+ */
+RestError.PARSE_ERROR = "PARSE_ERROR";
+/**
+ * Typeguard for RestError
+ * @param e - Something caught by a catch clause.
+ */
+function isRestError(e) {
+ if (e instanceof RestError) {
+ return true;
+ }
+ return coreUtil.isError(e) && e.name === "RestError";
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the tracingPolicy.
+ */
+const tracingPolicyName = "tracingPolicy";
+/**
+ * A simple policy to create OpenTelemetry Spans for each request made by the pipeline
+ * that has SpanOptions with a parent.
+ * Requests made without a parent Span will not be recorded.
+ * @param options - Options to configure the telemetry logged by the tracing policy.
+ */
+function tracingPolicy(options = {}) {
+ const userAgent = getUserAgentValue(options.userAgentPrefix);
+ const tracingClient = tryCreateTracingClient();
+ return {
+ name: tracingPolicyName,
+ async sendRequest(request, next) {
+ var _a, _b;
+ if (!tracingClient || !((_a = request.tracingOptions) === null || _a === void 0 ? void 0 : _a.tracingContext)) {
+ return next(request);
+ }
+ const { span, tracingContext } = (_b = tryCreateSpan(tracingClient, request, userAgent)) !== null && _b !== void 0 ? _b : {};
+ if (!span || !tracingContext) {
+ return next(request);
+ }
+ try {
+ const response = await tracingClient.withContext(tracingContext, next, request);
+ tryProcessResponse(span, response);
+ return response;
+ }
+ catch (err) {
+ tryProcessError(span, err);
+ throw err;
+ }
+ },
+ };
+}
+function tryCreateTracingClient() {
+ try {
+ return coreTracing.createTracingClient({
+ namespace: "",
+ packageName: "@azure/core-rest-pipeline",
+ packageVersion: SDK_VERSION,
+ });
+ }
+ catch (e) {
+ logger.warning(`Error when creating the TracingClient: ${coreUtil.getErrorMessage(e)}`);
+ return undefined;
+ }
+}
+function tryCreateSpan(tracingClient, request, userAgent) {
+ try {
+ // As per spec, we do not need to differentiate between HTTP and HTTPS in span name.
+ const { span, updatedOptions } = tracingClient.startSpan(`HTTP ${request.method}`, { tracingOptions: request.tracingOptions }, {
+ spanKind: "client",
+ spanAttributes: {
+ "http.method": request.method,
+ "http.url": request.url,
+ requestId: request.requestId,
+ },
+ });
+ // If the span is not recording, don't do any more work.
+ if (!span.isRecording()) {
+ span.end();
+ return undefined;
+ }
+ if (userAgent) {
+ span.setAttribute("http.user_agent", userAgent);
+ }
+ // set headers
+ const headers = tracingClient.createRequestHeaders(updatedOptions.tracingOptions.tracingContext);
+ for (const [key, value] of Object.entries(headers)) {
+ request.headers.set(key, value);
+ }
+ return { span, tracingContext: updatedOptions.tracingOptions.tracingContext };
+ }
+ catch (e) {
+ logger.warning(`Skipping creating a tracing span due to an error: ${coreUtil.getErrorMessage(e)}`);
+ return undefined;
+ }
+}
+function tryProcessError(span, error) {
+ try {
+ span.setStatus({
+ status: "error",
+ error: coreUtil.isError(error) ? error : undefined,
+ });
+ if (isRestError(error) && error.statusCode) {
+ span.setAttribute("http.status_code", error.statusCode);
+ }
+ span.end();
+ }
+ catch (e) {
+ logger.warning(`Skipping tracing span processing due to an error: ${coreUtil.getErrorMessage(e)}`);
+ }
+}
+function tryProcessResponse(span, response) {
+ try {
+ span.setAttribute("http.status_code", response.status);
+ const serviceRequestId = response.headers.get("x-ms-request-id");
+ if (serviceRequestId) {
+ span.setAttribute("serviceRequestId", serviceRequestId);
+ }
+ span.setStatus({
+ status: "success",
+ });
+ span.end();
+ }
+ catch (e) {
+ logger.warning(`Skipping tracing span processing due to an error: ${coreUtil.getErrorMessage(e)}`);
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Create a new pipeline with a default set of customizable policies.
+ * @param options - Options to configure a custom pipeline.
+ */
+function createPipelineFromOptions(options) {
+ var _a;
+ const pipeline = createEmptyPipeline();
+ if (coreUtil.isNode) {
+ if (options.tlsOptions) {
+ pipeline.addPolicy(tlsPolicy(options.tlsOptions));
+ }
+ pipeline.addPolicy(proxyPolicy(options.proxyOptions));
+ pipeline.addPolicy(decompressResponsePolicy());
+ }
+ pipeline.addPolicy(formDataPolicy());
+ pipeline.addPolicy(userAgentPolicy(options.userAgentOptions));
+ pipeline.addPolicy(setClientRequestIdPolicy((_a = options.telemetryOptions) === null || _a === void 0 ? void 0 : _a.clientRequestIdHeaderName));
+ pipeline.addPolicy(defaultRetryPolicy(options.retryOptions), { phase: "Retry" });
+ pipeline.addPolicy(tracingPolicy(options.userAgentOptions), { afterPhase: "Retry" });
+ if (coreUtil.isNode) {
+ // Both XHR and Fetch expect to handle redirects automatically,
+ // so only include this policy when we're in Node.
+ pipeline.addPolicy(redirectPolicy(options.redirectOptions), { afterPhase: "Retry" });
+ }
+ pipeline.addPolicy(logPolicy(options.loggingOptions), { afterPhase: "Sign" });
+ return pipeline;
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+function normalizeName(name) {
+ return name.toLowerCase();
+}
+function* headerIterator(map) {
+ for (const entry of map.values()) {
+ yield [entry.name, entry.value];
+ }
+}
+class HttpHeadersImpl {
+ constructor(rawHeaders) {
+ this._headersMap = new Map();
+ if (rawHeaders) {
+ for (const headerName of Object.keys(rawHeaders)) {
+ this.set(headerName, rawHeaders[headerName]);
+ }
+ }
+ }
+ /**
+ * Set a header in this collection with the provided name and value. The name is
+ * case-insensitive.
+ * @param name - The name of the header to set. This value is case-insensitive.
+ * @param value - The value of the header to set.
+ */
+ set(name, value) {
+ this._headersMap.set(normalizeName(name), { name, value: String(value) });
+ }
+ /**
+ * Get the header value for the provided header name, or undefined if no header exists in this
+ * collection with the provided name.
+ * @param name - The name of the header. This value is case-insensitive.
+ */
+ get(name) {
+ var _a;
+ return (_a = this._headersMap.get(normalizeName(name))) === null || _a === void 0 ? void 0 : _a.value;
+ }
+ /**
+ * Get whether or not this header collection contains a header entry for the provided header name.
+ * @param name - The name of the header to set. This value is case-insensitive.
+ */
+ has(name) {
+ return this._headersMap.has(normalizeName(name));
+ }
+ /**
+ * Remove the header with the provided headerName.
+ * @param name - The name of the header to remove.
+ */
+ delete(name) {
+ this._headersMap.delete(normalizeName(name));
+ }
+ /**
+ * Get the JSON object representation of this HTTP header collection.
+ */
+ toJSON(options = {}) {
+ const result = {};
+ if (options.preserveCase) {
+ for (const entry of this._headersMap.values()) {
+ result[entry.name] = entry.value;
+ }
+ }
+ else {
+ for (const [normalizedName, entry] of this._headersMap) {
+ result[normalizedName] = entry.value;
+ }
+ }
+ return result;
+ }
+ /**
+ * Get the string representation of this HTTP header collection.
+ */
+ toString() {
+ return JSON.stringify(this.toJSON({ preserveCase: true }));
+ }
+ /**
+ * Iterate over tuples of header [name, value] pairs.
+ */
+ [Symbol.iterator]() {
+ return headerIterator(this._headersMap);
+ }
+}
+/**
+ * Creates an object that satisfies the `HttpHeaders` interface.
+ * @param rawHeaders - A simple object representing initial headers
+ */
+function createHttpHeaders(rawHeaders) {
+ return new HttpHeadersImpl(rawHeaders);
+}
+
+// Copyright (c) Microsoft Corporation.
+const DEFAULT_TLS_SETTINGS = {};
+function isReadableStream(body) {
+ return body && typeof body.pipe === "function";
+}
+function isStreamComplete(stream) {
+ return new Promise((resolve) => {
+ stream.on("close", resolve);
+ stream.on("end", resolve);
+ stream.on("error", resolve);
+ });
+}
+function isArrayBuffer(body) {
+ return body && typeof body.byteLength === "number";
+}
+class ReportTransform extends stream.Transform {
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ _transform(chunk, _encoding, callback) {
+ this.push(chunk);
+ this.loadedBytes += chunk.length;
+ try {
+ this.progressCallback({ loadedBytes: this.loadedBytes });
+ callback();
+ }
+ catch (e) {
+ callback(e);
+ }
+ }
+ constructor(progressCallback) {
+ super();
+ this.loadedBytes = 0;
+ this.progressCallback = progressCallback;
+ }
+}
+/**
+ * A HttpClient implementation that uses Node's "https" module to send HTTPS requests.
+ * @internal
+ */
+class NodeHttpClient {
+ constructor() {
+ this.cachedHttpsAgents = new WeakMap();
+ }
+ /**
+ * Makes a request over an underlying transport layer and returns the response.
+ * @param request - The request to be made.
+ */
+ async sendRequest(request) {
+ var _a, _b, _c;
+ const abortController$1 = new abortController.AbortController();
+ let abortListener;
+ if (request.abortSignal) {
+ if (request.abortSignal.aborted) {
+ throw new abortController.AbortError("The operation was aborted.");
+ }
+ abortListener = (event) => {
+ if (event.type === "abort") {
+ abortController$1.abort();
+ }
+ };
+ request.abortSignal.addEventListener("abort", abortListener);
+ }
+ if (request.timeout > 0) {
+ setTimeout(() => {
+ abortController$1.abort();
+ }, request.timeout);
+ }
+ const acceptEncoding = request.headers.get("Accept-Encoding");
+ const shouldDecompress = (acceptEncoding === null || acceptEncoding === void 0 ? void 0 : acceptEncoding.includes("gzip")) || (acceptEncoding === null || acceptEncoding === void 0 ? void 0 : acceptEncoding.includes("deflate"));
+ let body = typeof request.body === "function" ? request.body() : request.body;
+ if (body && !request.headers.has("Content-Length")) {
+ const bodyLength = getBodyLength(body);
+ if (bodyLength !== null) {
+ request.headers.set("Content-Length", bodyLength);
+ }
+ }
+ let responseStream;
+ try {
+ if (body && request.onUploadProgress) {
+ const onUploadProgress = request.onUploadProgress;
+ const uploadReportStream = new ReportTransform(onUploadProgress);
+ uploadReportStream.on("error", (e) => {
+ logger.error("Error in upload progress", e);
+ });
+ if (isReadableStream(body)) {
+ body.pipe(uploadReportStream);
+ }
+ else {
+ uploadReportStream.end(body);
+ }
+ body = uploadReportStream;
+ }
+ const res = await this.makeRequest(request, abortController$1, body);
+ const headers = getResponseHeaders(res);
+ const status = (_a = res.statusCode) !== null && _a !== void 0 ? _a : 0;
+ const response = {
+ status,
+ headers,
+ request,
+ };
+ // Responses to HEAD must not have a body.
+ // If they do return a body, that body must be ignored.
+ if (request.method === "HEAD") {
+ // call resume() and not destroy() to avoid closing the socket
+ // and losing keep alive
+ res.resume();
+ return response;
+ }
+ responseStream = shouldDecompress ? getDecodedResponseStream(res, headers) : res;
+ const onDownloadProgress = request.onDownloadProgress;
+ if (onDownloadProgress) {
+ const downloadReportStream = new ReportTransform(onDownloadProgress);
+ downloadReportStream.on("error", (e) => {
+ logger.error("Error in download progress", e);
+ });
+ responseStream.pipe(downloadReportStream);
+ responseStream = downloadReportStream;
+ }
+ if (
+ // Value of POSITIVE_INFINITY in streamResponseStatusCodes is considered as any status code
+ ((_b = request.streamResponseStatusCodes) === null || _b === void 0 ? void 0 : _b.has(Number.POSITIVE_INFINITY)) ||
+ ((_c = request.streamResponseStatusCodes) === null || _c === void 0 ? void 0 : _c.has(response.status))) {
+ response.readableStreamBody = responseStream;
+ }
+ else {
+ response.bodyAsText = await streamToText(responseStream);
+ }
+ return response;
+ }
+ finally {
+ // clean up event listener
+ if (request.abortSignal && abortListener) {
+ let uploadStreamDone = Promise.resolve();
+ if (isReadableStream(body)) {
+ uploadStreamDone = isStreamComplete(body);
+ }
+ let downloadStreamDone = Promise.resolve();
+ if (isReadableStream(responseStream)) {
+ downloadStreamDone = isStreamComplete(responseStream);
+ }
+ Promise.all([uploadStreamDone, downloadStreamDone])
+ .then(() => {
+ var _a;
+ // eslint-disable-next-line promise/always-return
+ if (abortListener) {
+ (_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.removeEventListener("abort", abortListener);
+ }
+ })
+ .catch((e) => {
+ logger.warning("Error when cleaning up abortListener on httpRequest", e);
+ });
+ }
+ }
+ }
+ makeRequest(request, abortController$1, body) {
+ var _a;
+ const url = new URL(request.url);
+ const isInsecure = url.protocol !== "https:";
+ if (isInsecure && !request.allowInsecureConnection) {
+ throw new Error(`Cannot connect to ${request.url} while allowInsecureConnection is false.`);
+ }
+ const agent = (_a = request.agent) !== null && _a !== void 0 ? _a : this.getOrCreateAgent(request, isInsecure);
+ const options = {
+ agent,
+ hostname: url.hostname,
+ path: `${url.pathname}${url.search}`,
+ port: url.port,
+ method: request.method,
+ headers: request.headers.toJSON({ preserveCase: true }),
+ };
+ return new Promise((resolve, reject) => {
+ const req = isInsecure ? http__namespace.request(options, resolve) : https__namespace.request(options, resolve);
+ req.once("error", (err) => {
+ var _a;
+ reject(new RestError(err.message, { code: (_a = err.code) !== null && _a !== void 0 ? _a : RestError.REQUEST_SEND_ERROR, request }));
+ });
+ abortController$1.signal.addEventListener("abort", () => {
+ const abortError = new abortController.AbortError("The operation was aborted.");
+ req.destroy(abortError);
+ reject(abortError);
+ });
+ if (body && isReadableStream(body)) {
+ body.pipe(req);
+ }
+ else if (body) {
+ if (typeof body === "string" || Buffer.isBuffer(body)) {
+ req.end(body);
+ }
+ else if (isArrayBuffer(body)) {
+ req.end(ArrayBuffer.isView(body) ? Buffer.from(body.buffer) : Buffer.from(body));
+ }
+ else {
+ logger.error("Unrecognized body type", body);
+ reject(new RestError("Unrecognized body type"));
+ }
+ }
+ else {
+ // streams don't like "undefined" being passed as data
+ req.end();
+ }
+ });
+ }
+ getOrCreateAgent(request, isInsecure) {
+ var _a;
+ const disableKeepAlive = request.disableKeepAlive;
+ // Handle Insecure requests first
+ if (isInsecure) {
+ if (disableKeepAlive) {
+ // keepAlive:false is the default so we don't need a custom Agent
+ return http__namespace.globalAgent;
+ }
+ if (!this.cachedHttpAgent) {
+ // If there is no cached agent create a new one and cache it.
+ this.cachedHttpAgent = new http__namespace.Agent({ keepAlive: true });
+ }
+ return this.cachedHttpAgent;
+ }
+ else {
+ if (disableKeepAlive && !request.tlsSettings) {
+ // When there are no tlsSettings and keepAlive is false
+ // we don't need a custom agent
+ return https__namespace.globalAgent;
+ }
+ // We use the tlsSettings to index cached clients
+ const tlsSettings = (_a = request.tlsSettings) !== null && _a !== void 0 ? _a : DEFAULT_TLS_SETTINGS;
+ // Get the cached agent or create a new one with the
+ // provided values for keepAlive and tlsSettings
+ let agent = this.cachedHttpsAgents.get(tlsSettings);
+ if (agent && agent.options.keepAlive === !disableKeepAlive) {
+ return agent;
+ }
+ logger.info("No cached TLS Agent exist, creating a new Agent");
+ agent = new https__namespace.Agent(Object.assign({
+ // keepAlive is true if disableKeepAlive is false.
+ keepAlive: !disableKeepAlive }, tlsSettings));
+ this.cachedHttpsAgents.set(tlsSettings, agent);
+ return agent;
+ }
+ }
+}
+function getResponseHeaders(res) {
+ const headers = createHttpHeaders();
+ for (const header of Object.keys(res.headers)) {
+ const value = res.headers[header];
+ if (Array.isArray(value)) {
+ if (value.length > 0) {
+ headers.set(header, value[0]);
+ }
+ }
+ else if (value) {
+ headers.set(header, value);
+ }
+ }
+ return headers;
+}
+function getDecodedResponseStream(stream, headers) {
+ const contentEncoding = headers.get("Content-Encoding");
+ if (contentEncoding === "gzip") {
+ const unzip = zlib__namespace.createGunzip();
+ stream.pipe(unzip);
+ return unzip;
+ }
+ else if (contentEncoding === "deflate") {
+ const inflate = zlib__namespace.createInflate();
+ stream.pipe(inflate);
+ return inflate;
+ }
+ return stream;
+}
+function streamToText(stream) {
+ return new Promise((resolve, reject) => {
+ const buffer = [];
+ stream.on("data", (chunk) => {
+ if (Buffer.isBuffer(chunk)) {
+ buffer.push(chunk);
+ }
+ else {
+ buffer.push(Buffer.from(chunk));
+ }
+ });
+ stream.on("end", () => {
+ resolve(Buffer.concat(buffer).toString("utf8"));
+ });
+ stream.on("error", (e) => {
+ if (e && (e === null || e === void 0 ? void 0 : e.name) === "AbortError") {
+ reject(e);
+ }
+ else {
+ reject(new RestError(`Error reading response as text: ${e.message}`, {
+ code: RestError.PARSE_ERROR,
+ }));
+ }
+ });
+ });
+}
+/** @internal */
+function getBodyLength(body) {
+ if (!body) {
+ return 0;
+ }
+ else if (Buffer.isBuffer(body)) {
+ return body.length;
+ }
+ else if (isReadableStream(body)) {
+ return null;
+ }
+ else if (isArrayBuffer(body)) {
+ return body.byteLength;
+ }
+ else if (typeof body === "string") {
+ return Buffer.from(body).length;
+ }
+ else {
+ return null;
+ }
+}
+/**
+ * Create a new HttpClient instance for the NodeJS environment.
+ * @internal
+ */
+function createNodeHttpClient() {
+ return new NodeHttpClient();
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Create the correct HttpClient for the current environment.
+ */
+function createDefaultHttpClient() {
+ return createNodeHttpClient();
+}
+
+// Copyright (c) Microsoft Corporation.
+class PipelineRequestImpl {
+ constructor(options) {
+ var _a, _b, _c, _d, _e, _f, _g;
+ this.url = options.url;
+ this.body = options.body;
+ this.headers = (_a = options.headers) !== null && _a !== void 0 ? _a : createHttpHeaders();
+ this.method = (_b = options.method) !== null && _b !== void 0 ? _b : "GET";
+ this.timeout = (_c = options.timeout) !== null && _c !== void 0 ? _c : 0;
+ this.formData = options.formData;
+ this.disableKeepAlive = (_d = options.disableKeepAlive) !== null && _d !== void 0 ? _d : false;
+ this.proxySettings = options.proxySettings;
+ this.streamResponseStatusCodes = options.streamResponseStatusCodes;
+ this.withCredentials = (_e = options.withCredentials) !== null && _e !== void 0 ? _e : false;
+ this.abortSignal = options.abortSignal;
+ this.tracingOptions = options.tracingOptions;
+ this.onUploadProgress = options.onUploadProgress;
+ this.onDownloadProgress = options.onDownloadProgress;
+ this.requestId = options.requestId || coreUtil.randomUUID();
+ this.allowInsecureConnection = (_f = options.allowInsecureConnection) !== null && _f !== void 0 ? _f : false;
+ this.enableBrowserStreams = (_g = options.enableBrowserStreams) !== null && _g !== void 0 ? _g : false;
+ }
+}
+/**
+ * Creates a new pipeline request with the given options.
+ * This method is to allow for the easy setting of default values and not required.
+ * @param options - The options to create the request with.
+ */
+function createPipelineRequest(options) {
+ return new PipelineRequestImpl(options);
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the exponentialRetryPolicy.
+ */
+const exponentialRetryPolicyName = "exponentialRetryPolicy";
+/**
+ * A policy that attempts to retry requests while introducing an exponentially increasing delay.
+ * @param options - Options that configure retry logic.
+ */
+function exponentialRetryPolicy(options = {}) {
+ var _a;
+ return retryPolicy([
+ exponentialRetryStrategy(Object.assign(Object.assign({}, options), { ignoreSystemErrors: true })),
+ ], {
+ maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Name of the {@link systemErrorRetryPolicy}
+ */
+const systemErrorRetryPolicyName = "systemErrorRetryPolicy";
+/**
+ * A retry policy that specifically seeks to handle errors in the
+ * underlying transport layer (e.g. DNS lookup failures) rather than
+ * retryable error codes from the server itself.
+ * @param options - Options that customize the policy.
+ */
+function systemErrorRetryPolicy(options = {}) {
+ var _a;
+ return {
+ name: systemErrorRetryPolicyName,
+ sendRequest: retryPolicy([
+ exponentialRetryStrategy(Object.assign(Object.assign({}, options), { ignoreHttpStatusCodes: true })),
+ ], {
+ maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
+ }).sendRequest,
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Name of the {@link throttlingRetryPolicy}
+ */
+const throttlingRetryPolicyName = "throttlingRetryPolicy";
+/**
+ * A policy that retries when the server sends a 429 response with a Retry-After header.
+ *
+ * To learn more, please refer to
+ * https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits,
+ * https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits and
+ * https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/troubleshooting-throttling-errors
+ *
+ * @param options - Options that configure retry logic.
+ */
+function throttlingRetryPolicy(options = {}) {
+ var _a;
+ return {
+ name: throttlingRetryPolicyName,
+ sendRequest: retryPolicy([throttlingRetryStrategy()], {
+ maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
+ }).sendRequest,
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Default options for the cycler if none are provided
+const DEFAULT_CYCLER_OPTIONS = {
+ forcedRefreshWindowInMs: 1000,
+ retryIntervalInMs: 3000,
+ refreshWindowInMs: 1000 * 60 * 2, // Start refreshing 2m before expiry
+};
+/**
+ * Converts an an unreliable access token getter (which may resolve with null)
+ * into an AccessTokenGetter by retrying the unreliable getter in a regular
+ * interval.
+ *
+ * @param getAccessToken - A function that produces a promise of an access token that may fail by returning null.
+ * @param retryIntervalInMs - The time (in milliseconds) to wait between retry attempts.
+ * @param refreshTimeout - The timestamp after which the refresh attempt will fail, throwing an exception.
+ * @returns - A promise that, if it resolves, will resolve with an access token.
+ */
+async function beginRefresh(getAccessToken, retryIntervalInMs, refreshTimeout) {
+ // This wrapper handles exceptions gracefully as long as we haven't exceeded
+ // the timeout.
+ async function tryGetAccessToken() {
+ if (Date.now() < refreshTimeout) {
+ try {
+ return await getAccessToken();
+ }
+ catch (_a) {
+ return null;
+ }
+ }
+ else {
+ const finalToken = await getAccessToken();
+ // Timeout is up, so throw if it's still null
+ if (finalToken === null) {
+ throw new Error("Failed to refresh access token.");
+ }
+ return finalToken;
+ }
+ }
+ let token = await tryGetAccessToken();
+ while (token === null) {
+ await delay(retryIntervalInMs);
+ token = await tryGetAccessToken();
+ }
+ return token;
+}
+/**
+ * Creates a token cycler from a credential, scopes, and optional settings.
+ *
+ * A token cycler represents a way to reliably retrieve a valid access token
+ * from a TokenCredential. It will handle initializing the token, refreshing it
+ * when it nears expiration, and synchronizes refresh attempts to avoid
+ * concurrency hazards.
+ *
+ * @param credential - the underlying TokenCredential that provides the access
+ * token
+ * @param tokenCyclerOptions - optionally override default settings for the cycler
+ *
+ * @returns - a function that reliably produces a valid access token
+ */
+function createTokenCycler(credential, tokenCyclerOptions) {
+ let refreshWorker = null;
+ let token = null;
+ let tenantId;
+ const options = Object.assign(Object.assign({}, DEFAULT_CYCLER_OPTIONS), tokenCyclerOptions);
+ /**
+ * This little holder defines several predicates that we use to construct
+ * the rules of refreshing the token.
+ */
+ const cycler = {
+ /**
+ * Produces true if a refresh job is currently in progress.
+ */
+ get isRefreshing() {
+ return refreshWorker !== null;
+ },
+ /**
+ * Produces true if the cycler SHOULD refresh (we are within the refresh
+ * window and not already refreshing)
+ */
+ get shouldRefresh() {
+ var _a;
+ return (!cycler.isRefreshing &&
+ ((_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : 0) - options.refreshWindowInMs < Date.now());
+ },
+ /**
+ * Produces true if the cycler MUST refresh (null or nearly-expired
+ * token).
+ */
+ get mustRefresh() {
+ return (token === null || token.expiresOnTimestamp - options.forcedRefreshWindowInMs < Date.now());
+ },
+ };
+ /**
+ * Starts a refresh job or returns the existing job if one is already
+ * running.
+ */
+ function refresh(scopes, getTokenOptions) {
+ var _a;
+ if (!cycler.isRefreshing) {
+ // We bind `scopes` here to avoid passing it around a lot
+ const tryGetAccessToken = () => credential.getToken(scopes, getTokenOptions);
+ // Take advantage of promise chaining to insert an assignment to `token`
+ // before the refresh can be considered done.
+ refreshWorker = beginRefresh(tryGetAccessToken, options.retryIntervalInMs,
+ // If we don't have a token, then we should timeout immediately
+ (_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : Date.now())
+ .then((_token) => {
+ refreshWorker = null;
+ token = _token;
+ tenantId = getTokenOptions.tenantId;
+ return token;
+ })
+ .catch((reason) => {
+ // We also should reset the refresher if we enter a failed state. All
+ // existing awaiters will throw, but subsequent requests will start a
+ // new retry chain.
+ refreshWorker = null;
+ token = null;
+ tenantId = undefined;
+ throw reason;
+ });
+ }
+ return refreshWorker;
+ }
+ return async (scopes, tokenOptions) => {
+ //
+ // Simple rules:
+ // - If we MUST refresh, then return the refresh task, blocking
+ // the pipeline until a token is available.
+ // - If we SHOULD refresh, then run refresh but don't return it
+ // (we can still use the cached token).
+ // - Return the token, since it's fine if we didn't return in
+ // step 1.
+ //
+ // If the tenantId passed in token options is different to the one we have
+ // Or if we are in claim challenge and the token was rejected and a new access token need to be issued, we need to
+ // refresh the token with the new tenantId or token.
+ const mustRefresh = tenantId !== tokenOptions.tenantId || Boolean(tokenOptions.claims) || cycler.mustRefresh;
+ if (mustRefresh)
+ return refresh(scopes, tokenOptions);
+ if (cycler.shouldRefresh) {
+ refresh(scopes, tokenOptions);
+ }
+ return token;
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the bearerTokenAuthenticationPolicy.
+ */
+const bearerTokenAuthenticationPolicyName = "bearerTokenAuthenticationPolicy";
+/**
+ * Default authorize request handler
+ */
+async function defaultAuthorizeRequest(options) {
+ const { scopes, getAccessToken, request } = options;
+ const getTokenOptions = {
+ abortSignal: request.abortSignal,
+ tracingOptions: request.tracingOptions,
+ };
+ const accessToken = await getAccessToken(scopes, getTokenOptions);
+ if (accessToken) {
+ options.request.headers.set("Authorization", `Bearer ${accessToken.token}`);
+ }
+}
+/**
+ * We will retrieve the challenge only if the response status code was 401,
+ * and if the response contained the header "WWW-Authenticate" with a non-empty value.
+ */
+function getChallenge(response) {
+ const challenge = response.headers.get("WWW-Authenticate");
+ if (response.status === 401 && challenge) {
+ return challenge;
+ }
+ return;
+}
+/**
+ * A policy that can request a token from a TokenCredential implementation and
+ * then apply it to the Authorization header of a request as a Bearer token.
+ */
+function bearerTokenAuthenticationPolicy(options) {
+ var _a;
+ const { credential, scopes, challengeCallbacks } = options;
+ const logger$1 = options.logger || logger;
+ const callbacks = Object.assign({ authorizeRequest: (_a = challengeCallbacks === null || challengeCallbacks === void 0 ? void 0 : challengeCallbacks.authorizeRequest) !== null && _a !== void 0 ? _a : defaultAuthorizeRequest, authorizeRequestOnChallenge: challengeCallbacks === null || challengeCallbacks === void 0 ? void 0 : challengeCallbacks.authorizeRequestOnChallenge }, challengeCallbacks);
+ // This function encapsulates the entire process of reliably retrieving the token
+ // The options are left out of the public API until there's demand to configure this.
+ // Remember to extend `BearerTokenAuthenticationPolicyOptions` with `TokenCyclerOptions`
+ // in order to pass through the `options` object.
+ const getAccessToken = credential
+ ? createTokenCycler(credential /* , options */)
+ : () => Promise.resolve(null);
+ return {
+ name: bearerTokenAuthenticationPolicyName,
+ /**
+ * If there's no challenge parameter:
+ * - It will try to retrieve the token using the cache, or the credential's getToken.
+ * - Then it will try the next policy with or without the retrieved token.
+ *
+ * It uses the challenge parameters to:
+ * - Skip a first attempt to get the token from the credential if there's no cached token,
+ * since it expects the token to be retrievable only after the challenge.
+ * - Prepare the outgoing request if the `prepareRequest` method has been provided.
+ * - Send an initial request to receive the challenge if it fails.
+ * - Process a challenge if the response contains it.
+ * - Retrieve a token with the challenge information, then re-send the request.
+ */
+ async sendRequest(request, next) {
+ if (!request.url.toLowerCase().startsWith("https://")) {
+ throw new Error("Bearer token authentication is not permitted for non-TLS protected (non-https) URLs.");
+ }
+ await callbacks.authorizeRequest({
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ request,
+ getAccessToken,
+ logger: logger$1,
+ });
+ let response;
+ let error;
+ try {
+ response = await next(request);
+ }
+ catch (err) {
+ error = err;
+ response = err.response;
+ }
+ if (callbacks.authorizeRequestOnChallenge &&
+ (response === null || response === void 0 ? void 0 : response.status) === 401 &&
+ getChallenge(response)) {
+ // processes challenge
+ const shouldSendRequest = await callbacks.authorizeRequestOnChallenge({
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ request,
+ response,
+ getAccessToken,
+ logger: logger$1,
+ });
+ if (shouldSendRequest) {
+ return next(request);
+ }
+ }
+ if (error) {
+ throw error;
+ }
+ else {
+ return response;
+ }
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The programmatic identifier of the ndJsonPolicy.
+ */
+const ndJsonPolicyName = "ndJsonPolicy";
+/**
+ * ndJsonPolicy is a policy used to control keep alive settings for every request.
+ */
+function ndJsonPolicy() {
+ return {
+ name: ndJsonPolicyName,
+ async sendRequest(request, next) {
+ // There currently isn't a good way to bypass the serializer
+ if (typeof request.body === "string" && request.body.startsWith("[")) {
+ const body = JSON.parse(request.body);
+ if (Array.isArray(body)) {
+ request.body = body.map((item) => JSON.stringify(item) + "\n").join("");
+ }
+ }
+ return next(request);
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy.
+ */
+const auxiliaryAuthenticationHeaderPolicyName = "auxiliaryAuthenticationHeaderPolicy";
+const AUTHORIZATION_AUXILIARY_HEADER = "x-ms-authorization-auxiliary";
+async function sendAuthorizeRequest(options) {
+ var _a, _b;
+ const { scopes, getAccessToken, request } = options;
+ const getTokenOptions = {
+ abortSignal: request.abortSignal,
+ tracingOptions: request.tracingOptions,
+ };
+ return (_b = (_a = (await getAccessToken(scopes, getTokenOptions))) === null || _a === void 0 ? void 0 : _a.token) !== null && _b !== void 0 ? _b : "";
+}
+/**
+ * A policy for external tokens to `x-ms-authorization-auxiliary` header.
+ * This header will be used when creating a cross-tenant application we may need to handle authentication requests
+ * for resources that are in different tenants.
+ * You could see [ARM docs](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant) for a rundown of how this feature works
+ */
+function auxiliaryAuthenticationHeaderPolicy(options) {
+ const { credentials, scopes } = options;
+ const logger$1 = options.logger || logger;
+ const tokenCyclerMap = new WeakMap();
+ return {
+ name: auxiliaryAuthenticationHeaderPolicyName,
+ async sendRequest(request, next) {
+ if (!request.url.toLowerCase().startsWith("https://")) {
+ throw new Error("Bearer token authentication for auxiliary header is not permitted for non-TLS protected (non-https) URLs.");
+ }
+ if (!credentials || credentials.length === 0) {
+ logger$1.info(`${auxiliaryAuthenticationHeaderPolicyName} header will not be set due to empty credentials.`);
+ return next(request);
+ }
+ const tokenPromises = [];
+ for (const credential of credentials) {
+ let getAccessToken = tokenCyclerMap.get(credential);
+ if (!getAccessToken) {
+ getAccessToken = createTokenCycler(credential);
+ tokenCyclerMap.set(credential, getAccessToken);
+ }
+ tokenPromises.push(sendAuthorizeRequest({
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ request,
+ getAccessToken,
+ logger: logger$1,
+ }));
+ }
+ const auxiliaryTokens = (await Promise.all(tokenPromises)).filter((token) => Boolean(token));
+ if (auxiliaryTokens.length === 0) {
+ logger$1.warning(`None of the auxiliary tokens are valid. ${AUTHORIZATION_AUXILIARY_HEADER} header will not be set.`);
+ return next(request);
+ }
+ request.headers.set(AUTHORIZATION_AUXILIARY_HEADER, auxiliaryTokens.map((token) => `Bearer ${token}`).join(", "));
+ return next(request);
+ },
+ };
+}
+
+exports.RestError = RestError;
+exports.auxiliaryAuthenticationHeaderPolicy = auxiliaryAuthenticationHeaderPolicy;
+exports.auxiliaryAuthenticationHeaderPolicyName = auxiliaryAuthenticationHeaderPolicyName;
+exports.bearerTokenAuthenticationPolicy = bearerTokenAuthenticationPolicy;
+exports.bearerTokenAuthenticationPolicyName = bearerTokenAuthenticationPolicyName;
+exports.createDefaultHttpClient = createDefaultHttpClient;
+exports.createEmptyPipeline = createEmptyPipeline;
+exports.createHttpHeaders = createHttpHeaders;
+exports.createPipelineFromOptions = createPipelineFromOptions;
+exports.createPipelineRequest = createPipelineRequest;
+exports.decompressResponsePolicy = decompressResponsePolicy;
+exports.decompressResponsePolicyName = decompressResponsePolicyName;
+exports.defaultRetryPolicy = defaultRetryPolicy;
+exports.exponentialRetryPolicy = exponentialRetryPolicy;
+exports.exponentialRetryPolicyName = exponentialRetryPolicyName;
+exports.formDataPolicy = formDataPolicy;
+exports.formDataPolicyName = formDataPolicyName;
+exports.getDefaultProxySettings = getDefaultProxySettings;
+exports.isRestError = isRestError;
+exports.logPolicy = logPolicy;
+exports.logPolicyName = logPolicyName;
+exports.ndJsonPolicy = ndJsonPolicy;
+exports.ndJsonPolicyName = ndJsonPolicyName;
+exports.proxyPolicy = proxyPolicy;
+exports.proxyPolicyName = proxyPolicyName;
+exports.redirectPolicy = redirectPolicy;
+exports.redirectPolicyName = redirectPolicyName;
+exports.retryPolicy = retryPolicy;
+exports.setClientRequestIdPolicy = setClientRequestIdPolicy;
+exports.setClientRequestIdPolicyName = setClientRequestIdPolicyName;
+exports.systemErrorRetryPolicy = systemErrorRetryPolicy;
+exports.systemErrorRetryPolicyName = systemErrorRetryPolicyName;
+exports.throttlingRetryPolicy = throttlingRetryPolicy;
+exports.throttlingRetryPolicyName = throttlingRetryPolicyName;
+exports.tlsPolicy = tlsPolicy;
+exports.tlsPolicyName = tlsPolicyName;
+exports.tracingPolicy = tracingPolicy;
+exports.tracingPolicyName = tracingPolicyName;
+exports.userAgentPolicy = userAgentPolicy;
+exports.userAgentPolicyName = userAgentPolicyName;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 4175:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/** @internal */
+const knownContextKeys = {
+ span: Symbol.for("@azure/core-tracing span"),
+ namespace: Symbol.for("@azure/core-tracing namespace"),
+};
+/**
+ * Creates a new {@link TracingContext} with the given options.
+ * @param options - A set of known keys that may be set on the context.
+ * @returns A new {@link TracingContext} with the given options.
+ *
+ * @internal
+ */
+function createTracingContext(options = {}) {
+ let context = new TracingContextImpl(options.parentContext);
+ if (options.span) {
+ context = context.setValue(knownContextKeys.span, options.span);
+ }
+ if (options.namespace) {
+ context = context.setValue(knownContextKeys.namespace, options.namespace);
+ }
+ return context;
+}
+/** @internal */
+class TracingContextImpl {
+ constructor(initialContext) {
+ this._contextMap =
+ initialContext instanceof TracingContextImpl
+ ? new Map(initialContext._contextMap)
+ : new Map();
+ }
+ setValue(key, value) {
+ const newContext = new TracingContextImpl(this);
+ newContext._contextMap.set(key, value);
+ return newContext;
+ }
+ getValue(key) {
+ return this._contextMap.get(key);
+ }
+ deleteValue(key) {
+ const newContext = new TracingContextImpl(this);
+ newContext._contextMap.delete(key);
+ return newContext;
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+function createDefaultTracingSpan() {
+ return {
+ end: () => {
+ // noop
+ },
+ isRecording: () => false,
+ recordException: () => {
+ // noop
+ },
+ setAttribute: () => {
+ // noop
+ },
+ setStatus: () => {
+ // noop
+ },
+ };
+}
+function createDefaultInstrumenter() {
+ return {
+ createRequestHeaders: () => {
+ return {};
+ },
+ parseTraceparentHeader: () => {
+ return undefined;
+ },
+ startSpan: (_name, spanOptions) => {
+ return {
+ span: createDefaultTracingSpan(),
+ tracingContext: createTracingContext({ parentContext: spanOptions.tracingContext }),
+ };
+ },
+ withContext(_context, callback, ...callbackArgs) {
+ return callback(...callbackArgs);
+ },
+ };
+}
+/** @internal */
+let instrumenterImplementation;
+/**
+ * Extends the Azure SDK with support for a given instrumenter implementation.
+ *
+ * @param instrumenter - The instrumenter implementation to use.
+ */
+function useInstrumenter(instrumenter) {
+ instrumenterImplementation = instrumenter;
+}
+/**
+ * Gets the currently set instrumenter, a No-Op instrumenter by default.
+ *
+ * @returns The currently set instrumenter
+ */
+function getInstrumenter() {
+ if (!instrumenterImplementation) {
+ instrumenterImplementation = createDefaultInstrumenter();
+ }
+ return instrumenterImplementation;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Creates a new tracing client.
+ *
+ * @param options - Options used to configure the tracing client.
+ * @returns - An instance of {@link TracingClient}.
+ */
+function createTracingClient(options) {
+ const { namespace, packageName, packageVersion } = options;
+ function startSpan(name, operationOptions, spanOptions) {
+ var _a;
+ const startSpanResult = getInstrumenter().startSpan(name, Object.assign(Object.assign({}, spanOptions), { packageName: packageName, packageVersion: packageVersion, tracingContext: (_a = operationOptions === null || operationOptions === void 0 ? void 0 : operationOptions.tracingOptions) === null || _a === void 0 ? void 0 : _a.tracingContext }));
+ let tracingContext = startSpanResult.tracingContext;
+ const span = startSpanResult.span;
+ if (!tracingContext.getValue(knownContextKeys.namespace)) {
+ tracingContext = tracingContext.setValue(knownContextKeys.namespace, namespace);
+ }
+ span.setAttribute("az.namespace", tracingContext.getValue(knownContextKeys.namespace));
+ const updatedOptions = Object.assign({}, operationOptions, {
+ tracingOptions: Object.assign(Object.assign({}, operationOptions === null || operationOptions === void 0 ? void 0 : operationOptions.tracingOptions), { tracingContext }),
+ });
+ return {
+ span,
+ updatedOptions,
+ };
+ }
+ async function withSpan(name, operationOptions, callback, spanOptions) {
+ const { span, updatedOptions } = startSpan(name, operationOptions, spanOptions);
+ try {
+ const result = await withContext(updatedOptions.tracingOptions.tracingContext, () => Promise.resolve(callback(updatedOptions, span)));
+ span.setStatus({ status: "success" });
+ return result;
+ }
+ catch (err) {
+ span.setStatus({ status: "error", error: err });
+ throw err;
+ }
+ finally {
+ span.end();
+ }
+ }
+ function withContext(context, callback, ...callbackArgs) {
+ return getInstrumenter().withContext(context, callback, ...callbackArgs);
+ }
+ /**
+ * Parses a traceparent header value into a span identifier.
+ *
+ * @param traceparentHeader - The traceparent header to parse.
+ * @returns An implementation-specific identifier for the span.
+ */
+ function parseTraceparentHeader(traceparentHeader) {
+ return getInstrumenter().parseTraceparentHeader(traceparentHeader);
+ }
+ /**
+ * Creates a set of request headers to propagate tracing information to a backend.
+ *
+ * @param tracingContext - The context containing the span to serialize.
+ * @returns The set of headers to add to a request.
+ */
+ function createRequestHeaders(tracingContext) {
+ return getInstrumenter().createRequestHeaders(tracingContext);
+ }
+ return {
+ startSpan,
+ withSpan,
+ withContext,
+ parseTraceparentHeader,
+ createRequestHeaders,
+ };
+}
+
+exports.createTracingClient = createTracingClient;
+exports.useInstrumenter = useInstrumenter;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 1333:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var abortController = __nccwpck_require__(2557);
+var crypto = __nccwpck_require__(6113);
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Creates an abortable promise.
+ * @param buildPromise - A function that takes the resolve and reject functions as parameters.
+ * @param options - The options for the abortable promise.
+ * @returns A promise that can be aborted.
+ */
+function createAbortablePromise(buildPromise, options) {
+ const { cleanupBeforeAbort, abortSignal, abortErrorMsg } = options !== null && options !== void 0 ? options : {};
+ return new Promise((resolve, reject) => {
+ function rejectOnAbort() {
+ reject(new abortController.AbortError(abortErrorMsg !== null && abortErrorMsg !== void 0 ? abortErrorMsg : "The operation was aborted."));
+ }
+ function removeListeners() {
+ abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener("abort", onAbort);
+ }
+ function onAbort() {
+ cleanupBeforeAbort === null || cleanupBeforeAbort === void 0 ? void 0 : cleanupBeforeAbort();
+ removeListeners();
+ rejectOnAbort();
+ }
+ if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
+ return rejectOnAbort();
+ }
+ try {
+ buildPromise((x) => {
+ removeListeners();
+ resolve(x);
+ }, (x) => {
+ removeListeners();
+ reject(x);
+ });
+ }
+ catch (err) {
+ reject(err);
+ }
+ abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener("abort", onAbort);
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+const StandardAbortMessage = "The delay was aborted.";
+/**
+ * A wrapper for setTimeout that resolves a promise after timeInMs milliseconds.
+ * @param timeInMs - The number of milliseconds to be delayed.
+ * @param options - The options for delay - currently abort options
+ * @returns Promise that is resolved after timeInMs
+ */
+function delay(timeInMs, options) {
+ let token;
+ const { abortSignal, abortErrorMsg } = options !== null && options !== void 0 ? options : {};
+ return createAbortablePromise((resolve) => {
+ token = setTimeout(resolve, timeInMs);
+ }, {
+ cleanupBeforeAbort: () => clearTimeout(token),
+ abortSignal,
+ abortErrorMsg: abortErrorMsg !== null && abortErrorMsg !== void 0 ? abortErrorMsg : StandardAbortMessage,
+ });
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Returns a random integer value between a lower and upper bound,
+ * inclusive of both bounds.
+ * Note that this uses Math.random and isn't secure. If you need to use
+ * this for any kind of security purpose, find a better source of random.
+ * @param min - The smallest integer value allowed.
+ * @param max - The largest integer value allowed.
+ */
+function getRandomIntegerInclusive(min, max) {
+ // Make sure inputs are integers.
+ min = Math.ceil(min);
+ max = Math.floor(max);
+ // Pick a random offset from zero to the size of the range.
+ // Since Math.random() can never return 1, we have to make the range one larger
+ // in order to be inclusive of the maximum value after we take the floor.
+ const offset = Math.floor(Math.random() * (max - min + 1));
+ return offset + min;
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Helper to determine when an input is a generic JS object.
+ * @returns true when input is an object type that is not null, Array, RegExp, or Date.
+ */
+function isObject(input) {
+ return (typeof input === "object" &&
+ input !== null &&
+ !Array.isArray(input) &&
+ !(input instanceof RegExp) &&
+ !(input instanceof Date));
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Typeguard for an error object shape (has name and message)
+ * @param e - Something caught by a catch clause.
+ */
+function isError(e) {
+ if (isObject(e)) {
+ const hasName = typeof e.name === "string";
+ const hasMessage = typeof e.message === "string";
+ return hasName && hasMessage;
+ }
+ return false;
+}
+/**
+ * Given what is thought to be an error object, return the message if possible.
+ * If the message is missing, returns a stringified version of the input.
+ * @param e - Something thrown from a try block
+ * @returns The error message or a string of the input
+ */
+function getErrorMessage(e) {
+ if (isError(e)) {
+ return e.message;
+ }
+ else {
+ let stringified;
+ try {
+ if (typeof e === "object" && e) {
+ stringified = JSON.stringify(e);
+ }
+ else {
+ stringified = String(e);
+ }
+ }
+ catch (err) {
+ stringified = "[unable to stringify input]";
+ }
+ return `Unknown error ${stringified}`;
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Generates a SHA-256 HMAC signature.
+ * @param key - The HMAC key represented as a base64 string, used to generate the cryptographic HMAC hash.
+ * @param stringToSign - The data to be signed.
+ * @param encoding - The textual encoding to use for the returned HMAC digest.
+ */
+async function computeSha256Hmac(key, stringToSign, encoding) {
+ const decodedKey = Buffer.from(key, "base64");
+ return crypto.createHmac("sha256", decodedKey).update(stringToSign).digest(encoding);
+}
+/**
+ * Generates a SHA-256 hash.
+ * @param content - The data to be included in the hash.
+ * @param encoding - The textual encoding to use for the returned hash.
+ */
+async function computeSha256Hash(content, encoding) {
+ return crypto.createHash("sha256").update(content).digest(encoding);
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Helper TypeGuard that checks if something is defined or not.
+ * @param thing - Anything
+ */
+function isDefined(thing) {
+ return typeof thing !== "undefined" && thing !== null;
+}
+/**
+ * Helper TypeGuard that checks if the input is an object with the specified properties.
+ * @param thing - Anything.
+ * @param properties - The name of the properties that should appear in the object.
+ */
+function isObjectWithProperties(thing, properties) {
+ if (!isDefined(thing) || typeof thing !== "object") {
+ return false;
+ }
+ for (const property of properties) {
+ if (!objectHasProperty(thing, property)) {
+ return false;
+ }
+ }
+ return true;
+}
+/**
+ * Helper TypeGuard that checks if the input is an object with the specified property.
+ * @param thing - Any object.
+ * @param property - The name of the property that should appear in the object.
+ */
+function objectHasProperty(thing, property) {
+ return (isDefined(thing) && typeof thing === "object" && property in thing);
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/*
+ * NOTE: When moving this file, please update "react-native" section in package.json.
+ */
+/**
+ * Generated Universally Unique Identifier
+ *
+ * @returns RFC4122 v4 UUID.
+ */
+function generateUUID() {
+ let uuid = "";
+ for (let i = 0; i < 32; i++) {
+ // Generate a random number between 0 and 15
+ const randomNumber = Math.floor(Math.random() * 16);
+ // Set the UUID version to 4 in the 13th position
+ if (i === 12) {
+ uuid += "4";
+ }
+ else if (i === 16) {
+ // Set the UUID variant to "10" in the 17th position
+ uuid += (randomNumber & 0x3) | 0x8;
+ }
+ else {
+ // Add a random hexadecimal digit to the UUID string
+ uuid += randomNumber.toString(16);
+ }
+ // Add hyphens to the UUID string at the appropriate positions
+ if (i === 7 || i === 11 || i === 15 || i === 19) {
+ uuid += "-";
+ }
+ }
+ return uuid;
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+var _a$1;
+// NOTE: This is a workaround until we can use `globalThis.crypto.randomUUID` in Node.js 19+.
+let uuidFunction = typeof ((_a$1 = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a$1 === void 0 ? void 0 : _a$1.randomUUID) === "function"
+ ? globalThis.crypto.randomUUID.bind(globalThis.crypto)
+ : crypto.randomUUID;
+// Not defined in earlier versions of Node.js 14
+if (!uuidFunction) {
+ uuidFunction = generateUUID;
+}
+/**
+ * Generated Universally Unique Identifier
+ *
+ * @returns RFC4122 v4 UUID.
+ */
+function randomUUID() {
+ return uuidFunction();
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+var _a, _b, _c, _d;
+/**
+ * A constant that indicates whether the environment the code is running is a Web Browser.
+ */
+// eslint-disable-next-line @azure/azure-sdk/ts-no-window
+const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
+/**
+ * A constant that indicates whether the environment the code is running is a Web Worker.
+ */
+const isWebWorker = typeof self === "object" &&
+ typeof (self === null || self === void 0 ? void 0 : self.importScripts) === "function" &&
+ (((_a = self.constructor) === null || _a === void 0 ? void 0 : _a.name) === "DedicatedWorkerGlobalScope" ||
+ ((_b = self.constructor) === null || _b === void 0 ? void 0 : _b.name) === "ServiceWorkerGlobalScope" ||
+ ((_c = self.constructor) === null || _c === void 0 ? void 0 : _c.name) === "SharedWorkerGlobalScope");
+/**
+ * A constant that indicates whether the environment the code is running is Node.JS.
+ */
+const isNode = typeof process !== "undefined" && Boolean(process.version) && Boolean((_d = process.versions) === null || _d === void 0 ? void 0 : _d.node);
+/**
+ * A constant that indicates whether the environment the code is running is Deno.
+ */
+const isDeno = typeof Deno !== "undefined" &&
+ typeof Deno.version !== "undefined" &&
+ typeof Deno.version.deno !== "undefined";
+/**
+ * A constant that indicates whether the environment the code is running is Bun.sh.
+ */
+const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined";
+/**
+ * A constant that indicates whether the environment the code is running is in React-Native.
+ */
+// https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js
+const isReactNative = typeof navigator !== "undefined" && (navigator === null || navigator === void 0 ? void 0 : navigator.product) === "ReactNative";
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * The helper that transforms bytes with specific character encoding into string
+ * @param bytes - the uint8array bytes
+ * @param format - the format we use to encode the byte
+ * @returns a string of the encoded string
+ */
+function uint8ArrayToString(bytes, format) {
+ switch (format) {
+ case "utf-8":
+ return uint8ArrayToUtf8String(bytes);
+ case "base64":
+ return uint8ArrayToBase64(bytes);
+ case "base64url":
+ return uint8ArrayToBase64Url(bytes);
+ }
+}
+/**
+ * The helper that transforms string to specific character encoded bytes array.
+ * @param value - the string to be converted
+ * @param format - the format we use to decode the value
+ * @returns a uint8array
+ */
+function stringToUint8Array(value, format) {
+ switch (format) {
+ case "utf-8":
+ return utf8StringToUint8Array(value);
+ case "base64":
+ return base64ToUint8Array(value);
+ case "base64url":
+ return base64UrlToUint8Array(value);
+ }
+}
+/**
+ * Decodes a Uint8Array into a Base64 string.
+ * @internal
+ */
+function uint8ArrayToBase64(bytes) {
+ return Buffer.from(bytes).toString("base64");
+}
+/**
+ * Decodes a Uint8Array into a Base64Url string.
+ * @internal
+ */
+function uint8ArrayToBase64Url(bytes) {
+ return Buffer.from(bytes).toString("base64url");
+}
+/**
+ * Decodes a Uint8Array into a javascript string.
+ * @internal
+ */
+function uint8ArrayToUtf8String(bytes) {
+ return Buffer.from(bytes).toString("utf-8");
+}
+/**
+ * Encodes a JavaScript string into a Uint8Array.
+ * @internal
+ */
+function utf8StringToUint8Array(value) {
+ return Buffer.from(value);
+}
+/**
+ * Encodes a Base64 string into a Uint8Array.
+ * @internal
+ */
+function base64ToUint8Array(value) {
+ return Buffer.from(value, "base64");
+}
+/**
+ * Encodes a Base64Url string into a Uint8Array.
+ * @internal
+ */
+function base64UrlToUint8Array(value) {
+ return Buffer.from(value, "base64url");
+}
+
+exports.computeSha256Hash = computeSha256Hash;
+exports.computeSha256Hmac = computeSha256Hmac;
+exports.createAbortablePromise = createAbortablePromise;
+exports.delay = delay;
+exports.getErrorMessage = getErrorMessage;
+exports.getRandomIntegerInclusive = getRandomIntegerInclusive;
+exports.isBrowser = isBrowser;
+exports.isBun = isBun;
+exports.isDefined = isDefined;
+exports.isDeno = isDeno;
+exports.isError = isError;
+exports.isNode = isNode;
+exports.isObject = isObject;
+exports.isObjectWithProperties = isObjectWithProperties;
+exports.isReactNative = isReactNative;
+exports.isWebWorker = isWebWorker;
+exports.objectHasProperty = objectHasProperty;
+exports.randomUUID = randomUUID;
+exports.stringToUint8Array = stringToUint8Array;
+exports.uint8ArrayToString = uint8ArrayToString;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 3084:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var msalNode = __nccwpck_require__(2884);
+var logger$o = __nccwpck_require__(3233);
+var msalCommon = __nccwpck_require__(5728);
+var abortController = __nccwpck_require__(2557);
+var coreUtil = __nccwpck_require__(1333);
+var uuid = __nccwpck_require__(5840);
+var coreClient = __nccwpck_require__(9729);
+var coreRestPipeline = __nccwpck_require__(8121);
+var coreTracing = __nccwpck_require__(4175);
+var fs = __nccwpck_require__(7147);
+var os = __nccwpck_require__(2037);
+var path = __nccwpck_require__(1017);
+var promises = __nccwpck_require__(3292);
+var https = __nccwpck_require__(5687);
+var child_process = __nccwpck_require__(2081);
+var crypto = __nccwpck_require__(6113);
+var util = __nccwpck_require__(3837);
+var http = __nccwpck_require__(3685);
+var open = __nccwpck_require__(5768);
+var stoppable = __nccwpck_require__(4477);
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+function _interopNamespace(e) {
+ if (e && e.__esModule) return e;
+ var n = Object.create(null);
+ if (e) {
+ Object.keys(e).forEach(function (k) {
+ if (k !== 'default') {
+ var d = Object.getOwnPropertyDescriptor(e, k);
+ Object.defineProperty(n, k, d.get ? d : {
+ enumerable: true,
+ get: function () { return e[k]; }
+ });
+ }
+ });
+ }
+ n["default"] = e;
+ return Object.freeze(n);
+}
+
+var msalNode__namespace = /*#__PURE__*/_interopNamespace(msalNode);
+var msalCommon__namespace = /*#__PURE__*/_interopNamespace(msalCommon);
+var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
+var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
+var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
+var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
+var child_process__default = /*#__PURE__*/_interopDefaultLegacy(child_process);
+var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
+var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
+var open__default = /*#__PURE__*/_interopDefaultLegacy(open);
+var stoppable__default = /*#__PURE__*/_interopDefaultLegacy(stoppable);
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+function isErrorResponse(errorResponse) {
+ return (errorResponse &&
+ typeof errorResponse.error === "string" &&
+ typeof errorResponse.error_description === "string");
+}
+/**
+ * The Error.name value of an CredentialUnavailable
+ */
+const CredentialUnavailableErrorName = "CredentialUnavailableError";
+/**
+ * This signifies that the credential that was tried in a chained credential
+ * was not available to be used as the credential. Rather than treating this as
+ * an error that should halt the chain, it's caught and the chain continues
+ */
+class CredentialUnavailableError extends Error {
+ constructor(message) {
+ super(message);
+ this.name = CredentialUnavailableErrorName;
+ }
+}
+/**
+ * The Error.name value of an AuthenticationError
+ */
+const AuthenticationErrorName = "AuthenticationError";
+/**
+ * Provides details about a failure to authenticate with Azure Active
+ * Directory. The `errorResponse` field contains more details about
+ * the specific failure.
+ */
+class AuthenticationError extends Error {
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ constructor(statusCode, errorBody) {
+ let errorResponse = {
+ error: "unknown",
+ errorDescription: "An unknown error occurred and no additional details are available.",
+ };
+ if (isErrorResponse(errorBody)) {
+ errorResponse = convertOAuthErrorResponseToErrorResponse(errorBody);
+ }
+ else if (typeof errorBody === "string") {
+ try {
+ // Most error responses will contain JSON-formatted error details
+ // in the response body
+ const oauthErrorResponse = JSON.parse(errorBody);
+ errorResponse = convertOAuthErrorResponseToErrorResponse(oauthErrorResponse);
+ }
+ catch (e) {
+ if (statusCode === 400) {
+ errorResponse = {
+ error: "authority_not_found",
+ errorDescription: "The specified authority URL was not found.",
+ };
+ }
+ else {
+ errorResponse = {
+ error: "unknown_error",
+ errorDescription: `An unknown error has occurred. Response body:\n\n${errorBody}`,
+ };
+ }
+ }
+ }
+ else {
+ errorResponse = {
+ error: "unknown_error",
+ errorDescription: "An unknown error occurred and no additional details are available.",
+ };
+ }
+ super(`${errorResponse.error} Status code: ${statusCode}\nMore details:\n${errorResponse.errorDescription}`);
+ this.statusCode = statusCode;
+ this.errorResponse = errorResponse;
+ // Ensure that this type reports the correct name
+ this.name = AuthenticationErrorName;
+ }
+}
+/**
+ * The Error.name value of an AggregateAuthenticationError
+ */
+const AggregateAuthenticationErrorName = "AggregateAuthenticationError";
+/**
+ * Provides an `errors` array containing {@link AuthenticationError} instance
+ * for authentication failures from credentials in a {@link ChainedTokenCredential}.
+ */
+class AggregateAuthenticationError extends Error {
+ constructor(errors, errorMessage) {
+ const errorDetail = errors.join("\n");
+ super(`${errorMessage}\n${errorDetail}`);
+ this.errors = errors;
+ // Ensure that this type reports the correct name
+ this.name = AggregateAuthenticationErrorName;
+ }
+}
+function convertOAuthErrorResponseToErrorResponse(errorBody) {
+ return {
+ error: errorBody.error,
+ errorDescription: errorBody.error_description,
+ correlationId: errorBody.correlation_id,
+ errorCodes: errorBody.error_codes,
+ timestamp: errorBody.timestamp,
+ traceId: errorBody.trace_id,
+ };
+}
+/**
+ * Error used to enforce authentication after trying to retrieve a token silently.
+ */
+class AuthenticationRequiredError extends Error {
+ constructor(
+ /**
+ * Optional parameters. A message can be specified. The {@link GetTokenOptions} of the request can also be specified to more easily associate the error with the received parameters.
+ */
+ options) {
+ super(options.message);
+ this.scopes = options.scopes;
+ this.getTokenOptions = options.getTokenOptions;
+ this.name = "AuthenticationRequiredError";
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The AzureLogger used for all clients within the identity package
+ */
+const logger$n = logger$o.createClientLogger("identity");
+/**
+ * Separates a list of environment variable names into a plain object with two arrays: an array of missing environment variables and another array with assigned environment variables.
+ * @param supportedEnvVars - List of environment variable names
+ */
+function processEnvVars(supportedEnvVars) {
+ return supportedEnvVars.reduce((acc, envVariable) => {
+ if (process.env[envVariable]) {
+ acc.assigned.push(envVariable);
+ }
+ else {
+ acc.missing.push(envVariable);
+ }
+ return acc;
+ }, { missing: [], assigned: [] });
+}
+/**
+ * Formatting the success event on the credentials
+ */
+function formatSuccess(scope) {
+ return `SUCCESS. Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
+}
+/**
+ * Formatting the success event on the credentials
+ */
+function formatError(scope, error) {
+ let message = "ERROR.";
+ if (scope === null || scope === void 0 ? void 0 : scope.length) {
+ message += ` Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
+ }
+ return `${message} Error message: ${typeof error === "string" ? error : error.message}.`;
+}
+/**
+ * Generates a CredentialLoggerInstance.
+ *
+ * It logs with the format:
+ *
+ * `[title] => [message]`
+ *
+ */
+function credentialLoggerInstance(title, parent, log = logger$n) {
+ const fullTitle = parent ? `${parent.fullTitle} ${title}` : title;
+ function info(message) {
+ log.info(`${fullTitle} =>`, message);
+ }
+ function warning(message) {
+ log.warning(`${fullTitle} =>`, message);
+ }
+ function verbose(message) {
+ log.verbose(`${fullTitle} =>`, message);
+ }
+ return {
+ title,
+ fullTitle,
+ info,
+ warning,
+ verbose,
+ };
+}
+/**
+ * Generates a CredentialLogger, which is a logger declared at the credential's constructor, and used at any point in the credential.
+ * It has all the properties of a CredentialLoggerInstance, plus other logger instances, one per method.
+ *
+ * It logs with the format:
+ *
+ * `[title] => [message]`
+ * `[title] => getToken() => [message]`
+ *
+ */
+function credentialLogger(title, log = logger$n) {
+ const credLogger = credentialLoggerInstance(title, undefined, log);
+ return Object.assign(Object.assign({}, credLogger), { parent: log, getToken: credentialLoggerInstance("=> getToken()", credLogger, log) });
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Current version of the `@azure/identity` package.
+ */
+const SDK_VERSION = `3.3.0`;
+/**
+ * The default client ID for authentication
+ * @internal
+ */
+// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
+// Developer Sign On application is available
+// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
+const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
+/**
+ * The default tenant for authentication
+ * @internal
+ */
+const DefaultTenantId = "common";
+/**
+ * A list of known Azure authority hosts
+ */
+exports.AzureAuthorityHosts = void 0;
+(function (AzureAuthorityHosts) {
+ /**
+ * China-based Azure Authority Host
+ */
+ AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
+ /**
+ * Germany-based Azure Authority Host
+ */
+ AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
+ /**
+ * US Government Azure Authority Host
+ */
+ AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
+ /**
+ * Public Cloud Azure Authority Host
+ */
+ AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
+})(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
+/**
+ * The default authority host.
+ */
+const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
+/**
+ * Allow acquiring tokens for any tenant for multi-tentant auth.
+ */
+const ALL_TENANTS = ["*"];
+const CACHE_CAE_SUFFIX = ".cae";
+const CACHE_NON_CAE_SUFFIX = ".nocae";
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Latest AuthenticationRecord version
+ * @internal
+ */
+const LatestAuthenticationRecordVersion = "1.0";
+/**
+ * Ensures the validity of the MSAL token
+ * @internal
+ */
+function ensureValidMsalToken(scopes, logger, msalToken, getTokenOptions) {
+ const error = (message) => {
+ logger.getToken.info(message);
+ return new AuthenticationRequiredError({
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ getTokenOptions,
+ message,
+ });
+ };
+ if (!msalToken) {
+ throw error("No response");
+ }
+ if (!msalToken.expiresOn) {
+ throw error(`Response had no "expiresOn" property.`);
+ }
+ if (!msalToken.accessToken) {
+ throw error(`Response had no "accessToken" property.`);
+ }
+}
+/**
+ * Generates a valid authority by combining a host with a tenantId.
+ * @internal
+ */
+function getAuthority(tenantId, host) {
+ if (!host) {
+ host = DefaultAuthorityHost;
+ }
+ if (new RegExp(`${tenantId}/?$`).test(host)) {
+ return host;
+ }
+ if (host.endsWith("/")) {
+ return host + tenantId;
+ }
+ else {
+ return `${host}/${tenantId}`;
+ }
+}
+/**
+ * Generates the known authorities.
+ * If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
+ * For that reason, we have to force MSAL to disable validating the authority
+ * by sending it within the known authorities in the MSAL configuration.
+ * @internal
+ */
+function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
+ if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
+ return [authorityHost];
+ }
+ return [];
+}
+/**
+ * Generates a logger that can be passed to the MSAL clients.
+ * @param logger - The logger of the credential.
+ * @internal
+ */
+const defaultLoggerCallback = (logger, platform = coreUtil.isNode ? "Node" : "Browser") => (level, message, containsPii) => {
+ if (containsPii) {
+ return;
+ }
+ switch (level) {
+ case msalCommon__namespace.LogLevel.Error:
+ logger.info(`MSAL ${platform} V2 error: ${message}`);
+ return;
+ case msalCommon__namespace.LogLevel.Info:
+ logger.info(`MSAL ${platform} V2 info message: ${message}`);
+ return;
+ case msalCommon__namespace.LogLevel.Verbose:
+ logger.info(`MSAL ${platform} V2 verbose message: ${message}`);
+ return;
+ case msalCommon__namespace.LogLevel.Warning:
+ logger.info(`MSAL ${platform} V2 warning: ${message}`);
+ return;
+ }
+};
+/**
+ * @internal
+ */
+function getMSALLogLevel(logLevel) {
+ switch (logLevel) {
+ case "error":
+ return msalCommon__namespace.LogLevel.Error;
+ case "info":
+ return msalCommon__namespace.LogLevel.Info;
+ case "verbose":
+ return msalCommon__namespace.LogLevel.Verbose;
+ case "warning":
+ return msalCommon__namespace.LogLevel.Warning;
+ default:
+ // default msal logging level should be Info
+ return msalCommon__namespace.LogLevel.Info;
+ }
+}
+/**
+ * The common utility functions for the MSAL clients.
+ * Defined as a class so that the classes extending this one can have access to its methods and protected properties.
+ *
+ * It keeps track of a logger and an in-memory copy of the AuthenticationRecord.
+ *
+ * @internal
+ */
+class MsalBaseUtilities {
+ constructor(options) {
+ this.logger = options.logger;
+ this.account = options.authenticationRecord;
+ }
+ /**
+ * Generates a UUID
+ */
+ generateUuid() {
+ return uuid.v4();
+ }
+ /**
+ * Handles the MSAL authentication result.
+ * If the result has an account, we update the local account reference.
+ * If the token received is invalid, an error will be thrown depending on what's missing.
+ */
+ handleResult(scopes, clientId, result, getTokenOptions) {
+ if (result === null || result === void 0 ? void 0 : result.account) {
+ this.account = msalToPublic(clientId, result.account);
+ }
+ ensureValidMsalToken(scopes, this.logger, result, getTokenOptions);
+ this.logger.getToken.info(formatSuccess(scopes));
+ return {
+ token: result.accessToken,
+ expiresOnTimestamp: result.expiresOn.getTime(),
+ };
+ }
+ /**
+ * Handles MSAL errors.
+ */
+ handleError(scopes, error, getTokenOptions) {
+ if (error.name === "AuthError" ||
+ error.name === "ClientAuthError" ||
+ error.name === "BrowserAuthError") {
+ const msalError = error;
+ switch (msalError.errorCode) {
+ case "endpoints_resolution_error":
+ this.logger.info(formatError(scopes, error.message));
+ return new CredentialUnavailableError(error.message);
+ case "device_code_polling_cancelled":
+ return new abortController.AbortError("The authentication has been aborted by the caller.");
+ case "consent_required":
+ case "interaction_required":
+ case "login_required":
+ this.logger.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
+ break;
+ default:
+ this.logger.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
+ break;
+ }
+ }
+ if (error.name === "ClientConfigurationError" ||
+ error.name === "BrowserConfigurationAuthError" ||
+ error.name === "AbortError") {
+ return error;
+ }
+ return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
+ }
+}
+// transformations.ts
+function publicToMsal(account) {
+ const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [""];
+ return Object.assign(Object.assign({}, account), { localAccountId: account.homeAccountId, environment });
+}
+function msalToPublic(clientId, account) {
+ const record = {
+ authority: getAuthority(account.tenantId, account.environment),
+ homeAccountId: account.homeAccountId,
+ tenantId: account.tenantId || DefaultTenantId,
+ username: account.username,
+ clientId,
+ version: LatestAuthenticationRecordVersion,
+ };
+ return record;
+}
+/**
+ * Serializes an `AuthenticationRecord` into a string.
+ *
+ * The output of a serialized authentication record will contain the following properties:
+ *
+ * - "authority"
+ * - "homeAccountId"
+ * - "clientId"
+ * - "tenantId"
+ * - "username"
+ * - "version"
+ *
+ * To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
+ */
+function serializeAuthenticationRecord(record) {
+ return JSON.stringify(record);
+}
+/**
+ * Deserializes a previously serialized authentication record from a string into an object.
+ *
+ * The input string must contain the following properties:
+ *
+ * - "authority"
+ * - "homeAccountId"
+ * - "clientId"
+ * - "tenantId"
+ * - "username"
+ * - "version"
+ *
+ * If the version we receive is unsupported, an error will be thrown.
+ *
+ * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
+ *
+ * @param serializedRecord - Authentication record previously serialized into string.
+ * @returns AuthenticationRecord.
+ */
+function deserializeAuthenticationRecord(serializedRecord) {
+ const parsed = JSON.parse(serializedRecord);
+ if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
+ throw Error("Unsupported AuthenticationRecord version");
+ }
+ return parsed;
+}
+
+// Copyright (c) Microsoft Corporation.
+function createConfigurationErrorMessage(tenantId) {
+ return `The current credential is not configured to acquire tokens for tenant ${tenantId}. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant.`;
+}
+/**
+ * Of getToken contains a tenantId, this functions allows picking this tenantId as the appropriate for authentication,
+ * unless multitenant authentication has been disabled through the AZURE_IDENTITY_DISABLE_MULTITENANTAUTH (on Node.js),
+ * or unless the original tenant Id is `adfs`.
+ * @internal
+ */
+function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = [], logger) {
+ var _a;
+ let resolvedTenantId;
+ if (process.env.AZURE_IDENTITY_DISABLE_MULTITENANTAUTH) {
+ resolvedTenantId = tenantId;
+ }
+ else if (tenantId === "adfs") {
+ resolvedTenantId = tenantId;
+ }
+ else {
+ resolvedTenantId = (_a = getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.tenantId) !== null && _a !== void 0 ? _a : tenantId;
+ }
+ if (tenantId &&
+ resolvedTenantId !== tenantId &&
+ !additionallyAllowedTenantIds.includes("*") &&
+ !additionallyAllowedTenantIds.some((t) => t.localeCompare(resolvedTenantId) === 0)) {
+ const message = createConfigurationErrorMessage(tenantId);
+ logger === null || logger === void 0 ? void 0 : logger.info(message);
+ throw new CredentialUnavailableError(message);
+ }
+ return resolvedTenantId;
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * @internal
+ */
+function checkTenantId(logger, tenantId) {
+ if (!tenantId.match(/^[0-9a-zA-Z-.:/]+$/)) {
+ const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://docs.microsoft.com/partner-center/find-ids-and-domain-names.");
+ logger.info(formatError("", error));
+ throw error;
+ }
+}
+/**
+ * @internal
+ */
+function resolveTenantId(logger, tenantId, clientId) {
+ if (tenantId) {
+ checkTenantId(logger, tenantId);
+ return tenantId;
+ }
+ if (!clientId) {
+ clientId = DeveloperSignOnClientId;
+ }
+ if (clientId !== DeveloperSignOnClientId) {
+ return "common";
+ }
+ return "organizations";
+}
+/**
+ * @internal
+ */
+function resolveAddionallyAllowedTenantIds(additionallyAllowedTenants) {
+ if (!additionallyAllowedTenants || additionallyAllowedTenants.length === 0) {
+ return [];
+ }
+ if (additionallyAllowedTenants.includes("*")) {
+ return ALL_TENANTS;
+ }
+ return additionallyAllowedTenants;
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+function getIdentityTokenEndpointSuffix(tenantId) {
+ if (tenantId === "adfs") {
+ return "oauth2/token";
+ }
+ else {
+ return "oauth2/v2.0/token";
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Creates a span using the global tracer.
+ * @internal
+ */
+const tracingClient = coreTracing.createTracingClient({
+ namespace: "Microsoft.AAD",
+ packageName: "@azure/identity",
+ packageVersion: SDK_VERSION,
+});
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+const DefaultScopeSuffix = "/.default";
+const imdsHost = "http://169.254.169.254";
+const imdsEndpointPath = "/metadata/identity/oauth2/token";
+const imdsApiVersion = "2018-02-01";
+const azureArcAPIVersion = "2019-11-01";
+const azureFabricVersion = "2019-07-01-preview";
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
+ * These are GET requests that require sending a `resource` parameter on the query.
+ * This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
+ * Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
+ *
+ * For that reason, when we encounter multiple scopes, we return undefined.
+ * It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
+ */
+function mapScopesToResource(scopes) {
+ let scope = "";
+ if (Array.isArray(scopes)) {
+ if (scopes.length !== 1) {
+ return;
+ }
+ scope = scopes[0];
+ }
+ else if (typeof scopes === "string") {
+ scope = scopes;
+ }
+ if (!scope.endsWith(DefaultScopeSuffix)) {
+ return scope;
+ }
+ return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
+}
+/**
+ * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
+ * @param body - A parsed response body from the authentication endpoint.
+ */
+function parseExpirationTimestamp(body) {
+ if (typeof body.expires_on === "number") {
+ return body.expires_on * 1000;
+ }
+ if (typeof body.expires_on === "string") {
+ const asNumber = +body.expires_on;
+ if (!isNaN(asNumber)) {
+ return asNumber * 1000;
+ }
+ const asDate = Date.parse(body.expires_on);
+ if (!isNaN(asDate)) {
+ return asDate;
+ }
+ }
+ if (typeof body.expires_in === "number") {
+ return Date.now() + body.expires_in * 1000;
+ }
+ throw new Error(`Failed to parse token expiration from body. expires_in="${body.expires_in}", expires_on="${body.expires_on}"`);
+}
+
+// Copyright (c) Microsoft Corporation.
+const noCorrelationId = "noCorrelationId";
+/**
+ * @internal
+ */
+function getIdentityClientAuthorityHost(options) {
+ // The authorityHost can come from options or from the AZURE_AUTHORITY_HOST environment variable.
+ let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
+ // The AZURE_AUTHORITY_HOST environment variable can only be provided in Node.js.
+ if (coreUtil.isNode) {
+ authorityHost = authorityHost !== null && authorityHost !== void 0 ? authorityHost : process.env.AZURE_AUTHORITY_HOST;
+ }
+ // If the authorityHost is not provided, we use the default one from the public cloud: https://login.microsoftonline.com
+ return authorityHost !== null && authorityHost !== void 0 ? authorityHost : DefaultAuthorityHost;
+}
+/**
+ * The network module used by the Identity credentials.
+ *
+ * It allows for credentials to abort any pending request independently of the MSAL flow,
+ * by calling to the `abortRequests()` method.
+ *
+ */
+class IdentityClient extends coreClient.ServiceClient {
+ constructor(options) {
+ var _a, _b;
+ const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;
+ const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
+ ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
+ : `${packageDetails}`;
+ const baseUri = getIdentityClientAuthorityHost(options);
+ if (!baseUri.startsWith("https:")) {
+ throw new Error("The authorityHost address must use the 'https' protocol.");
+ }
+ super(Object.assign(Object.assign({ requestContentType: "application/json; charset=utf-8", retryOptions: {
+ maxRetries: 3,
+ } }, options), { userAgentOptions: {
+ userAgentPrefix,
+ }, baseUri }));
+ this.authorityHost = baseUri;
+ this.abortControllers = new Map();
+ this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
+ // used for WorkloadIdentity
+ this.tokenCredentialOptions = Object.assign({}, options);
+ }
+ async sendTokenRequest(request) {
+ logger$n.info(`IdentityClient: sending token request to [${request.url}]`);
+ const response = await this.sendRequest(request);
+ if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
+ const parsedBody = JSON.parse(response.bodyAsText);
+ if (!parsedBody.access_token) {
+ return null;
+ }
+ this.logIdentifiers(response);
+ const token = {
+ accessToken: {
+ token: parsedBody.access_token,
+ expiresOnTimestamp: parseExpirationTimestamp(parsedBody),
+ },
+ refreshToken: parsedBody.refresh_token,
+ };
+ logger$n.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
+ return token;
+ }
+ else {
+ const error = new AuthenticationError(response.status, response.bodyAsText);
+ logger$n.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
+ throw error;
+ }
+ }
+ async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, options = {}) {
+ if (refreshToken === undefined) {
+ return null;
+ }
+ logger$n.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
+ const refreshParams = {
+ grant_type: "refresh_token",
+ client_id: clientId,
+ refresh_token: refreshToken,
+ scope: scopes,
+ };
+ if (clientSecret !== undefined) {
+ refreshParams.client_secret = clientSecret;
+ }
+ const query = new URLSearchParams(refreshParams);
+ return tracingClient.withSpan("IdentityClient.refreshAccessToken", options, async (updatedOptions) => {
+ try {
+ const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);
+ const request = coreRestPipeline.createPipelineRequest({
+ url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,
+ method: "POST",
+ body: query.toString(),
+ abortSignal: options.abortSignal,
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ "Content-Type": "application/x-www-form-urlencoded",
+ }),
+ tracingOptions: updatedOptions.tracingOptions,
+ });
+ const response = await this.sendTokenRequest(request);
+ logger$n.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
+ return response;
+ }
+ catch (err) {
+ if (err.name === AuthenticationErrorName &&
+ err.errorResponse.error === "interaction_required") {
+ // It's likely that the refresh token has expired, so
+ // return null so that the credential implementation will
+ // initiate the authentication flow again.
+ logger$n.info(`IdentityClient: interaction required for client ID: ${clientId}`);
+ return null;
+ }
+ else {
+ logger$n.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
+ throw err;
+ }
+ }
+ });
+ }
+ // Here is a custom layer that allows us to abort requests that go through MSAL,
+ // since MSAL doesn't allow us to pass options all the way through.
+ generateAbortSignal(correlationId) {
+ const controller = new abortController.AbortController();
+ const controllers = this.abortControllers.get(correlationId) || [];
+ controllers.push(controller);
+ this.abortControllers.set(correlationId, controllers);
+ const existingOnAbort = controller.signal.onabort;
+ controller.signal.onabort = (...params) => {
+ this.abortControllers.set(correlationId, undefined);
+ if (existingOnAbort) {
+ existingOnAbort(...params);
+ }
+ };
+ return controller.signal;
+ }
+ abortRequests(correlationId) {
+ const key = correlationId || noCorrelationId;
+ const controllers = [
+ ...(this.abortControllers.get(key) || []),
+ // MSAL passes no correlation ID to the get requests...
+ ...(this.abortControllers.get(noCorrelationId) || []),
+ ];
+ if (!controllers.length) {
+ return;
+ }
+ for (const controller of controllers) {
+ controller.abort();
+ }
+ this.abortControllers.set(key, undefined);
+ }
+ getCorrelationId(options) {
+ var _a;
+ const parameter = (_a = options === null || options === void 0 ? void 0 : options.body) === null || _a === void 0 ? void 0 : _a.split("&").map((part) => part.split("=")).find(([key]) => key === "client-request-id");
+ return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;
+ }
+ // The MSAL network module methods follow
+ async sendGetRequestAsync(url, options) {
+ const request = coreRestPipeline.createPipelineRequest({
+ url,
+ method: "GET",
+ body: options === null || options === void 0 ? void 0 : options.body,
+ headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
+ abortSignal: this.generateAbortSignal(noCorrelationId),
+ });
+ const response = await this.sendRequest(request);
+ this.logIdentifiers(response);
+ return {
+ body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
+ headers: response.headers.toJSON(),
+ status: response.status,
+ };
+ }
+ async sendPostRequestAsync(url, options) {
+ const request = coreRestPipeline.createPipelineRequest({
+ url,
+ method: "POST",
+ body: options === null || options === void 0 ? void 0 : options.body,
+ headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
+ // MSAL doesn't send the correlation ID on the get requests.
+ abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),
+ });
+ const response = await this.sendRequest(request);
+ this.logIdentifiers(response);
+ return {
+ body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
+ headers: response.headers.toJSON(),
+ status: response.status,
+ };
+ }
+ /**
+ *
+ * @internal
+ */
+ getTokenCredentialOptions() {
+ return this.tokenCredentialOptions;
+ }
+ /**
+ * If allowLoggingAccountIdentifiers was set on the constructor options
+ * we try to log the account identifiers by parsing the received access token.
+ *
+ * The account identifiers we try to log are:
+ * - `appid`: The application or Client Identifier.
+ * - `upn`: User Principal Name.
+ * - It might not be available in some authentication scenarios.
+ * - If it's not available, we put a placeholder: "No User Principal Name available".
+ * - `tid`: Tenant Identifier.
+ * - `oid`: Object Identifier of the authenticated user.
+ */
+ logIdentifiers(response) {
+ if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {
+ return;
+ }
+ const unavailableUpn = "No User Principal Name available";
+ try {
+ const parsed = response.parsedBody || JSON.parse(response.bodyAsText);
+ const accessToken = parsed.access_token;
+ if (!accessToken) {
+ // Without an access token allowLoggingAccountIdentifiers isn't useful.
+ return;
+ }
+ const base64Metadata = accessToken.split(".")[1];
+ const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
+ logger$n.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
+ }
+ catch (e) {
+ logger$n.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+/**
+ * Helps specify a regional authority, or "AutoDiscoverRegion" to auto-detect the region.
+ */
+var RegionalAuthority;
+(function (RegionalAuthority) {
+ /** Instructs MSAL to attempt to discover the region */
+ RegionalAuthority["AutoDiscoverRegion"] = "AutoDiscoverRegion";
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus' region. */
+ RegionalAuthority["USWest"] = "westus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus2' region. */
+ RegionalAuthority["USWest2"] = "westus2";
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralus' region. */
+ RegionalAuthority["USCentral"] = "centralus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus' region. */
+ RegionalAuthority["USEast"] = "eastus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus2' region. */
+ RegionalAuthority["USEast2"] = "eastus2";
+ /** Uses the {@link RegionalAuthority} for the Azure 'northcentralus' region. */
+ RegionalAuthority["USNorthCentral"] = "northcentralus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'southcentralus' region. */
+ RegionalAuthority["USSouthCentral"] = "southcentralus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'westcentralus' region. */
+ RegionalAuthority["USWestCentral"] = "westcentralus";
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadacentral' region. */
+ RegionalAuthority["CanadaCentral"] = "canadacentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadaeast' region. */
+ RegionalAuthority["CanadaEast"] = "canadaeast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'brazilsouth' region. */
+ RegionalAuthority["BrazilSouth"] = "brazilsouth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'northeurope' region. */
+ RegionalAuthority["EuropeNorth"] = "northeurope";
+ /** Uses the {@link RegionalAuthority} for the Azure 'westeurope' region. */
+ RegionalAuthority["EuropeWest"] = "westeurope";
+ /** Uses the {@link RegionalAuthority} for the Azure 'uksouth' region. */
+ RegionalAuthority["UKSouth"] = "uksouth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'ukwest' region. */
+ RegionalAuthority["UKWest"] = "ukwest";
+ /** Uses the {@link RegionalAuthority} for the Azure 'francecentral' region. */
+ RegionalAuthority["FranceCentral"] = "francecentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'francesouth' region. */
+ RegionalAuthority["FranceSouth"] = "francesouth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandnorth' region. */
+ RegionalAuthority["SwitzerlandNorth"] = "switzerlandnorth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandwest' region. */
+ RegionalAuthority["SwitzerlandWest"] = "switzerlandwest";
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynorth' region. */
+ RegionalAuthority["GermanyNorth"] = "germanynorth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanywestcentral' region. */
+ RegionalAuthority["GermanyWestCentral"] = "germanywestcentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwaywest' region. */
+ RegionalAuthority["NorwayWest"] = "norwaywest";
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwayeast' region. */
+ RegionalAuthority["NorwayEast"] = "norwayeast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastasia' region. */
+ RegionalAuthority["AsiaEast"] = "eastasia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'southeastasia' region. */
+ RegionalAuthority["AsiaSouthEast"] = "southeastasia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'japaneast' region. */
+ RegionalAuthority["JapanEast"] = "japaneast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'japanwest' region. */
+ RegionalAuthority["JapanWest"] = "japanwest";
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiaeast' region. */
+ RegionalAuthority["AustraliaEast"] = "australiaeast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiasoutheast' region. */
+ RegionalAuthority["AustraliaSouthEast"] = "australiasoutheast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral' region. */
+ RegionalAuthority["AustraliaCentral"] = "australiacentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral2' region. */
+ RegionalAuthority["AustraliaCentral2"] = "australiacentral2";
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralindia' region. */
+ RegionalAuthority["IndiaCentral"] = "centralindia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'southindia' region. */
+ RegionalAuthority["IndiaSouth"] = "southindia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'westindia' region. */
+ RegionalAuthority["IndiaWest"] = "westindia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreasouth' region. */
+ RegionalAuthority["KoreaSouth"] = "koreasouth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreacentral' region. */
+ RegionalAuthority["KoreaCentral"] = "koreacentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaecentral' region. */
+ RegionalAuthority["UAECentral"] = "uaecentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaenorth' region. */
+ RegionalAuthority["UAENorth"] = "uaenorth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricanorth' region. */
+ RegionalAuthority["SouthAfricaNorth"] = "southafricanorth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricawest' region. */
+ RegionalAuthority["SouthAfricaWest"] = "southafricawest";
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth' region. */
+ RegionalAuthority["ChinaNorth"] = "chinanorth";
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast' region. */
+ RegionalAuthority["ChinaEast"] = "chinaeast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth2' region. */
+ RegionalAuthority["ChinaNorth2"] = "chinanorth2";
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast2' region. */
+ RegionalAuthority["ChinaEast2"] = "chinaeast2";
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanycentral' region. */
+ RegionalAuthority["GermanyCentral"] = "germanycentral";
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynortheast' region. */
+ RegionalAuthority["GermanyNorthEast"] = "germanynortheast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovvirginia' region. */
+ RegionalAuthority["GovernmentUSVirginia"] = "usgovvirginia";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgoviowa' region. */
+ RegionalAuthority["GovernmentUSIowa"] = "usgoviowa";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovarizona' region. */
+ RegionalAuthority["GovernmentUSArizona"] = "usgovarizona";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovtexas' region. */
+ RegionalAuthority["GovernmentUSTexas"] = "usgovtexas";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodeast' region. */
+ RegionalAuthority["GovernmentUSDodEast"] = "usdodeast";
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodcentral' region. */
+ RegionalAuthority["GovernmentUSDodCentral"] = "usdodcentral";
+})(RegionalAuthority || (RegionalAuthority = {}));
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The current persistence provider, undefined by default.
+ * @internal
+ */
+let persistenceProvider = undefined;
+/**
+ * An object that allows setting the persistence provider.
+ * @internal
+ */
+const msalNodeFlowCacheControl = {
+ setPersistence(pluginProvider) {
+ persistenceProvider = pluginProvider;
+ },
+};
+/**
+ * MSAL partial base client for Node.js.
+ *
+ * It completes the input configuration with some default values.
+ * It also provides with utility protected methods that can be used from any of the clients,
+ * which includes handlers for successful responses and errors.
+ *
+ * @internal
+ */
+class MsalNode extends MsalBaseUtilities {
+ constructor(options) {
+ var _a, _b, _c, _d;
+ super(options);
+ // protected publicApp: msalNode.PublicClientApplication | undefined;
+ // protected publicAppCae: msalNode.PublicClientApplication | undefined;
+ // protected confidentialApp: msalNode.ConfidentialClientApplication | undefined;
+ // protected confidentialAppCae: msalNode.ConfidentialClientApplication | undefined;
+ this.app = {};
+ this.caeApp = {};
+ this.requiresConfidential = false;
+ this.msalConfig = this.defaultNodeMsalConfig(options);
+ this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
+ this.clientId = this.msalConfig.auth.clientId;
+ if (options === null || options === void 0 ? void 0 : options.getAssertion) {
+ this.getAssertion = options.getAssertion;
+ }
+ // If persistence has been configured
+ if (persistenceProvider !== undefined && ((_b = options.tokenCachePersistenceOptions) === null || _b === void 0 ? void 0 : _b.enabled)) {
+ const nonCaeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
+ const caeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
+ this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
+ this.createCachePluginCae = () => persistenceProvider(caeOptions);
+ }
+ else if ((_c = options.tokenCachePersistenceOptions) === null || _c === void 0 ? void 0 : _c.enabled) {
+ throw new Error([
+ "Persistent token caching was requested, but no persistence provider was configured.",
+ "You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
+ "`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
+ ].join(" "));
+ }
+ this.azureRegion = (_d = options.regionalAuthority) !== null && _d !== void 0 ? _d : process.env.AZURE_REGIONAL_AUTHORITY_NAME;
+ if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) {
+ this.azureRegion = "AUTO_DISCOVER";
+ }
+ }
+ /**
+ * Generates a MSAL configuration that generally works for Node.js
+ */
+ defaultNodeMsalConfig(options) {
+ var _a;
+ const clientId = options.clientId || DeveloperSignOnClientId;
+ const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
+ this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
+ const authority = getAuthority(tenantId, this.authorityHost);
+ this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
+ const clientCapabilities = [];
+ return {
+ auth: {
+ clientId,
+ authority,
+ knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
+ clientCapabilities,
+ },
+ // Cache is defined in this.prepare();
+ system: {
+ networkClient: this.identityClient,
+ loggerOptions: {
+ loggerCallback: defaultLoggerCallback(options.logger),
+ logLevel: getMSALLogLevel(logger$o.getLogLevel()),
+ piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
+ },
+ },
+ };
+ }
+ getApp(appType, enableCae) {
+ const app = enableCae ? this.caeApp : this.app;
+ if (appType === "publicFirst") {
+ return (app.public || app.confidential);
+ }
+ else if (appType === "confidentialFirst") {
+ return (app.confidential || app.public);
+ }
+ else if (appType === "confidential") {
+ return app.confidential;
+ }
+ else {
+ return app.public;
+ }
+ }
+ /**
+ * Prepares the MSAL applications.
+ */
+ async init(options) {
+ if (options === null || options === void 0 ? void 0 : options.abortSignal) {
+ options.abortSignal.addEventListener("abort", () => {
+ // This will abort any pending request in the IdentityClient,
+ // based on the received or generated correlationId
+ this.identityClient.abortRequests(options.correlationId);
+ });
+ }
+ const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
+ this.msalConfig.auth.clientCapabilities = ["cp1"];
+ }
+ if (app.public || app.confidential) {
+ return;
+ }
+ if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
+ this.msalConfig.cache = {
+ cachePlugin: await this.createCachePluginCae(),
+ };
+ }
+ if (this.createCachePlugin !== undefined) {
+ this.msalConfig.cache = {
+ cachePlugin: await this.createCachePlugin(),
+ };
+ }
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
+ this.caeApp.public = new msalNode__namespace.PublicClientApplication(this.msalConfig);
+ }
+ else {
+ this.app.public = new msalNode__namespace.PublicClientApplication(this.msalConfig);
+ }
+ if (this.getAssertion) {
+ this.msalConfig.auth.clientAssertion = await this.getAssertion();
+ }
+ // The confidential client requires either a secret, assertion or certificate.
+ if (this.msalConfig.auth.clientSecret ||
+ this.msalConfig.auth.clientAssertion ||
+ this.msalConfig.auth.clientCertificate) {
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
+ this.caeApp.confidential = new msalNode__namespace.ConfidentialClientApplication(this.msalConfig);
+ }
+ else {
+ this.app.confidential = new msalNode__namespace.ConfidentialClientApplication(this.msalConfig);
+ }
+ }
+ else {
+ if (this.requiresConfidential) {
+ throw new Error("Unable to generate the MSAL confidential client. Missing either the client's secret, certificate or assertion.");
+ }
+ }
+ }
+ /**
+ * Allows the cancellation of a MSAL request.
+ */
+ withCancellation(promise, abortSignal, onCancel) {
+ return new Promise((resolve, reject) => {
+ promise
+ .then((msalToken) => {
+ return resolve(msalToken);
+ })
+ .catch(reject);
+ if (abortSignal) {
+ abortSignal.addEventListener("abort", () => {
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
+ });
+ }
+ });
+ }
+ /**
+ * Returns the existing account, attempts to load the account from MSAL.
+ */
+ async getActiveAccount(enableCae = false) {
+ if (this.account) {
+ return this.account;
+ }
+ const cache = this.getApp("confidentialFirst", enableCae).getTokenCache();
+ const accountsByTenant = await (cache === null || cache === void 0 ? void 0 : cache.getAllAccounts());
+ if (!accountsByTenant) {
+ return;
+ }
+ if (accountsByTenant.length === 1) {
+ this.account = msalToPublic(this.clientId, accountsByTenant[0]);
+ }
+ else {
+ this.logger
+ .info(`More than one account was found authenticated for this Client ID and Tenant ID.
+However, no "authenticationRecord" has been provided for this credential,
+therefore we're unable to pick between these accounts.
+A new login attempt will be requested, to ensure the correct account is picked.
+To work with multiple accounts for the same Client ID and Tenant ID, please provide an "authenticationRecord" when initializing a credential to prevent this from happening.`);
+ return;
+ }
+ return this.account;
+ }
+ /**
+ * Attempts to retrieve a token from cache.
+ */
+ async getTokenSilent(scopes, options) {
+ var _a, _b, _c;
+ await this.getActiveAccount(options === null || options === void 0 ? void 0 : options.enableCae);
+ if (!this.account) {
+ throw new AuthenticationRequiredError({
+ scopes,
+ getTokenOptions: options,
+ message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
+ });
+ }
+ const silentRequest = {
+ // To be able to re-use the account, the Token Cache must also have been provided.
+ account: publicToMsal(this.account),
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
+ scopes,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ };
+ try {
+ this.logger.info("Attempting to acquire token silently");
+ /**
+ * The following code to retrieve all accounts is done as a workaround in an attempt to force the
+ * refresh of the token cache with the token and the account passed in through the
+ * `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
+ * This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
+ */
+ await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
+ const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
+ return this.handleResult(scopes, this.clientId, response || undefined);
+ }
+ catch (err) {
+ throw this.handleError(scopes, err, options);
+ }
+ }
+ /**
+ * Wrapper around each MSAL flow get token operation: doGetToken.
+ * If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
+ */
+ async getToken(scopes, options = {}) {
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
+ this.tenantId;
+ options.authority = getAuthority(tenantId, this.authorityHost);
+ options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || this.generateUuid();
+ await this.init(options);
+ try {
+ // MSAL now caches tokens based on their claims,
+ // so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
+ // This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
+ const optionsClaims = options.claims;
+ if (optionsClaims) {
+ this.cachedClaims = optionsClaims;
+ }
+ if (this.cachedClaims && !optionsClaims) {
+ options.claims = this.cachedClaims;
+ }
+ // We don't return the promise since we want to catch errors right here.
+ return await this.getTokenSilent(scopes, options);
+ }
+ catch (err) {
+ if (err.name !== "AuthenticationRequiredError") {
+ throw err;
+ }
+ if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
+ throw new AuthenticationRequiredError({
+ scopes,
+ getTokenOptions: options,
+ message: "Automatic authentication has been disabled. You may call the authentication() method.",
+ });
+ }
+ this.logger.info(`Silent authentication failed, falling back to interactive method.`);
+ return this.doGetToken(scopes, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const CommonTenantId = "common";
+const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
+const logger$m = credentialLogger("VisualStudioCodeCredential");
+let findCredentials = undefined;
+const vsCodeCredentialControl = {
+ setVsCodeCredentialFinder(finder) {
+ findCredentials = finder;
+ },
+};
+// Map of unsupported Tenant IDs and the errors we will be throwing.
+const unsupportedTenantIds = {
+ adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants.",
+};
+function checkUnsupportedTenant(tenantId) {
+ // If the Tenant ID isn't supported, we throw.
+ const unsupportedTenantError = unsupportedTenantIds[tenantId];
+ if (unsupportedTenantError) {
+ throw new CredentialUnavailableError(unsupportedTenantError);
+ }
+}
+const mapVSCodeAuthorityHosts = {
+ AzureCloud: exports.AzureAuthorityHosts.AzurePublicCloud,
+ AzureChina: exports.AzureAuthorityHosts.AzureChina,
+ AzureGermanCloud: exports.AzureAuthorityHosts.AzureGermany,
+ AzureUSGovernment: exports.AzureAuthorityHosts.AzureGovernment,
+};
+/**
+ * Attempts to load a specific property from the VSCode configurations of the current OS.
+ * If it fails at any point, returns undefined.
+ */
+function getPropertyFromVSCode(property) {
+ const settingsPath = ["User", "settings.json"];
+ // Eventually we can add more folders for more versions of VSCode.
+ const vsCodeFolder = "Code";
+ const homedir = os__default["default"].homedir();
+ function loadProperty(...pathSegments) {
+ const fullPath = path__default["default"].join(...pathSegments, vsCodeFolder, ...settingsPath);
+ const settings = JSON.parse(fs__default["default"].readFileSync(fullPath, { encoding: "utf8" }));
+ return settings[property];
+ }
+ try {
+ let appData;
+ switch (process.platform) {
+ case "win32":
+ appData = process.env.APPDATA;
+ return appData ? loadProperty(appData) : undefined;
+ case "darwin":
+ return loadProperty(homedir, "Library", "Application Support");
+ case "linux":
+ return loadProperty(homedir, ".config");
+ default:
+ return;
+ }
+ }
+ catch (e) {
+ logger$m.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
+ return;
+ }
+}
+/**
+ * Connects to Azure using the credential provided by the VSCode extension 'Azure Account'.
+ * Once the user has logged in via the extension, this credential can share the same refresh token
+ * that is cached by the extension.
+ *
+ * It's a [known issue](https://github.com/Azure/azure-sdk-for-js/issues/20500) that this credential doesn't
+ * work with [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
+ * versions newer than **0.9.11**. A long-term fix to this problem is in progress. In the meantime, consider
+ * authenticating with {@link AzureCliCredential}.
+ */
+class VisualStudioCodeCredential {
+ /**
+ * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.
+ *
+ * **Note**: `VisualStudioCodeCredential` is provided by a plugin package:
+ * `@azure/identity-vscode`. If this package is not installed and registered
+ * using the plugin API (`useIdentityPlugin`), then authentication using
+ * `VisualStudioCodeCredential` will not be available.
+ *
+ * @param options - Options for configuring the client which makes the authentication request.
+ */
+ constructor(options) {
+ // We want to make sure we use the one assigned by the user on the VSCode settings.
+ // Or just `AzureCloud` by default.
+ this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
+ // Picking an authority host based on the cloud name.
+ const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
+ this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
+ if (options && options.tenantId) {
+ checkTenantId(logger$m, options.tenantId);
+ this.tenantId = options.tenantId;
+ }
+ else {
+ this.tenantId = CommonTenantId;
+ }
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ checkUnsupportedTenant(this.tenantId);
+ }
+ /**
+ * Runs preparations for any further getToken request.
+ */
+ async prepare() {
+ // Attempts to load the tenant from the VSCode configuration file.
+ const settingsTenant = getPropertyFromVSCode("azure.tenant");
+ if (settingsTenant) {
+ this.tenantId = settingsTenant;
+ }
+ checkUnsupportedTenant(this.tenantId);
+ }
+ /**
+ * Runs preparations for any further getToken, but only once.
+ */
+ prepareOnce() {
+ if (!this.preparePromise) {
+ this.preparePromise = this.prepare();
+ }
+ return this.preparePromise;
+ }
+ /**
+ * Returns the token found by searching VSCode's authentication cache or
+ * returns null if no token could be found.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * `TokenCredential` implementation might make.
+ */
+ async getToken(scopes, options) {
+ var _a, _b;
+ await this.prepareOnce();
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$m) || this.tenantId;
+ if (findCredentials === undefined) {
+ throw new CredentialUnavailableError([
+ "No implementation of `VisualStudioCodeCredential` is available.",
+ "You must install the identity-vscode plugin package (`npm install --save-dev @azure/identity-vscode`)",
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
+ "`useIdentityPlugin(vsCodePlugin)` before creating a `VisualStudioCodeCredential`.",
+ "To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.",
+ ].join(" "));
+ }
+ let scopeString = typeof scopes === "string" ? scopes : scopes.join(" ");
+ // Check to make sure the scope we get back is a valid scope
+ if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
+ const error = new Error("Invalid scope was specified by the user or calling client");
+ logger$m.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ if (scopeString.indexOf("offline_access") < 0) {
+ scopeString += " offline_access";
+ }
+ // findCredentials returns an array similar to:
+ // [
+ // {
+ // account: "",
+ // password: "",
+ // },
+ // /* ... */
+ // ]
+ const credentials = await findCredentials();
+ // If we can't find the credential based on the name, we'll pick the first one available.
+ const { password: refreshToken } = (_b = (_a = credentials.find(({ account }) => account === this.cloudName)) !== null && _a !== void 0 ? _a : credentials[0]) !== null && _b !== void 0 ? _b : {};
+ if (refreshToken) {
+ const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
+ if (tokenResponse) {
+ logger$m.getToken.info(formatSuccess(scopes));
+ return tokenResponse.accessToken;
+ }
+ else {
+ const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
+ logger$m.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ }
+ else {
+ const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
+ logger$m.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * The context passed to an Identity plugin. This contains objects that
+ * plugins can use to set backend implementations.
+ * @internal
+ */
+const pluginContext = {
+ cachePluginControl: msalNodeFlowCacheControl,
+ vsCodeCredentialControl: vsCodeCredentialControl,
+};
+/**
+ * Extend Azure Identity with additional functionality. Pass a plugin from
+ * a plugin package, such as:
+ *
+ * - `@azure/identity-cache-persistence`: provides persistent token caching
+ * - `@azure/identity-vscode`: provides the dependencies of
+ * `VisualStudioCodeCredential` and enables it
+ *
+ * Example:
+ *
+ * ```javascript
+ * import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
+ *
+ * import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
+ * useIdentityPlugin(cachePersistencePlugin);
+ *
+ * // The plugin has the capability to extend `DefaultAzureCredential` and to
+ * // add middleware to the underlying credentials, such as persistence.
+ * const credential = new DefaultAzureCredential({
+ * tokenCachePersistenceOptions: {
+ * enabled: true
+ * }
+ * });
+ * ```
+ *
+ * @param plugin - the plugin to register
+ */
+function useIdentityPlugin(plugin) {
+ plugin(pluginContext);
+}
+
+// Copyright (c) Microsoft Corporation.
+const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
+const logger$l = credentialLogger(msiName$6);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions$5(scopes, clientId) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
+ }
+ const queryParameters = {
+ resource,
+ "api-version": "2017-09-01",
+ };
+ if (clientId) {
+ queryParameters.clientid = clientId;
+ }
+ const query = new URLSearchParams(queryParameters);
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
+ if (!process.env.MSI_ENDPOINT) {
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
+ }
+ if (!process.env.MSI_SECRET) {
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
+ }
+ return {
+ url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
+ method: "GET",
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ secret: process.env.MSI_SECRET,
+ }),
+ };
+}
+/**
+ * Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
+ */
+const appServiceMsi2017 = {
+ name: "appServiceMsi2017",
+ async isAvailable({ scopes }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$l.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ const env = process.env;
+ const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
+ if (!result) {
+ logger$l.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { identityClient, scopes, clientId, resourceId } = configuration;
+ if (resourceId) {
+ logger$l.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
+ }
+ logger$l.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
+ allowInsecureConnection: true }));
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
+const logger$k = credentialLogger(msiName$5);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions$4(scopes, clientId, resourceId) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
+ }
+ const body = {
+ resource,
+ };
+ if (clientId) {
+ body.client_id = clientId;
+ }
+ if (resourceId) {
+ body.msi_res_id = resourceId;
+ }
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
+ if (!process.env.MSI_ENDPOINT) {
+ throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
+ }
+ const params = new URLSearchParams(body);
+ return {
+ url: process.env.MSI_ENDPOINT,
+ method: "POST",
+ body: params.toString(),
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ Metadata: "true",
+ "Content-Type": "application/x-www-form-urlencoded",
+ }),
+ };
+}
+/**
+ * Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
+ * Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
+ */
+const cloudShellMsi = {
+ name: "cloudShellMsi",
+ async isAvailable({ scopes }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$k.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ const result = Boolean(process.env.MSI_ENDPOINT);
+ if (!result) {
+ logger$k.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { identityClient, scopes, clientId, resourceId } = configuration;
+ if (clientId) {
+ logger$k.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
+ }
+ if (resourceId) {
+ logger$k.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
+ }
+ logger$k.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
+ allowInsecureConnection: true }));
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const msiName$4 = "ManagedIdentityCredential - IMDS";
+const logger$j = credentialLogger(msiName$4);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
+ var _a;
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
+ }
+ const { skipQuery, skipMetadataHeader } = options || {};
+ let query = "";
+ // Pod Identity will try to process this request even if the Metadata header is missing.
+ // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
+ if (!skipQuery) {
+ const queryParameters = {
+ resource,
+ "api-version": imdsApiVersion,
+ };
+ if (clientId) {
+ queryParameters.client_id = clientId;
+ }
+ if (resourceId) {
+ queryParameters.msi_res_id = resourceId;
+ }
+ const params = new URLSearchParams(queryParameters);
+ query = `?${params.toString()}`;
+ }
+ const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
+ const rawHeaders = {
+ Accept: "application/json",
+ Metadata: "true",
+ };
+ // Remove the Metadata header to invoke a request error from some IMDS endpoints.
+ if (skipMetadataHeader) {
+ delete rawHeaders.Metadata;
+ }
+ return {
+ // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
+ url: `${url}${query}`,
+ method: "GET",
+ headers: coreRestPipeline.createHttpHeaders(rawHeaders),
+ };
+}
+// 800ms -> 1600ms -> 3200ms
+const imdsMsiRetryConfig = {
+ maxRetries: 3,
+ startDelayInMs: 800,
+ intervalIncrement: 2,
+};
+/**
+ * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
+ */
+const imdsMsi = {
+ name: "imdsMsi",
+ async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$j.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
+ return true;
+ }
+ if (!identityClient) {
+ throw new Error("Missing IdentityClient");
+ }
+ const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
+ skipMetadataHeader: true,
+ skipQuery: true,
+ });
+ return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
+ var _a;
+ requestOptions.tracingOptions = options.tracingOptions;
+ // Create a request with a timeout since we expect that
+ // not having a "Metadata" header should cause an error to be
+ // returned quickly from the endpoint, proving its availability.
+ const request = coreRestPipeline.createPipelineRequest(requestOptions);
+ // Default to 300 if the default of 0 is used.
+ // Negative values can still be used to disable the timeout.
+ request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 300;
+ // This MSI uses the imdsEndpoint to get the token, which only uses http://
+ request.allowInsecureConnection = true;
+ try {
+ logger$j.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
+ await identityClient.sendRequest(request);
+ }
+ catch (err) {
+ // If the request failed, or Node.js was unable to establish a connection,
+ // or the host was down, we'll assume the IMDS endpoint isn't available.
+ if (coreUtil.isError(err)) {
+ logger$j.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
+ }
+ logger$j.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
+ return false;
+ }
+ // If we received any response, the endpoint is available
+ logger$j.info(`${msiName$4}: The Azure IMDS endpoint is available`);
+ return true;
+ });
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { identityClient, scopes, clientId, resourceId } = configuration;
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
+ logger$j.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
+ }
+ else {
+ logger$j.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
+ }
+ let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
+ for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
+ try {
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ }
+ catch (error) {
+ if (error.statusCode === 404) {
+ await coreUtil.delay(nextDelayInMs);
+ nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
+ continue;
+ }
+ throw error;
+ }
+ }
+ throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
+const logger$i = credentialLogger(msiName$3);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions$2(scopes, clientId, resourceId) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
+ }
+ const queryParameters = {
+ resource,
+ "api-version": azureArcAPIVersion,
+ };
+ if (clientId) {
+ queryParameters.client_id = clientId;
+ }
+ if (resourceId) {
+ queryParameters.msi_res_id = resourceId;
+ }
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
+ if (!process.env.IDENTITY_ENDPOINT) {
+ throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
+ }
+ const query = new URLSearchParams(queryParameters);
+ return coreRestPipeline.createPipelineRequest({
+ // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
+ method: "GET",
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ Metadata: "true",
+ }),
+ });
+}
+/**
+ * Retrieves the file contents at the given path using promises.
+ * Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
+ */
+function readFileAsync$1(path, options) {
+ return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
+ if (err) {
+ reject(err);
+ }
+ resolve(data);
+ }));
+}
+/**
+ * Does a request to the authentication provider that results in a file path.
+ */
+async function filePathRequest(identityClient, requestPrepareOptions) {
+ const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
+ if (response.status !== 401) {
+ let message = "";
+ if (response.bodyAsText) {
+ message = ` Response: ${response.bodyAsText}`;
+ }
+ throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
+ }
+ const authHeader = response.headers.get("www-authenticate") || "";
+ try {
+ return authHeader.split("=").slice(1)[0];
+ }
+ catch (e) {
+ throw Error(`Invalid www-authenticate header format: ${authHeader}`);
+ }
+}
+/**
+ * Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
+ */
+const arcMsi = {
+ name: "arc",
+ async isAvailable({ scopes }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$i.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
+ if (!result) {
+ logger$i.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ var _a;
+ const { identityClient, scopes, clientId, resourceId } = configuration;
+ if (clientId) {
+ logger$i.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
+ }
+ if (resourceId) {
+ logger$i.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
+ }
+ logger$i.info(`${msiName$3}: Authenticating.`);
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
+ const filePath = await filePathRequest(identityClient, requestOptions);
+ if (!filePath) {
+ throw new Error(`${msiName$3}: Failed to find the token file.`);
+ }
+ const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
+ (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
+ allowInsecureConnection: true }));
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
+ * @internal
+ */
+class MsalClientAssertion extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.requiresConfidential = true;
+ this.getAssertion = options.getAssertion;
+ }
+ async doGetToken(scopes, options = {}) {
+ try {
+ const assertion = await this.getAssertion();
+ const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential({
+ scopes,
+ correlationId: options.correlationId,
+ azureRegion: this.azureRegion,
+ authority: options.authority,
+ claims: options.claims,
+ clientAssertion: assertion,
+ });
+ // The Client Credential flow does not return an account,
+ // so each time getToken gets called, we will have to acquire a new token through the service.
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (err) {
+ let err2 = err;
+ if (err === null || err === undefined) {
+ err2 = new Error(JSON.stringify(err));
+ }
+ else {
+ err2 = coreUtil.isError(err) ? err : new Error(String(err));
+ }
+ throw this.handleError(scopes, err2, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$h = credentialLogger("ClientAssertionCredential");
+/**
+ * Authenticates a service principal with a JWT assertion.
+ */
+class ClientAssertionCredential {
+ /**
+ * Creates an instance of the ClientAssertionCredential with the details
+ * needed to authenticate against Azure Active Directory with a client
+ * assertion provided by the developer through the `getAssertion` function parameter.
+ *
+ * @param tenantId - The Azure Active Directory tenant (directory) ID.
+ * @param clientId - The client (application) ID of an App Registration in the tenant.
+ * @param getAssertion - A function that retrieves the assertion for the credential to use.
+ * @param options - Options for configuring the client which makes the authentication request.
+ */
+ constructor(tenantId, clientId, getAssertion, options = {}) {
+ if (!tenantId || !clientId || !getAssertion) {
+ throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
+ }
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.clientId = clientId;
+ this.options = options;
+ this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$h, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$h);
+ const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
+ return this.msalFlow.getToken(arrayScopes, newOptions);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const credentialName$3 = "WorkloadIdentityCredential";
+/**
+ * Contains the list of all supported environment variable names so that an
+ * appropriate error message can be generated when no credentials can be
+ * configured.
+ *
+ * @internal
+ */
+const SupportedWorkloadEnvironmentVariables = [
+ "AZURE_TENANT_ID",
+ "AZURE_CLIENT_ID",
+ "AZURE_FEDERATED_TOKEN_FILE",
+];
+const logger$g = credentialLogger(credentialName$3);
+/**
+ * Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
+ * to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
+ * authentication, applications authenticate themselves using their own identity, rather than using a shared service
+ * principal or managed identity. Under the hood, Workload Identity authentication uses the concept of Service Account
+ * Credentials (SACs), which are automatically created by Azure and stored securely in the VM. By using Workload
+ * Identity authentication, you can avoid the need to manage and rotate service principals or managed identities for
+ * each application on each VM. Additionally, because SACs are created automatically and managed by Azure, you don't
+ * need to worry about storing and securing sensitive credentials themselves.
+ * The WorkloadIdentityCredential supports Azure workload identity authentication on Azure Kubernetes and acquires
+ * a token using the SACs available in the Azure Kubernetes environment.
+ * Refer to Azure Active Directory
+ * Workload Identity for more information.
+ */
+class WorkloadIdentityCredential {
+ /**
+ * WorkloadIdentityCredential supports Azure workload identity on Kubernetes.
+ *
+ * @param options - The identity client options to use for authentication.
+ */
+ constructor(options) {
+ this.azureFederatedTokenFileContent = undefined;
+ this.cacheDate = undefined;
+ // Logging environment variables for error details
+ const assignedEnv = processEnvVars(SupportedWorkloadEnvironmentVariables).assigned.join(", ");
+ logger$g.info(`Found the following environment variables: ${assignedEnv}`);
+ const workloadIdentityCredentialOptions = options !== null && options !== void 0 ? options : {};
+ const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID;
+ const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID;
+ this.federatedTokenFilePath =
+ workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE;
+ if (tenantId) {
+ checkTenantId(logger$g, tenantId);
+ }
+ if (clientId && tenantId && this.federatedTokenFilePath) {
+ logger$g.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
+ this.client = new ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options);
+ }
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options) {
+ if (!this.client) {
+ const errorMessage = `${credentialName$3}: is unavailable. tenantId, clientId, and federatedTokenFilePath are required parameters.
+ In DefaultAzureCredential and ManagedIdentityCredential, these can be provided as environment variables -
+ "AZURE_TENANT_ID",
+ "AZURE_CLIENT_ID",
+ "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot `;
+ logger$g.info(errorMessage);
+ throw new CredentialUnavailableError(errorMessage);
+ }
+ logger$g.info("Invoking getToken() of Client Assertion Credential");
+ return this.client.getToken(scopes, options);
+ }
+ async readFileContents() {
+ // Cached assertions expire after 5 minutes
+ if (this.cacheDate !== undefined && Date.now() - this.cacheDate >= 1000 * 60 * 5) {
+ this.azureFederatedTokenFileContent = undefined;
+ }
+ if (!this.federatedTokenFilePath) {
+ throw new CredentialUnavailableError(`${credentialName$3}: is unavailable. Invalid file path provided ${this.federatedTokenFilePath}.`);
+ }
+ if (!this.azureFederatedTokenFileContent) {
+ const file = await promises.readFile(this.federatedTokenFilePath, "utf8");
+ const value = file.trim();
+ if (!value) {
+ throw new CredentialUnavailableError(`${credentialName$3}: is unavailable. No content on the file ${this.federatedTokenFilePath}.`);
+ }
+ else {
+ this.azureFederatedTokenFileContent = value;
+ this.cacheDate = Date.now();
+ }
+ }
+ return this.azureFederatedTokenFileContent;
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const msiName$2 = "ManagedIdentityCredential - Token Exchange";
+const logger$f = credentialLogger(msiName$2);
+/**
+ * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
+ */
+function tokenExchangeMsi() {
+ return {
+ name: "tokenExchangeMsi",
+ async isAvailable({ clientId }) {
+ const env = process.env;
+ const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
+ env.AZURE_TENANT_ID &&
+ process.env.AZURE_FEDERATED_TOKEN_FILE);
+ if (!result) {
+ logger$f.info(`${msiName$2}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { scopes, clientId } = configuration;
+ const identityClientTokenCredentialOptions = {};
+ const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
+ const token = await workloadIdentityCredential.getToken(scopes, getTokenOptions);
+ return token;
+ },
+ };
+}
+
+// Copyright (c) Microsoft Corporation.
+// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
+//
+// FROM node:12
+// RUN wget https://host.any/path/bash.sh
+// CMD ["bash", "bash.sh"]
+//
+// Where the bash script contains:
+//
+// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
+//
+const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
+const logger$e = credentialLogger(msiName$1);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions$1(scopes, clientId, resourceId) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
+ }
+ const queryParameters = {
+ resource,
+ "api-version": azureFabricVersion,
+ };
+ if (clientId) {
+ queryParameters.client_id = clientId;
+ }
+ if (resourceId) {
+ queryParameters.msi_res_id = resourceId;
+ }
+ const query = new URLSearchParams(queryParameters);
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
+ if (!process.env.IDENTITY_ENDPOINT) {
+ throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
+ }
+ if (!process.env.IDENTITY_HEADER) {
+ throw new Error("Missing environment variable: IDENTITY_HEADER");
+ }
+ return {
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
+ method: "GET",
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ secret: process.env.IDENTITY_HEADER,
+ }),
+ };
+}
+/**
+ * Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
+ */
+const fabricMsi = {
+ name: "fabricMsi",
+ async isAvailable({ scopes }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$e.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ const env = process.env;
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
+ if (!result) {
+ logger$e.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { scopes, identityClient, clientId, resourceId } = configuration;
+ if (resourceId) {
+ logger$e.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
+ }
+ logger$e.info([
+ `${msiName$1}:`,
+ "Using the endpoint and the secret coming from the environment variables:",
+ `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
+ "IDENTITY_HEADER=[REDACTED] and",
+ "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
+ ].join(" "));
+ const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
+ request.agent = new https__default["default"].Agent({
+ // This is necessary because Service Fabric provides a self-signed certificate.
+ // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
+ rejectUnauthorized: false,
+ });
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
+const logger$d = credentialLogger(msiName);
+/**
+ * Generates the options used on the request for an access token.
+ */
+function prepareRequestOptions(scopes, clientId, resourceId) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ throw new Error(`${msiName}: Multiple scopes are not supported.`);
+ }
+ const queryParameters = {
+ resource,
+ "api-version": "2019-08-01",
+ };
+ if (clientId) {
+ queryParameters.client_id = clientId;
+ }
+ if (resourceId) {
+ queryParameters.mi_res_id = resourceId;
+ }
+ const query = new URLSearchParams(queryParameters);
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
+ if (!process.env.IDENTITY_ENDPOINT) {
+ throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
+ }
+ if (!process.env.IDENTITY_HEADER) {
+ throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
+ }
+ return {
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
+ method: "GET",
+ headers: coreRestPipeline.createHttpHeaders({
+ Accept: "application/json",
+ "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
+ }),
+ };
+}
+/**
+ * Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
+ */
+const appServiceMsi2019 = {
+ name: "appServiceMsi2019",
+ async isAvailable({ scopes }) {
+ const resource = mapScopesToResource(scopes);
+ if (!resource) {
+ logger$d.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
+ return false;
+ }
+ const env = process.env;
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
+ if (!result) {
+ logger$d.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
+ }
+ return result;
+ },
+ async getToken(configuration, getTokenOptions = {}) {
+ const { identityClient, scopes, clientId, resourceId } = configuration;
+ logger$d.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
+ allowInsecureConnection: true }));
+ const tokenResponse = await identityClient.sendTokenRequest(request);
+ return (tokenResponse && tokenResponse.accessToken) || null;
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const logger$c = credentialLogger("ManagedIdentityCredential");
+/**
+ * Attempts authentication using a managed identity available at the deployment environment.
+ * This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
+ * Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
+ *
+ * More information about configuring managed identities can be found here:
+ * https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
+ */
+class ManagedIdentityCredential {
+ /**
+ * @internal
+ * @hidden
+ */
+ constructor(clientIdOrOptions, options) {
+ var _a;
+ this.isEndpointUnavailable = null;
+ this.isAppTokenProviderInitialized = false;
+ let _options;
+ if (typeof clientIdOrOptions === "string") {
+ this.clientId = clientIdOrOptions;
+ _options = options;
+ }
+ else {
+ this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
+ _options = clientIdOrOptions;
+ }
+ this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
+ // For JavaScript users.
+ if (this.clientId && this.resourceId) {
+ throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
+ }
+ this.identityClient = new IdentityClient(_options);
+ this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
+ maxRetries: 0,
+ } }));
+ /** authority host validation and metadata discovery to be skipped in managed identity
+ * since this wasn't done previously before adding token cache support
+ */
+ this.confidentialApp = new msalNode.ConfidentialClientApplication({
+ auth: {
+ clientId: (_a = this.clientId) !== null && _a !== void 0 ? _a : DeveloperSignOnClientId,
+ clientSecret: "dummy-secret",
+ cloudDiscoveryMetadata: '{"tenant_discovery_endpoint":"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}',
+ authorityMetadata: '{"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"kerberos_endpoint":"https://login.microsoftonline.com/common/kerberos","tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}',
+ clientCapabilities: [],
+ },
+ system: {
+ loggerOptions: {
+ logLevel: getMSALLogLevel(logger$o.getLogLevel()),
+ },
+ },
+ });
+ }
+ async cachedAvailableMSI(scopes, getTokenOptions) {
+ if (this.cachedMSI) {
+ return this.cachedMSI;
+ }
+ const MSIs = [
+ arcMsi,
+ fabricMsi,
+ appServiceMsi2019,
+ appServiceMsi2017,
+ cloudShellMsi,
+ tokenExchangeMsi(),
+ imdsMsi,
+ ];
+ for (const msi of MSIs) {
+ if (await msi.isAvailable({
+ scopes,
+ identityClient: this.isAvailableIdentityClient,
+ clientId: this.clientId,
+ resourceId: this.resourceId,
+ getTokenOptions,
+ })) {
+ this.cachedMSI = msi;
+ return msi;
+ }
+ }
+ throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
+ }
+ async authenticateManagedIdentity(scopes, getTokenOptions) {
+ const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
+ try {
+ // Determining the available MSI, and avoiding checking for other MSIs while the program is running.
+ const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
+ return availableMSI.getToken({
+ identityClient: this.identityClient,
+ scopes,
+ clientId: this.clientId,
+ resourceId: this.resourceId,
+ }, updatedOptions);
+ }
+ catch (err) {
+ span.setStatus({
+ status: "error",
+ error: err,
+ });
+ throw err;
+ }
+ finally {
+ span.end();
+ }
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ * If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options) {
+ let result = null;
+ const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.getToken`, options);
+ try {
+ // isEndpointAvailable can be true, false, or null,
+ // If it's null, it means we don't yet know whether
+ // the endpoint is available and need to check for it.
+ if (this.isEndpointUnavailable !== true) {
+ const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
+ if (availableMSI.name === "tokenExchangeMsi") {
+ result = await this.authenticateManagedIdentity(scopes, updatedOptions);
+ }
+ else {
+ const appTokenParameters = {
+ correlationId: this.identityClient.getCorrelationId(),
+ tenantId: (options === null || options === void 0 ? void 0 : options.tenantId) || "organizations",
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ };
+ // Added a check to see if SetAppTokenProvider was already defined.
+ this.initializeSetAppTokenProvider();
+ const authenticationResult = await this.confidentialApp.acquireTokenByClientCredential(Object.assign({}, appTokenParameters));
+ result = this.handleResult(scopes, authenticationResult || undefined);
+ }
+ if (result === null) {
+ // If authenticateManagedIdentity returns null,
+ // it means no MSI endpoints are available.
+ // If so, we avoid trying to reach to them in future requests.
+ this.isEndpointUnavailable = true;
+ // It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
+ // yet we had no access token. For this reason, we'll throw once with a specific message:
+ const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
+ logger$c.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ // Since `authenticateManagedIdentity` didn't throw, and the result was not null,
+ // We will assume that this endpoint is reachable from this point forward,
+ // and avoid pinging again to it.
+ this.isEndpointUnavailable = false;
+ }
+ else {
+ // We've previously determined that the endpoint was unavailable,
+ // either because it was unreachable or permanently unable to authenticate.
+ const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
+ logger$c.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ logger$c.getToken.info(formatSuccess(scopes));
+ return result;
+ }
+ catch (err) {
+ // CredentialUnavailable errors are expected to reach here.
+ // We intend them to bubble up, so that DefaultAzureCredential can catch them.
+ if (err.name === "AuthenticationRequiredError") {
+ throw err;
+ }
+ // Expected errors to reach this point:
+ // - Errors coming from a method unexpectedly breaking.
+ // - When identityClient.sendTokenRequest throws, in which case
+ // if the status code was 400, it means that the endpoint is working,
+ // but no identity is available.
+ span.setStatus({
+ status: "error",
+ error: err,
+ });
+ // If either the network is unreachable,
+ // we can safely assume the credential is unavailable.
+ if (err.code === "ENETUNREACH") {
+ const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
+ logger$c.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ // If either the host was unreachable,
+ // we can safely assume the credential is unavailable.
+ if (err.code === "EHOSTUNREACH") {
+ const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
+ logger$c.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ // If err.statusCode has a value of 400, it comes from sendTokenRequest,
+ // and it means that the endpoint is working, but that no identity is available.
+ if (err.statusCode === 400) {
+ throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
+ }
+ // If the error has no status code, we can assume there was no available identity.
+ // This will throw silently during any ChainedTokenCredential.
+ if (err.statusCode === undefined) {
+ throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Authentication failed. Message ${err.message}`);
+ }
+ // Any other error should break the chain.
+ throw new AuthenticationError(err.statusCode, {
+ error: `${ManagedIdentityCredential.name} authentication failed.`,
+ error_description: err.message,
+ });
+ }
+ finally {
+ // Finally is always called, both if we return and if we throw in the above try/catch.
+ span.end();
+ }
+ }
+ /**
+ * Handles the MSAL authentication result.
+ * If the result has an account, we update the local account reference.
+ * If the token received is invalid, an error will be thrown depending on what's missing.
+ */
+ handleResult(scopes, result, getTokenOptions) {
+ this.ensureValidMsalToken(scopes, result, getTokenOptions);
+ logger$c.getToken.info(formatSuccess(scopes));
+ return {
+ token: result.accessToken,
+ expiresOnTimestamp: result.expiresOn.getTime(),
+ };
+ }
+ /**
+ * Ensures the validity of the MSAL token
+ * @internal
+ */
+ ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
+ const error = (message) => {
+ logger$c.getToken.info(message);
+ return new AuthenticationRequiredError({
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
+ getTokenOptions,
+ message,
+ });
+ };
+ if (!msalToken) {
+ throw error("No response");
+ }
+ if (!msalToken.expiresOn) {
+ throw error(`Response had no "expiresOn" property.`);
+ }
+ if (!msalToken.accessToken) {
+ throw error(`Response had no "accessToken" property.`);
+ }
+ }
+ initializeSetAppTokenProvider() {
+ if (!this.isAppTokenProviderInitialized) {
+ this.confidentialApp.SetAppTokenProvider(async (appTokenProviderParameters) => {
+ logger$c.info(`SetAppTokenProvider invoked with parameters- ${JSON.stringify(appTokenProviderParameters)}`);
+ const getTokenOptions = Object.assign({}, appTokenProviderParameters);
+ logger$c.info(`authenticateManagedIdentity invoked with scopes- ${JSON.stringify(appTokenProviderParameters.scopes)} and getTokenOptions - ${JSON.stringify(getTokenOptions)}`);
+ const resultToken = await this.authenticateManagedIdentity(appTokenProviderParameters.scopes, getTokenOptions);
+ if (resultToken) {
+ logger$c.info(`SetAppTokenProvider will save the token in cache`);
+ const expiresInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.expiresOnTimestamp)
+ ? Math.floor((resultToken.expiresOnTimestamp - Date.now()) / 1000)
+ : 0;
+ return {
+ accessToken: resultToken === null || resultToken === void 0 ? void 0 : resultToken.token,
+ expiresInSeconds,
+ };
+ }
+ else {
+ logger$c.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
+ return {
+ accessToken: "no_access_token_returned",
+ expiresInSeconds: 0,
+ };
+ }
+ });
+ this.isAppTokenProviderInitialized = true;
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Ensures the scopes value is an array.
+ * @internal
+ */
+function ensureScopes(scopes) {
+ return Array.isArray(scopes) ? scopes : [scopes];
+}
+/**
+ * Throws if the received scope is not valid.
+ * @internal
+ */
+function ensureValidScopeForDevTimeCreds(scope, logger) {
+ if (!scope.match(/^[0-9a-zA-Z-.:/]+$/)) {
+ const error = new Error("Invalid scope was specified by the user or calling client");
+ logger.getToken.info(formatError(scope, error));
+ throw error;
+ }
+}
+/**
+ * Returns the resource out of a scope.
+ * @internal
+ */
+function getScopeResource(scope) {
+ return scope.replace(/\/.default$/, "");
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Mockable reference to the CLI credential cliCredentialFunctions
+ * @internal
+ */
+const cliCredentialInternals = {
+ /**
+ * @internal
+ */
+ getSafeWorkingDir() {
+ if (process.platform === "win32") {
+ if (!process.env.SystemRoot) {
+ throw new Error("Azure CLI credential expects a 'SystemRoot' environment variable");
+ }
+ return process.env.SystemRoot;
+ }
+ else {
+ return "/bin";
+ }
+ },
+ /**
+ * Gets the access token from Azure CLI
+ * @param resource - The resource to use when getting the token
+ * @internal
+ */
+ async getAzureCliAccessToken(resource, tenantId, timeout) {
+ let tenantSection = [];
+ if (tenantId) {
+ tenantSection = ["--tenant", tenantId];
+ }
+ return new Promise((resolve, reject) => {
+ try {
+ child_process__default["default"].execFile("az", [
+ "account",
+ "get-access-token",
+ "--output",
+ "json",
+ "--resource",
+ resource,
+ ...tenantSection,
+ ], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true, timeout }, (error, stdout, stderr) => {
+ resolve({ stdout: stdout, stderr: stderr, error });
+ });
+ }
+ catch (err) {
+ reject(err);
+ }
+ });
+ },
+};
+const logger$b = credentialLogger("AzureCliCredential");
+/**
+ * This credential will use the currently logged-in user login information
+ * via the Azure CLI ('az') commandline tool.
+ * To do so, it will read the user access token and expire time
+ * with Azure CLI command "az account get-access-token".
+ */
+class AzureCliCredential {
+ /**
+ * Creates an instance of the {@link AzureCliCredential}.
+ *
+ * To use this credential, ensure that you have already logged
+ * in via the 'az' tool using the command "az login" from the commandline.
+ *
+ * @param options - Options, to optionally allow multi-tenant requests.
+ */
+ constructor(options) {
+ this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
+ const scope = typeof scopes === "string" ? scopes : scopes[0];
+ logger$b.getToken.info(`Using the scope ${scope}`);
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
+ var _a, _b, _c, _d;
+ try {
+ ensureValidScopeForDevTimeCreds(scope, logger$b);
+ const resource = getScopeResource(scope);
+ const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.timeout);
+ const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
+ const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
+ const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
+ if (isNotInstallError) {
+ const error = new CredentialUnavailableError("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
+ logger$b.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ if (isLoginError) {
+ const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
+ logger$b.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ try {
+ const responseData = obj.stdout;
+ const response = JSON.parse(responseData);
+ logger$b.getToken.info(formatSuccess(scopes));
+ const returnValue = {
+ token: response.accessToken,
+ expiresOnTimestamp: new Date(response.expiresOn).getTime(),
+ };
+ return returnValue;
+ }
+ catch (e) {
+ if (obj.stderr) {
+ throw new CredentialUnavailableError(obj.stderr);
+ }
+ throw e;
+ }
+ }
+ catch (err) {
+ const error = err.name === "CredentialUnavailableError"
+ ? err
+ : new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
+ logger$b.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Easy to mock childProcess utils.
+ * @internal
+ */
+const processUtils = {
+ /**
+ * Promisifying childProcess.execFile
+ * @internal
+ */
+ execFile(file, params, options) {
+ return new Promise((resolve, reject) => {
+ child_process__namespace.execFile(file, params, options, (error, stdout, stderr) => {
+ if (Buffer.isBuffer(stdout)) {
+ stdout = stdout.toString("utf8");
+ }
+ if (Buffer.isBuffer(stderr)) {
+ stderr = stderr.toString("utf8");
+ }
+ if (stderr || error) {
+ reject(stderr ? new Error(stderr) : error);
+ }
+ else {
+ resolve(stdout);
+ }
+ });
+ });
+ },
+};
+
+// Copyright (c) Microsoft Corporation.
+const logger$a = credentialLogger("AzurePowerShellCredential");
+const isWindows = process.platform === "win32";
+/**
+ * Returns a platform-appropriate command name by appending ".exe" on Windows.
+ *
+ * @internal
+ */
+function formatCommand(commandName) {
+ if (isWindows) {
+ return `${commandName}.exe`;
+ }
+ else {
+ return commandName;
+ }
+}
+/**
+ * Receives a list of commands to run, executes them, then returns the outputs.
+ * If anything fails, an error is thrown.
+ * @internal
+ */
+async function runCommands(commands, timeout) {
+ const results = [];
+ for (const command of commands) {
+ const [file, ...parameters] = command;
+ const result = (await processUtils.execFile(file, parameters, {
+ encoding: "utf8",
+ timeout,
+ }));
+ results.push(result);
+ }
+ return results;
+}
+/**
+ * Known PowerShell errors
+ * @internal
+ */
+const powerShellErrors = {
+ login: "Run Connect-AzAccount to login",
+ installed: "The specified module 'Az.Accounts' with version '2.2.0' was not loaded because no valid module file was found in any module directory",
+};
+/**
+ * Messages to use when throwing in this credential.
+ * @internal
+ */
+const powerShellPublicErrorMessages = {
+ login: "Please run 'Connect-AzAccount' from PowerShell to authenticate before using this credential.",
+ installed: `The 'Az.Account' module >= 2.2.0 is not installed. Install the Azure Az PowerShell module with: "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force".`,
+ troubleshoot: `To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot.`,
+};
+// PowerShell Azure User not logged in error check.
+const isLoginError = (err) => err.message.match(`(.*)${powerShellErrors.login}(.*)`);
+// Az Module not Installed in Azure PowerShell check.
+const isNotInstalledError = (err) => err.message.match(powerShellErrors.installed);
+/**
+ * The PowerShell commands to be tried, in order.
+ *
+ * @internal
+ */
+const commandStack = [formatCommand("pwsh")];
+if (isWindows) {
+ commandStack.push(formatCommand("powershell"));
+}
+/**
+ * This credential will use the currently logged-in user information from the
+ * Azure PowerShell module. To do so, it will read the user access token and
+ * expire time with Azure PowerShell command `Get-AzAccessToken -ResourceUrl {ResourceScope}`
+ */
+class AzurePowerShellCredential {
+ /**
+ * Creates an instance of the {@link AzurePowerShellCredential}.
+ *
+ * To use this credential:
+ * - Install the Azure Az PowerShell module with:
+ * `Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force`.
+ * - You have already logged in to Azure PowerShell using the command
+ * `Connect-AzAccount` from the command line.
+ *
+ * @param options - Options, to optionally allow multi-tenant requests.
+ */
+ constructor(options) {
+ this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
+ }
+ /**
+ * Gets the access token from Azure PowerShell
+ * @param resource - The resource to use when getting the token
+ */
+ async getAzurePowerShellAccessToken(resource, tenantId, timeout) {
+ // Clone the stack to avoid mutating it while iterating
+ for (const powerShellCommand of [...commandStack]) {
+ try {
+ await runCommands([[powerShellCommand, "/?"]], timeout);
+ }
+ catch (e) {
+ // Remove this credential from the original stack so that we don't try it again.
+ commandStack.shift();
+ continue;
+ }
+ let tenantSection = "";
+ if (tenantId) {
+ tenantSection = `-TenantId "${tenantId}"`;
+ }
+ const results = await runCommands([
+ [
+ powerShellCommand,
+ "-Command",
+ "Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru",
+ ],
+ [
+ powerShellCommand,
+ "-Command",
+ `Get-AzAccessToken ${tenantSection} -ResourceUrl "${resource}" | ConvertTo-Json`,
+ ],
+ ]);
+ const result = results[1];
+ try {
+ return JSON.parse(result);
+ }
+ catch (e) {
+ throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
+ }
+ }
+ throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
+ const scope = typeof scopes === "string" ? scopes : scopes[0];
+ try {
+ ensureValidScopeForDevTimeCreds(scope, logger$a);
+ logger$a.getToken.info(`Using the scope ${scope}`);
+ const resource = getScopeResource(scope);
+ const response = await this.getAzurePowerShellAccessToken(resource, tenantId, this.timeout);
+ logger$a.getToken.info(formatSuccess(scopes));
+ return {
+ token: response.Token,
+ expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
+ };
+ }
+ catch (err) {
+ if (isNotInstalledError(err)) {
+ const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
+ logger$a.getToken.info(formatError(scope, error));
+ throw error;
+ }
+ else if (isLoginError(err)) {
+ const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
+ logger$a.getToken.info(formatError(scope, error));
+ throw error;
+ }
+ const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
+ logger$a.getToken.info(formatError(scope, error));
+ throw error;
+ }
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * @internal
+ */
+const logger$9 = credentialLogger("ChainedTokenCredential");
+/**
+ * Enables multiple `TokenCredential` implementations to be tried in order
+ * until one of the getToken methods returns an access token.
+ */
+class ChainedTokenCredential {
+ /**
+ * Creates an instance of ChainedTokenCredential using the given credentials.
+ *
+ * @param sources - `TokenCredential` implementations to be tried in order.
+ *
+ * Example usage:
+ * ```javascript
+ * const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
+ * const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
+ * const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
+ * ```
+ */
+ constructor(...sources) {
+ this._sources = [];
+ this._sources = sources;
+ }
+ /**
+ * Returns the first access token returned by one of the chained
+ * `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError}
+ * when one or more credentials throws an {@link AuthenticationError} and
+ * no credentials have returned an access token.
+ *
+ * This method is called automatically by Azure SDK client libraries. You may call this method
+ * directly, but you must also handle token caching and token refreshing.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * `TokenCredential` implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ const { token } = await this.getTokenInternal(scopes, options);
+ return token;
+ }
+ async getTokenInternal(scopes, options = {}) {
+ let token = null;
+ let successfulCredential;
+ const errors = [];
+ return tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => {
+ for (let i = 0; i < this._sources.length && token === null; i++) {
+ try {
+ token = await this._sources[i].getToken(scopes, updatedOptions);
+ successfulCredential = this._sources[i];
+ }
+ catch (err) {
+ if (err.name === "CredentialUnavailableError" ||
+ err.name === "AuthenticationRequiredError") {
+ errors.push(err);
+ }
+ else {
+ logger$9.getToken.info(formatError(scopes, err));
+ throw err;
+ }
+ }
+ }
+ if (!token && errors.length > 0) {
+ const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
+ logger$9.getToken.info(formatError(scopes, err));
+ throw err;
+ }
+ logger$9.getToken.info(`Result for ${successfulCredential.constructor.name}: ${formatSuccess(scopes)}`);
+ if (token === null) {
+ throw new CredentialUnavailableError("Failed to retrieve a valid token");
+ }
+ return { token, successfulCredential };
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const readFileAsync = util.promisify(fs.readFile);
+/**
+ * Tries to asynchronously load a certificate from the given path.
+ *
+ * @param configuration - Either the PEM value or the path to the certificate.
+ * @param sendCertificateChain - Option to include x5c header for SubjectName and Issuer name authorization.
+ * @returns - The certificate parts, or `undefined` if the certificate could not be loaded.
+ * @internal
+ */
+async function parseCertificate(configuration, sendCertificateChain) {
+ const certificateParts = {};
+ const certificate = configuration
+ .certificate;
+ const certificatePath = configuration
+ .certificatePath;
+ certificateParts.certificateContents =
+ certificate || (await readFileAsync(certificatePath, "utf8"));
+ if (sendCertificateChain) {
+ certificateParts.x5c = certificateParts.certificateContents;
+ }
+ const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g;
+ const publicKeys = [];
+ // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c
+ let match;
+ do {
+ match = certificatePattern.exec(certificateParts.certificateContents);
+ if (match) {
+ publicKeys.push(match[3]);
+ }
+ } while (match);
+ if (publicKeys.length === 0) {
+ throw new Error("The file at the specified path does not contain a PEM-encoded certificate.");
+ }
+ certificateParts.thumbprint = crypto.createHash("sha1")
+ .update(Buffer.from(publicKeys[0], "base64"))
+ .digest("hex")
+ .toUpperCase();
+ return certificateParts;
+}
+/**
+ * MSAL client certificate client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
+ * @internal
+ */
+class MsalClientCertificate extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.requiresConfidential = true;
+ this.configuration = options.configuration;
+ this.sendCertificateChain = options.sendCertificateChain;
+ }
+ // Changing the MSAL configuration asynchronously
+ async init(options) {
+ try {
+ const parts = await parseCertificate(this.configuration, this.sendCertificateChain);
+ let privateKey;
+ if (this.configuration.certificatePassword !== undefined) {
+ const privateKeyObject = crypto.createPrivateKey({
+ key: parts.certificateContents,
+ passphrase: this.configuration.certificatePassword,
+ format: "pem",
+ });
+ privateKey = privateKeyObject
+ .export({
+ format: "pem",
+ type: "pkcs8",
+ })
+ .toString();
+ }
+ else {
+ privateKey = parts.certificateContents;
+ }
+ this.msalConfig.auth.clientCertificate = {
+ thumbprint: parts.thumbprint,
+ privateKey: privateKey,
+ x5c: parts.x5c,
+ };
+ }
+ catch (error) {
+ this.logger.info(formatError("", error));
+ throw error;
+ }
+ return super.init(options);
+ }
+ async doGetToken(scopes, options = {}) {
+ try {
+ const clientCredReq = {
+ scopes,
+ correlationId: options.correlationId,
+ azureRegion: this.azureRegion,
+ authority: options.authority,
+ claims: options.claims,
+ };
+ const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential(clientCredReq);
+ // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,
+ // The Client Credential flow does not return the account information from the authentication service,
+ // so each time getToken gets called, we will have to acquire a new token through the service.
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (err) {
+ throw this.handleError(scopes, err, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const credentialName$2 = "ClientCertificateCredential";
+const logger$8 = credentialLogger(credentialName$2);
+/**
+ * Enables authentication to Azure Active Directory using a PEM-encoded
+ * certificate that is assigned to an App Registration. More information
+ * on how to configure certificate authentication can be found here:
+ *
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad
+ *
+ */
+class ClientCertificateCredential {
+ constructor(tenantId, clientId, certificatePathOrConfiguration, options = {}) {
+ if (!tenantId || !clientId) {
+ throw new Error(`${credentialName$2}: tenantId and clientId are required parameters.`);
+ }
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ const configuration = Object.assign({}, (typeof certificatePathOrConfiguration === "string"
+ ? {
+ certificatePath: certificatePathOrConfiguration,
+ }
+ : certificatePathOrConfiguration));
+ const certificate = configuration
+ .certificate;
+ const certificatePath = configuration.certificatePath;
+ if (!configuration || !(certificate || certificatePath)) {
+ throw new Error(`${credentialName$2}: Provide either a PEM certificate in string form, or the path to that certificate in the filesystem. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
+ }
+ if (certificate && certificatePath) {
+ throw new Error(`${credentialName$2}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
+ }
+ this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
+ logger: logger$8,
+ clientId,
+ tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${credentialName$2}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$8);
+ const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
+ return this.msalFlow.getToken(arrayScopes, newOptions);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * MSAL client secret client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
+ * @internal
+ */
+class MsalClientSecret extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.requiresConfidential = true;
+ this.msalConfig.auth.clientSecret = options.clientSecret;
+ }
+ async doGetToken(scopes, options = {}) {
+ try {
+ const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential({
+ scopes,
+ correlationId: options.correlationId,
+ azureRegion: this.azureRegion,
+ authority: options.authority,
+ claims: options.claims,
+ });
+ // The Client Credential flow does not return an account,
+ // so each time getToken gets called, we will have to acquire a new token through the service.
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (err) {
+ throw this.handleError(scopes, err, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$7 = credentialLogger("ClientSecretCredential");
+/**
+ * Enables authentication to Azure Active Directory using a client secret
+ * that was generated for an App Registration. More information on how
+ * to configure a client secret can be found here:
+ *
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
+ *
+ */
+class ClientSecretCredential {
+ /**
+ * Creates an instance of the ClientSecretCredential with the details
+ * needed to authenticate against Azure Active Directory with a client
+ * secret.
+ *
+ * @param tenantId - The Azure Active Directory tenant (directory) ID.
+ * @param clientId - The client (application) ID of an App Registration in the tenant.
+ * @param clientSecret - A client secret that was generated for the App Registration.
+ * @param options - Options for configuring the client which makes the authentication request.
+ */
+ constructor(tenantId, clientId, clientSecret, options = {}) {
+ if (!tenantId || !clientId || !clientSecret) {
+ throw new Error("ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.");
+ }
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$7,
+ clientId,
+ tenantId,
+ clientSecret, tokenCredentialOptions: options }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$7);
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, newOptions);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * MSAL username and password client. Calls to the MSAL's public application's `acquireTokenByUsernamePassword` during `doGetToken`.
+ * @internal
+ */
+class MsalUsernamePassword extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.username = options.username;
+ this.password = options.password;
+ }
+ async doGetToken(scopes, options) {
+ try {
+ const requestOptions = {
+ scopes,
+ username: this.username,
+ password: this.password,
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ };
+ const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByUsernamePassword(requestOptions);
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (error) {
+ throw this.handleError(scopes, error, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$6 = credentialLogger("UsernamePasswordCredential");
+/**
+ * Enables authentication to Azure Active Directory with a user's
+ * username and password. This credential requires a high degree of
+ * trust so you should only use it when other, more secure credential
+ * types can't be used.
+ */
+class UsernamePasswordCredential {
+ /**
+ * Creates an instance of the UsernamePasswordCredential with the details
+ * needed to authenticate against Azure Active Directory with a username
+ * and password.
+ *
+ * @param tenantId - The Azure Active Directory tenant (directory).
+ * @param clientId - The client (application) ID of an App Registration in the tenant.
+ * @param username - The user account's e-mail address (user name).
+ * @param password - The user account's account password
+ * @param options - Options for configuring the client which makes the authentication request.
+ */
+ constructor(tenantId, clientId, username, password, options = {}) {
+ if (!tenantId || !clientId || !username || !password) {
+ throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
+ }
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$6,
+ clientId,
+ tenantId,
+ username,
+ password, tokenCredentialOptions: options || {} }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * If the user provided the option `disableAutomaticAuthentication`,
+ * once the token can't be retrieved silently,
+ * this method won't attempt to request user interaction to retrieve the token.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$6);
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, newOptions);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Contains the list of all supported environment variable names so that an
+ * appropriate error message can be generated when no credentials can be
+ * configured.
+ *
+ * @internal
+ */
+const AllSupportedEnvironmentVariables = [
+ "AZURE_TENANT_ID",
+ "AZURE_CLIENT_ID",
+ "AZURE_CLIENT_SECRET",
+ "AZURE_CLIENT_CERTIFICATE_PATH",
+ "AZURE_CLIENT_CERTIFICATE_PASSWORD",
+ "AZURE_USERNAME",
+ "AZURE_PASSWORD",
+ "AZURE_ADDITIONALLY_ALLOWED_TENANTS",
+];
+function getAdditionallyAllowedTenants() {
+ var _a;
+ const additionallyAllowedValues = (_a = process.env.AZURE_ADDITIONALLY_ALLOWED_TENANTS) !== null && _a !== void 0 ? _a : "";
+ return additionallyAllowedValues.split(";");
+}
+const credentialName$1 = "EnvironmentCredential";
+const logger$5 = credentialLogger(credentialName$1);
+/**
+ * Enables authentication to Azure Active Directory using a client secret or certificate, or as a user
+ * with a username and password.
+ */
+class EnvironmentCredential {
+ /**
+ * Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
+ *
+ * Required environment variables:
+ * - `AZURE_TENANT_ID`: The Azure Active Directory tenant (directory) ID.
+ * - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
+ *
+ * If setting the AZURE_TENANT_ID, then you can also set the additionally allowed tenants
+ * - `AZURE_ADDITIONALLY_ALLOWED_TENANTS`: For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens with a single semicolon delimited string. Use * to allow all tenants.
+ *
+ * Environment variables used for client credential authentication:
+ * - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration.
+ * - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret.
+ * - `AZURE_CLIENT_CERTIFICATE_PASSWORD`: (optional) password for the certificate file.
+ *
+ * Alternatively, users can provide environment variables for username and password authentication:
+ * - `AZURE_USERNAME`: Username to authenticate with.
+ * - `AZURE_PASSWORD`: Password to authenticate with.
+ *
+ * If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown.
+ * If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown.
+ *
+ * @param options - Options for configuring the client which makes the authentication request.
+ */
+ constructor(options) {
+ // Keep track of any missing environment variables for error details
+ this._credential = undefined;
+ const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
+ logger$5.info(`Found the following environment variables: ${assigned}`);
+ const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
+ const additionallyAllowedTenantIds = getAdditionallyAllowedTenants();
+ const newOptions = Object.assign(Object.assign({}, options), { additionallyAllowedTenantIds });
+ if (tenantId) {
+ checkTenantId(logger$5, tenantId);
+ }
+ if (tenantId && clientId && clientSecret) {
+ logger$5.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
+ this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, newOptions);
+ return;
+ }
+ const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
+ const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD;
+ if (tenantId && clientId && certificatePath) {
+ logger$5.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
+ this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions);
+ return;
+ }
+ const username = process.env.AZURE_USERNAME;
+ const password = process.env.AZURE_PASSWORD;
+ if (tenantId && clientId && username && password) {
+ logger$5.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
+ this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, newOptions);
+ }
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - Optional parameters. See {@link GetTokenOptions}.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${credentialName$1}.getToken`, options, async (newOptions) => {
+ if (this._credential) {
+ try {
+ const result = await this._credential.getToken(scopes, newOptions);
+ logger$5.getToken.info(formatSuccess(scopes));
+ return result;
+ }
+ catch (err) {
+ const authenticationError = new AuthenticationError(400, {
+ error: `${credentialName$1} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
+ error_description: err.message.toString().split("More details:").join(""),
+ });
+ logger$5.getToken.info(formatError(scopes, authenticationError));
+ throw authenticationError;
+ }
+ }
+ throw new CredentialUnavailableError(`${credentialName$1} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Mockable reference to the Developer CLI credential cliCredentialFunctions
+ * @internal
+ */
+const developerCliCredentialInternals = {
+ /**
+ * @internal
+ */
+ getSafeWorkingDir() {
+ if (process.platform === "win32") {
+ if (!process.env.SystemRoot) {
+ throw new Error("Azure Developer CLI credential expects a 'SystemRoot' environment variable");
+ }
+ return process.env.SystemRoot;
+ }
+ else {
+ return "/bin";
+ }
+ },
+ /**
+ * Gets the access token from Azure Developer CLI
+ * @param scopes - The scopes to use when getting the token
+ * @internal
+ */
+ async getAzdAccessToken(scopes, tenantId, timeout) {
+ let tenantSection = [];
+ if (tenantId) {
+ tenantSection = ["--tenant-id", tenantId];
+ }
+ return new Promise((resolve, reject) => {
+ try {
+ child_process__default["default"].execFile("azd", [
+ "auth",
+ "token",
+ "--output",
+ "json",
+ ...scopes.reduce((previous, current) => previous.concat("--scope", current), []),
+ ...tenantSection,
+ ], {
+ cwd: developerCliCredentialInternals.getSafeWorkingDir(),
+ shell: true,
+ timeout,
+ }, (error, stdout, stderr) => {
+ resolve({ stdout, stderr, error });
+ });
+ }
+ catch (err) {
+ reject(err);
+ }
+ });
+ },
+};
+const logger$4 = credentialLogger("AzureDeveloperCliCredential");
+/**
+ * Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
+ * resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
+ * to Azure developers. It allows users to authenticate as a user and/or a service principal against
+ * Azure Active Directory (Azure AD)
+ * . The AzureDeveloperCliCredential authenticates in a development environment and acquires a token on behalf of
+ * the logged-in user or service principal in the Azure Developer CLI. It acts as the Azure Developer CLI logged in user or
+ * service principal and executes an Azure CLI command underneath to authenticate the application against
+ * Azure Active Directory.
+ *
+ * Configure AzureDeveloperCliCredential
+ *
+ * To use this credential, the developer needs to authenticate locally in Azure Developer CLI using one of the
+ * commands below:
+ *
+ *
+ * - Run "azd auth login" in Azure Developer CLI to authenticate interactively as a user.
+ * - Run "azd auth login --client-id clientID --client-secret clientSecret
+ * --tenant-id tenantID" to authenticate as a service principal.
+ *
+ *
+ * You may need to repeat this process after a certain time period, depending on the refresh token validity in your
+ * organization. Generally, the refresh token validity period is a few weeks to a few months.
+ * AzureDeveloperCliCredential will prompt you to sign in again.
+ */
+class AzureDeveloperCliCredential {
+ /**
+ * Creates an instance of the {@link AzureDeveloperCliCredential}.
+ *
+ * To use this credential, ensure that you have already logged
+ * in via the 'azd' tool using the command "azd auth login" from the commandline.
+ *
+ * @param options - Options, to optionally allow multi-tenant requests.
+ */
+ constructor(options) {
+ this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
+ let scopeList;
+ if (typeof scopes === "string") {
+ scopeList = [scopes];
+ }
+ else {
+ scopeList = scopes;
+ }
+ logger$4.getToken.info(`Using the scopes ${scopes}`);
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
+ var _a, _b, _c, _d;
+ try {
+ const obj = await developerCliCredentialInternals.getAzdAccessToken(scopeList, tenantId, this.timeout);
+ const isNotLoggedInError = ((_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("not logged in, run `azd login` to login")) ||
+ ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("not logged in, run `azd auth login` to login"));
+ const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("azd:(.*)not found")) ||
+ ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'azd' is not recognized"));
+ if (isNotInstallError || (obj.error && obj.error.code === "ENOENT")) {
+ const error = new CredentialUnavailableError("Azure Developer CLI couldn't be found. To mitigate this issue, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.");
+ logger$4.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ if (isNotLoggedInError) {
+ const error = new CredentialUnavailableError("Please run 'azd auth login' from a command prompt to authenticate before using this credential. For more information, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.");
+ logger$4.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ try {
+ const resp = JSON.parse(obj.stdout);
+ logger$4.getToken.info(formatSuccess(scopes));
+ return {
+ token: resp.token,
+ expiresOnTimestamp: new Date(resp.expiresOn).getTime(),
+ };
+ }
+ catch (e) {
+ if (obj.stderr) {
+ throw new CredentialUnavailableError(obj.stderr);
+ }
+ throw e;
+ }
+ }
+ catch (err) {
+ const error = err.name === "CredentialUnavailableError"
+ ? err
+ : new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
+ logger$4.getToken.info(formatError(scopes, error));
+ throw error;
+ }
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * A shim around ManagedIdentityCredential that adapts it to accept
+ * `DefaultAzureCredentialOptions`.
+ *
+ * @internal
+ */
+class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
+ // Constructor overload with just the other default options
+ // Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
+ constructor(options) {
+ var _a, _b, _c;
+ const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
+ const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
+ const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
+ const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
+ const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
+ // ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
+ if (managedResourceId) {
+ const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
+ super(managedIdentityResourceIdOptions);
+ }
+ else if (workloadFile && workloadIdentityClientId) {
+ const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId: tenantId });
+ super(workloadIdentityClientId, workloadIdentityCredentialOptions);
+ }
+ else if (managedIdentityClientId) {
+ const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
+ super(managedIdentityClientOptions);
+ }
+ else {
+ super(options);
+ }
+ }
+}
+/**
+ * A shim around WorkloadIdentityCredential that adapts it to accept
+ * `DefaultAzureCredentialOptions`.
+ *
+ * @internal
+ */
+class DefaultWorkloadIdentityCredential extends WorkloadIdentityCredential {
+ // Constructor overload with just the other default options
+ // Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
+ constructor(options) {
+ var _a, _b, _c;
+ const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
+ const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
+ const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
+ const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
+ if (workloadFile && workloadIdentityClientId) {
+ const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId, clientId: workloadIdentityClientId, tokenFilePath: workloadFile });
+ super(workloadIdentityCredentialOptions);
+ }
+ else if (tenantId) {
+ const workloadIdentityClientTenantOptions = Object.assign(Object.assign({}, options), { tenantId });
+ super(workloadIdentityClientTenantOptions);
+ }
+ else {
+ super(options);
+ }
+ }
+}
+class DefaultAzureDeveloperCliCredential extends AzureDeveloperCliCredential {
+ constructor(options) {
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
+ }
+}
+class DefaultAzureCliCredential extends AzureCliCredential {
+ constructor(options) {
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
+ }
+}
+class DefaultAzurePowershellCredential extends AzurePowerShellCredential {
+ constructor(options) {
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
+ }
+}
+const defaultCredentials = [
+ EnvironmentCredential,
+ DefaultWorkloadIdentityCredential,
+ DefaultManagedIdentityCredential,
+ DefaultAzureCliCredential,
+ DefaultAzurePowershellCredential,
+ DefaultAzureDeveloperCliCredential,
+];
+/**
+ * Provides a default {@link ChainedTokenCredential} configuration that should
+ * work for most applications that use the Azure SDK.
+ */
+class DefaultAzureCredential extends ChainedTokenCredential {
+ constructor(options) {
+ super(...defaultCredentials.map((ctor) => new ctor(options)));
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * A call to open(), but mockable
+ * @internal
+ */
+const interactiveBrowserMockable = {
+ open: open__default["default"],
+};
+/**
+ * This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`
+ * to trigger the authentication flow, and then respond based on the values obtained from the redirect callback
+ * @internal
+ */
+class MsalOpenBrowser extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.logger = credentialLogger("Node.js MSAL Open Browser");
+ this.redirectUri = options.redirectUri;
+ this.loginHint = options.loginHint;
+ const url = new URL(this.redirectUri);
+ this.port = parseInt(url.port);
+ if (isNaN(this.port)) {
+ this.port = 80;
+ }
+ this.hostname = url.hostname;
+ }
+ async acquireTokenByCode(request, enableCae) {
+ return this.getApp("public", enableCae).acquireTokenByCode(request);
+ }
+ doGetToken(scopes, options) {
+ return new Promise((resolve, reject) => {
+ const socketToDestroy = [];
+ const requestListener = (req, res) => {
+ var _a;
+ if (!req.url) {
+ reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
+ return;
+ }
+ let url;
+ try {
+ url = new URL(req.url, this.redirectUri);
+ }
+ catch (e) {
+ reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
+ return;
+ }
+ const tokenRequest = {
+ code: url.searchParams.get("code"),
+ redirectUri: this.redirectUri,
+ scopes: scopes,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ codeVerifier: (_a = this.pkceCodes) === null || _a === void 0 ? void 0 : _a.verifier,
+ };
+ this.acquireTokenByCode(tokenRequest, options === null || options === void 0 ? void 0 : options.enableCae)
+ .then((authResponse) => {
+ if (authResponse === null || authResponse === void 0 ? void 0 : authResponse.account) {
+ this.account = msalToPublic(this.clientId, authResponse.account);
+ }
+ const successMessage = `Authentication Complete. You can close the browser and return to the application.`;
+ if (authResponse && authResponse.expiresOn) {
+ const expiresOnTimestamp = authResponse === null || authResponse === void 0 ? void 0 : authResponse.expiresOn.valueOf();
+ res.writeHead(200);
+ res.end(successMessage);
+ this.logger.getToken.info(formatSuccess(scopes));
+ resolve({
+ expiresOnTimestamp,
+ token: authResponse.accessToken,
+ });
+ }
+ else {
+ const errorMessage = formatError(scopes, `${url.searchParams.get("error")}. ${url.searchParams.get("error_description")}`);
+ res.writeHead(500);
+ res.end(errorMessage);
+ this.logger.getToken.info(errorMessage);
+ reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
+ }
+ cleanup();
+ return;
+ })
+ .catch(() => {
+ const errorMessage = formatError(scopes, `${url.searchParams.get("error")}. ${url.searchParams.get("error_description")}`);
+ res.writeHead(500);
+ res.end(errorMessage);
+ this.logger.getToken.info(errorMessage);
+ reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
+ cleanup();
+ });
+ };
+ const app = http__default["default"].createServer(requestListener);
+ const server = stoppable__default["default"](app);
+ const listen = app.listen(this.port, this.hostname, () => this.logger.info(`InteractiveBrowserCredential listening on port ${this.port}!`));
+ function cleanup() {
+ if (listen) {
+ listen.close();
+ }
+ for (const socket of socketToDestroy) {
+ socket.destroy();
+ }
+ if (server) {
+ server.close();
+ server.stop();
+ }
+ }
+ app.on("connection", (socket) => socketToDestroy.push(socket));
+ app.on("error", (err) => {
+ cleanup();
+ const code = err.code;
+ if (code === "EACCES" || code === "EADDRINUSE") {
+ reject(new CredentialUnavailableError([
+ `InteractiveBrowserCredential: Access denied to port ${this.port}.`,
+ `Try sending a redirect URI with a different port, as follows:`,
+ '`new InteractiveBrowserCredential({ redirectUri: "http://localhost:1337" })`',
+ ].join(" ")));
+ }
+ else {
+ reject(new CredentialUnavailableError(`InteractiveBrowserCredential: Failed to start the necessary web server. Error: ${err.message}`));
+ }
+ });
+ app.on("listening", () => {
+ const openPromise = this.openAuthCodeUrl(scopes, options);
+ const abortSignal = options === null || options === void 0 ? void 0 : options.abortSignal;
+ if (abortSignal) {
+ abortSignal.addEventListener("abort", () => {
+ cleanup();
+ reject(new Error("Aborted"));
+ });
+ }
+ openPromise.catch((e) => {
+ cleanup();
+ reject(e);
+ });
+ });
+ });
+ }
+ async openAuthCodeUrl(scopeArray, options) {
+ // Initialize CryptoProvider instance
+ const cryptoProvider = new msalNode__namespace.CryptoProvider();
+ // Generate PKCE Codes before starting the authorization flow
+ this.pkceCodes = await cryptoProvider.generatePkceCodes();
+ const authCodeUrlParameters = {
+ scopes: scopeArray,
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
+ redirectUri: this.redirectUri,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ loginHint: this.loginHint,
+ codeChallenge: this.pkceCodes.challenge,
+ codeChallengeMethod: "S256", // Use SHA256 Algorithm
+ };
+ const response = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).getAuthCodeUrl(authCodeUrlParameters);
+ try {
+ // A new instance on macOS only which allows it to not hang, does not fix the issue on linux
+ await interactiveBrowserMockable.open(response, { wait: true, newInstance: true });
+ }
+ catch (e) {
+ throw new CredentialUnavailableError(`InteractiveBrowserCredential: Could not open a browser window. Error: ${e.message}`);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$3 = credentialLogger("InteractiveBrowserCredential");
+/**
+ * Enables authentication to Azure Active Directory inside of the web browser
+ * using the interactive login flow.
+ */
+class InteractiveBrowserCredential {
+ /**
+ * Creates an instance of InteractiveBrowserCredential with the details needed.
+ *
+ * This credential uses the [Authorization Code Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
+ * On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
+ * On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
+ *
+ * For Node.js, if a `clientId` is provided, the Azure Active Directory application will need to be configured to have a "Mobile and desktop applications" redirect endpoint.
+ * Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://docs.microsoft.com/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris).
+ *
+ * @param options - Options for configuring the client which makes the authentication requests.
+ */
+ constructor(options = {}) {
+ const redirectUri = typeof options.redirectUri === "function"
+ ? options.redirectUri()
+ : options.redirectUri || "http://localhost";
+ this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger: logger$3,
+ redirectUri }));
+ this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * If the user provided the option `disableAutomaticAuthentication`,
+ * once the token can't be retrieved silently,
+ * this method won't attempt to request user interaction to retrieve the token.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$3);
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
+ });
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
+ *
+ * On Node.js, this credential has [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) enabled by default.
+ * PKCE is a security feature that mitigates authentication code interception attacks.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async authenticate(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
+ const arrayScopes = ensureScopes(scopes);
+ await this.msalFlow.getToken(arrayScopes, newOptions);
+ return this.msalFlow.getActiveAccount();
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * MSAL device code client. Calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`.
+ * @internal
+ */
+class MsalDeviceCode extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.userPromptCallback = options.userPromptCallback;
+ }
+ async doGetToken(scopes, options) {
+ try {
+ const requestOptions = {
+ deviceCodeCallback: this.userPromptCallback,
+ scopes,
+ cancel: false,
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ };
+ const promise = this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByDeviceCode(requestOptions);
+ const deviceResponse = await this.withCancellation(promise, options === null || options === void 0 ? void 0 : options.abortSignal, () => {
+ requestOptions.cancel = true;
+ });
+ return this.handleResult(scopes, this.clientId, deviceResponse || undefined);
+ }
+ catch (error) {
+ throw this.handleError(scopes, error, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$2 = credentialLogger("DeviceCodeCredential");
+/**
+ * Method that logs the user code from the DeviceCodeCredential.
+ * @param deviceCodeInfo - The device code.
+ */
+function defaultDeviceCodePromptCallback(deviceCodeInfo) {
+ console.log(deviceCodeInfo.message);
+}
+/**
+ * Enables authentication to Azure Active Directory using a device code
+ * that the user can enter into https://microsoft.com/devicelogin.
+ */
+class DeviceCodeCredential {
+ /**
+ * Creates an instance of DeviceCodeCredential with the details needed
+ * to initiate the device code authorization flow with Azure Active Directory.
+ *
+ * A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin
+ *
+ * Developers can configure how this message is shown by passing a custom `userPromptCallback`:
+ *
+ * ```js
+ * const credential = new DeviceCodeCredential({
+ * tenantId: env.AZURE_TENANT_ID,
+ * clientId: env.AZURE_CLIENT_ID,
+ * userPromptCallback: (info) => {
+ * console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
+ * }
+ * });
+ * ```
+ *
+ * @param options - Options for configuring the client which makes the authentication requests.
+ */
+ constructor(options) {
+ this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger: logger$2, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
+ this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * If the user provided the option `disableAutomaticAuthentication`,
+ * once the token can't be retrieved silently,
+ * this method won't attempt to request user interaction to retrieve the token.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$2);
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
+ });
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async authenticate(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
+ const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
+ await this.msalFlow.getToken(arrayScopes, newOptions);
+ return this.msalFlow.getActiveAccount();
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`
+ * to trigger the authentication flow, and then respond based on the values obtained from the redirect callback
+ * @internal
+ */
+class MsalAuthorizationCode extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.logger = credentialLogger("Node.js MSAL Authorization Code");
+ this.redirectUri = options.redirectUri;
+ this.authorizationCode = options.authorizationCode;
+ if (options.clientSecret) {
+ this.msalConfig.auth.clientSecret = options.clientSecret;
+ }
+ }
+ async getAuthCodeUrl(options) {
+ await this.init();
+ return this.getApp("confidentialFirst", options.enableCae).getAuthCodeUrl({
+ scopes: options.scopes,
+ redirectUri: options.redirectUri,
+ });
+ }
+ async doGetToken(scopes, options) {
+ try {
+ const result = await this.getApp("confidentialFirst", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByCode({
+ scopes,
+ redirectUri: this.redirectUri,
+ code: this.authorizationCode,
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
+ authority: options === null || options === void 0 ? void 0 : options.authority,
+ claims: options === null || options === void 0 ? void 0 : options.claims,
+ });
+ // The Client Credential flow does not return an account,
+ // so each time getToken gets called, we will have to acquire a new token through the service.
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (err) {
+ throw this.handleError(scopes, err, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const logger$1 = credentialLogger("AuthorizationCodeCredential");
+/**
+ * Enables authentication to Azure Active Directory using an authorization code
+ * that was obtained through the authorization code flow, described in more detail
+ * in the Azure Active Directory documentation:
+ *
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
+ */
+class AuthorizationCodeCredential {
+ /**
+ * @hidden
+ * @internal
+ */
+ constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
+ checkTenantId(logger$1, tenantId);
+ let clientSecret = clientSecretOrAuthorizationCode;
+ if (typeof redirectUriOrOptions === "string") {
+ // the clientId+clientSecret constructor
+ this.authorizationCode = authorizationCodeOrRedirectUri;
+ this.redirectUri = redirectUriOrOptions;
+ // in this case, options are good as they come
+ }
+ else {
+ // clientId only
+ this.authorizationCode = clientSecretOrAuthorizationCode;
+ this.redirectUri = authorizationCodeOrRedirectUri;
+ clientSecret = undefined;
+ options = redirectUriOrOptions;
+ }
+ // TODO: Validate tenant if provided
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
+ this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
+ clientId,
+ tenantId, tokenCredentialOptions: options || {}, logger: logger$1, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure any requests this
+ * TokenCredential implementation might make.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
+ const tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
+ newOptions.tenantId = tenantId;
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * MSAL on behalf of flow. Calls to MSAL's confidential application's `acquireTokenOnBehalfOf` during `doGetToken`.
+ * @internal
+ */
+class MsalOnBehalfOf extends MsalNode {
+ constructor(options) {
+ super(options);
+ this.logger.info("Initialized MSAL's On-Behalf-Of flow");
+ this.requiresConfidential = true;
+ this.userAssertionToken = options.userAssertionToken;
+ this.certificatePath = options.certificatePath;
+ this.sendCertificateChain = options.sendCertificateChain;
+ this.clientSecret = options.clientSecret;
+ }
+ // Changing the MSAL configuration asynchronously
+ async init(options) {
+ if (this.certificatePath) {
+ try {
+ const parts = await parseCertificate({ certificatePath: this.certificatePath }, this.sendCertificateChain);
+ this.msalConfig.auth.clientCertificate = {
+ thumbprint: parts.thumbprint,
+ privateKey: parts.certificateContents,
+ x5c: parts.x5c,
+ };
+ }
+ catch (error) {
+ this.logger.info(formatError("", error));
+ throw error;
+ }
+ }
+ else {
+ this.msalConfig.auth.clientSecret = this.clientSecret;
+ }
+ return super.init(options);
+ }
+ async doGetToken(scopes, options = {}) {
+ try {
+ const result = await this.getApp("confidential", options.enableCae).acquireTokenOnBehalfOf({
+ scopes,
+ correlationId: options.correlationId,
+ authority: options.authority,
+ claims: options.claims,
+ oboAssertion: this.userAssertionToken,
+ });
+ return this.handleResult(scopes, this.clientId, result || undefined);
+ }
+ catch (err) {
+ throw this.handleError(scopes, err, options);
+ }
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+const credentialName = "OnBehalfOfCredential";
+const logger = credentialLogger(credentialName);
+/**
+ * Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
+ */
+class OnBehalfOfCredential {
+ constructor(options) {
+ this.options = options;
+ const { clientSecret } = options;
+ const { certificatePath } = options;
+ const { tenantId, clientId, userAssertionToken, additionallyAllowedTenants: additionallyAllowedTenantIds, } = options;
+ if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
+ throw new Error(`${credentialName}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
+ }
+ this.tenantId = tenantId;
+ this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(additionallyAllowedTenantIds);
+ this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger, tokenCredentialOptions: this.options }));
+ }
+ /**
+ * Authenticates with Azure Active Directory and returns an access token if successful.
+ * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
+ *
+ * @param scopes - The list of scopes for which the token will have access.
+ * @param options - The options used to configure the underlying network requests.
+ */
+ async getToken(scopes, options = {}) {
+ return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger);
+ const arrayScopes = ensureScopes(scopes);
+ return this.msalFlow.getToken(arrayScopes, newOptions);
+ });
+ }
+}
+
+// Copyright (c) Microsoft Corporation.
+/**
+ * Returns a new instance of the {@link DefaultAzureCredential}.
+ */
+function getDefaultAzureCredential() {
+ return new DefaultAzureCredential();
+}
+
+exports.AggregateAuthenticationError = AggregateAuthenticationError;
+exports.AggregateAuthenticationErrorName = AggregateAuthenticationErrorName;
+exports.AuthenticationError = AuthenticationError;
+exports.AuthenticationErrorName = AuthenticationErrorName;
+exports.AuthenticationRequiredError = AuthenticationRequiredError;
+exports.AuthorizationCodeCredential = AuthorizationCodeCredential;
+exports.AzureCliCredential = AzureCliCredential;
+exports.AzureDeveloperCliCredential = AzureDeveloperCliCredential;
+exports.AzurePowerShellCredential = AzurePowerShellCredential;
+exports.ChainedTokenCredential = ChainedTokenCredential;
+exports.ClientAssertionCredential = ClientAssertionCredential;
+exports.ClientCertificateCredential = ClientCertificateCredential;
+exports.ClientSecretCredential = ClientSecretCredential;
+exports.CredentialUnavailableError = CredentialUnavailableError;
+exports.CredentialUnavailableErrorName = CredentialUnavailableErrorName;
+exports.DefaultAzureCredential = DefaultAzureCredential;
+exports.DeviceCodeCredential = DeviceCodeCredential;
+exports.EnvironmentCredential = EnvironmentCredential;
+exports.InteractiveBrowserCredential = InteractiveBrowserCredential;
+exports.ManagedIdentityCredential = ManagedIdentityCredential;
+exports.OnBehalfOfCredential = OnBehalfOfCredential;
+exports.UsernamePasswordCredential = UsernamePasswordCredential;
+exports.VisualStudioCodeCredential = VisualStudioCodeCredential;
+exports.WorkloadIdentityCredential = WorkloadIdentityCredential;
+exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
+exports.getDefaultAzureCredential = getDefaultAzureCredential;
+exports.logger = logger$n;
+exports.serializeAuthenticationRecord = serializeAuthenticationRecord;
+exports.useIdentityPlugin = useIdentityPlugin;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 3233:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+var os = __nccwpck_require__(2037);
+var util = __nccwpck_require__(3837);
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
+
+// Copyright (c) Microsoft Corporation.
+function log(message, ...args) {
+ process.stderr.write(`${util__default["default"].format(message, ...args)}${os.EOL}`);
+}
+
+// Copyright (c) Microsoft Corporation.
+const debugEnvVariable = (typeof process !== "undefined" && process.env && process.env.DEBUG) || undefined;
+let enabledString;
+let enabledNamespaces = [];
+let skippedNamespaces = [];
+const debuggers = [];
+if (debugEnvVariable) {
+ enable(debugEnvVariable);
+}
+const debugObj = Object.assign((namespace) => {
+ return createDebugger(namespace);
+}, {
+ enable,
+ enabled,
+ disable,
+ log,
+});
+function enable(namespaces) {
+ enabledString = namespaces;
+ enabledNamespaces = [];
+ skippedNamespaces = [];
+ const wildcard = /\*/g;
+ const namespaceList = namespaces.split(",").map((ns) => ns.trim().replace(wildcard, ".*?"));
+ for (const ns of namespaceList) {
+ if (ns.startsWith("-")) {
+ skippedNamespaces.push(new RegExp(`^${ns.substr(1)}$`));
+ }
+ else {
+ enabledNamespaces.push(new RegExp(`^${ns}$`));
+ }
+ }
+ for (const instance of debuggers) {
+ instance.enabled = enabled(instance.namespace);
+ }
+}
+function enabled(namespace) {
+ if (namespace.endsWith("*")) {
+ return true;
+ }
+ for (const skipped of skippedNamespaces) {
+ if (skipped.test(namespace)) {
+ return false;
+ }
+ }
+ for (const enabledNamespace of enabledNamespaces) {
+ if (enabledNamespace.test(namespace)) {
+ return true;
+ }
+ }
+ return false;
+}
+function disable() {
+ const result = enabledString || "";
+ enable("");
+ return result;
+}
+function createDebugger(namespace) {
+ const newDebugger = Object.assign(debug, {
+ enabled: enabled(namespace),
+ destroy,
+ log: debugObj.log,
+ namespace,
+ extend,
+ });
+ function debug(...args) {
+ if (!newDebugger.enabled) {
+ return;
+ }
+ if (args.length > 0) {
+ args[0] = `${namespace} ${args[0]}`;
+ }
+ newDebugger.log(...args);
+ }
+ debuggers.push(newDebugger);
+ return newDebugger;
+}
+function destroy() {
+ const index = debuggers.indexOf(this);
+ if (index >= 0) {
+ debuggers.splice(index, 1);
+ return true;
+ }
+ return false;
+}
+function extend(namespace) {
+ const newDebugger = createDebugger(`${this.namespace}:${namespace}`);
+ newDebugger.log = this.log;
+ return newDebugger;
+}
+var debug = debugObj;
+
+// Copyright (c) Microsoft Corporation.
+const registeredLoggers = new Set();
+const logLevelFromEnv = (typeof process !== "undefined" && process.env && process.env.AZURE_LOG_LEVEL) || undefined;
+let azureLogLevel;
+/**
+ * The AzureLogger provides a mechanism for overriding where logs are output to.
+ * By default, logs are sent to stderr.
+ * Override the `log` method to redirect logs to another location.
+ */
+const AzureLogger = debug("azure");
+AzureLogger.log = (...args) => {
+ debug.log(...args);
+};
+const AZURE_LOG_LEVELS = ["verbose", "info", "warning", "error"];
+if (logLevelFromEnv) {
+ // avoid calling setLogLevel because we don't want a mis-set environment variable to crash
+ if (isAzureLogLevel(logLevelFromEnv)) {
+ setLogLevel(logLevelFromEnv);
+ }
+ else {
+ console.error(`AZURE_LOG_LEVEL set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
+ }
+}
+/**
+ * Immediately enables logging at the specified log level. If no level is specified, logging is disabled.
+ * @param level - The log level to enable for logging.
+ * Options from most verbose to least verbose are:
+ * - verbose
+ * - info
+ * - warning
+ * - error
+ */
+function setLogLevel(level) {
+ if (level && !isAzureLogLevel(level)) {
+ throw new Error(`Unknown log level '${level}'. Acceptable values: ${AZURE_LOG_LEVELS.join(",")}`);
+ }
+ azureLogLevel = level;
+ const enabledNamespaces = [];
+ for (const logger of registeredLoggers) {
+ if (shouldEnable(logger)) {
+ enabledNamespaces.push(logger.namespace);
+ }
+ }
+ debug.enable(enabledNamespaces.join(","));
+}
+/**
+ * Retrieves the currently specified log level.
+ */
+function getLogLevel() {
+ return azureLogLevel;
+}
+const levelMap = {
+ verbose: 400,
+ info: 300,
+ warning: 200,
+ error: 100,
+};
+/**
+ * Creates a logger for use by the Azure SDKs that inherits from `AzureLogger`.
+ * @param namespace - The name of the SDK package.
+ * @hidden
+ */
+function createClientLogger(namespace) {
+ const clientRootLogger = AzureLogger.extend(namespace);
+ patchLogMethod(AzureLogger, clientRootLogger);
+ return {
+ error: createLogger(clientRootLogger, "error"),
+ warning: createLogger(clientRootLogger, "warning"),
+ info: createLogger(clientRootLogger, "info"),
+ verbose: createLogger(clientRootLogger, "verbose"),
+ };
+}
+function patchLogMethod(parent, child) {
+ child.log = (...args) => {
+ parent.log(...args);
+ };
+}
+function createLogger(parent, level) {
+ const logger = Object.assign(parent.extend(level), {
+ level,
+ });
+ patchLogMethod(parent, logger);
+ if (shouldEnable(logger)) {
+ const enabledNamespaces = debug.disable();
+ debug.enable(enabledNamespaces + "," + logger.namespace);
+ }
+ registeredLoggers.add(logger);
+ return logger;
+}
+function shouldEnable(logger) {
+ return Boolean(azureLogLevel && levelMap[logger.level] <= levelMap[azureLogLevel]);
+}
+function isAzureLogLevel(logLevel) {
+ return AZURE_LOG_LEVELS.includes(logLevel);
+}
+
+exports.AzureLogger = AzureLogger;
+exports.createClientLogger = createClientLogger;
+exports.getLogLevel = getLogLevel;
+exports.setLogLevel = setLogLevel;
+//# sourceMappingURL=index.js.map
+
+
+/***/ }),
+
+/***/ 5728:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+/*! @azure/msal-common v13.2.1 2023-08-07 */
+
+'use strict';
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */
+/* global Reflect, Promise */
+
+var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+};
+
+function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+}
+
+var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+
+function __awaiter(thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ 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) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+}
+
+function __generator(thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+}
+
+function __spreadArrays() {
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+ r[k] = a[j];
+ return r;
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var Constants = {
+ LIBRARY_NAME: "MSAL.JS",
+ SKU: "msal.js.common",
+ // Prefix for all library cache entries
+ CACHE_PREFIX: "msal",
+ // default authority
+ DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/",
+ DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com",
+ DEFAULT_COMMON_TENANT: "common",
+ // ADFS String
+ ADFS: "adfs",
+ DSTS: "dstsv2",
+ // Default AAD Instance Discovery Endpoint
+ AAD_INSTANCE_DISCOVERY_ENDPT: "https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=",
+ // CIAM URL
+ CIAM_AUTH_URL: ".ciamlogin.com",
+ AAD_TENANT_DOMAIN_SUFFIX: ".onmicrosoft.com",
+ // Resource delimiter - used for certain cache entries
+ RESOURCE_DELIM: "|",
+ // Placeholder for non-existent account ids/objects
+ NO_ACCOUNT: "NO_ACCOUNT",
+ // Claims
+ CLAIMS: "claims",
+ // Consumer UTID
+ CONSUMER_UTID: "9188040d-6c67-4c5b-b112-36a304b66dad",
+ // Default scopes
+ OPENID_SCOPE: "openid",
+ PROFILE_SCOPE: "profile",
+ OFFLINE_ACCESS_SCOPE: "offline_access",
+ EMAIL_SCOPE: "email",
+ // Default response type for authorization code flow
+ CODE_RESPONSE_TYPE: "code",
+ CODE_GRANT_TYPE: "authorization_code",
+ RT_GRANT_TYPE: "refresh_token",
+ FRAGMENT_RESPONSE_MODE: "fragment",
+ S256_CODE_CHALLENGE_METHOD: "S256",
+ URL_FORM_CONTENT_TYPE: "application/x-www-form-urlencoded;charset=utf-8",
+ AUTHORIZATION_PENDING: "authorization_pending",
+ NOT_DEFINED: "not_defined",
+ EMPTY_STRING: "",
+ NOT_APPLICABLE: "N/A",
+ FORWARD_SLASH: "/",
+ IMDS_ENDPOINT: "http://169.254.169.254/metadata/instance/compute/location",
+ IMDS_VERSION: "2020-06-01",
+ IMDS_TIMEOUT: 2000,
+ AZURE_REGION_AUTO_DISCOVER_FLAG: "TryAutoDetect",
+ REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX: "login.microsoft.com",
+ REGIONAL_AUTH_NON_MSI_QUERY_STRING: "allowestsrnonmsi=true",
+ KNOWN_PUBLIC_CLOUDS: ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"],
+ TOKEN_RESPONSE_TYPE: "token",
+ ID_TOKEN_RESPONSE_TYPE: "id_token",
+ SHR_NONCE_VALIDITY: 240,
+ INVALID_INSTANCE: "invalid_instance",
+};
+var OIDC_DEFAULT_SCOPES = [
+ Constants.OPENID_SCOPE,
+ Constants.PROFILE_SCOPE,
+ Constants.OFFLINE_ACCESS_SCOPE
+];
+var OIDC_SCOPES = __spreadArrays(OIDC_DEFAULT_SCOPES, [
+ Constants.EMAIL_SCOPE
+]);
+/**
+ * Request header names
+ */
+exports.HeaderNames = void 0;
+(function (HeaderNames) {
+ HeaderNames["CONTENT_TYPE"] = "Content-Type";
+ HeaderNames["RETRY_AFTER"] = "Retry-After";
+ HeaderNames["CCS_HEADER"] = "X-AnchorMailbox";
+ HeaderNames["WWWAuthenticate"] = "WWW-Authenticate";
+ HeaderNames["AuthenticationInfo"] = "Authentication-Info";
+ HeaderNames["X_MS_REQUEST_ID"] = "x-ms-request-id";
+ HeaderNames["X_MS_HTTP_VERSION"] = "x-ms-httpver";
+})(exports.HeaderNames || (exports.HeaderNames = {}));
+/**
+ * Persistent cache keys MSAL which stay while user is logged in.
+ */
+exports.PersistentCacheKeys = void 0;
+(function (PersistentCacheKeys) {
+ PersistentCacheKeys["ID_TOKEN"] = "idtoken";
+ PersistentCacheKeys["CLIENT_INFO"] = "client.info";
+ PersistentCacheKeys["ADAL_ID_TOKEN"] = "adal.idtoken";
+ PersistentCacheKeys["ERROR"] = "error";
+ PersistentCacheKeys["ERROR_DESC"] = "error.description";
+ PersistentCacheKeys["ACTIVE_ACCOUNT"] = "active-account";
+ PersistentCacheKeys["ACTIVE_ACCOUNT_FILTERS"] = "active-account-filters"; // new cache entry for active_account for a more robust version for browser
+})(exports.PersistentCacheKeys || (exports.PersistentCacheKeys = {}));
+/**
+ * String constants related to AAD Authority
+ */
+var AADAuthorityConstants;
+(function (AADAuthorityConstants) {
+ AADAuthorityConstants["COMMON"] = "common";
+ AADAuthorityConstants["ORGANIZATIONS"] = "organizations";
+ AADAuthorityConstants["CONSUMERS"] = "consumers";
+})(AADAuthorityConstants || (AADAuthorityConstants = {}));
+/**
+ * Keys in the hashParams sent by AAD Server
+ */
+exports.AADServerParamKeys = void 0;
+(function (AADServerParamKeys) {
+ AADServerParamKeys["CLIENT_ID"] = "client_id";
+ AADServerParamKeys["REDIRECT_URI"] = "redirect_uri";
+ AADServerParamKeys["RESPONSE_TYPE"] = "response_type";
+ AADServerParamKeys["RESPONSE_MODE"] = "response_mode";
+ AADServerParamKeys["GRANT_TYPE"] = "grant_type";
+ AADServerParamKeys["CLAIMS"] = "claims";
+ AADServerParamKeys["SCOPE"] = "scope";
+ AADServerParamKeys["ERROR"] = "error";
+ AADServerParamKeys["ERROR_DESCRIPTION"] = "error_description";
+ AADServerParamKeys["ACCESS_TOKEN"] = "access_token";
+ AADServerParamKeys["ID_TOKEN"] = "id_token";
+ AADServerParamKeys["REFRESH_TOKEN"] = "refresh_token";
+ AADServerParamKeys["EXPIRES_IN"] = "expires_in";
+ AADServerParamKeys["STATE"] = "state";
+ AADServerParamKeys["NONCE"] = "nonce";
+ AADServerParamKeys["PROMPT"] = "prompt";
+ AADServerParamKeys["SESSION_STATE"] = "session_state";
+ AADServerParamKeys["CLIENT_INFO"] = "client_info";
+ AADServerParamKeys["CODE"] = "code";
+ AADServerParamKeys["CODE_CHALLENGE"] = "code_challenge";
+ AADServerParamKeys["CODE_CHALLENGE_METHOD"] = "code_challenge_method";
+ AADServerParamKeys["CODE_VERIFIER"] = "code_verifier";
+ AADServerParamKeys["CLIENT_REQUEST_ID"] = "client-request-id";
+ AADServerParamKeys["X_CLIENT_SKU"] = "x-client-SKU";
+ AADServerParamKeys["X_CLIENT_VER"] = "x-client-VER";
+ AADServerParamKeys["X_CLIENT_OS"] = "x-client-OS";
+ AADServerParamKeys["X_CLIENT_CPU"] = "x-client-CPU";
+ AADServerParamKeys["X_CLIENT_CURR_TELEM"] = "x-client-current-telemetry";
+ AADServerParamKeys["X_CLIENT_LAST_TELEM"] = "x-client-last-telemetry";
+ AADServerParamKeys["X_MS_LIB_CAPABILITY"] = "x-ms-lib-capability";
+ AADServerParamKeys["X_APP_NAME"] = "x-app-name";
+ AADServerParamKeys["X_APP_VER"] = "x-app-ver";
+ AADServerParamKeys["POST_LOGOUT_URI"] = "post_logout_redirect_uri";
+ AADServerParamKeys["ID_TOKEN_HINT"] = "id_token_hint";
+ AADServerParamKeys["DEVICE_CODE"] = "device_code";
+ AADServerParamKeys["CLIENT_SECRET"] = "client_secret";
+ AADServerParamKeys["CLIENT_ASSERTION"] = "client_assertion";
+ AADServerParamKeys["CLIENT_ASSERTION_TYPE"] = "client_assertion_type";
+ AADServerParamKeys["TOKEN_TYPE"] = "token_type";
+ AADServerParamKeys["REQ_CNF"] = "req_cnf";
+ AADServerParamKeys["OBO_ASSERTION"] = "assertion";
+ AADServerParamKeys["REQUESTED_TOKEN_USE"] = "requested_token_use";
+ AADServerParamKeys["ON_BEHALF_OF"] = "on_behalf_of";
+ AADServerParamKeys["FOCI"] = "foci";
+ AADServerParamKeys["CCS_HEADER"] = "X-AnchorMailbox";
+ AADServerParamKeys["RETURN_SPA_CODE"] = "return_spa_code";
+ AADServerParamKeys["NATIVE_BROKER"] = "nativebroker";
+ AADServerParamKeys["LOGOUT_HINT"] = "logout_hint";
+})(exports.AADServerParamKeys || (exports.AADServerParamKeys = {}));
+/**
+ * Claims request keys
+ */
+exports.ClaimsRequestKeys = void 0;
+(function (ClaimsRequestKeys) {
+ ClaimsRequestKeys["ACCESS_TOKEN"] = "access_token";
+ ClaimsRequestKeys["XMS_CC"] = "xms_cc";
+})(exports.ClaimsRequestKeys || (exports.ClaimsRequestKeys = {}));
+/**
+ * we considered making this "enum" in the request instead of string, however it looks like the allowed list of
+ * prompt values kept changing over past couple of years. There are some undocumented prompt values for some
+ * internal partners too, hence the choice of generic "string" type instead of the "enum"
+ */
+var PromptValue = {
+ LOGIN: "login",
+ SELECT_ACCOUNT: "select_account",
+ CONSENT: "consent",
+ NONE: "none",
+ CREATE: "create",
+ NO_SESSION: "no_session"
+};
+/**
+ * SSO Types - generated to populate hints
+ */
+exports.SSOTypes = void 0;
+(function (SSOTypes) {
+ SSOTypes["ACCOUNT"] = "account";
+ SSOTypes["SID"] = "sid";
+ SSOTypes["LOGIN_HINT"] = "login_hint";
+ SSOTypes["ID_TOKEN"] = "id_token";
+ SSOTypes["DOMAIN_HINT"] = "domain_hint";
+ SSOTypes["ORGANIZATIONS"] = "organizations";
+ SSOTypes["CONSUMERS"] = "consumers";
+ SSOTypes["ACCOUNT_ID"] = "accountIdentifier";
+ SSOTypes["HOMEACCOUNT_ID"] = "homeAccountIdentifier";
+})(exports.SSOTypes || (exports.SSOTypes = {}));
+/**
+ * allowed values for codeVerifier
+ */
+var CodeChallengeMethodValues = {
+ PLAIN: "plain",
+ S256: "S256"
+};
+/**
+ * The method used to encode the code verifier for the code challenge parameter. can be one
+ * of plain or s256. if excluded, code challenge is assumed to be plaintext. for more
+ * information, see the pkce rcf: https://tools.ietf.org/html/rfc7636
+ */
+[
+ CodeChallengeMethodValues.PLAIN,
+ CodeChallengeMethodValues.S256
+];
+/**
+ * allowed values for response_mode
+ */
+exports.ResponseMode = void 0;
+(function (ResponseMode) {
+ ResponseMode["QUERY"] = "query";
+ ResponseMode["FRAGMENT"] = "fragment";
+ ResponseMode["FORM_POST"] = "form_post";
+})(exports.ResponseMode || (exports.ResponseMode = {}));
+/**
+ * allowed grant_type
+ */
+var GrantType;
+(function (GrantType) {
+ GrantType["IMPLICIT_GRANT"] = "implicit";
+ GrantType["AUTHORIZATION_CODE_GRANT"] = "authorization_code";
+ GrantType["CLIENT_CREDENTIALS_GRANT"] = "client_credentials";
+ GrantType["RESOURCE_OWNER_PASSWORD_GRANT"] = "password";
+ GrantType["REFRESH_TOKEN_GRANT"] = "refresh_token";
+ GrantType["DEVICE_CODE_GRANT"] = "device_code";
+ GrantType["JWT_BEARER"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
+})(GrantType || (GrantType = {}));
+/**
+ * Account types in Cache
+ */
+exports.CacheAccountType = void 0;
+(function (CacheAccountType) {
+ CacheAccountType["MSSTS_ACCOUNT_TYPE"] = "MSSTS";
+ CacheAccountType["ADFS_ACCOUNT_TYPE"] = "ADFS";
+ CacheAccountType["MSAV1_ACCOUNT_TYPE"] = "MSA";
+ CacheAccountType["GENERIC_ACCOUNT_TYPE"] = "Generic"; // NTLM, Kerberos, FBA, Basic etc
+})(exports.CacheAccountType || (exports.CacheAccountType = {}));
+/**
+ * Separators used in cache
+ */
+var Separators;
+(function (Separators) {
+ Separators["CACHE_KEY_SEPARATOR"] = "-";
+ Separators["CLIENT_INFO_SEPARATOR"] = ".";
+})(Separators || (Separators = {}));
+/**
+ * Credential Type stored in the cache
+ */
+exports.CredentialType = void 0;
+(function (CredentialType) {
+ CredentialType["ID_TOKEN"] = "IdToken";
+ CredentialType["ACCESS_TOKEN"] = "AccessToken";
+ CredentialType["ACCESS_TOKEN_WITH_AUTH_SCHEME"] = "AccessToken_With_AuthScheme";
+ CredentialType["REFRESH_TOKEN"] = "RefreshToken";
+})(exports.CredentialType || (exports.CredentialType = {}));
+/**
+ * Combine all cache types
+ */
+exports.CacheType = void 0;
+(function (CacheType) {
+ CacheType[CacheType["ADFS"] = 1001] = "ADFS";
+ CacheType[CacheType["MSA"] = 1002] = "MSA";
+ CacheType[CacheType["MSSTS"] = 1003] = "MSSTS";
+ CacheType[CacheType["GENERIC"] = 1004] = "GENERIC";
+ CacheType[CacheType["ACCESS_TOKEN"] = 2001] = "ACCESS_TOKEN";
+ CacheType[CacheType["REFRESH_TOKEN"] = 2002] = "REFRESH_TOKEN";
+ CacheType[CacheType["ID_TOKEN"] = 2003] = "ID_TOKEN";
+ CacheType[CacheType["APP_METADATA"] = 3001] = "APP_METADATA";
+ CacheType[CacheType["UNDEFINED"] = 9999] = "UNDEFINED";
+})(exports.CacheType || (exports.CacheType = {}));
+/**
+ * More Cache related constants
+ */
+var APP_METADATA = "appmetadata";
+var CLIENT_INFO = "client_info";
+var THE_FAMILY_ID = "1";
+var AUTHORITY_METADATA_CONSTANTS = {
+ CACHE_KEY: "authority-metadata",
+ REFRESH_TIME_SECONDS: 3600 * 24 // 24 Hours
+};
+var AuthorityMetadataSource;
+(function (AuthorityMetadataSource) {
+ AuthorityMetadataSource["CONFIG"] = "config";
+ AuthorityMetadataSource["CACHE"] = "cache";
+ AuthorityMetadataSource["NETWORK"] = "network";
+ AuthorityMetadataSource["HARDCODED_VALUES"] = "hardcoded_values";
+})(AuthorityMetadataSource || (AuthorityMetadataSource = {}));
+var SERVER_TELEM_CONSTANTS = {
+ SCHEMA_VERSION: 5,
+ MAX_CUR_HEADER_BYTES: 80,
+ MAX_LAST_HEADER_BYTES: 330,
+ MAX_CACHED_ERRORS: 50,
+ CACHE_KEY: "server-telemetry",
+ CATEGORY_SEPARATOR: "|",
+ VALUE_SEPARATOR: ",",
+ OVERFLOW_TRUE: "1",
+ OVERFLOW_FALSE: "0",
+ UNKNOWN_ERROR: "unknown_error"
+};
+/**
+ * Type of the authentication request
+ */
+exports.AuthenticationScheme = void 0;
+(function (AuthenticationScheme) {
+ AuthenticationScheme["BEARER"] = "Bearer";
+ AuthenticationScheme["POP"] = "pop";
+ AuthenticationScheme["SSH"] = "ssh-cert";
+})(exports.AuthenticationScheme || (exports.AuthenticationScheme = {}));
+/**
+ * Constants related to throttling
+ */
+var ThrottlingConstants = {
+ // Default time to throttle RequestThumbprint in seconds
+ DEFAULT_THROTTLE_TIME_SECONDS: 60,
+ // Default maximum time to throttle in seconds, overrides what the server sends back
+ DEFAULT_MAX_THROTTLE_TIME_SECONDS: 3600,
+ // Prefix for storing throttling entries
+ THROTTLING_PREFIX: "throttling",
+ // Value assigned to the x-ms-lib-capability header to indicate to the server the library supports throttling
+ X_MS_LIB_CAPABILITY_VALUE: "retry-after, h429"
+};
+var Errors = {
+ INVALID_GRANT_ERROR: "invalid_grant",
+ CLIENT_MISMATCH_ERROR: "client_mismatch",
+};
+/**
+ * Password grant parameters
+ */
+exports.PasswordGrantConstants = void 0;
+(function (PasswordGrantConstants) {
+ PasswordGrantConstants["username"] = "username";
+ PasswordGrantConstants["password"] = "password";
+})(exports.PasswordGrantConstants || (exports.PasswordGrantConstants = {}));
+/**
+ * Response codes
+ */
+var ResponseCodes;
+(function (ResponseCodes) {
+ ResponseCodes[ResponseCodes["httpSuccess"] = 200] = "httpSuccess";
+ ResponseCodes[ResponseCodes["httpBadRequest"] = 400] = "httpBadRequest";
+})(ResponseCodes || (ResponseCodes = {}));
+/**
+ * Region Discovery Sources
+ */
+var RegionDiscoverySources;
+(function (RegionDiscoverySources) {
+ RegionDiscoverySources["FAILED_AUTO_DETECTION"] = "1";
+ RegionDiscoverySources["INTERNAL_CACHE"] = "2";
+ RegionDiscoverySources["ENVIRONMENT_VARIABLE"] = "3";
+ RegionDiscoverySources["IMDS"] = "4";
+})(RegionDiscoverySources || (RegionDiscoverySources = {}));
+/**
+ * Region Discovery Outcomes
+ */
+var RegionDiscoveryOutcomes;
+(function (RegionDiscoveryOutcomes) {
+ RegionDiscoveryOutcomes["CONFIGURED_MATCHES_DETECTED"] = "1";
+ RegionDiscoveryOutcomes["CONFIGURED_NO_AUTO_DETECTION"] = "2";
+ RegionDiscoveryOutcomes["CONFIGURED_NOT_DETECTED"] = "3";
+ RegionDiscoveryOutcomes["AUTO_DETECTION_REQUESTED_SUCCESSFUL"] = "4";
+ RegionDiscoveryOutcomes["AUTO_DETECTION_REQUESTED_FAILED"] = "5";
+})(RegionDiscoveryOutcomes || (RegionDiscoveryOutcomes = {}));
+var CacheOutcome;
+(function (CacheOutcome) {
+ CacheOutcome["NO_CACHE_HIT"] = "0";
+ CacheOutcome["FORCE_REFRESH"] = "1";
+ CacheOutcome["NO_CACHED_ACCESS_TOKEN"] = "2";
+ CacheOutcome["CACHED_ACCESS_TOKEN_EXPIRED"] = "3";
+ CacheOutcome["REFRESH_CACHED_ACCESS_TOKEN"] = "4";
+ CacheOutcome["CLAIMS_REQUESTED_CACHE_SKIPPED"] = "5";
+})(CacheOutcome || (CacheOutcome = {}));
+var JsonTypes;
+(function (JsonTypes) {
+ JsonTypes["Jwt"] = "JWT";
+ JsonTypes["Jwk"] = "JWK";
+ JsonTypes["Pop"] = "pop";
+})(JsonTypes || (JsonTypes = {}));
+var ONE_DAY_IN_MS = 86400000;
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * AuthErrorMessage class containing string constants used by error codes and messages.
+ */
+var AuthErrorMessage = {
+ unexpectedError: {
+ code: "unexpected_error",
+ desc: "Unexpected error in authentication."
+ },
+ postRequestFailed: {
+ code: "post_request_failed",
+ desc: "Post request failed from the network, could be a 4xx/5xx or a network unavailability. Please check the exact error code for details."
+ }
+};
+/**
+ * General error class thrown by the MSAL.js library.
+ */
+var AuthError = /** @class */ (function (_super) {
+ __extends(AuthError, _super);
+ function AuthError(errorCode, errorMessage, suberror) {
+ var _this = this;
+ var errorString = errorMessage ? errorCode + ": " + errorMessage : errorCode;
+ _this = _super.call(this, errorString) || this;
+ Object.setPrototypeOf(_this, AuthError.prototype);
+ _this.errorCode = errorCode || Constants.EMPTY_STRING;
+ _this.errorMessage = errorMessage || Constants.EMPTY_STRING;
+ _this.subError = suberror || Constants.EMPTY_STRING;
+ _this.name = "AuthError";
+ return _this;
+ }
+ AuthError.prototype.setCorrelationId = function (correlationId) {
+ this.correlationId = correlationId;
+ };
+ /**
+ * Creates an error that is thrown when something unexpected happens in the library.
+ * @param errDesc
+ */
+ AuthError.createUnexpectedError = function (errDesc) {
+ return new AuthError(AuthErrorMessage.unexpectedError.code, AuthErrorMessage.unexpectedError.desc + ": " + errDesc);
+ };
+ /**
+ * Creates an error for post request failures.
+ * @param errDesc
+ * @returns
+ */
+ AuthError.createPostRequestFailed = function (errDesc) {
+ return new AuthError(AuthErrorMessage.postRequestFailed.code, AuthErrorMessage.postRequestFailed.desc + ": " + errDesc);
+ };
+ return AuthError;
+}(Error));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var DEFAULT_CRYPTO_IMPLEMENTATION = {
+ createNewGuid: function () {
+ var notImplErr = "Crypto interface - createNewGuid() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ },
+ base64Decode: function () {
+ var notImplErr = "Crypto interface - base64Decode() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ },
+ base64Encode: function () {
+ var notImplErr = "Crypto interface - base64Encode() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ },
+ generatePkceCodes: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - generatePkceCodes() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ getPublicKeyThumbprint: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - getPublicKeyThumbprint() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ removeTokenBindingKey: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - removeTokenBindingKey() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ clearKeystore: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - clearKeystore() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ signJwt: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - signJwt() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ hashString: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Crypto interface - hashString() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ }
+};
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * ClientAuthErrorMessage class containing string constants used by error codes and messages.
+ */
+var ClientAuthErrorMessage = {
+ clientInfoDecodingError: {
+ code: "client_info_decoding_error",
+ desc: "The client info could not be parsed/decoded correctly. Please review the trace to determine the root cause."
+ },
+ clientInfoEmptyError: {
+ code: "client_info_empty_error",
+ desc: "The client info was empty. Please review the trace to determine the root cause."
+ },
+ tokenParsingError: {
+ code: "token_parsing_error",
+ desc: "Token cannot be parsed. Please review stack trace to determine root cause."
+ },
+ nullOrEmptyToken: {
+ code: "null_or_empty_token",
+ desc: "The token is null or empty. Please review the trace to determine the root cause."
+ },
+ endpointResolutionError: {
+ code: "endpoints_resolution_error",
+ desc: "Error: could not resolve endpoints. Please check network and try again."
+ },
+ networkError: {
+ code: "network_error",
+ desc: "Network request failed. Please check network trace to determine root cause."
+ },
+ unableToGetOpenidConfigError: {
+ code: "openid_config_error",
+ desc: "Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints."
+ },
+ hashNotDeserialized: {
+ code: "hash_not_deserialized",
+ desc: "The hash parameters could not be deserialized. Please review the trace to determine the root cause."
+ },
+ blankGuidGenerated: {
+ code: "blank_guid_generated",
+ desc: "The guid generated was blank. Please review the trace to determine the root cause."
+ },
+ invalidStateError: {
+ code: "invalid_state",
+ desc: "State was not the expected format. Please check the logs to determine whether the request was sent using ProtocolUtils.setRequestState()."
+ },
+ stateMismatchError: {
+ code: "state_mismatch",
+ desc: "State mismatch error. Please check your network. Continued requests may cause cache overflow."
+ },
+ stateNotFoundError: {
+ code: "state_not_found",
+ desc: "State not found"
+ },
+ nonceMismatchError: {
+ code: "nonce_mismatch",
+ desc: "Nonce mismatch error. This may be caused by a race condition in concurrent requests."
+ },
+ nonceNotFoundError: {
+ code: "nonce_not_found",
+ desc: "nonce not found"
+ },
+ authTimeNotFoundError: {
+ code: "auth_time_not_found",
+ desc: "Max Age was requested and the ID token is missing the auth_time variable." +
+ " auth_time is an optional claim and is not enabled by default - it must be enabled." +
+ " See https://aka.ms/msaljs/optional-claims for more information."
+ },
+ maxAgeTranspiredError: {
+ code: "max_age_transpired",
+ desc: "Max Age is set to 0, or too much time has elapsed since the last end-user authentication."
+ },
+ noTokensFoundError: {
+ code: "no_tokens_found",
+ desc: "No tokens were found for the given scopes, and no authorization code was passed to acquireToken. You must retrieve an authorization code before making a call to acquireToken()."
+ },
+ multipleMatchingTokens: {
+ code: "multiple_matching_tokens",
+ desc: "The cache contains multiple tokens satisfying the requirements. " +
+ "Call AcquireToken again providing more requirements such as authority or account."
+ },
+ multipleMatchingAccounts: {
+ code: "multiple_matching_accounts",
+ desc: "The cache contains multiple accounts satisfying the given parameters. Please pass more info to obtain the correct account"
+ },
+ multipleMatchingAppMetadata: {
+ code: "multiple_matching_appMetadata",
+ desc: "The cache contains multiple appMetadata satisfying the given parameters. Please pass more info to obtain the correct appMetadata"
+ },
+ tokenRequestCannotBeMade: {
+ code: "request_cannot_be_made",
+ desc: "Token request cannot be made without authorization code or refresh token."
+ },
+ appendEmptyScopeError: {
+ code: "cannot_append_empty_scope",
+ desc: "Cannot append null or empty scope to ScopeSet. Please check the stack trace for more info."
+ },
+ removeEmptyScopeError: {
+ code: "cannot_remove_empty_scope",
+ desc: "Cannot remove null or empty scope from ScopeSet. Please check the stack trace for more info."
+ },
+ appendScopeSetError: {
+ code: "cannot_append_scopeset",
+ desc: "Cannot append ScopeSet due to error."
+ },
+ emptyInputScopeSetError: {
+ code: "empty_input_scopeset",
+ desc: "Empty input ScopeSet cannot be processed."
+ },
+ DeviceCodePollingCancelled: {
+ code: "device_code_polling_cancelled",
+ desc: "Caller has cancelled token endpoint polling during device code flow by setting DeviceCodeRequest.cancel = true."
+ },
+ DeviceCodeExpired: {
+ code: "device_code_expired",
+ desc: "Device code is expired."
+ },
+ DeviceCodeUnknownError: {
+ code: "device_code_unknown_error",
+ desc: "Device code stopped polling for unknown reasons."
+ },
+ NoAccountInSilentRequest: {
+ code: "no_account_in_silent_request",
+ desc: "Please pass an account object, silent flow is not supported without account information"
+ },
+ invalidCacheRecord: {
+ code: "invalid_cache_record",
+ desc: "Cache record object was null or undefined."
+ },
+ invalidCacheEnvironment: {
+ code: "invalid_cache_environment",
+ desc: "Invalid environment when attempting to create cache entry"
+ },
+ noAccountFound: {
+ code: "no_account_found",
+ desc: "No account found in cache for given key."
+ },
+ CachePluginError: {
+ code: "no cache plugin set on CacheManager",
+ desc: "ICachePlugin needs to be set before using readFromStorage or writeFromStorage"
+ },
+ noCryptoObj: {
+ code: "no_crypto_object",
+ desc: "No crypto object detected. This is required for the following operation: "
+ },
+ invalidCacheType: {
+ code: "invalid_cache_type",
+ desc: "Invalid cache type"
+ },
+ unexpectedAccountType: {
+ code: "unexpected_account_type",
+ desc: "Unexpected account type."
+ },
+ unexpectedCredentialType: {
+ code: "unexpected_credential_type",
+ desc: "Unexpected credential type."
+ },
+ invalidAssertion: {
+ code: "invalid_assertion",
+ desc: "Client assertion must meet requirements described in https://tools.ietf.org/html/rfc7515"
+ },
+ invalidClientCredential: {
+ code: "invalid_client_credential",
+ desc: "Client credential (secret, certificate, or assertion) must not be empty when creating a confidential client. An application should at most have one credential"
+ },
+ tokenRefreshRequired: {
+ code: "token_refresh_required",
+ desc: "Cannot return token from cache because it must be refreshed. This may be due to one of the following reasons: forceRefresh parameter is set to true, claims have been requested, there is no cached access token or it is expired."
+ },
+ userTimeoutReached: {
+ code: "user_timeout_reached",
+ desc: "User defined timeout for device code polling reached",
+ },
+ tokenClaimsRequired: {
+ code: "token_claims_cnf_required_for_signedjwt",
+ desc: "Cannot generate a POP jwt if the token_claims are not populated"
+ },
+ noAuthorizationCodeFromServer: {
+ code: "authorization_code_missing_from_server_response",
+ desc: "Server response does not contain an authorization code to proceed"
+ },
+ noAzureRegionDetected: {
+ code: "no_azure_region_detected",
+ desc: "No azure region was detected and no fallback was made available"
+ },
+ accessTokenEntityNullError: {
+ code: "access_token_entity_null",
+ desc: "Access token entity is null, please check logs and cache to ensure a valid access token is present."
+ },
+ bindingKeyNotRemovedError: {
+ code: "binding_key_not_removed",
+ desc: "Could not remove the credential's binding key from storage."
+ },
+ logoutNotSupported: {
+ code: "end_session_endpoint_not_supported",
+ desc: "Provided authority does not support logout."
+ },
+ keyIdMissing: {
+ code: "key_id_missing",
+ desc: "A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key."
+ },
+ noNetworkConnectivity: {
+ code: "no_network_connectivity",
+ desc: "No network connectivity. Check your internet connection."
+ },
+ userCanceledError: {
+ code: "user_canceled",
+ desc: "User canceled the flow."
+ }
+};
+/**
+ * Error thrown when there is an error in the client code running on the browser.
+ */
+var ClientAuthError = /** @class */ (function (_super) {
+ __extends(ClientAuthError, _super);
+ function ClientAuthError(errorCode, errorMessage) {
+ var _this = _super.call(this, errorCode, errorMessage) || this;
+ _this.name = "ClientAuthError";
+ Object.setPrototypeOf(_this, ClientAuthError.prototype);
+ return _this;
+ }
+ /**
+ * Creates an error thrown when client info object doesn't decode correctly.
+ * @param caughtError
+ */
+ ClientAuthError.createClientInfoDecodingError = function (caughtError) {
+ return new ClientAuthError(ClientAuthErrorMessage.clientInfoDecodingError.code, ClientAuthErrorMessage.clientInfoDecodingError.desc + " Failed with error: " + caughtError);
+ };
+ /**
+ * Creates an error thrown if the client info is empty.
+ * @param rawClientInfo
+ */
+ ClientAuthError.createClientInfoEmptyError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.clientInfoEmptyError.code, "" + ClientAuthErrorMessage.clientInfoEmptyError.desc);
+ };
+ /**
+ * Creates an error thrown when the id token extraction errors out.
+ * @param err
+ */
+ ClientAuthError.createTokenParsingError = function (caughtExtractionError) {
+ return new ClientAuthError(ClientAuthErrorMessage.tokenParsingError.code, ClientAuthErrorMessage.tokenParsingError.desc + " Failed with error: " + caughtExtractionError);
+ };
+ /**
+ * Creates an error thrown when the id token string is null or empty.
+ * @param invalidRawTokenString
+ */
+ ClientAuthError.createTokenNullOrEmptyError = function (invalidRawTokenString) {
+ return new ClientAuthError(ClientAuthErrorMessage.nullOrEmptyToken.code, ClientAuthErrorMessage.nullOrEmptyToken.desc + " Raw Token Value: " + invalidRawTokenString);
+ };
+ /**
+ * Creates an error thrown when the endpoint discovery doesn't complete correctly.
+ */
+ ClientAuthError.createEndpointDiscoveryIncompleteError = function (errDetail) {
+ return new ClientAuthError(ClientAuthErrorMessage.endpointResolutionError.code, ClientAuthErrorMessage.endpointResolutionError.desc + " Detail: " + errDetail);
+ };
+ /**
+ * Creates an error thrown when the fetch client throws
+ */
+ ClientAuthError.createNetworkError = function (endpoint, errDetail) {
+ return new ClientAuthError(ClientAuthErrorMessage.networkError.code, ClientAuthErrorMessage.networkError.desc + " | Fetch client threw: " + errDetail + " | Attempted to reach: " + endpoint.split("?")[0]);
+ };
+ /**
+ * Creates an error thrown when the openid-configuration endpoint cannot be reached or does not contain the required data
+ */
+ ClientAuthError.createUnableToGetOpenidConfigError = function (errDetail) {
+ return new ClientAuthError(ClientAuthErrorMessage.unableToGetOpenidConfigError.code, ClientAuthErrorMessage.unableToGetOpenidConfigError.desc + " Attempted to retrieve endpoints from: " + errDetail);
+ };
+ /**
+ * Creates an error thrown when the hash cannot be deserialized.
+ * @param hashParamObj
+ */
+ ClientAuthError.createHashNotDeserializedError = function (hashParamObj) {
+ return new ClientAuthError(ClientAuthErrorMessage.hashNotDeserialized.code, ClientAuthErrorMessage.hashNotDeserialized.desc + " Given Object: " + hashParamObj);
+ };
+ /**
+ * Creates an error thrown when the state cannot be parsed.
+ * @param invalidState
+ */
+ ClientAuthError.createInvalidStateError = function (invalidState, errorString) {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidStateError.code, ClientAuthErrorMessage.invalidStateError.desc + " Invalid State: " + invalidState + ", Root Err: " + errorString);
+ };
+ /**
+ * Creates an error thrown when two states do not match.
+ */
+ ClientAuthError.createStateMismatchError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.stateMismatchError.code, ClientAuthErrorMessage.stateMismatchError.desc);
+ };
+ /**
+ * Creates an error thrown when the state is not present
+ * @param missingState
+ */
+ ClientAuthError.createStateNotFoundError = function (missingState) {
+ return new ClientAuthError(ClientAuthErrorMessage.stateNotFoundError.code, ClientAuthErrorMessage.stateNotFoundError.desc + ": " + missingState);
+ };
+ /**
+ * Creates an error thrown when the nonce does not match.
+ */
+ ClientAuthError.createNonceMismatchError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.nonceMismatchError.code, ClientAuthErrorMessage.nonceMismatchError.desc);
+ };
+ /**
+ * Creates an error thrown when max_age was provided in the request, but auth_time is not in the token claims
+ * @param missingNonce
+ */
+ ClientAuthError.createAuthTimeNotFoundError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.authTimeNotFoundError.code, ClientAuthErrorMessage.authTimeNotFoundError.desc);
+ };
+ /**
+ * Creates an error thrown when too much time has elapsed since the last end-user authentication
+ */
+ ClientAuthError.createMaxAgeTranspiredError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.maxAgeTranspiredError.code, ClientAuthErrorMessage.maxAgeTranspiredError.desc);
+ };
+ /**
+ * Creates an error thrown when the mnonce is not present
+ * @param missingNonce
+ */
+ ClientAuthError.createNonceNotFoundError = function (missingNonce) {
+ return new ClientAuthError(ClientAuthErrorMessage.nonceNotFoundError.code, ClientAuthErrorMessage.nonceNotFoundError.desc + ": " + missingNonce);
+ };
+ /**
+ * Throws error when multiple tokens are in cache.
+ */
+ ClientAuthError.createMultipleMatchingTokensInCacheError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.multipleMatchingTokens.code, ClientAuthErrorMessage.multipleMatchingTokens.desc + ".");
+ };
+ /**
+ * Throws error when multiple accounts are in cache for the given params
+ */
+ ClientAuthError.createMultipleMatchingAccountsInCacheError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.multipleMatchingAccounts.code, ClientAuthErrorMessage.multipleMatchingAccounts.desc);
+ };
+ /**
+ * Throws error when multiple appMetada are in cache for the given clientId.
+ */
+ ClientAuthError.createMultipleMatchingAppMetadataInCacheError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.multipleMatchingAppMetadata.code, ClientAuthErrorMessage.multipleMatchingAppMetadata.desc);
+ };
+ /**
+ * Throws error when no auth code or refresh token is given to ServerTokenRequestParameters.
+ */
+ ClientAuthError.createTokenRequestCannotBeMadeError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.tokenRequestCannotBeMade.code, ClientAuthErrorMessage.tokenRequestCannotBeMade.desc);
+ };
+ /**
+ * Throws error when attempting to append a null, undefined or empty scope to a set
+ * @param givenScope
+ */
+ ClientAuthError.createAppendEmptyScopeToSetError = function (givenScope) {
+ return new ClientAuthError(ClientAuthErrorMessage.appendEmptyScopeError.code, ClientAuthErrorMessage.appendEmptyScopeError.desc + " Given Scope: " + givenScope);
+ };
+ /**
+ * Throws error when attempting to append a null, undefined or empty scope to a set
+ * @param givenScope
+ */
+ ClientAuthError.createRemoveEmptyScopeFromSetError = function (givenScope) {
+ return new ClientAuthError(ClientAuthErrorMessage.removeEmptyScopeError.code, ClientAuthErrorMessage.removeEmptyScopeError.desc + " Given Scope: " + givenScope);
+ };
+ /**
+ * Throws error when attempting to append null or empty ScopeSet.
+ * @param appendError
+ */
+ ClientAuthError.createAppendScopeSetError = function (appendError) {
+ return new ClientAuthError(ClientAuthErrorMessage.appendScopeSetError.code, ClientAuthErrorMessage.appendScopeSetError.desc + " Detail Error: " + appendError);
+ };
+ /**
+ * Throws error if ScopeSet is null or undefined.
+ * @param givenScopeSet
+ */
+ ClientAuthError.createEmptyInputScopeSetError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.emptyInputScopeSetError.code, "" + ClientAuthErrorMessage.emptyInputScopeSetError.desc);
+ };
+ /**
+ * Throws error if user sets CancellationToken.cancel = true during polling of token endpoint during device code flow
+ */
+ ClientAuthError.createDeviceCodeCancelledError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.DeviceCodePollingCancelled.code, "" + ClientAuthErrorMessage.DeviceCodePollingCancelled.desc);
+ };
+ /**
+ * Throws error if device code is expired
+ */
+ ClientAuthError.createDeviceCodeExpiredError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.DeviceCodeExpired.code, "" + ClientAuthErrorMessage.DeviceCodeExpired.desc);
+ };
+ /**
+ * Throws error if device code is expired
+ */
+ ClientAuthError.createDeviceCodeUnknownError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.DeviceCodeUnknownError.code, "" + ClientAuthErrorMessage.DeviceCodeUnknownError.desc);
+ };
+ /**
+ * Throws error when silent requests are made without an account object
+ */
+ ClientAuthError.createNoAccountInSilentRequestError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.NoAccountInSilentRequest.code, "" + ClientAuthErrorMessage.NoAccountInSilentRequest.desc);
+ };
+ /**
+ * Throws error when cache record is null or undefined.
+ */
+ ClientAuthError.createNullOrUndefinedCacheRecord = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidCacheRecord.code, ClientAuthErrorMessage.invalidCacheRecord.desc);
+ };
+ /**
+ * Throws error when provided environment is not part of the CloudDiscoveryMetadata object
+ */
+ ClientAuthError.createInvalidCacheEnvironmentError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidCacheEnvironment.code, ClientAuthErrorMessage.invalidCacheEnvironment.desc);
+ };
+ /**
+ * Throws error when account is not found in cache.
+ */
+ ClientAuthError.createNoAccountFoundError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.noAccountFound.code, ClientAuthErrorMessage.noAccountFound.desc);
+ };
+ /**
+ * Throws error if ICachePlugin not set on CacheManager.
+ */
+ ClientAuthError.createCachePluginError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.CachePluginError.code, "" + ClientAuthErrorMessage.CachePluginError.desc);
+ };
+ /**
+ * Throws error if crypto object not found.
+ * @param operationName
+ */
+ ClientAuthError.createNoCryptoObjectError = function (operationName) {
+ return new ClientAuthError(ClientAuthErrorMessage.noCryptoObj.code, "" + ClientAuthErrorMessage.noCryptoObj.desc + operationName);
+ };
+ /**
+ * Throws error if cache type is invalid.
+ */
+ ClientAuthError.createInvalidCacheTypeError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidCacheType.code, "" + ClientAuthErrorMessage.invalidCacheType.desc);
+ };
+ /**
+ * Throws error if unexpected account type.
+ */
+ ClientAuthError.createUnexpectedAccountTypeError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.unexpectedAccountType.code, "" + ClientAuthErrorMessage.unexpectedAccountType.desc);
+ };
+ /**
+ * Throws error if unexpected credential type.
+ */
+ ClientAuthError.createUnexpectedCredentialTypeError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.unexpectedCredentialType.code, "" + ClientAuthErrorMessage.unexpectedCredentialType.desc);
+ };
+ /**
+ * Throws error if client assertion is not valid.
+ */
+ ClientAuthError.createInvalidAssertionError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidAssertion.code, "" + ClientAuthErrorMessage.invalidAssertion.desc);
+ };
+ /**
+ * Throws error if client assertion is not valid.
+ */
+ ClientAuthError.createInvalidCredentialError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.invalidClientCredential.code, "" + ClientAuthErrorMessage.invalidClientCredential.desc);
+ };
+ /**
+ * Throws error if token cannot be retrieved from cache due to refresh being required.
+ */
+ ClientAuthError.createRefreshRequiredError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.tokenRefreshRequired.code, ClientAuthErrorMessage.tokenRefreshRequired.desc);
+ };
+ /**
+ * Throws error if the user defined timeout is reached.
+ */
+ ClientAuthError.createUserTimeoutReachedError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.userTimeoutReached.code, ClientAuthErrorMessage.userTimeoutReached.desc);
+ };
+ /*
+ * Throws error if token claims are not populated for a signed jwt generation
+ */
+ ClientAuthError.createTokenClaimsRequiredError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.tokenClaimsRequired.code, ClientAuthErrorMessage.tokenClaimsRequired.desc);
+ };
+ /**
+ * Throws error when the authorization code is missing from the server response
+ */
+ ClientAuthError.createNoAuthCodeInServerResponseError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.noAuthorizationCodeFromServer.code, ClientAuthErrorMessage.noAuthorizationCodeFromServer.desc);
+ };
+ ClientAuthError.createBindingKeyNotRemovedError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.bindingKeyNotRemovedError.code, ClientAuthErrorMessage.bindingKeyNotRemovedError.desc);
+ };
+ /**
+ * Thrown when logout is attempted for an authority that doesnt have an end_session_endpoint
+ */
+ ClientAuthError.createLogoutNotSupportedError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.logoutNotSupported.code, ClientAuthErrorMessage.logoutNotSupported.desc);
+ };
+ /**
+ * Create an error when kid attribute is missing from a PoP token's cache record
+ */
+ ClientAuthError.createKeyIdMissingError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.keyIdMissing.code, ClientAuthErrorMessage.keyIdMissing.desc);
+ };
+ /**
+ * Create an error when the client does not have network connectivity
+ */
+ ClientAuthError.createNoNetworkConnectivityError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.noNetworkConnectivity.code, ClientAuthErrorMessage.noNetworkConnectivity.desc);
+ };
+ /**
+ * Create an error when the user cancels the flow
+ */
+ ClientAuthError.createUserCanceledError = function () {
+ return new ClientAuthError(ClientAuthErrorMessage.userCanceledError.code, ClientAuthErrorMessage.userCanceledError.desc);
+ };
+ return ClientAuthError;
+}(AuthError));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * @hidden
+ */
+var StringUtils = /** @class */ (function () {
+ function StringUtils() {
+ }
+ /**
+ * decode a JWT
+ *
+ * @param authToken
+ */
+ StringUtils.decodeAuthToken = function (authToken) {
+ if (StringUtils.isEmpty(authToken)) {
+ throw ClientAuthError.createTokenNullOrEmptyError(authToken);
+ }
+ var tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/;
+ var matches = tokenPartsRegex.exec(authToken);
+ if (!matches || matches.length < 4) {
+ throw ClientAuthError.createTokenParsingError("Given token is malformed: " + JSON.stringify(authToken));
+ }
+ var crackedToken = {
+ header: matches[1],
+ JWSPayload: matches[2],
+ JWSSig: matches[3]
+ };
+ return crackedToken;
+ };
+ /**
+ * Check if a string is empty.
+ *
+ * @param str
+ */
+ StringUtils.isEmpty = function (str) {
+ return (typeof str === "undefined" || !str || 0 === str.length);
+ };
+ /**
+ * Check if stringified object is empty
+ * @param strObj
+ */
+ StringUtils.isEmptyObj = function (strObj) {
+ if (strObj && !StringUtils.isEmpty(strObj)) {
+ try {
+ var obj = JSON.parse(strObj);
+ return Object.keys(obj).length === 0;
+ }
+ catch (e) { }
+ }
+ return true;
+ };
+ StringUtils.startsWith = function (str, search) {
+ return str.indexOf(search) === 0;
+ };
+ StringUtils.endsWith = function (str, search) {
+ return (str.length >= search.length) && (str.lastIndexOf(search) === (str.length - search.length));
+ };
+ /**
+ * Parses string into an object.
+ *
+ * @param query
+ */
+ StringUtils.queryStringToObject = function (query) {
+ var obj = {};
+ var params = query.split("&");
+ var decode = function (s) { return decodeURIComponent(s.replace(/\+/g, " ")); };
+ params.forEach(function (pair) {
+ if (pair.trim()) {
+ var _a = pair.split(/=(.+)/g, 2), key = _a[0], value = _a[1]; // Split on the first occurence of the '=' character
+ if (key && value) {
+ obj[decode(key)] = decode(value);
+ }
+ }
+ });
+ return obj;
+ };
+ /**
+ * Trims entries in an array.
+ *
+ * @param arr
+ */
+ StringUtils.trimArrayEntries = function (arr) {
+ return arr.map(function (entry) { return entry.trim(); });
+ };
+ /**
+ * Removes empty strings from array
+ * @param arr
+ */
+ StringUtils.removeEmptyStringsFromArray = function (arr) {
+ return arr.filter(function (entry) {
+ return !StringUtils.isEmpty(entry);
+ });
+ };
+ /**
+ * Attempts to parse a string into JSON
+ * @param str
+ */
+ StringUtils.jsonParseHelper = function (str) {
+ try {
+ return JSON.parse(str);
+ }
+ catch (e) {
+ return null;
+ }
+ };
+ /**
+ * Tests if a given string matches a given pattern, with support for wildcards and queries.
+ * @param pattern Wildcard pattern to string match. Supports "*" for wildcards and "?" for queries
+ * @param input String to match against
+ */
+ StringUtils.matchPattern = function (pattern, input) {
+ /**
+ * Wildcard support: https://stackoverflow.com/a/3117248/4888559
+ * Queries: replaces "?" in string with escaped "\?" for regex test
+ */
+ var regex = new RegExp(pattern.replace(/\\/g, "\\\\").replace(/\*/g, "[^ ]*").replace(/\?/g, "\\\?")); // eslint-disable-line security/detect-non-literal-regexp
+ return regex.test(input);
+ };
+ return StringUtils;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Log message level.
+ */
+exports.LogLevel = void 0;
+(function (LogLevel) {
+ LogLevel[LogLevel["Error"] = 0] = "Error";
+ LogLevel[LogLevel["Warning"] = 1] = "Warning";
+ LogLevel[LogLevel["Info"] = 2] = "Info";
+ LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
+ LogLevel[LogLevel["Trace"] = 4] = "Trace";
+})(exports.LogLevel || (exports.LogLevel = {}));
+/**
+ * Class which facilitates logging of messages to a specific place.
+ */
+var Logger = /** @class */ (function () {
+ function Logger(loggerOptions, packageName, packageVersion) {
+ // Current log level, defaults to info.
+ this.level = exports.LogLevel.Info;
+ var defaultLoggerCallback = function () {
+ return;
+ };
+ var setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
+ this.localCallback = setLoggerOptions.loggerCallback || defaultLoggerCallback;
+ this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
+ this.level = typeof (setLoggerOptions.logLevel) === "number" ? setLoggerOptions.logLevel : exports.LogLevel.Info;
+ this.correlationId = setLoggerOptions.correlationId || Constants.EMPTY_STRING;
+ this.packageName = packageName || Constants.EMPTY_STRING;
+ this.packageVersion = packageVersion || Constants.EMPTY_STRING;
+ }
+ Logger.createDefaultLoggerOptions = function () {
+ return {
+ loggerCallback: function () {
+ // allow users to not set loggerCallback
+ },
+ piiLoggingEnabled: false,
+ logLevel: exports.LogLevel.Info
+ };
+ };
+ /**
+ * Create new Logger with existing configurations.
+ */
+ Logger.prototype.clone = function (packageName, packageVersion, correlationId) {
+ return new Logger({ loggerCallback: this.localCallback, piiLoggingEnabled: this.piiLoggingEnabled, logLevel: this.level, correlationId: correlationId || this.correlationId }, packageName, packageVersion);
+ };
+ /**
+ * Log message with required options.
+ */
+ Logger.prototype.logMessage = function (logMessage, options) {
+ if ((options.logLevel > this.level) || (!this.piiLoggingEnabled && options.containsPii)) {
+ return;
+ }
+ var timestamp = new Date().toUTCString();
+ // Add correlationId to logs if set, correlationId provided on log messages take precedence
+ var logHeader;
+ if (!StringUtils.isEmpty(options.correlationId)) {
+ logHeader = "[" + timestamp + "] : [" + options.correlationId + "]";
+ }
+ else if (!StringUtils.isEmpty(this.correlationId)) {
+ logHeader = "[" + timestamp + "] : [" + this.correlationId + "]";
+ }
+ else {
+ logHeader = "[" + timestamp + "]";
+ }
+ var log = logHeader + " : " + this.packageName + "@" + this.packageVersion + " : " + exports.LogLevel[options.logLevel] + " - " + logMessage;
+ // debug(`msal:${LogLevel[options.logLevel]}${options.containsPii ? "-Pii": Constants.EMPTY_STRING}${options.context ? `:${options.context}` : Constants.EMPTY_STRING}`)(logMessage);
+ this.executeCallback(options.logLevel, log, options.containsPii || false);
+ };
+ /**
+ * Execute callback with message.
+ */
+ Logger.prototype.executeCallback = function (level, message, containsPii) {
+ if (this.localCallback) {
+ this.localCallback(level, message, containsPii);
+ }
+ };
+ /**
+ * Logs error messages.
+ */
+ Logger.prototype.error = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Error,
+ containsPii: false,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs error messages with PII.
+ */
+ Logger.prototype.errorPii = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Error,
+ containsPii: true,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs warning messages.
+ */
+ Logger.prototype.warning = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Warning,
+ containsPii: false,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs warning messages with PII.
+ */
+ Logger.prototype.warningPii = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Warning,
+ containsPii: true,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs info messages.
+ */
+ Logger.prototype.info = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Info,
+ containsPii: false,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs info messages with PII.
+ */
+ Logger.prototype.infoPii = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Info,
+ containsPii: true,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs verbose messages.
+ */
+ Logger.prototype.verbose = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Verbose,
+ containsPii: false,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs verbose messages with PII.
+ */
+ Logger.prototype.verbosePii = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Verbose,
+ containsPii: true,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs trace messages.
+ */
+ Logger.prototype.trace = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Trace,
+ containsPii: false,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Logs trace messages with PII.
+ */
+ Logger.prototype.tracePii = function (message, correlationId) {
+ this.logMessage(message, {
+ logLevel: exports.LogLevel.Trace,
+ containsPii: true,
+ correlationId: correlationId || Constants.EMPTY_STRING
+ });
+ };
+ /**
+ * Returns whether PII Logging is enabled or not.
+ */
+ Logger.prototype.isPiiLoggingEnabled = function () {
+ return this.piiLoggingEnabled || false;
+ };
+ return Logger;
+}());
+
+/* eslint-disable header/header */
+var name = "@azure/msal-common";
+var version = "13.2.1";
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+exports.AzureCloudInstance = void 0;
+(function (AzureCloudInstance) {
+ // AzureCloudInstance is not specified.
+ AzureCloudInstance[AzureCloudInstance["None"] = 0] = "None";
+ // Microsoft Azure public cloud
+ AzureCloudInstance["AzurePublic"] = "https://login.microsoftonline.com";
+ // Microsoft PPE
+ AzureCloudInstance["AzurePpe"] = "https://login.windows-ppe.net";
+ // Microsoft Chinese national cloud
+ AzureCloudInstance["AzureChina"] = "https://login.chinacloudapi.cn";
+ // Microsoft German national cloud ("Black Forest")
+ AzureCloudInstance["AzureGermany"] = "https://login.microsoftonline.de";
+ // US Government cloud
+ AzureCloudInstance["AzureUsGovernment"] = "https://login.microsoftonline.us";
+})(exports.AzureCloudInstance || (exports.AzureCloudInstance = {}));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * ClientConfigurationErrorMessage class containing string constants used by error codes and messages.
+ */
+var ClientConfigurationErrorMessage = {
+ redirectUriNotSet: {
+ code: "redirect_uri_empty",
+ desc: "A redirect URI is required for all calls, and none has been set."
+ },
+ postLogoutUriNotSet: {
+ code: "post_logout_uri_empty",
+ desc: "A post logout redirect has not been set."
+ },
+ claimsRequestParsingError: {
+ code: "claims_request_parsing_error",
+ desc: "Could not parse the given claims request object."
+ },
+ authorityUriInsecure: {
+ code: "authority_uri_insecure",
+ desc: "Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options"
+ },
+ urlParseError: {
+ code: "url_parse_error",
+ desc: "URL could not be parsed into appropriate segments."
+ },
+ urlEmptyError: {
+ code: "empty_url_error",
+ desc: "URL was empty or null."
+ },
+ emptyScopesError: {
+ code: "empty_input_scopes_error",
+ desc: "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token."
+ },
+ nonArrayScopesError: {
+ code: "nonarray_input_scopes_error",
+ desc: "Scopes cannot be passed as non-array."
+ },
+ clientIdSingleScopeError: {
+ code: "clientid_input_scopes_error",
+ desc: "Client ID can only be provided as a single scope."
+ },
+ invalidPrompt: {
+ code: "invalid_prompt_value",
+ desc: "Supported prompt values are 'login', 'select_account', 'consent', 'create', 'none' and 'no_session'. Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest",
+ },
+ invalidClaimsRequest: {
+ code: "invalid_claims",
+ desc: "Given claims parameter must be a stringified JSON object."
+ },
+ tokenRequestEmptyError: {
+ code: "token_request_empty",
+ desc: "Token request was empty and not found in cache."
+ },
+ logoutRequestEmptyError: {
+ code: "logout_request_empty",
+ desc: "The logout request was null or undefined."
+ },
+ invalidCodeChallengeMethod: {
+ code: "invalid_code_challenge_method",
+ desc: "code_challenge_method passed is invalid. Valid values are \"plain\" and \"S256\"."
+ },
+ invalidCodeChallengeParams: {
+ code: "pkce_params_missing",
+ desc: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request"
+ },
+ invalidCloudDiscoveryMetadata: {
+ code: "invalid_cloud_discovery_metadata",
+ desc: "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields"
+ },
+ invalidAuthorityMetadata: {
+ code: "invalid_authority_metadata",
+ desc: "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields."
+ },
+ untrustedAuthority: {
+ code: "untrusted_authority",
+ desc: "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter."
+ },
+ invalidAzureCloudInstance: {
+ code: "invalid_azure_cloud_instance",
+ desc: "Invalid AzureCloudInstance provided. Please refer MSAL JS docs: aks.ms/msaljs/azure_cloud_instance for valid values"
+ },
+ missingSshJwk: {
+ code: "missing_ssh_jwk",
+ desc: "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme."
+ },
+ missingSshKid: {
+ code: "missing_ssh_kid",
+ desc: "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme."
+ },
+ missingNonceAuthenticationHeader: {
+ code: "missing_nonce_authentication_header",
+ desc: "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce."
+ },
+ invalidAuthenticationHeader: {
+ code: "invalid_authentication_header",
+ desc: "Invalid authentication header provided"
+ },
+ authorityMismatch: {
+ code: "authority_mismatch",
+ desc: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority."
+ }
+};
+/**
+ * Error thrown when there is an error in configuration of the MSAL.js library.
+ */
+var ClientConfigurationError = /** @class */ (function (_super) {
+ __extends(ClientConfigurationError, _super);
+ function ClientConfigurationError(errorCode, errorMessage) {
+ var _this = _super.call(this, errorCode, errorMessage) || this;
+ _this.name = "ClientConfigurationError";
+ Object.setPrototypeOf(_this, ClientConfigurationError.prototype);
+ return _this;
+ }
+ /**
+ * Creates an error thrown when the redirect uri is empty (not set by caller)
+ */
+ ClientConfigurationError.createRedirectUriEmptyError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.redirectUriNotSet.code, ClientConfigurationErrorMessage.redirectUriNotSet.desc);
+ };
+ /**
+ * Creates an error thrown when the post-logout redirect uri is empty (not set by caller)
+ */
+ ClientConfigurationError.createPostLogoutRedirectUriEmptyError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.postLogoutUriNotSet.code, ClientConfigurationErrorMessage.postLogoutUriNotSet.desc);
+ };
+ /**
+ * Creates an error thrown when the claims request could not be successfully parsed
+ */
+ ClientConfigurationError.createClaimsRequestParsingError = function (claimsRequestParseError) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.claimsRequestParsingError.code, ClientConfigurationErrorMessage.claimsRequestParsingError.desc + " Given value: " + claimsRequestParseError);
+ };
+ /**
+ * Creates an error thrown if authority uri is given an insecure protocol.
+ * @param urlString
+ */
+ ClientConfigurationError.createInsecureAuthorityUriError = function (urlString) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityUriInsecure.code, ClientConfigurationErrorMessage.authorityUriInsecure.desc + " Given URI: " + urlString);
+ };
+ /**
+ * Creates an error thrown if URL string does not parse into separate segments.
+ * @param urlString
+ */
+ ClientConfigurationError.createUrlParseError = function (urlParseError) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.urlParseError.code, ClientConfigurationErrorMessage.urlParseError.desc + " Given Error: " + urlParseError);
+ };
+ /**
+ * Creates an error thrown if URL string is empty or null.
+ * @param urlString
+ */
+ ClientConfigurationError.createUrlEmptyError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.urlEmptyError.code, ClientConfigurationErrorMessage.urlEmptyError.desc);
+ };
+ /**
+ * Error thrown when scopes are empty.
+ * @param scopesValue
+ */
+ ClientConfigurationError.createEmptyScopesArrayError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.emptyScopesError.code, "" + ClientConfigurationErrorMessage.emptyScopesError.desc);
+ };
+ /**
+ * Error thrown when client id scope is not provided as single scope.
+ * @param inputScopes
+ */
+ ClientConfigurationError.createClientIdSingleScopeError = function (inputScopes) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.clientIdSingleScopeError.code, ClientConfigurationErrorMessage.clientIdSingleScopeError.desc + " Given Scopes: " + inputScopes);
+ };
+ /**
+ * Error thrown when prompt is not an allowed type.
+ * @param promptValue
+ */
+ ClientConfigurationError.createInvalidPromptError = function (promptValue) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidPrompt.code, ClientConfigurationErrorMessage.invalidPrompt.desc + " Given value: " + promptValue);
+ };
+ /**
+ * Creates error thrown when claims parameter is not a stringified JSON object
+ */
+ ClientConfigurationError.createInvalidClaimsRequestError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidClaimsRequest.code, ClientConfigurationErrorMessage.invalidClaimsRequest.desc);
+ };
+ /**
+ * Throws error when token request is empty and nothing cached in storage.
+ */
+ ClientConfigurationError.createEmptyLogoutRequestError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.logoutRequestEmptyError.code, ClientConfigurationErrorMessage.logoutRequestEmptyError.desc);
+ };
+ /**
+ * Throws error when token request is empty and nothing cached in storage.
+ */
+ ClientConfigurationError.createEmptyTokenRequestError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.tokenRequestEmptyError.code, ClientConfigurationErrorMessage.tokenRequestEmptyError.desc);
+ };
+ /**
+ * Throws error when an invalid code_challenge_method is passed by the user
+ */
+ ClientConfigurationError.createInvalidCodeChallengeMethodError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeMethod.code, ClientConfigurationErrorMessage.invalidCodeChallengeMethod.desc);
+ };
+ /**
+ * Throws error when both params: code_challenge and code_challenge_method are not passed together
+ */
+ ClientConfigurationError.createInvalidCodeChallengeParamsError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeParams.code, ClientConfigurationErrorMessage.invalidCodeChallengeParams.desc);
+ };
+ /**
+ * Throws an error when the user passes invalid cloudDiscoveryMetadata
+ */
+ ClientConfigurationError.createInvalidCloudDiscoveryMetadataError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.code, ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.desc);
+ };
+ /**
+ * Throws an error when the user passes invalid cloudDiscoveryMetadata
+ */
+ ClientConfigurationError.createInvalidAuthorityMetadataError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthorityMetadata.code, ClientConfigurationErrorMessage.invalidAuthorityMetadata.desc);
+ };
+ /**
+ * Throws error when provided authority is not a member of the trusted host list
+ */
+ ClientConfigurationError.createUntrustedAuthorityError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.untrustedAuthority.code, ClientConfigurationErrorMessage.untrustedAuthority.desc);
+ };
+ /**
+ * Throws error when the AzureCloudInstance is set to an invalid value
+ */
+ ClientConfigurationError.createInvalidAzureCloudInstanceError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAzureCloudInstance.code, ClientConfigurationErrorMessage.invalidAzureCloudInstance.desc);
+ };
+ /**
+ * Throws an error when the authentication scheme is set to SSH but the SSH public key is omitted from the request
+ */
+ ClientConfigurationError.createMissingSshJwkError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshJwk.code, ClientConfigurationErrorMessage.missingSshJwk.desc);
+ };
+ /**
+ * Throws an error when the authentication scheme is set to SSH but the SSH public key ID is omitted from the request
+ */
+ ClientConfigurationError.createMissingSshKidError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshKid.code, ClientConfigurationErrorMessage.missingSshKid.desc);
+ };
+ /**
+ * Throws error when provided headers don't contain a header that a server nonce can be extracted from
+ */
+ ClientConfigurationError.createMissingNonceAuthenticationHeadersError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.code, ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.desc);
+ };
+ /**
+ * Throws error when a provided header is invalid in any way
+ */
+ ClientConfigurationError.createInvalidAuthenticationHeaderError = function (invalidHeaderName, details) {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthenticationHeader.code, ClientConfigurationErrorMessage.invalidAuthenticationHeader.desc + ". Invalid header: " + invalidHeaderName + ". Details: " + details);
+ };
+ /**
+ * Create an error when the authority provided in request does not match authority provided in account or MSAL.js configuration.
+ */
+ ClientConfigurationError.createAuthorityMismatchError = function () {
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityMismatch.code, ClientConfigurationErrorMessage.authorityMismatch.desc);
+ };
+ return ClientConfigurationError;
+}(ClientAuthError));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * The ScopeSet class creates a set of scopes. Scopes are case-insensitive, unique values, so the Set object in JS makes
+ * the most sense to implement for this class. All scopes are trimmed and converted to lower case strings in intersection and union functions
+ * to ensure uniqueness of strings.
+ */
+var ScopeSet = /** @class */ (function () {
+ function ScopeSet(inputScopes) {
+ var _this = this;
+ // Filter empty string and null/undefined array items
+ var scopeArr = inputScopes ? StringUtils.trimArrayEntries(__spreadArrays(inputScopes)) : [];
+ var filteredInput = scopeArr ? StringUtils.removeEmptyStringsFromArray(scopeArr) : [];
+ // Validate and filter scopes (validate function throws if validation fails)
+ this.validateInputScopes(filteredInput);
+ this.scopes = new Set(); // Iterator in constructor not supported by IE11
+ filteredInput.forEach(function (scope) { return _this.scopes.add(scope); });
+ }
+ /**
+ * Factory method to create ScopeSet from space-delimited string
+ * @param inputScopeString
+ * @param appClientId
+ * @param scopesRequired
+ */
+ ScopeSet.fromString = function (inputScopeString) {
+ var scopeString = inputScopeString || Constants.EMPTY_STRING;
+ var inputScopes = scopeString.split(" ");
+ return new ScopeSet(inputScopes);
+ };
+ /**
+ * Creates the set of scopes to search for in cache lookups
+ * @param inputScopeString
+ * @returns
+ */
+ ScopeSet.createSearchScopes = function (inputScopeString) {
+ var scopeSet = new ScopeSet(inputScopeString);
+ if (!scopeSet.containsOnlyOIDCScopes()) {
+ scopeSet.removeOIDCScopes();
+ }
+ else {
+ scopeSet.removeScope(Constants.OFFLINE_ACCESS_SCOPE);
+ }
+ return scopeSet;
+ };
+ /**
+ * Used to validate the scopes input parameter requested by the developer.
+ * @param {Array} inputScopes - Developer requested permissions. Not all scopes are guaranteed to be included in the access token returned.
+ * @param {boolean} scopesRequired - Boolean indicating whether the scopes array is required or not
+ */
+ ScopeSet.prototype.validateInputScopes = function (inputScopes) {
+ // Check if scopes are required but not given or is an empty array
+ if (!inputScopes || inputScopes.length < 1) {
+ throw ClientConfigurationError.createEmptyScopesArrayError();
+ }
+ };
+ /**
+ * Check if a given scope is present in this set of scopes.
+ * @param scope
+ */
+ ScopeSet.prototype.containsScope = function (scope) {
+ var lowerCaseScopes = this.printScopesLowerCase().split(" ");
+ var lowerCaseScopesSet = new ScopeSet(lowerCaseScopes);
+ // compare lowercase scopes
+ return !StringUtils.isEmpty(scope) ? lowerCaseScopesSet.scopes.has(scope.toLowerCase()) : false;
+ };
+ /**
+ * Check if a set of scopes is present in this set of scopes.
+ * @param scopeSet
+ */
+ ScopeSet.prototype.containsScopeSet = function (scopeSet) {
+ var _this = this;
+ if (!scopeSet || scopeSet.scopes.size <= 0) {
+ return false;
+ }
+ return (this.scopes.size >= scopeSet.scopes.size && scopeSet.asArray().every(function (scope) { return _this.containsScope(scope); }));
+ };
+ /**
+ * Check if set of scopes contains only the defaults
+ */
+ ScopeSet.prototype.containsOnlyOIDCScopes = function () {
+ var _this = this;
+ var defaultScopeCount = 0;
+ OIDC_SCOPES.forEach(function (defaultScope) {
+ if (_this.containsScope(defaultScope)) {
+ defaultScopeCount += 1;
+ }
+ });
+ return this.scopes.size === defaultScopeCount;
+ };
+ /**
+ * Appends single scope if passed
+ * @param newScope
+ */
+ ScopeSet.prototype.appendScope = function (newScope) {
+ if (!StringUtils.isEmpty(newScope)) {
+ this.scopes.add(newScope.trim());
+ }
+ };
+ /**
+ * Appends multiple scopes if passed
+ * @param newScopes
+ */
+ ScopeSet.prototype.appendScopes = function (newScopes) {
+ var _this = this;
+ try {
+ newScopes.forEach(function (newScope) { return _this.appendScope(newScope); });
+ }
+ catch (e) {
+ throw ClientAuthError.createAppendScopeSetError(e);
+ }
+ };
+ /**
+ * Removes element from set of scopes.
+ * @param scope
+ */
+ ScopeSet.prototype.removeScope = function (scope) {
+ if (StringUtils.isEmpty(scope)) {
+ throw ClientAuthError.createRemoveEmptyScopeFromSetError(scope);
+ }
+ this.scopes.delete(scope.trim());
+ };
+ /**
+ * Removes default scopes from set of scopes
+ * Primarily used to prevent cache misses if the default scopes are not returned from the server
+ */
+ ScopeSet.prototype.removeOIDCScopes = function () {
+ var _this = this;
+ OIDC_SCOPES.forEach(function (defaultScope) {
+ _this.scopes.delete(defaultScope);
+ });
+ };
+ /**
+ * Combines an array of scopes with the current set of scopes.
+ * @param otherScopes
+ */
+ ScopeSet.prototype.unionScopeSets = function (otherScopes) {
+ if (!otherScopes) {
+ throw ClientAuthError.createEmptyInputScopeSetError();
+ }
+ var unionScopes = new Set(); // Iterator in constructor not supported in IE11
+ otherScopes.scopes.forEach(function (scope) { return unionScopes.add(scope.toLowerCase()); });
+ this.scopes.forEach(function (scope) { return unionScopes.add(scope.toLowerCase()); });
+ return unionScopes;
+ };
+ /**
+ * Check if scopes intersect between this set and another.
+ * @param otherScopes
+ */
+ ScopeSet.prototype.intersectingScopeSets = function (otherScopes) {
+ if (!otherScopes) {
+ throw ClientAuthError.createEmptyInputScopeSetError();
+ }
+ // Do not allow OIDC scopes to be the only intersecting scopes
+ if (!otherScopes.containsOnlyOIDCScopes()) {
+ otherScopes.removeOIDCScopes();
+ }
+ var unionScopes = this.unionScopeSets(otherScopes);
+ var sizeOtherScopes = otherScopes.getScopeCount();
+ var sizeThisScopes = this.getScopeCount();
+ var sizeUnionScopes = unionScopes.size;
+ return sizeUnionScopes < (sizeThisScopes + sizeOtherScopes);
+ };
+ /**
+ * Returns size of set of scopes.
+ */
+ ScopeSet.prototype.getScopeCount = function () {
+ return this.scopes.size;
+ };
+ /**
+ * Returns the scopes as an array of string values
+ */
+ ScopeSet.prototype.asArray = function () {
+ var array = [];
+ this.scopes.forEach(function (val) { return array.push(val); });
+ return array;
+ };
+ /**
+ * Prints scopes into a space-delimited string
+ */
+ ScopeSet.prototype.printScopes = function () {
+ if (this.scopes) {
+ var scopeArr = this.asArray();
+ return scopeArr.join(" ");
+ }
+ return Constants.EMPTY_STRING;
+ };
+ /**
+ * Prints scopes into a space-delimited lower-case string (used for caching)
+ */
+ ScopeSet.prototype.printScopesLowerCase = function () {
+ return this.printScopes().toLowerCase();
+ };
+ return ScopeSet;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Function to build a client info object from server clientInfo string
+ * @param rawClientInfo
+ * @param crypto
+ */
+function buildClientInfo(rawClientInfo, crypto) {
+ if (StringUtils.isEmpty(rawClientInfo)) {
+ throw ClientAuthError.createClientInfoEmptyError();
+ }
+ try {
+ var decodedClientInfo = crypto.base64Decode(rawClientInfo);
+ return JSON.parse(decodedClientInfo);
+ }
+ catch (e) {
+ throw ClientAuthError.createClientInfoDecodingError(e.message);
+ }
+}
+/**
+ * Function to build a client info object from cached homeAccountId string
+ * @param homeAccountId
+ */
+function buildClientInfoFromHomeAccountId(homeAccountId) {
+ if (StringUtils.isEmpty(homeAccountId)) {
+ throw ClientAuthError.createClientInfoDecodingError("Home account ID was empty.");
+ }
+ var clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
+ return {
+ uid: clientInfoParts[0],
+ utid: clientInfoParts.length < 2 ? Constants.EMPTY_STRING : clientInfoParts[1]
+ };
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Authority types supported by MSAL.
+ */
+exports.AuthorityType = void 0;
+(function (AuthorityType) {
+ AuthorityType[AuthorityType["Default"] = 0] = "Default";
+ AuthorityType[AuthorityType["Adfs"] = 1] = "Adfs";
+ AuthorityType[AuthorityType["Dsts"] = 2] = "Dsts";
+ AuthorityType[AuthorityType["Ciam"] = 3] = "Ciam";
+})(exports.AuthorityType || (exports.AuthorityType = {}));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
+ *
+ * Key : Value Schema
+ *
+ * Key: --
+ *
+ * Value Schema:
+ * {
+ * homeAccountId: home account identifier for the auth scheme,
+ * environment: entity that issued the token, represented as a full host
+ * realm: Full tenant or organizational identifier that the account belongs to
+ * localAccountId: Original tenant-specific accountID, usually used for legacy cases
+ * username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
+ * authorityType: Accounts authority type as a string
+ * name: Full name for the account, including given name and family name,
+ * clientInfo: Full base64 encoded client info received from ESTS
+ * lastModificationTime: last time this entity was modified in the cache
+ * lastModificationApp:
+ * idTokenClaims: Object containing claims parsed from ID token
+ * nativeAccountId: Account identifier on the native device
+ * }
+ */
+var AccountEntity = /** @class */ (function () {
+ function AccountEntity() {
+ }
+ /**
+ * Generate Account Id key component as per the schema: -
+ */
+ AccountEntity.prototype.generateAccountId = function () {
+ var accountId = [this.homeAccountId, this.environment];
+ return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * Generate Account Cache Key as per the schema: --
+ */
+ AccountEntity.prototype.generateAccountKey = function () {
+ return AccountEntity.generateAccountCacheKey({
+ homeAccountId: this.homeAccountId,
+ environment: this.environment,
+ tenantId: this.realm,
+ username: this.username,
+ localAccountId: this.localAccountId
+ });
+ };
+ /**
+ * returns the type of the cache (in this case account)
+ */
+ AccountEntity.prototype.generateType = function () {
+ switch (this.authorityType) {
+ case exports.CacheAccountType.ADFS_ACCOUNT_TYPE:
+ return exports.CacheType.ADFS;
+ case exports.CacheAccountType.MSAV1_ACCOUNT_TYPE:
+ return exports.CacheType.MSA;
+ case exports.CacheAccountType.MSSTS_ACCOUNT_TYPE:
+ return exports.CacheType.MSSTS;
+ case exports.CacheAccountType.GENERIC_ACCOUNT_TYPE:
+ return exports.CacheType.GENERIC;
+ default: {
+ throw ClientAuthError.createUnexpectedAccountTypeError();
+ }
+ }
+ };
+ /**
+ * Returns the AccountInfo interface for this account.
+ */
+ AccountEntity.prototype.getAccountInfo = function () {
+ return {
+ homeAccountId: this.homeAccountId,
+ environment: this.environment,
+ tenantId: this.realm,
+ username: this.username,
+ localAccountId: this.localAccountId,
+ name: this.name,
+ idTokenClaims: this.idTokenClaims,
+ nativeAccountId: this.nativeAccountId
+ };
+ };
+ /**
+ * Generates account key from interface
+ * @param accountInterface
+ */
+ AccountEntity.generateAccountCacheKey = function (accountInterface) {
+ var accountKey = [
+ accountInterface.homeAccountId,
+ accountInterface.environment || Constants.EMPTY_STRING,
+ accountInterface.tenantId || Constants.EMPTY_STRING,
+ ];
+ return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
+ * @param clientInfo
+ * @param authority
+ * @param idToken
+ * @param policy
+ */
+ AccountEntity.createAccount = function (clientInfo, homeAccountId, idToken, authority, cloudGraphHostName, msGraphHost, environment, nativeAccountId) {
+ var _a, _b, _c, _d, _e, _f;
+ var account = new AccountEntity();
+ account.authorityType = exports.CacheAccountType.MSSTS_ACCOUNT_TYPE;
+ account.clientInfo = clientInfo;
+ account.homeAccountId = homeAccountId;
+ account.nativeAccountId = nativeAccountId;
+ var env = environment || (authority && authority.getPreferredCache());
+ if (!env) {
+ throw ClientAuthError.createInvalidCacheEnvironmentError();
+ }
+ account.environment = env;
+ // non AAD scenarios can have empty realm
+ account.realm = ((_a = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _a === void 0 ? void 0 : _a.tid) || Constants.EMPTY_STRING;
+ if (idToken) {
+ account.idTokenClaims = idToken.claims;
+ // How do you account for MSA CID here?
+ account.localAccountId = ((_b = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _b === void 0 ? void 0 : _b.oid) || ((_c = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _c === void 0 ? void 0 : _c.sub) || Constants.EMPTY_STRING;
+ /*
+ * In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
+ * In most cases it will contain a single email. This field should not be relied upon if a custom
+ * policy is configured to return more than 1 email.
+ */
+ var preferredUsername = (_d = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _d === void 0 ? void 0 : _d.preferred_username;
+ var email = ((_e = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _e === void 0 ? void 0 : _e.emails) ? idToken.claims.emails[0] : null;
+ account.username = preferredUsername || email || Constants.EMPTY_STRING;
+ account.name = (_f = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _f === void 0 ? void 0 : _f.name;
+ }
+ account.cloudGraphHostName = cloudGraphHostName;
+ account.msGraphHost = msGraphHost;
+ return account;
+ };
+ /**
+ * Builds non-AAD/ADFS account.
+ * @param authority
+ * @param idToken
+ */
+ AccountEntity.createGenericAccount = function (homeAccountId, idToken, authority, cloudGraphHostName, msGraphHost, environment) {
+ var _a, _b, _c, _d;
+ var account = new AccountEntity();
+ account.authorityType = (authority &&
+ authority.authorityType === exports.AuthorityType.Adfs) ? exports.CacheAccountType.ADFS_ACCOUNT_TYPE : exports.CacheAccountType.GENERIC_ACCOUNT_TYPE;
+ account.homeAccountId = homeAccountId;
+ // non AAD scenarios can have empty realm
+ account.realm = Constants.EMPTY_STRING;
+ var env = environment || authority && authority.getPreferredCache();
+ if (!env) {
+ throw ClientAuthError.createInvalidCacheEnvironmentError();
+ }
+ if (idToken) {
+ // How do you account for MSA CID here?
+ account.localAccountId = ((_a = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _a === void 0 ? void 0 : _a.oid) || ((_b = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _b === void 0 ? void 0 : _b.sub) || Constants.EMPTY_STRING;
+ // upn claim for most ADFS scenarios
+ account.username = ((_c = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _c === void 0 ? void 0 : _c.upn) || Constants.EMPTY_STRING;
+ account.name = ((_d = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _d === void 0 ? void 0 : _d.name) || Constants.EMPTY_STRING;
+ account.idTokenClaims = idToken === null || idToken === void 0 ? void 0 : idToken.claims;
+ }
+ account.environment = env;
+ account.cloudGraphHostName = cloudGraphHostName;
+ account.msGraphHost = msGraphHost;
+ /*
+ * add uniqueName to claims
+ * account.name = idToken.claims.uniqueName;
+ */
+ return account;
+ };
+ /**
+ * Generate HomeAccountId from server response
+ * @param serverClientInfo
+ * @param authType
+ */
+ AccountEntity.generateHomeAccountId = function (serverClientInfo, authType, logger, cryptoObj, idToken) {
+ var _a;
+ var accountId = ((_a = idToken === null || idToken === void 0 ? void 0 : idToken.claims) === null || _a === void 0 ? void 0 : _a.sub) ? idToken.claims.sub : Constants.EMPTY_STRING;
+ // since ADFS does not have tid and does not set client_info
+ if (authType === exports.AuthorityType.Adfs || authType === exports.AuthorityType.Dsts) {
+ return accountId;
+ }
+ // for cases where there is clientInfo
+ if (serverClientInfo) {
+ try {
+ var clientInfo = buildClientInfo(serverClientInfo, cryptoObj);
+ if (!StringUtils.isEmpty(clientInfo.uid) && !StringUtils.isEmpty(clientInfo.utid)) {
+ return "" + clientInfo.uid + Separators.CLIENT_INFO_SEPARATOR + clientInfo.utid;
+ }
+ }
+ catch (e) { }
+ }
+ // default to "sub" claim
+ logger.verbose("No client info in response");
+ return accountId;
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ AccountEntity.isAccountEntity = function (entity) {
+ if (!entity) {
+ return false;
+ }
+ return (entity.hasOwnProperty("homeAccountId") &&
+ entity.hasOwnProperty("environment") &&
+ entity.hasOwnProperty("realm") &&
+ entity.hasOwnProperty("localAccountId") &&
+ entity.hasOwnProperty("username") &&
+ entity.hasOwnProperty("authorityType"));
+ };
+ /**
+ * Helper function to determine whether 2 accountInfo objects represent the same account
+ * @param accountA
+ * @param accountB
+ * @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
+ */
+ AccountEntity.accountInfoIsEqual = function (accountA, accountB, compareClaims) {
+ if (!accountA || !accountB) {
+ return false;
+ }
+ var claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
+ if (compareClaims) {
+ var accountAClaims = (accountA.idTokenClaims || {});
+ var accountBClaims = (accountB.idTokenClaims || {});
+ // issued at timestamp and nonce are expected to change each time a new id token is acquired
+ claimsMatch = (accountAClaims.iat === accountBClaims.iat) &&
+ (accountAClaims.nonce === accountBClaims.nonce);
+ }
+ return (accountA.homeAccountId === accountB.homeAccountId) &&
+ (accountA.localAccountId === accountB.localAccountId) &&
+ (accountA.username === accountB.username) &&
+ (accountA.tenantId === accountB.tenantId) &&
+ (accountA.environment === accountB.environment) &&
+ (accountA.nativeAccountId === accountB.nativeAccountId) &&
+ claimsMatch;
+ };
+ return AccountEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * JWT Token representation class. Parses token string and generates claims object.
+ */
+var AuthToken = /** @class */ (function () {
+ function AuthToken(rawToken, crypto) {
+ if (StringUtils.isEmpty(rawToken)) {
+ throw ClientAuthError.createTokenNullOrEmptyError(rawToken);
+ }
+ this.rawToken = rawToken;
+ this.claims = AuthToken.extractTokenClaims(rawToken, crypto);
+ }
+ /**
+ * Extract token by decoding the rawToken
+ *
+ * @param encodedToken
+ */
+ AuthToken.extractTokenClaims = function (encodedToken, crypto) {
+ var decodedToken = StringUtils.decodeAuthToken(encodedToken);
+ // token will be decoded to get the username
+ try {
+ var base64TokenPayload = decodedToken.JWSPayload;
+ // base64Decode() should throw an error if there is an issue
+ var base64Decoded = crypto.base64Decode(base64TokenPayload);
+ return JSON.parse(base64Decoded);
+ }
+ catch (err) {
+ throw ClientAuthError.createTokenParsingError(err);
+ }
+ };
+ /**
+ * Determine if the token's max_age has transpired
+ */
+ AuthToken.checkMaxAge = function (authTime, maxAge) {
+ /*
+ * per https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
+ * To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access,
+ * provide a value of 0 for the max_age parameter and the AS will force a fresh login.
+ */
+ var fiveMinuteSkew = 300000; // five minutes in milliseconds
+ if ((maxAge === 0) || ((Date.now() - fiveMinuteSkew) > (authTime + maxAge))) {
+ throw ClientAuthError.createMaxAgeTranspiredError();
+ }
+ };
+ return AuthToken;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
+ */
+var CacheManager = /** @class */ (function () {
+ function CacheManager(clientId, cryptoImpl, logger) {
+ this.clientId = clientId;
+ this.cryptoImpl = cryptoImpl;
+ this.commonLogger = logger.clone(name, version);
+ }
+ /**
+ * Returns all accounts in cache
+ */
+ CacheManager.prototype.getAllAccounts = function () {
+ var _this = this;
+ var allAccountKeys = this.getAccountKeys();
+ if (allAccountKeys.length < 1) {
+ return [];
+ }
+ var accountEntities = allAccountKeys.reduce(function (accounts, key) {
+ var entity = _this.getAccount(key);
+ if (!entity) {
+ return accounts;
+ }
+ accounts.push(entity);
+ return accounts;
+ }, []);
+ if (accountEntities.length < 1) {
+ return [];
+ }
+ else {
+ var allAccounts = accountEntities.map(function (accountEntity) {
+ return _this.getAccountInfoFromEntity(accountEntity);
+ });
+ return allAccounts;
+ }
+ };
+ /**
+ * Gets accountInfo object based on provided filters
+ */
+ CacheManager.prototype.getAccountInfoFilteredBy = function (accountFilter) {
+ var allAccounts = this.getAccountsFilteredBy(accountFilter);
+ if (allAccounts.length > 0) {
+ return this.getAccountInfoFromEntity(allAccounts[0]);
+ }
+ else {
+ return null;
+ }
+ };
+ CacheManager.prototype.getAccountInfoFromEntity = function (accountEntity) {
+ var accountInfo = accountEntity.getAccountInfo();
+ var idToken = this.getIdToken(accountInfo);
+ if (idToken) {
+ accountInfo.idToken = idToken.secret;
+ accountInfo.idTokenClaims = new AuthToken(idToken.secret, this.cryptoImpl).claims;
+ }
+ return accountInfo;
+ };
+ /**
+ * saves a cache record
+ * @param cacheRecord
+ */
+ CacheManager.prototype.saveCacheRecord = function (cacheRecord) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ if (!cacheRecord) {
+ throw ClientAuthError.createNullOrUndefinedCacheRecord();
+ }
+ if (!!cacheRecord.account) {
+ this.setAccount(cacheRecord.account);
+ }
+ if (!!cacheRecord.idToken) {
+ this.setIdTokenCredential(cacheRecord.idToken);
+ }
+ if (!!!cacheRecord.accessToken) return [3 /*break*/, 2];
+ return [4 /*yield*/, this.saveAccessToken(cacheRecord.accessToken)];
+ case 1:
+ _a.sent();
+ _a.label = 2;
+ case 2:
+ if (!!cacheRecord.refreshToken) {
+ this.setRefreshTokenCredential(cacheRecord.refreshToken);
+ }
+ if (!!cacheRecord.appMetadata) {
+ this.setAppMetadata(cacheRecord.appMetadata);
+ }
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * saves access token credential
+ * @param credential
+ */
+ CacheManager.prototype.saveAccessToken = function (credential) {
+ return __awaiter(this, void 0, void 0, function () {
+ var accessTokenFilter, tokenKeys, currentScopes, removedAccessTokens;
+ var _this = this;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ accessTokenFilter = {
+ clientId: credential.clientId,
+ credentialType: credential.credentialType,
+ environment: credential.environment,
+ homeAccountId: credential.homeAccountId,
+ realm: credential.realm,
+ tokenType: credential.tokenType,
+ requestedClaimsHash: credential.requestedClaimsHash
+ };
+ tokenKeys = this.getTokenKeys();
+ currentScopes = ScopeSet.fromString(credential.target);
+ removedAccessTokens = [];
+ tokenKeys.accessToken.forEach(function (key) {
+ if (!_this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) {
+ return;
+ }
+ var tokenEntity = _this.getAccessTokenCredential(key);
+ if (tokenEntity && _this.credentialMatchesFilter(tokenEntity, accessTokenFilter)) {
+ var tokenScopeSet = ScopeSet.fromString(tokenEntity.target);
+ if (tokenScopeSet.intersectingScopeSets(currentScopes)) {
+ removedAccessTokens.push(_this.removeAccessToken(key));
+ }
+ }
+ });
+ return [4 /*yield*/, Promise.all(removedAccessTokens)];
+ case 1:
+ _a.sent();
+ this.setAccessTokenCredential(credential);
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * retrieve accounts matching all provided filters; if no filter is set, get all accounts
+ * not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared
+ * @param homeAccountId
+ * @param environment
+ * @param realm
+ */
+ CacheManager.prototype.getAccountsFilteredBy = function (accountFilter) {
+ var _this = this;
+ var allAccountKeys = this.getAccountKeys();
+ var matchingAccounts = [];
+ allAccountKeys.forEach(function (cacheKey) {
+ if (!_this.isAccountKey(cacheKey, accountFilter.homeAccountId, accountFilter.realm)) {
+ // Don't parse value if the key doesn't match the account filters
+ return;
+ }
+ var entity = _this.getAccount(cacheKey);
+ if (!entity) {
+ return;
+ }
+ if (!!accountFilter.homeAccountId && !_this.matchHomeAccountId(entity, accountFilter.homeAccountId)) {
+ return;
+ }
+ if (!!accountFilter.localAccountId && !_this.matchLocalAccountId(entity, accountFilter.localAccountId)) {
+ return;
+ }
+ if (!!accountFilter.username && !_this.matchUsername(entity, accountFilter.username)) {
+ return;
+ }
+ if (!!accountFilter.environment && !_this.matchEnvironment(entity, accountFilter.environment)) {
+ return;
+ }
+ if (!!accountFilter.realm && !_this.matchRealm(entity, accountFilter.realm)) {
+ return;
+ }
+ if (!!accountFilter.nativeAccountId && !_this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) {
+ return;
+ }
+ matchingAccounts.push(entity);
+ });
+ return matchingAccounts;
+ };
+ /**
+ * Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
+ * @param key
+ * @param homeAccountId
+ * @param tenantId
+ * @returns
+ */
+ CacheManager.prototype.isAccountKey = function (key, homeAccountId, tenantId) {
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
+ // Account cache keys contain 3 items separated by '-' (each item may also contain '-')
+ return false;
+ }
+ if (homeAccountId && !key.toLowerCase().includes(homeAccountId.toLowerCase())) {
+ return false;
+ }
+ if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
+ return false;
+ }
+ // Do not check environment as aliasing can cause false negatives
+ return true;
+ };
+ /**
+ * Returns true if the given key matches our credential key schema.
+ * @param key
+ */
+ CacheManager.prototype.isCredentialKey = function (key) {
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
+ // Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
+ return false;
+ }
+ var lowerCaseKey = key.toLowerCase();
+ // Credential keys must indicate what credential type they represent
+ if (lowerCaseKey.indexOf(exports.CredentialType.ID_TOKEN.toLowerCase()) === -1 &&
+ lowerCaseKey.indexOf(exports.CredentialType.ACCESS_TOKEN.toLowerCase()) === -1 &&
+ lowerCaseKey.indexOf(exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 &&
+ lowerCaseKey.indexOf(exports.CredentialType.REFRESH_TOKEN.toLowerCase()) === -1) {
+ return false;
+ }
+ if (lowerCaseKey.indexOf(exports.CredentialType.REFRESH_TOKEN.toLowerCase()) > -1) {
+ // Refresh tokens must contain the client id or family id
+ var clientIdValidation = "" + exports.CredentialType.REFRESH_TOKEN + Separators.CACHE_KEY_SEPARATOR + this.clientId + Separators.CACHE_KEY_SEPARATOR;
+ var familyIdValidation = "" + exports.CredentialType.REFRESH_TOKEN + Separators.CACHE_KEY_SEPARATOR + THE_FAMILY_ID + Separators.CACHE_KEY_SEPARATOR;
+ if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 && lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) {
+ return false;
+ }
+ }
+ else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
+ // Tokens must contain the clientId
+ return false;
+ }
+ return true;
+ };
+ /**
+ * Returns whether or not the given credential entity matches the filter
+ * @param entity
+ * @param filter
+ * @returns
+ */
+ CacheManager.prototype.credentialMatchesFilter = function (entity, filter) {
+ if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) {
+ return false;
+ }
+ if (!!filter.userAssertionHash && !this.matchUserAssertionHash(entity, filter.userAssertionHash)) {
+ return false;
+ }
+ /*
+ * homeAccountId can be undefined, and we want to filter out cached items that have a homeAccountId of ""
+ * because we don't want a client_credential request to return a cached token that has a homeAccountId
+ */
+ if ((typeof filter.homeAccountId === "string") && !this.matchHomeAccountId(entity, filter.homeAccountId)) {
+ return false;
+ }
+ if (!!filter.environment && !this.matchEnvironment(entity, filter.environment)) {
+ return false;
+ }
+ if (!!filter.realm && !this.matchRealm(entity, filter.realm)) {
+ return false;
+ }
+ if (!!filter.credentialType && !this.matchCredentialType(entity, filter.credentialType)) {
+ return false;
+ }
+ if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) {
+ return false;
+ }
+ /*
+ * idTokens do not have "target", target specific refreshTokens do exist for some types of authentication
+ * Resource specific refresh tokens case will be added when the support is deemed necessary
+ */
+ if (!!filter.target && !this.matchTarget(entity, filter.target)) {
+ return false;
+ }
+ // If request OR cached entity has requested Claims Hash, check if they match
+ if (filter.requestedClaimsHash || entity.requestedClaimsHash) {
+ // Don't match if either is undefined or they are different
+ if (entity.requestedClaimsHash !== filter.requestedClaimsHash) {
+ return false;
+ }
+ }
+ // Access Token with Auth Scheme specific matching
+ if (entity.credentialType === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) {
+ if (!!filter.tokenType && !this.matchTokenType(entity, filter.tokenType)) {
+ return false;
+ }
+ // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
+ if (filter.tokenType === exports.AuthenticationScheme.SSH) {
+ if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ /**
+ * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata
+ * @param filter
+ */
+ CacheManager.prototype.getAppMetadataFilteredBy = function (filter) {
+ return this.getAppMetadataFilteredByInternal(filter.environment, filter.clientId);
+ };
+ /**
+ * Support function to help match appMetadata
+ * @param environment
+ * @param clientId
+ */
+ CacheManager.prototype.getAppMetadataFilteredByInternal = function (environment, clientId) {
+ var _this = this;
+ var allCacheKeys = this.getKeys();
+ var matchingAppMetadata = {};
+ allCacheKeys.forEach(function (cacheKey) {
+ // don't parse any non-appMetadata type cache entities
+ if (!_this.isAppMetadata(cacheKey)) {
+ return;
+ }
+ // Attempt retrieval
+ var entity = _this.getAppMetadata(cacheKey);
+ if (!entity) {
+ return;
+ }
+ if (!!environment && !_this.matchEnvironment(entity, environment)) {
+ return;
+ }
+ if (!!clientId && !_this.matchClientId(entity, clientId)) {
+ return;
+ }
+ matchingAppMetadata[cacheKey] = entity;
+ });
+ return matchingAppMetadata;
+ };
+ /**
+ * retrieve authorityMetadata that contains a matching alias
+ * @param filter
+ */
+ CacheManager.prototype.getAuthorityMetadataByAlias = function (host) {
+ var _this = this;
+ var allCacheKeys = this.getAuthorityMetadataKeys();
+ var matchedEntity = null;
+ allCacheKeys.forEach(function (cacheKey) {
+ // don't parse any non-authorityMetadata type cache entities
+ if (!_this.isAuthorityMetadata(cacheKey) || cacheKey.indexOf(_this.clientId) === -1) {
+ return;
+ }
+ // Attempt retrieval
+ var entity = _this.getAuthorityMetadata(cacheKey);
+ if (!entity) {
+ return;
+ }
+ if (entity.aliases.indexOf(host) === -1) {
+ return;
+ }
+ matchedEntity = entity;
+ });
+ return matchedEntity;
+ };
+ /**
+ * Removes all accounts and related tokens from cache.
+ */
+ CacheManager.prototype.removeAllAccounts = function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var allAccountKeys, removedAccounts;
+ var _this = this;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ allAccountKeys = this.getAccountKeys();
+ removedAccounts = [];
+ allAccountKeys.forEach(function (cacheKey) {
+ removedAccounts.push(_this.removeAccount(cacheKey));
+ });
+ return [4 /*yield*/, Promise.all(removedAccounts)];
+ case 1:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Removes the account and related tokens for a given account key
+ * @param account
+ */
+ CacheManager.prototype.removeAccount = function (accountKey) {
+ return __awaiter(this, void 0, void 0, function () {
+ var account;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ account = this.getAccount(accountKey);
+ if (!account) {
+ throw ClientAuthError.createNoAccountFoundError();
+ }
+ return [4 /*yield*/, this.removeAccountContext(account)];
+ case 1:
+ _a.sent();
+ this.removeItem(accountKey);
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Removes credentials associated with the provided account
+ * @param account
+ */
+ CacheManager.prototype.removeAccountContext = function (account) {
+ return __awaiter(this, void 0, void 0, function () {
+ var allTokenKeys, accountId, removedCredentials;
+ var _this = this;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ allTokenKeys = this.getTokenKeys();
+ accountId = account.generateAccountId();
+ removedCredentials = [];
+ allTokenKeys.idToken.forEach(function (key) {
+ if (key.indexOf(accountId) === 0) {
+ _this.removeIdToken(key);
+ }
+ });
+ allTokenKeys.accessToken.forEach(function (key) {
+ if (key.indexOf(accountId) === 0) {
+ removedCredentials.push(_this.removeAccessToken(key));
+ }
+ });
+ allTokenKeys.refreshToken.forEach(function (key) {
+ if (key.indexOf(accountId) === 0) {
+ _this.removeRefreshToken(key);
+ }
+ });
+ return [4 /*yield*/, Promise.all(removedCredentials)];
+ case 1:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * returns a boolean if the given credential is removed
+ * @param credential
+ */
+ CacheManager.prototype.removeAccessToken = function (key) {
+ return __awaiter(this, void 0, void 0, function () {
+ var credential, accessTokenWithAuthSchemeEntity, kid;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ credential = this.getAccessTokenCredential(key);
+ if (!credential) {
+ return [2 /*return*/];
+ }
+ if (!(credential.credentialType.toLowerCase() === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase())) return [3 /*break*/, 4];
+ if (!(credential.tokenType === exports.AuthenticationScheme.POP)) return [3 /*break*/, 4];
+ accessTokenWithAuthSchemeEntity = credential;
+ kid = accessTokenWithAuthSchemeEntity.keyId;
+ if (!kid) return [3 /*break*/, 4];
+ _a.label = 1;
+ case 1:
+ _a.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, this.cryptoImpl.removeTokenBindingKey(kid)];
+ case 2:
+ _a.sent();
+ return [3 /*break*/, 4];
+ case 3:
+ _a.sent();
+ throw ClientAuthError.createBindingKeyNotRemovedError();
+ case 4: return [2 /*return*/, this.removeItem(key)];
+ }
+ });
+ });
+ };
+ /**
+ * Removes all app metadata objects from cache.
+ */
+ CacheManager.prototype.removeAppMetadata = function () {
+ var _this = this;
+ var allCacheKeys = this.getKeys();
+ allCacheKeys.forEach(function (cacheKey) {
+ if (_this.isAppMetadata(cacheKey)) {
+ _this.removeItem(cacheKey);
+ }
+ });
+ return true;
+ };
+ /**
+ * Retrieve the cached credentials into a cacherecord
+ * @param account
+ * @param clientId
+ * @param scopes
+ * @param environment
+ * @param authScheme
+ */
+ CacheManager.prototype.readCacheRecord = function (account, request, environment) {
+ var tokenKeys = this.getTokenKeys();
+ var cachedAccount = this.readAccountFromCache(account);
+ var cachedIdToken = this.getIdToken(account, tokenKeys);
+ var cachedAccessToken = this.getAccessToken(account, request, tokenKeys);
+ var cachedRefreshToken = this.getRefreshToken(account, false, tokenKeys);
+ var cachedAppMetadata = this.readAppMetadataFromCache(environment);
+ if (cachedAccount && cachedIdToken) {
+ cachedAccount.idTokenClaims = new AuthToken(cachedIdToken.secret, this.cryptoImpl).claims;
+ }
+ return {
+ account: cachedAccount,
+ idToken: cachedIdToken,
+ accessToken: cachedAccessToken,
+ refreshToken: cachedRefreshToken,
+ appMetadata: cachedAppMetadata,
+ };
+ };
+ /**
+ * Retrieve AccountEntity from cache
+ * @param account
+ */
+ CacheManager.prototype.readAccountFromCache = function (account) {
+ var accountKey = AccountEntity.generateAccountCacheKey(account);
+ return this.getAccount(accountKey);
+ };
+ /**
+ * Retrieve IdTokenEntity from cache
+ * @param clientId
+ * @param account
+ * @param inputRealm
+ */
+ CacheManager.prototype.getIdToken = function (account, tokenKeys) {
+ this.commonLogger.trace("CacheManager - getIdToken called");
+ var idTokenFilter = {
+ homeAccountId: account.homeAccountId,
+ environment: account.environment,
+ credentialType: exports.CredentialType.ID_TOKEN,
+ clientId: this.clientId,
+ realm: account.tenantId,
+ };
+ var idTokens = this.getIdTokensByFilter(idTokenFilter, tokenKeys);
+ var numIdTokens = idTokens.length;
+ if (numIdTokens < 1) {
+ this.commonLogger.info("CacheManager:getIdToken - No token found");
+ return null;
+ }
+ else if (numIdTokens > 1) {
+ throw ClientAuthError.createMultipleMatchingTokensInCacheError();
+ }
+ this.commonLogger.info("CacheManager:getIdToken - Returning id token");
+ return idTokens[0];
+ };
+ /**
+ * Gets all idTokens matching the given filter
+ * @param filter
+ * @returns
+ */
+ CacheManager.prototype.getIdTokensByFilter = function (filter, tokenKeys) {
+ var _this = this;
+ var idTokenKeys = tokenKeys && tokenKeys.idToken || this.getTokenKeys().idToken;
+ var idTokens = [];
+ idTokenKeys.forEach(function (key) {
+ if (!_this.idTokenKeyMatchesFilter(key, __assign({ clientId: _this.clientId }, filter))) {
+ return;
+ }
+ var idToken = _this.getIdTokenCredential(key);
+ if (idToken && _this.credentialMatchesFilter(idToken, filter)) {
+ idTokens.push(idToken);
+ }
+ });
+ return idTokens;
+ };
+ /**
+ * Validate the cache key against filter before retrieving and parsing cache value
+ * @param key
+ * @param filter
+ * @returns
+ */
+ CacheManager.prototype.idTokenKeyMatchesFilter = function (inputKey, filter) {
+ var key = inputKey.toLowerCase();
+ if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
+ return false;
+ }
+ return true;
+ };
+ /**
+ * Removes idToken from the cache
+ * @param key
+ */
+ CacheManager.prototype.removeIdToken = function (key) {
+ this.removeItem(key);
+ };
+ /**
+ * Removes refresh token from the cache
+ * @param key
+ */
+ CacheManager.prototype.removeRefreshToken = function (key) {
+ this.removeItem(key);
+ };
+ /**
+ * Retrieve AccessTokenEntity from cache
+ * @param clientId
+ * @param account
+ * @param scopes
+ * @param authScheme
+ */
+ CacheManager.prototype.getAccessToken = function (account, request, tokenKeys) {
+ var _this = this;
+ this.commonLogger.trace("CacheManager - getAccessToken called");
+ var scopes = ScopeSet.createSearchScopes(request.scopes);
+ var authScheme = request.authenticationScheme || exports.AuthenticationScheme.BEARER;
+ /*
+ * Distinguish between Bearer and PoP/SSH token cache types
+ * Cast to lowercase to handle "bearer" from ADFS
+ */
+ var credentialType = (authScheme && authScheme.toLowerCase() !== exports.AuthenticationScheme.BEARER.toLowerCase()) ? exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : exports.CredentialType.ACCESS_TOKEN;
+ var accessTokenFilter = {
+ homeAccountId: account.homeAccountId,
+ environment: account.environment,
+ credentialType: credentialType,
+ clientId: this.clientId,
+ realm: account.tenantId,
+ target: scopes,
+ tokenType: authScheme,
+ keyId: request.sshKid,
+ requestedClaimsHash: request.requestedClaimsHash,
+ };
+ var accessTokenKeys = tokenKeys && tokenKeys.accessToken || this.getTokenKeys().accessToken;
+ var accessTokens = [];
+ accessTokenKeys.forEach(function (key) {
+ // Validate key
+ if (_this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) {
+ var accessToken = _this.getAccessTokenCredential(key);
+ // Validate value
+ if (accessToken && _this.credentialMatchesFilter(accessToken, accessTokenFilter)) {
+ accessTokens.push(accessToken);
+ }
+ }
+ });
+ var numAccessTokens = accessTokens.length;
+ if (numAccessTokens < 1) {
+ this.commonLogger.info("CacheManager:getAccessToken - No token found");
+ return null;
+ }
+ else if (numAccessTokens > 1) {
+ throw ClientAuthError.createMultipleMatchingTokensInCacheError();
+ }
+ this.commonLogger.info("CacheManager:getAccessToken - Returning access token");
+ return accessTokens[0];
+ };
+ /**
+ * Validate the cache key against filter before retrieving and parsing cache value
+ * @param key
+ * @param filter
+ * @param keyMustContainAllScopes
+ * @returns
+ */
+ CacheManager.prototype.accessTokenKeyMatchesFilter = function (inputKey, filter, keyMustContainAllScopes) {
+ var key = inputKey.toLowerCase();
+ if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.requestedClaimsHash && key.indexOf(filter.requestedClaimsHash.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.target) {
+ var scopes = filter.target.asArray();
+ for (var i = 0; i < scopes.length; i++) {
+ if (keyMustContainAllScopes && !key.includes(scopes[i].toLowerCase())) {
+ // When performing a cache lookup a missing scope would be a cache miss
+ return false;
+ }
+ else if (!keyMustContainAllScopes && key.includes(scopes[i].toLowerCase())) {
+ // When performing a cache write, any token with a subset of requested scopes should be replaced
+ return true;
+ }
+ }
+ }
+ return true;
+ };
+ /**
+ * Gets all access tokens matching the filter
+ * @param filter
+ * @returns
+ */
+ CacheManager.prototype.getAccessTokensByFilter = function (filter) {
+ var _this = this;
+ var tokenKeys = this.getTokenKeys();
+ var accessTokens = [];
+ tokenKeys.accessToken.forEach(function (key) {
+ if (!_this.accessTokenKeyMatchesFilter(key, filter, true)) {
+ return;
+ }
+ var accessToken = _this.getAccessTokenCredential(key);
+ if (accessToken && _this.credentialMatchesFilter(accessToken, filter)) {
+ accessTokens.push(accessToken);
+ }
+ });
+ return accessTokens;
+ };
+ /**
+ * Helper to retrieve the appropriate refresh token from cache
+ * @param clientId
+ * @param account
+ * @param familyRT
+ */
+ CacheManager.prototype.getRefreshToken = function (account, familyRT, tokenKeys) {
+ var _this = this;
+ this.commonLogger.trace("CacheManager - getRefreshToken called");
+ var id = familyRT ? THE_FAMILY_ID : undefined;
+ var refreshTokenFilter = {
+ homeAccountId: account.homeAccountId,
+ environment: account.environment,
+ credentialType: exports.CredentialType.REFRESH_TOKEN,
+ clientId: this.clientId,
+ familyId: id,
+ };
+ var refreshTokenKeys = tokenKeys && tokenKeys.refreshToken || this.getTokenKeys().refreshToken;
+ var refreshTokens = [];
+ refreshTokenKeys.forEach(function (key) {
+ // Validate key
+ if (_this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) {
+ var refreshToken = _this.getRefreshTokenCredential(key);
+ // Validate value
+ if (refreshToken && _this.credentialMatchesFilter(refreshToken, refreshTokenFilter)) {
+ refreshTokens.push(refreshToken);
+ }
+ }
+ });
+ var numRefreshTokens = refreshTokens.length;
+ if (numRefreshTokens < 1) {
+ this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found.");
+ return null;
+ }
+ // address the else case after remove functions address environment aliases
+ this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token");
+ return refreshTokens[0];
+ };
+ /**
+ * Validate the cache key against filter before retrieving and parsing cache value
+ * @param key
+ * @param filter
+ */
+ CacheManager.prototype.refreshTokenKeyMatchesFilter = function (inputKey, filter) {
+ var key = inputKey.toLowerCase();
+ if (filter.familyId && key.indexOf(filter.familyId.toLowerCase()) === -1) {
+ return false;
+ }
+ // If familyId is used, clientId is not in the key
+ if (!filter.familyId && filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
+ return false;
+ }
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
+ return false;
+ }
+ return true;
+ };
+ /**
+ * Retrieve AppMetadataEntity from cache
+ */
+ CacheManager.prototype.readAppMetadataFromCache = function (environment) {
+ var appMetadataFilter = {
+ environment: environment,
+ clientId: this.clientId,
+ };
+ var appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter);
+ var appMetadataEntries = Object.keys(appMetadata).map(function (key) { return appMetadata[key]; });
+ var numAppMetadata = appMetadataEntries.length;
+ if (numAppMetadata < 1) {
+ return null;
+ }
+ else if (numAppMetadata > 1) {
+ throw ClientAuthError.createMultipleMatchingAppMetadataInCacheError();
+ }
+ return appMetadataEntries[0];
+ };
+ /**
+ * Return the family_id value associated with FOCI
+ * @param environment
+ * @param clientId
+ */
+ CacheManager.prototype.isAppMetadataFOCI = function (environment) {
+ var appMetadata = this.readAppMetadataFromCache(environment);
+ return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID);
+ };
+ /**
+ * helper to match account ids
+ * @param value
+ * @param homeAccountId
+ */
+ CacheManager.prototype.matchHomeAccountId = function (entity, homeAccountId) {
+ return !!((typeof entity.homeAccountId === "string") && (homeAccountId === entity.homeAccountId));
+ };
+ /**
+ * helper to match account ids
+ * @param entity
+ * @param localAccountId
+ * @returns
+ */
+ CacheManager.prototype.matchLocalAccountId = function (entity, localAccountId) {
+ return !!((typeof entity.localAccountId === "string") && (localAccountId === entity.localAccountId));
+ };
+ /**
+ * helper to match usernames
+ * @param entity
+ * @param username
+ * @returns
+ */
+ CacheManager.prototype.matchUsername = function (entity, username) {
+ return !!((typeof entity.username === "string") && (username.toLowerCase() === entity.username.toLowerCase()));
+ };
+ /**
+ * helper to match assertion
+ * @param value
+ * @param oboAssertion
+ */
+ CacheManager.prototype.matchUserAssertionHash = function (entity, userAssertionHash) {
+ return !!(entity.userAssertionHash && userAssertionHash === entity.userAssertionHash);
+ };
+ /**
+ * helper to match environment
+ * @param value
+ * @param environment
+ */
+ CacheManager.prototype.matchEnvironment = function (entity, environment) {
+ var cloudMetadata = this.getAuthorityMetadataByAlias(environment);
+ if (cloudMetadata && cloudMetadata.aliases.indexOf(entity.environment) > -1) {
+ return true;
+ }
+ return false;
+ };
+ /**
+ * helper to match credential type
+ * @param entity
+ * @param credentialType
+ */
+ CacheManager.prototype.matchCredentialType = function (entity, credentialType) {
+ return (entity.credentialType && credentialType.toLowerCase() === entity.credentialType.toLowerCase());
+ };
+ /**
+ * helper to match client ids
+ * @param entity
+ * @param clientId
+ */
+ CacheManager.prototype.matchClientId = function (entity, clientId) {
+ return !!(entity.clientId && clientId === entity.clientId);
+ };
+ /**
+ * helper to match family ids
+ * @param entity
+ * @param familyId
+ */
+ CacheManager.prototype.matchFamilyId = function (entity, familyId) {
+ return !!(entity.familyId && familyId === entity.familyId);
+ };
+ /**
+ * helper to match realm
+ * @param entity
+ * @param realm
+ */
+ CacheManager.prototype.matchRealm = function (entity, realm) {
+ return !!(entity.realm && realm === entity.realm);
+ };
+ /**
+ * helper to match nativeAccountId
+ * @param entity
+ * @param nativeAccountId
+ * @returns boolean indicating the match result
+ */
+ CacheManager.prototype.matchNativeAccountId = function (entity, nativeAccountId) {
+ return !!(entity.nativeAccountId && nativeAccountId === entity.nativeAccountId);
+ };
+ /**
+ * Returns true if the target scopes are a subset of the current entity's scopes, false otherwise.
+ * @param entity
+ * @param target
+ */
+ CacheManager.prototype.matchTarget = function (entity, target) {
+ var isNotAccessTokenCredential = (entity.credentialType !== exports.CredentialType.ACCESS_TOKEN && entity.credentialType !== exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME);
+ if (isNotAccessTokenCredential || !entity.target) {
+ return false;
+ }
+ var entityScopeSet = ScopeSet.fromString(entity.target);
+ return entityScopeSet.containsScopeSet(target);
+ };
+ /**
+ * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise
+ * @param entity
+ * @param tokenType
+ */
+ CacheManager.prototype.matchTokenType = function (entity, tokenType) {
+ return !!(entity.tokenType && entity.tokenType === tokenType);
+ };
+ /**
+ * Returns true if the credential's keyId matches the one in the request, false otherwise
+ * @param entity
+ * @param tokenType
+ */
+ CacheManager.prototype.matchKeyId = function (entity, keyId) {
+ return !!(entity.keyId && entity.keyId === keyId);
+ };
+ /**
+ * returns if a given cache entity is of the type appmetadata
+ * @param key
+ */
+ CacheManager.prototype.isAppMetadata = function (key) {
+ return key.indexOf(APP_METADATA) !== -1;
+ };
+ /**
+ * returns if a given cache entity is of the type authoritymetadata
+ * @param key
+ */
+ CacheManager.prototype.isAuthorityMetadata = function (key) {
+ return key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) !== -1;
+ };
+ /**
+ * returns cache key used for cloud instance metadata
+ */
+ CacheManager.prototype.generateAuthorityMetadataCacheKey = function (authority) {
+ return AUTHORITY_METADATA_CONSTANTS.CACHE_KEY + "-" + this.clientId + "-" + authority;
+ };
+ /**
+ * Helper to convert serialized data to object
+ * @param obj
+ * @param json
+ */
+ CacheManager.toObject = function (obj, json) {
+ for (var propertyName in json) {
+ obj[propertyName] = json[propertyName];
+ }
+ return obj;
+ };
+ return CacheManager;
+}());
+var DefaultStorageClass = /** @class */ (function (_super) {
+ __extends(DefaultStorageClass, _super);
+ function DefaultStorageClass() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ DefaultStorageClass.prototype.setAccount = function () {
+ var notImplErr = "Storage interface - setAccount() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAccount = function () {
+ var notImplErr = "Storage interface - getAccount() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setIdTokenCredential = function () {
+ var notImplErr = "Storage interface - setIdTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getIdTokenCredential = function () {
+ var notImplErr = "Storage interface - getIdTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setAccessTokenCredential = function () {
+ var notImplErr = "Storage interface - setAccessTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAccessTokenCredential = function () {
+ var notImplErr = "Storage interface - getAccessTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setRefreshTokenCredential = function () {
+ var notImplErr = "Storage interface - setRefreshTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getRefreshTokenCredential = function () {
+ var notImplErr = "Storage interface - getRefreshTokenCredential() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setAppMetadata = function () {
+ var notImplErr = "Storage interface - setAppMetadata() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAppMetadata = function () {
+ var notImplErr = "Storage interface - getAppMetadata() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setServerTelemetry = function () {
+ var notImplErr = "Storage interface - setServerTelemetry() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getServerTelemetry = function () {
+ var notImplErr = "Storage interface - getServerTelemetry() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setAuthorityMetadata = function () {
+ var notImplErr = "Storage interface - setAuthorityMetadata() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAuthorityMetadata = function () {
+ var notImplErr = "Storage interface - getAuthorityMetadata() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAuthorityMetadataKeys = function () {
+ var notImplErr = "Storage interface - getAuthorityMetadataKeys() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.setThrottlingCache = function () {
+ var notImplErr = "Storage interface - setThrottlingCache() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getThrottlingCache = function () {
+ var notImplErr = "Storage interface - getThrottlingCache() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.removeItem = function () {
+ var notImplErr = "Storage interface - removeItem() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.containsKey = function () {
+ var notImplErr = "Storage interface - containsKey() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getKeys = function () {
+ var notImplErr = "Storage interface - getKeys() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getAccountKeys = function () {
+ var notImplErr = "Storage interface - getAccountKeys() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.getTokenKeys = function () {
+ var notImplErr = "Storage interface - getTokenKeys() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ DefaultStorageClass.prototype.clear = function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Storage interface - clear() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ };
+ DefaultStorageClass.prototype.updateCredentialCacheKey = function () {
+ var notImplErr = "Storage interface - updateCredentialCacheKey() has not been implemented for the cacheStorage interface.";
+ throw AuthError.createUnexpectedError(notImplErr);
+ };
+ return DefaultStorageClass;
+}(CacheManager));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+// Token renewal offset default in seconds
+var DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
+var DEFAULT_SYSTEM_OPTIONS = {
+ tokenRenewalOffsetSeconds: DEFAULT_TOKEN_RENEWAL_OFFSET_SEC,
+ preventCorsPreflight: false
+};
+var DEFAULT_LOGGER_IMPLEMENTATION = {
+ loggerCallback: function () {
+ // allow users to not set loggerCallback
+ },
+ piiLoggingEnabled: false,
+ logLevel: exports.LogLevel.Info,
+ correlationId: Constants.EMPTY_STRING
+};
+var DEFAULT_CACHE_OPTIONS = {
+ claimsBasedCachingEnabled: true
+};
+var DEFAULT_NETWORK_IMPLEMENTATION = {
+ sendGetRequestAsync: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Network interface - sendGetRequestAsync() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ },
+ sendPostRequestAsync: function () {
+ return __awaiter(this, void 0, void 0, function () {
+ var notImplErr;
+ return __generator(this, function (_a) {
+ notImplErr = "Network interface - sendPostRequestAsync() has not been implemented";
+ throw AuthError.createUnexpectedError(notImplErr);
+ });
+ });
+ }
+};
+var DEFAULT_LIBRARY_INFO = {
+ sku: Constants.SKU,
+ version: version,
+ cpu: Constants.EMPTY_STRING,
+ os: Constants.EMPTY_STRING
+};
+var DEFAULT_CLIENT_CREDENTIALS = {
+ clientSecret: Constants.EMPTY_STRING,
+ clientAssertion: undefined
+};
+var DEFAULT_AZURE_CLOUD_OPTIONS = {
+ azureCloudInstance: exports.AzureCloudInstance.None,
+ tenant: "" + Constants.DEFAULT_COMMON_TENANT
+};
+var DEFAULT_TELEMETRY_OPTIONS = {
+ application: {
+ appName: "",
+ appVersion: ""
+ }
+};
+/**
+ * Function that sets the default options when not explicitly configured from app developer
+ *
+ * @param Configuration
+ *
+ * @returns Configuration
+ */
+function buildClientConfiguration(_a) {
+ var userAuthOptions = _a.authOptions, userSystemOptions = _a.systemOptions, userLoggerOption = _a.loggerOptions, userCacheOptions = _a.cacheOptions, storageImplementation = _a.storageInterface, networkImplementation = _a.networkInterface, cryptoImplementation = _a.cryptoInterface, clientCredentials = _a.clientCredentials, libraryInfo = _a.libraryInfo, telemetry = _a.telemetry, serverTelemetryManager = _a.serverTelemetryManager, persistencePlugin = _a.persistencePlugin, serializableCache = _a.serializableCache;
+ var loggerOptions = __assign(__assign({}, DEFAULT_LOGGER_IMPLEMENTATION), userLoggerOption);
+ return {
+ authOptions: buildAuthOptions(userAuthOptions),
+ systemOptions: __assign(__assign({}, DEFAULT_SYSTEM_OPTIONS), userSystemOptions),
+ loggerOptions: loggerOptions,
+ cacheOptions: __assign(__assign({}, DEFAULT_CACHE_OPTIONS), userCacheOptions),
+ storageInterface: storageImplementation || new DefaultStorageClass(userAuthOptions.clientId, DEFAULT_CRYPTO_IMPLEMENTATION, new Logger(loggerOptions)),
+ networkInterface: networkImplementation || DEFAULT_NETWORK_IMPLEMENTATION,
+ cryptoInterface: cryptoImplementation || DEFAULT_CRYPTO_IMPLEMENTATION,
+ clientCredentials: clientCredentials || DEFAULT_CLIENT_CREDENTIALS,
+ libraryInfo: __assign(__assign({}, DEFAULT_LIBRARY_INFO), libraryInfo),
+ telemetry: __assign(__assign({}, DEFAULT_TELEMETRY_OPTIONS), telemetry),
+ serverTelemetryManager: serverTelemetryManager || null,
+ persistencePlugin: persistencePlugin || null,
+ serializableCache: serializableCache || null,
+ };
+}
+/**
+ * Construct authoptions from the client and platform passed values
+ * @param authOptions
+ */
+function buildAuthOptions(authOptions) {
+ return __assign({ clientCapabilities: [], azureCloudOptions: DEFAULT_AZURE_CLOUD_OPTIONS, skipAuthorityMetadataCache: false }, authOptions);
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Error thrown when there is an error with the server code, for example, unavailability.
+ */
+var ServerError = /** @class */ (function (_super) {
+ __extends(ServerError, _super);
+ function ServerError(errorCode, errorMessage, subError) {
+ var _this = _super.call(this, errorCode, errorMessage, subError) || this;
+ _this.name = "ServerError";
+ Object.setPrototypeOf(_this, ServerError.prototype);
+ return _this;
+ }
+ return ServerError;
+}(AuthError));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var ThrottlingUtils = /** @class */ (function () {
+ function ThrottlingUtils() {
+ }
+ /**
+ * Prepares a RequestThumbprint to be stored as a key.
+ * @param thumbprint
+ */
+ ThrottlingUtils.generateThrottlingStorageKey = function (thumbprint) {
+ return ThrottlingConstants.THROTTLING_PREFIX + "." + JSON.stringify(thumbprint);
+ };
+ /**
+ * Performs necessary throttling checks before a network request.
+ * @param cacheManager
+ * @param thumbprint
+ */
+ ThrottlingUtils.preProcess = function (cacheManager, thumbprint) {
+ var _a;
+ var key = ThrottlingUtils.generateThrottlingStorageKey(thumbprint);
+ var value = cacheManager.getThrottlingCache(key);
+ if (value) {
+ if (value.throttleTime < Date.now()) {
+ cacheManager.removeItem(key);
+ return;
+ }
+ throw new ServerError(((_a = value.errorCodes) === null || _a === void 0 ? void 0 : _a.join(" ")) || Constants.EMPTY_STRING, value.errorMessage, value.subError);
+ }
+ };
+ /**
+ * Performs necessary throttling checks after a network request.
+ * @param cacheManager
+ * @param thumbprint
+ * @param response
+ */
+ ThrottlingUtils.postProcess = function (cacheManager, thumbprint, response) {
+ if (ThrottlingUtils.checkResponseStatus(response) || ThrottlingUtils.checkResponseForRetryAfter(response)) {
+ var thumbprintValue = {
+ throttleTime: ThrottlingUtils.calculateThrottleTime(parseInt(response.headers[exports.HeaderNames.RETRY_AFTER])),
+ error: response.body.error,
+ errorCodes: response.body.error_codes,
+ errorMessage: response.body.error_description,
+ subError: response.body.suberror
+ };
+ cacheManager.setThrottlingCache(ThrottlingUtils.generateThrottlingStorageKey(thumbprint), thumbprintValue);
+ }
+ };
+ /**
+ * Checks a NetworkResponse object's status codes against 429 or 5xx
+ * @param response
+ */
+ ThrottlingUtils.checkResponseStatus = function (response) {
+ return response.status === 429 || response.status >= 500 && response.status < 600;
+ };
+ /**
+ * Checks a NetworkResponse object's RetryAfter header
+ * @param response
+ */
+ ThrottlingUtils.checkResponseForRetryAfter = function (response) {
+ if (response.headers) {
+ return response.headers.hasOwnProperty(exports.HeaderNames.RETRY_AFTER) && (response.status < 200 || response.status >= 300);
+ }
+ return false;
+ };
+ /**
+ * Calculates the Unix-time value for a throttle to expire given throttleTime in seconds.
+ * @param throttleTime
+ */
+ ThrottlingUtils.calculateThrottleTime = function (throttleTime) {
+ var time = throttleTime <= 0 ? 0 : throttleTime;
+ var currentSeconds = Date.now() / 1000;
+ return Math.floor(Math.min(currentSeconds + (time || ThrottlingConstants.DEFAULT_THROTTLE_TIME_SECONDS), currentSeconds + ThrottlingConstants.DEFAULT_MAX_THROTTLE_TIME_SECONDS) * 1000);
+ };
+ ThrottlingUtils.removeThrottle = function (cacheManager, clientId, request, homeAccountIdentifier) {
+ var thumbprint = {
+ clientId: clientId,
+ authority: request.authority,
+ scopes: request.scopes,
+ homeAccountIdentifier: homeAccountIdentifier,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ var key = this.generateThrottlingStorageKey(thumbprint);
+ cacheManager.removeItem(key);
+ };
+ return ThrottlingUtils;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var NetworkManager = /** @class */ (function () {
+ function NetworkManager(networkClient, cacheManager) {
+ this.networkClient = networkClient;
+ this.cacheManager = cacheManager;
+ }
+ /**
+ * Wraps sendPostRequestAsync with necessary preflight and postflight logic
+ * @param thumbprint
+ * @param tokenEndpoint
+ * @param options
+ */
+ NetworkManager.prototype.sendPostRequest = function (thumbprint, tokenEndpoint, options) {
+ return __awaiter(this, void 0, void 0, function () {
+ var response, e_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ ThrottlingUtils.preProcess(this.cacheManager, thumbprint);
+ _a.label = 1;
+ case 1:
+ _a.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, this.networkClient.sendPostRequestAsync(tokenEndpoint, options)];
+ case 2:
+ response = _a.sent();
+ return [3 /*break*/, 4];
+ case 3:
+ e_1 = _a.sent();
+ if (e_1 instanceof AuthError) {
+ throw e_1;
+ }
+ else {
+ throw ClientAuthError.createNetworkError(tokenEndpoint, e_1);
+ }
+ case 4:
+ ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response);
+ return [2 /*return*/, response];
+ }
+ });
+ });
+ };
+ return NetworkManager;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+exports.CcsCredentialType = void 0;
+(function (CcsCredentialType) {
+ CcsCredentialType["HOME_ACCOUNT_ID"] = "home_account_id";
+ CcsCredentialType["UPN"] = "UPN";
+})(exports.CcsCredentialType || (exports.CcsCredentialType = {}));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Validates server consumable params from the "request" objects
+ */
+var RequestValidator = /** @class */ (function () {
+ function RequestValidator() {
+ }
+ /**
+ * Utility to check if the `redirectUri` in the request is a non-null value
+ * @param redirectUri
+ */
+ RequestValidator.validateRedirectUri = function (redirectUri) {
+ if (StringUtils.isEmpty(redirectUri)) {
+ throw ClientConfigurationError.createRedirectUriEmptyError();
+ }
+ };
+ /**
+ * Utility to validate prompt sent by the user in the request
+ * @param prompt
+ */
+ RequestValidator.validatePrompt = function (prompt) {
+ var promptValues = [];
+ for (var value in PromptValue) {
+ promptValues.push(PromptValue[value]);
+ }
+ if (promptValues.indexOf(prompt) < 0) {
+ throw ClientConfigurationError.createInvalidPromptError(prompt);
+ }
+ };
+ RequestValidator.validateClaims = function (claims) {
+ try {
+ JSON.parse(claims);
+ }
+ catch (e) {
+ throw ClientConfigurationError.createInvalidClaimsRequestError();
+ }
+ };
+ /**
+ * Utility to validate code_challenge and code_challenge_method
+ * @param codeChallenge
+ * @param codeChallengeMethod
+ */
+ RequestValidator.validateCodeChallengeParams = function (codeChallenge, codeChallengeMethod) {
+ if (StringUtils.isEmpty(codeChallenge) || StringUtils.isEmpty(codeChallengeMethod)) {
+ throw ClientConfigurationError.createInvalidCodeChallengeParamsError();
+ }
+ else {
+ this.validateCodeChallengeMethod(codeChallengeMethod);
+ }
+ };
+ /**
+ * Utility to validate code_challenge_method
+ * @param codeChallengeMethod
+ */
+ RequestValidator.validateCodeChallengeMethod = function (codeChallengeMethod) {
+ if ([
+ CodeChallengeMethodValues.PLAIN,
+ CodeChallengeMethodValues.S256
+ ].indexOf(codeChallengeMethod) < 0) {
+ throw ClientConfigurationError.createInvalidCodeChallengeMethodError();
+ }
+ };
+ /**
+ * Removes unnecessary, duplicate, and empty string query parameters from extraQueryParameters
+ * @param request
+ */
+ RequestValidator.sanitizeEQParams = function (eQParams, queryParams) {
+ if (!eQParams) {
+ return {};
+ }
+ // Remove any query parameters already included in SSO params
+ queryParams.forEach(function (value, key) {
+ if (eQParams[key]) {
+ delete eQParams[key];
+ }
+ });
+ // remove empty string parameters
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ return Object.fromEntries(Object.entries(eQParams).filter(function (_a) {
+ _a[0]; var value = _a[1];
+ return value !== "";
+ }));
+ };
+ return RequestValidator;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var RequestParameterBuilder = /** @class */ (function () {
+ function RequestParameterBuilder() {
+ this.parameters = new Map();
+ }
+ /**
+ * add response_type = code
+ */
+ RequestParameterBuilder.prototype.addResponseTypeCode = function () {
+ this.parameters.set(exports.AADServerParamKeys.RESPONSE_TYPE, encodeURIComponent(Constants.CODE_RESPONSE_TYPE));
+ };
+ /**
+ * add response_type = token id_token
+ */
+ RequestParameterBuilder.prototype.addResponseTypeForTokenAndIdToken = function () {
+ this.parameters.set(exports.AADServerParamKeys.RESPONSE_TYPE, encodeURIComponent(Constants.TOKEN_RESPONSE_TYPE + " " + Constants.ID_TOKEN_RESPONSE_TYPE));
+ };
+ /**
+ * add response_mode. defaults to query.
+ * @param responseMode
+ */
+ RequestParameterBuilder.prototype.addResponseMode = function (responseMode) {
+ this.parameters.set(exports.AADServerParamKeys.RESPONSE_MODE, encodeURIComponent((responseMode) ? responseMode : exports.ResponseMode.QUERY));
+ };
+ /**
+ * Add flag to indicate STS should attempt to use WAM if available
+ */
+ RequestParameterBuilder.prototype.addNativeBroker = function () {
+ this.parameters.set(exports.AADServerParamKeys.NATIVE_BROKER, encodeURIComponent("1"));
+ };
+ /**
+ * add scopes. set addOidcScopes to false to prevent default scopes in non-user scenarios
+ * @param scopeSet
+ * @param addOidcScopes
+ */
+ RequestParameterBuilder.prototype.addScopes = function (scopes, addOidcScopes) {
+ if (addOidcScopes === void 0) { addOidcScopes = true; }
+ var requestScopes = addOidcScopes ? __spreadArrays(scopes || [], OIDC_DEFAULT_SCOPES) : scopes || [];
+ var scopeSet = new ScopeSet(requestScopes);
+ this.parameters.set(exports.AADServerParamKeys.SCOPE, encodeURIComponent(scopeSet.printScopes()));
+ };
+ /**
+ * add clientId
+ * @param clientId
+ */
+ RequestParameterBuilder.prototype.addClientId = function (clientId) {
+ this.parameters.set(exports.AADServerParamKeys.CLIENT_ID, encodeURIComponent(clientId));
+ };
+ /**
+ * add redirect_uri
+ * @param redirectUri
+ */
+ RequestParameterBuilder.prototype.addRedirectUri = function (redirectUri) {
+ RequestValidator.validateRedirectUri(redirectUri);
+ this.parameters.set(exports.AADServerParamKeys.REDIRECT_URI, encodeURIComponent(redirectUri));
+ };
+ /**
+ * add post logout redirectUri
+ * @param redirectUri
+ */
+ RequestParameterBuilder.prototype.addPostLogoutRedirectUri = function (redirectUri) {
+ RequestValidator.validateRedirectUri(redirectUri);
+ this.parameters.set(exports.AADServerParamKeys.POST_LOGOUT_URI, encodeURIComponent(redirectUri));
+ };
+ /**
+ * add id_token_hint to logout request
+ * @param idTokenHint
+ */
+ RequestParameterBuilder.prototype.addIdTokenHint = function (idTokenHint) {
+ this.parameters.set(exports.AADServerParamKeys.ID_TOKEN_HINT, encodeURIComponent(idTokenHint));
+ };
+ /**
+ * add domain_hint
+ * @param domainHint
+ */
+ RequestParameterBuilder.prototype.addDomainHint = function (domainHint) {
+ this.parameters.set(exports.SSOTypes.DOMAIN_HINT, encodeURIComponent(domainHint));
+ };
+ /**
+ * add login_hint
+ * @param loginHint
+ */
+ RequestParameterBuilder.prototype.addLoginHint = function (loginHint) {
+ this.parameters.set(exports.SSOTypes.LOGIN_HINT, encodeURIComponent(loginHint));
+ };
+ /**
+ * Adds the CCS (Cache Credential Service) query parameter for login_hint
+ * @param loginHint
+ */
+ RequestParameterBuilder.prototype.addCcsUpn = function (loginHint) {
+ this.parameters.set(exports.HeaderNames.CCS_HEADER, encodeURIComponent("UPN:" + loginHint));
+ };
+ /**
+ * Adds the CCS (Cache Credential Service) query parameter for account object
+ * @param loginHint
+ */
+ RequestParameterBuilder.prototype.addCcsOid = function (clientInfo) {
+ this.parameters.set(exports.HeaderNames.CCS_HEADER, encodeURIComponent("Oid:" + clientInfo.uid + "@" + clientInfo.utid));
+ };
+ /**
+ * add sid
+ * @param sid
+ */
+ RequestParameterBuilder.prototype.addSid = function (sid) {
+ this.parameters.set(exports.SSOTypes.SID, encodeURIComponent(sid));
+ };
+ /**
+ * add claims
+ * @param claims
+ */
+ RequestParameterBuilder.prototype.addClaims = function (claims, clientCapabilities) {
+ var mergedClaims = this.addClientCapabilitiesToClaims(claims, clientCapabilities);
+ RequestValidator.validateClaims(mergedClaims);
+ this.parameters.set(exports.AADServerParamKeys.CLAIMS, encodeURIComponent(mergedClaims));
+ };
+ /**
+ * add correlationId
+ * @param correlationId
+ */
+ RequestParameterBuilder.prototype.addCorrelationId = function (correlationId) {
+ this.parameters.set(exports.AADServerParamKeys.CLIENT_REQUEST_ID, encodeURIComponent(correlationId));
+ };
+ /**
+ * add library info query params
+ * @param libraryInfo
+ */
+ RequestParameterBuilder.prototype.addLibraryInfo = function (libraryInfo) {
+ // Telemetry Info
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_SKU, libraryInfo.sku);
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_VER, libraryInfo.version);
+ if (libraryInfo.os) {
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_OS, libraryInfo.os);
+ }
+ if (libraryInfo.cpu) {
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_CPU, libraryInfo.cpu);
+ }
+ };
+ /**
+ * Add client telemetry parameters
+ * @param appTelemetry
+ */
+ RequestParameterBuilder.prototype.addApplicationTelemetry = function (appTelemetry) {
+ if (appTelemetry === null || appTelemetry === void 0 ? void 0 : appTelemetry.appName) {
+ this.parameters.set(exports.AADServerParamKeys.X_APP_NAME, appTelemetry.appName);
+ }
+ if (appTelemetry === null || appTelemetry === void 0 ? void 0 : appTelemetry.appVersion) {
+ this.parameters.set(exports.AADServerParamKeys.X_APP_VER, appTelemetry.appVersion);
+ }
+ };
+ /**
+ * add prompt
+ * @param prompt
+ */
+ RequestParameterBuilder.prototype.addPrompt = function (prompt) {
+ RequestValidator.validatePrompt(prompt);
+ this.parameters.set("" + exports.AADServerParamKeys.PROMPT, encodeURIComponent(prompt));
+ };
+ /**
+ * add state
+ * @param state
+ */
+ RequestParameterBuilder.prototype.addState = function (state) {
+ if (!StringUtils.isEmpty(state)) {
+ this.parameters.set(exports.AADServerParamKeys.STATE, encodeURIComponent(state));
+ }
+ };
+ /**
+ * add nonce
+ * @param nonce
+ */
+ RequestParameterBuilder.prototype.addNonce = function (nonce) {
+ this.parameters.set(exports.AADServerParamKeys.NONCE, encodeURIComponent(nonce));
+ };
+ /**
+ * add code_challenge and code_challenge_method
+ * - throw if either of them are not passed
+ * @param codeChallenge
+ * @param codeChallengeMethod
+ */
+ RequestParameterBuilder.prototype.addCodeChallengeParams = function (codeChallenge, codeChallengeMethod) {
+ RequestValidator.validateCodeChallengeParams(codeChallenge, codeChallengeMethod);
+ if (codeChallenge && codeChallengeMethod) {
+ this.parameters.set(exports.AADServerParamKeys.CODE_CHALLENGE, encodeURIComponent(codeChallenge));
+ this.parameters.set(exports.AADServerParamKeys.CODE_CHALLENGE_METHOD, encodeURIComponent(codeChallengeMethod));
+ }
+ else {
+ throw ClientConfigurationError.createInvalidCodeChallengeParamsError();
+ }
+ };
+ /**
+ * add the `authorization_code` passed by the user to exchange for a token
+ * @param code
+ */
+ RequestParameterBuilder.prototype.addAuthorizationCode = function (code) {
+ this.parameters.set(exports.AADServerParamKeys.CODE, encodeURIComponent(code));
+ };
+ /**
+ * add the `authorization_code` passed by the user to exchange for a token
+ * @param code
+ */
+ RequestParameterBuilder.prototype.addDeviceCode = function (code) {
+ this.parameters.set(exports.AADServerParamKeys.DEVICE_CODE, encodeURIComponent(code));
+ };
+ /**
+ * add the `refreshToken` passed by the user
+ * @param refreshToken
+ */
+ RequestParameterBuilder.prototype.addRefreshToken = function (refreshToken) {
+ this.parameters.set(exports.AADServerParamKeys.REFRESH_TOKEN, encodeURIComponent(refreshToken));
+ };
+ /**
+ * add the `code_verifier` passed by the user to exchange for a token
+ * @param codeVerifier
+ */
+ RequestParameterBuilder.prototype.addCodeVerifier = function (codeVerifier) {
+ this.parameters.set(exports.AADServerParamKeys.CODE_VERIFIER, encodeURIComponent(codeVerifier));
+ };
+ /**
+ * add client_secret
+ * @param clientSecret
+ */
+ RequestParameterBuilder.prototype.addClientSecret = function (clientSecret) {
+ this.parameters.set(exports.AADServerParamKeys.CLIENT_SECRET, encodeURIComponent(clientSecret));
+ };
+ /**
+ * add clientAssertion for confidential client flows
+ * @param clientAssertion
+ */
+ RequestParameterBuilder.prototype.addClientAssertion = function (clientAssertion) {
+ if (!StringUtils.isEmpty(clientAssertion)) {
+ this.parameters.set(exports.AADServerParamKeys.CLIENT_ASSERTION, encodeURIComponent(clientAssertion));
+ }
+ };
+ /**
+ * add clientAssertionType for confidential client flows
+ * @param clientAssertionType
+ */
+ RequestParameterBuilder.prototype.addClientAssertionType = function (clientAssertionType) {
+ if (!StringUtils.isEmpty(clientAssertionType)) {
+ this.parameters.set(exports.AADServerParamKeys.CLIENT_ASSERTION_TYPE, encodeURIComponent(clientAssertionType));
+ }
+ };
+ /**
+ * add OBO assertion for confidential client flows
+ * @param clientAssertion
+ */
+ RequestParameterBuilder.prototype.addOboAssertion = function (oboAssertion) {
+ this.parameters.set(exports.AADServerParamKeys.OBO_ASSERTION, encodeURIComponent(oboAssertion));
+ };
+ /**
+ * add grant type
+ * @param grantType
+ */
+ RequestParameterBuilder.prototype.addRequestTokenUse = function (tokenUse) {
+ this.parameters.set(exports.AADServerParamKeys.REQUESTED_TOKEN_USE, encodeURIComponent(tokenUse));
+ };
+ /**
+ * add grant type
+ * @param grantType
+ */
+ RequestParameterBuilder.prototype.addGrantType = function (grantType) {
+ this.parameters.set(exports.AADServerParamKeys.GRANT_TYPE, encodeURIComponent(grantType));
+ };
+ /**
+ * add client info
+ *
+ */
+ RequestParameterBuilder.prototype.addClientInfo = function () {
+ this.parameters.set(CLIENT_INFO, "1");
+ };
+ /**
+ * add extraQueryParams
+ * @param eQParams
+ */
+ RequestParameterBuilder.prototype.addExtraQueryParameters = function (eQParams) {
+ var _this = this;
+ var sanitizedEQParams = RequestValidator.sanitizeEQParams(eQParams, this.parameters);
+ Object.keys(sanitizedEQParams).forEach(function (key) {
+ _this.parameters.set(key, eQParams[key]);
+ });
+ };
+ RequestParameterBuilder.prototype.addClientCapabilitiesToClaims = function (claims, clientCapabilities) {
+ var mergedClaims;
+ // Parse provided claims into JSON object or initialize empty object
+ if (!claims) {
+ mergedClaims = {};
+ }
+ else {
+ try {
+ mergedClaims = JSON.parse(claims);
+ }
+ catch (e) {
+ throw ClientConfigurationError.createInvalidClaimsRequestError();
+ }
+ }
+ if (clientCapabilities && clientCapabilities.length > 0) {
+ if (!mergedClaims.hasOwnProperty(exports.ClaimsRequestKeys.ACCESS_TOKEN)) {
+ // Add access_token key to claims object
+ mergedClaims[exports.ClaimsRequestKeys.ACCESS_TOKEN] = {};
+ }
+ // Add xms_cc claim with provided clientCapabilities to access_token key
+ mergedClaims[exports.ClaimsRequestKeys.ACCESS_TOKEN][exports.ClaimsRequestKeys.XMS_CC] = {
+ values: clientCapabilities
+ };
+ }
+ return JSON.stringify(mergedClaims);
+ };
+ /**
+ * adds `username` for Password Grant flow
+ * @param username
+ */
+ RequestParameterBuilder.prototype.addUsername = function (username) {
+ this.parameters.set(exports.PasswordGrantConstants.username, encodeURIComponent(username));
+ };
+ /**
+ * adds `password` for Password Grant flow
+ * @param password
+ */
+ RequestParameterBuilder.prototype.addPassword = function (password) {
+ this.parameters.set(exports.PasswordGrantConstants.password, encodeURIComponent(password));
+ };
+ /**
+ * add pop_jwk to query params
+ * @param cnfString
+ */
+ RequestParameterBuilder.prototype.addPopToken = function (cnfString) {
+ if (!StringUtils.isEmpty(cnfString)) {
+ this.parameters.set(exports.AADServerParamKeys.TOKEN_TYPE, exports.AuthenticationScheme.POP);
+ this.parameters.set(exports.AADServerParamKeys.REQ_CNF, encodeURIComponent(cnfString));
+ }
+ };
+ /**
+ * add SSH JWK and key ID to query params
+ */
+ RequestParameterBuilder.prototype.addSshJwk = function (sshJwkString) {
+ if (!StringUtils.isEmpty(sshJwkString)) {
+ this.parameters.set(exports.AADServerParamKeys.TOKEN_TYPE, exports.AuthenticationScheme.SSH);
+ this.parameters.set(exports.AADServerParamKeys.REQ_CNF, encodeURIComponent(sshJwkString));
+ }
+ };
+ /**
+ * add server telemetry fields
+ * @param serverTelemetryManager
+ */
+ RequestParameterBuilder.prototype.addServerTelemetry = function (serverTelemetryManager) {
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_CURR_TELEM, serverTelemetryManager.generateCurrentRequestHeaderValue());
+ this.parameters.set(exports.AADServerParamKeys.X_CLIENT_LAST_TELEM, serverTelemetryManager.generateLastRequestHeaderValue());
+ };
+ /**
+ * Adds parameter that indicates to the server that throttling is supported
+ */
+ RequestParameterBuilder.prototype.addThrottling = function () {
+ this.parameters.set(exports.AADServerParamKeys.X_MS_LIB_CAPABILITY, ThrottlingConstants.X_MS_LIB_CAPABILITY_VALUE);
+ };
+ /**
+ * Adds logout_hint parameter for "silent" logout which prevent server account picker
+ */
+ RequestParameterBuilder.prototype.addLogoutHint = function (logoutHint) {
+ this.parameters.set(exports.AADServerParamKeys.LOGOUT_HINT, encodeURIComponent(logoutHint));
+ };
+ /**
+ * Utility to create a URL from the params map
+ */
+ RequestParameterBuilder.prototype.createQueryString = function () {
+ var queryParameterArray = new Array();
+ this.parameters.forEach(function (value, key) {
+ queryParameterArray.push(key + "=" + value);
+ });
+ return queryParameterArray.join("&");
+ };
+ return RequestParameterBuilder;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
+ */
+var BaseClient = /** @class */ (function () {
+ function BaseClient(configuration, performanceClient) {
+ // Set the configuration
+ this.config = buildClientConfiguration(configuration);
+ // Initialize the logger
+ this.logger = new Logger(this.config.loggerOptions, name, version);
+ // Initialize crypto
+ this.cryptoUtils = this.config.cryptoInterface;
+ // Initialize storage interface
+ this.cacheManager = this.config.storageInterface;
+ // Set the network interface
+ this.networkClient = this.config.networkInterface;
+ // Set the NetworkManager
+ this.networkManager = new NetworkManager(this.networkClient, this.cacheManager);
+ // Set TelemetryManager
+ this.serverTelemetryManager = this.config.serverTelemetryManager;
+ // set Authority
+ this.authority = this.config.authOptions.authority;
+ // set performance telemetry client
+ this.performanceClient = performanceClient;
+ }
+ /**
+ * Creates default headers for requests to token endpoint
+ */
+ BaseClient.prototype.createTokenRequestHeaders = function (ccsCred) {
+ var headers = {};
+ headers[exports.HeaderNames.CONTENT_TYPE] = Constants.URL_FORM_CONTENT_TYPE;
+ if (!this.config.systemOptions.preventCorsPreflight && ccsCred) {
+ switch (ccsCred.type) {
+ case exports.CcsCredentialType.HOME_ACCOUNT_ID:
+ try {
+ var clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
+ headers[exports.HeaderNames.CCS_HEADER] = "Oid:" + clientInfo.uid + "@" + clientInfo.utid;
+ }
+ catch (e) {
+ this.logger.verbose("Could not parse home account ID for CCS Header: " + e);
+ }
+ break;
+ case exports.CcsCredentialType.UPN:
+ headers[exports.HeaderNames.CCS_HEADER] = "UPN: " + ccsCred.credential;
+ break;
+ }
+ }
+ return headers;
+ };
+ /**
+ * Http post to token endpoint
+ * @param tokenEndpoint
+ * @param queryString
+ * @param headers
+ * @param thumbprint
+ */
+ BaseClient.prototype.executePostToTokenEndpoint = function (tokenEndpoint, queryString, headers, thumbprint) {
+ return __awaiter(this, void 0, void 0, function () {
+ var response;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.networkManager.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers: headers })];
+ case 1:
+ response = _a.sent();
+ if (this.config.serverTelemetryManager && response.status < 500 && response.status !== 429) {
+ // Telemetry data successfully logged by server, clear Telemetry cache
+ this.config.serverTelemetryManager.clearTelemetryCache();
+ }
+ return [2 /*return*/, response];
+ }
+ });
+ });
+ };
+ /**
+ * Updates the authority object of the client. Endpoint discovery must be completed.
+ * @param updatedAuthority
+ */
+ BaseClient.prototype.updateAuthority = function (updatedAuthority) {
+ if (!updatedAuthority.discoveryComplete()) {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Updated authority has not completed endpoint discovery.");
+ }
+ this.authority = updatedAuthority;
+ };
+ /**
+ * Creates query string for the /token request
+ * @param request
+ */
+ BaseClient.prototype.createTokenQueryParameters = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ if (request.tokenQueryParameters) {
+ parameterBuilder.addExtraQueryParameters(request.tokenQueryParameters);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ return BaseClient;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Base type for credentials to be stored in the cache: eg: ACCESS_TOKEN, ID_TOKEN etc
+ *
+ * Key:Value Schema:
+ *
+ * Key: -------
+ *
+ * Value Schema:
+ * {
+ * homeAccountId: home account identifier for the auth scheme,
+ * environment: entity that issued the token, represented as a full host
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
+ * clientId: client ID of the application
+ * secret: Actual credential as a string
+ * familyId: Family ID identifier, usually only used for refresh tokens
+ * realm: Full tenant or organizational identifier that the account belongs to
+ * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
+ * tokenType: Matches the authentication scheme for which the token was issued (i.e. Bearer or pop)
+ * requestedClaimsHash: Matches the SHA 256 hash of the claims object included in the token request
+ * userAssertionHash: Matches the SHA 256 hash of the obo_assertion for the OBO flow
+ * }
+ */
+var CredentialEntity = /** @class */ (function () {
+ function CredentialEntity() {
+ }
+ /**
+ * Generate Account Id key component as per the schema: -
+ */
+ CredentialEntity.prototype.generateAccountId = function () {
+ return CredentialEntity.generateAccountIdForCacheKey(this.homeAccountId, this.environment);
+ };
+ /**
+ * Generate Credential Id key component as per the schema: --
+ */
+ CredentialEntity.prototype.generateCredentialId = function () {
+ return CredentialEntity.generateCredentialIdForCacheKey(this.credentialType, this.clientId, this.realm, this.familyId);
+ };
+ /**
+ * Generate target key component as per schema:
+ */
+ CredentialEntity.prototype.generateTarget = function () {
+ return CredentialEntity.generateTargetForCacheKey(this.target);
+ };
+ /**
+ * generates credential key
+ */
+ CredentialEntity.prototype.generateCredentialKey = function () {
+ return CredentialEntity.generateCredentialCacheKey(this.homeAccountId, this.environment, this.credentialType, this.clientId, this.realm, this.target, this.familyId, this.tokenType, this.requestedClaimsHash);
+ };
+ /**
+ * returns the type of the cache (in this case credential)
+ */
+ CredentialEntity.prototype.generateType = function () {
+ switch (this.credentialType) {
+ case exports.CredentialType.ID_TOKEN:
+ return exports.CacheType.ID_TOKEN;
+ case exports.CredentialType.ACCESS_TOKEN:
+ case exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME:
+ return exports.CacheType.ACCESS_TOKEN;
+ case exports.CredentialType.REFRESH_TOKEN:
+ return exports.CacheType.REFRESH_TOKEN;
+ default: {
+ throw ClientAuthError.createUnexpectedCredentialTypeError();
+ }
+ }
+ };
+ /**
+ * generates credential key
+ * -\-----
+ */
+ CredentialEntity.generateCredentialCacheKey = function (homeAccountId, environment, credentialType, clientId, realm, target, familyId, tokenType, requestedClaimsHash) {
+ var credentialKey = [
+ this.generateAccountIdForCacheKey(homeAccountId, environment),
+ this.generateCredentialIdForCacheKey(credentialType, clientId, realm, familyId),
+ this.generateTargetForCacheKey(target),
+ this.generateClaimsHashForCacheKey(requestedClaimsHash),
+ this.generateSchemeForCacheKey(tokenType)
+ ];
+ return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * generates Account Id for keys
+ * @param homeAccountId
+ * @param environment
+ */
+ CredentialEntity.generateAccountIdForCacheKey = function (homeAccountId, environment) {
+ var accountId = [homeAccountId, environment];
+ return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * Generates Credential Id for keys
+ * @param credentialType
+ * @param realm
+ * @param clientId
+ * @param familyId
+ */
+ CredentialEntity.generateCredentialIdForCacheKey = function (credentialType, clientId, realm, familyId) {
+ var clientOrFamilyId = credentialType === exports.CredentialType.REFRESH_TOKEN
+ ? familyId || clientId
+ : clientId;
+ var credentialId = [
+ credentialType,
+ clientOrFamilyId,
+ realm || Constants.EMPTY_STRING,
+ ];
+ return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * Generate target key component as per schema:
+ */
+ CredentialEntity.generateTargetForCacheKey = function (scopes) {
+ return (scopes || Constants.EMPTY_STRING).toLowerCase();
+ };
+ /**
+ * Generate requested claims key component as per schema:
+ */
+ CredentialEntity.generateClaimsHashForCacheKey = function (requestedClaimsHash) {
+ return (requestedClaimsHash || Constants.EMPTY_STRING).toLowerCase();
+ };
+ /**
+ * Generate scheme key componenet as per schema:
+ */
+ CredentialEntity.generateSchemeForCacheKey = function (tokenType) {
+ /*
+ * PoP Tokens and SSH certs include scheme in cache key
+ * Cast to lowercase to handle "bearer" from ADFS
+ */
+ return (tokenType && tokenType.toLowerCase() !== exports.AuthenticationScheme.BEARER.toLowerCase()) ? tokenType.toLowerCase() : Constants.EMPTY_STRING;
+ };
+ return CredentialEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * ID_TOKEN Cache
+ *
+ * Key:Value Schema:
+ *
+ * Key Example: uid.utid-login.microsoftonline.com-idtoken-clientId-contoso.com-
+ *
+ * Value Schema:
+ * {
+ * homeAccountId: home account identifier for the auth scheme,
+ * environment: entity that issued the token, represented as a full host
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
+ * clientId: client ID of the application
+ * secret: Actual credential as a string
+ * realm: Full tenant or organizational identifier that the account belongs to
+ * }
+ */
+var IdTokenEntity = /** @class */ (function (_super) {
+ __extends(IdTokenEntity, _super);
+ function IdTokenEntity() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ /**
+ * Create IdTokenEntity
+ * @param homeAccountId
+ * @param authenticationResult
+ * @param clientId
+ * @param authority
+ */
+ IdTokenEntity.createIdTokenEntity = function (homeAccountId, environment, idToken, clientId, tenantId) {
+ var idTokenEntity = new IdTokenEntity();
+ idTokenEntity.credentialType = exports.CredentialType.ID_TOKEN;
+ idTokenEntity.homeAccountId = homeAccountId;
+ idTokenEntity.environment = environment;
+ idTokenEntity.clientId = clientId;
+ idTokenEntity.secret = idToken;
+ idTokenEntity.realm = tenantId;
+ return idTokenEntity;
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ IdTokenEntity.isIdTokenEntity = function (entity) {
+ if (!entity) {
+ return false;
+ }
+ return (entity.hasOwnProperty("homeAccountId") &&
+ entity.hasOwnProperty("environment") &&
+ entity.hasOwnProperty("credentialType") &&
+ entity.hasOwnProperty("realm") &&
+ entity.hasOwnProperty("clientId") &&
+ entity.hasOwnProperty("secret") &&
+ entity["credentialType"] === exports.CredentialType.ID_TOKEN);
+ };
+ return IdTokenEntity;
+}(CredentialEntity));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Utility class which exposes functions for managing date and time operations.
+ */
+var TimeUtils = /** @class */ (function () {
+ function TimeUtils() {
+ }
+ /**
+ * return the current time in Unix time (seconds).
+ */
+ TimeUtils.nowSeconds = function () {
+ // Date.getTime() returns in milliseconds.
+ return Math.round(new Date().getTime() / 1000.0);
+ };
+ /**
+ * check if a token is expired based on given UTC time in seconds.
+ * @param expiresOn
+ */
+ TimeUtils.isTokenExpired = function (expiresOn, offset) {
+ // check for access token expiry
+ var expirationSec = Number(expiresOn) || 0;
+ var offsetCurrentTimeSec = TimeUtils.nowSeconds() + offset;
+ // If current time + offset is greater than token expiration time, then token is expired.
+ return (offsetCurrentTimeSec > expirationSec);
+ };
+ /**
+ * If the current time is earlier than the time that a token was cached at, we must discard the token
+ * i.e. The system clock was turned back after acquiring the cached token
+ * @param cachedAt
+ * @param offset
+ */
+ TimeUtils.wasClockTurnedBack = function (cachedAt) {
+ var cachedAtSec = Number(cachedAt);
+ return cachedAtSec > TimeUtils.nowSeconds();
+ };
+ /**
+ * Waits for t number of milliseconds
+ * @param t number
+ * @param value T
+ */
+ TimeUtils.delay = function (t, value) {
+ return new Promise(function (resolve) { return setTimeout(function () { return resolve(value); }, t); });
+ };
+ return TimeUtils;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * ACCESS_TOKEN Credential Type
+ *
+ * Key:Value Schema:
+ *
+ * Key Example: uid.utid-login.microsoftonline.com-accesstoken-clientId-contoso.com-user.read
+ *
+ * Value Schema:
+ * {
+ * homeAccountId: home account identifier for the auth scheme,
+ * environment: entity that issued the token, represented as a full host
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
+ * clientId: client ID of the application
+ * secret: Actual credential as a string
+ * familyId: Family ID identifier, usually only used for refresh tokens
+ * realm: Full tenant or organizational identifier that the account belongs to
+ * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
+ * cachedAt: Absolute device time when entry was created in the cache.
+ * expiresOn: Token expiry time, calculated based on current UTC time in seconds. Represented as a string.
+ * extendedExpiresOn: Additional extended expiry time until when token is valid in case of server-side outage. Represented as string in UTC seconds.
+ * keyId: used for POP and SSH tokenTypes
+ * tokenType: Type of the token issued. Usually "Bearer"
+ * }
+ */
+var AccessTokenEntity = /** @class */ (function (_super) {
+ __extends(AccessTokenEntity, _super);
+ function AccessTokenEntity() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ /**
+ * Create AccessTokenEntity
+ * @param homeAccountId
+ * @param environment
+ * @param accessToken
+ * @param clientId
+ * @param tenantId
+ * @param scopes
+ * @param expiresOn
+ * @param extExpiresOn
+ */
+ AccessTokenEntity.createAccessTokenEntity = function (homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, cryptoUtils, refreshOn, tokenType, userAssertionHash, keyId, requestedClaims, requestedClaimsHash) {
+ var _a, _b;
+ var atEntity = new AccessTokenEntity();
+ atEntity.homeAccountId = homeAccountId;
+ atEntity.credentialType = exports.CredentialType.ACCESS_TOKEN;
+ atEntity.secret = accessToken;
+ var currentTime = TimeUtils.nowSeconds();
+ atEntity.cachedAt = currentTime.toString();
+ /*
+ * Token expiry time.
+ * This value should be calculated based on the current UTC time measured locally and the value expires_in Represented as a string in JSON.
+ */
+ atEntity.expiresOn = expiresOn.toString();
+ atEntity.extendedExpiresOn = extExpiresOn.toString();
+ if (refreshOn) {
+ atEntity.refreshOn = refreshOn.toString();
+ }
+ atEntity.environment = environment;
+ atEntity.clientId = clientId;
+ atEntity.realm = tenantId;
+ atEntity.target = scopes;
+ atEntity.userAssertionHash = userAssertionHash;
+ atEntity.tokenType = StringUtils.isEmpty(tokenType) ? exports.AuthenticationScheme.BEARER : tokenType;
+ if (requestedClaims) {
+ atEntity.requestedClaims = requestedClaims;
+ atEntity.requestedClaimsHash = requestedClaimsHash;
+ }
+ /*
+ * Create Access Token With Auth Scheme instead of regular access token
+ * Cast to lower to handle "bearer" from ADFS
+ */
+ if (((_a = atEntity.tokenType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== exports.AuthenticationScheme.BEARER.toLowerCase()) {
+ atEntity.credentialType = exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
+ switch (atEntity.tokenType) {
+ case exports.AuthenticationScheme.POP:
+ // Make sure keyId is present and add it to credential
+ var tokenClaims = AuthToken.extractTokenClaims(accessToken, cryptoUtils);
+ if (!((_b = tokenClaims === null || tokenClaims === void 0 ? void 0 : tokenClaims.cnf) === null || _b === void 0 ? void 0 : _b.kid)) {
+ throw ClientAuthError.createTokenClaimsRequiredError();
+ }
+ atEntity.keyId = tokenClaims.cnf.kid;
+ break;
+ case exports.AuthenticationScheme.SSH:
+ atEntity.keyId = keyId;
+ }
+ }
+ return atEntity;
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ AccessTokenEntity.isAccessTokenEntity = function (entity) {
+ if (!entity) {
+ return false;
+ }
+ return (entity.hasOwnProperty("homeAccountId") &&
+ entity.hasOwnProperty("environment") &&
+ entity.hasOwnProperty("credentialType") &&
+ entity.hasOwnProperty("realm") &&
+ entity.hasOwnProperty("clientId") &&
+ entity.hasOwnProperty("secret") &&
+ entity.hasOwnProperty("target") &&
+ (entity["credentialType"] === exports.CredentialType.ACCESS_TOKEN || entity["credentialType"] === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME));
+ };
+ return AccessTokenEntity;
+}(CredentialEntity));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * REFRESH_TOKEN Cache
+ *
+ * Key:Value Schema:
+ *
+ * Key Example: uid.utid-login.microsoftonline.com-refreshtoken-clientId--
+ *
+ * Value:
+ * {
+ * homeAccountId: home account identifier for the auth scheme,
+ * environment: entity that issued the token, represented as a full host
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
+ * clientId: client ID of the application
+ * secret: Actual credential as a string
+ * familyId: Family ID identifier, '1' represents Microsoft Family
+ * realm: Full tenant or organizational identifier that the account belongs to
+ * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
+ * }
+ */
+var RefreshTokenEntity = /** @class */ (function (_super) {
+ __extends(RefreshTokenEntity, _super);
+ function RefreshTokenEntity() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ /**
+ * Create RefreshTokenEntity
+ * @param homeAccountId
+ * @param authenticationResult
+ * @param clientId
+ * @param authority
+ */
+ RefreshTokenEntity.createRefreshTokenEntity = function (homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash) {
+ var rtEntity = new RefreshTokenEntity();
+ rtEntity.clientId = clientId;
+ rtEntity.credentialType = exports.CredentialType.REFRESH_TOKEN;
+ rtEntity.environment = environment;
+ rtEntity.homeAccountId = homeAccountId;
+ rtEntity.secret = refreshToken;
+ rtEntity.userAssertionHash = userAssertionHash;
+ if (familyId)
+ rtEntity.familyId = familyId;
+ return rtEntity;
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ RefreshTokenEntity.isRefreshTokenEntity = function (entity) {
+ if (!entity) {
+ return false;
+ }
+ return (entity.hasOwnProperty("homeAccountId") &&
+ entity.hasOwnProperty("environment") &&
+ entity.hasOwnProperty("credentialType") &&
+ entity.hasOwnProperty("clientId") &&
+ entity.hasOwnProperty("secret") &&
+ entity["credentialType"] === exports.CredentialType.REFRESH_TOKEN);
+ };
+ return RefreshTokenEntity;
+}(CredentialEntity));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * InteractionRequiredServerErrorMessage contains string constants used by error codes and messages returned by the server indicating interaction is required
+ */
+var InteractionRequiredServerErrorMessage = [
+ "interaction_required",
+ "consent_required",
+ "login_required"
+];
+var InteractionRequiredAuthSubErrorMessage = [
+ "message_only",
+ "additional_action",
+ "basic_action",
+ "user_password_expired",
+ "consent_required"
+];
+/**
+ * Interaction required errors defined by the SDK
+ */
+var InteractionRequiredAuthErrorMessage = {
+ noTokensFoundError: {
+ code: "no_tokens_found",
+ desc: "No refresh token found in the cache. Please sign-in."
+ },
+ native_account_unavailable: {
+ code: "native_account_unavailable",
+ desc: "The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API."
+ }
+};
+/**
+ * Error thrown when user interaction is required.
+ */
+var InteractionRequiredAuthError = /** @class */ (function (_super) {
+ __extends(InteractionRequiredAuthError, _super);
+ function InteractionRequiredAuthError(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims) {
+ var _this = _super.call(this, errorCode, errorMessage, subError) || this;
+ Object.setPrototypeOf(_this, InteractionRequiredAuthError.prototype);
+ _this.timestamp = timestamp || Constants.EMPTY_STRING;
+ _this.traceId = traceId || Constants.EMPTY_STRING;
+ _this.correlationId = correlationId || Constants.EMPTY_STRING;
+ _this.claims = claims || Constants.EMPTY_STRING;
+ _this.name = "InteractionRequiredAuthError";
+ return _this;
+ }
+ /**
+ * Helper function used to determine if an error thrown by the server requires interaction to resolve
+ * @param errorCode
+ * @param errorString
+ * @param subError
+ */
+ InteractionRequiredAuthError.isInteractionRequiredError = function (errorCode, errorString, subError) {
+ var isInteractionRequiredErrorCode = !!errorCode && InteractionRequiredServerErrorMessage.indexOf(errorCode) > -1;
+ var isInteractionRequiredSubError = !!subError && InteractionRequiredAuthSubErrorMessage.indexOf(subError) > -1;
+ var isInteractionRequiredErrorDesc = !!errorString && InteractionRequiredServerErrorMessage.some(function (irErrorCode) {
+ return errorString.indexOf(irErrorCode) > -1;
+ });
+ return isInteractionRequiredErrorCode || isInteractionRequiredErrorDesc || isInteractionRequiredSubError;
+ };
+ /**
+ * Creates an error thrown when the authorization code required for a token request is null or empty.
+ */
+ InteractionRequiredAuthError.createNoTokensFoundError = function () {
+ return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.noTokensFoundError.code, InteractionRequiredAuthErrorMessage.noTokensFoundError.desc);
+ };
+ /**
+ * Creates an error thrown when the native broker returns ACCOUNT_UNAVAILABLE status, indicating that the account was removed and interactive sign-in is required
+ * @returns
+ */
+ InteractionRequiredAuthError.createNativeAccountUnavailableError = function () {
+ return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.native_account_unavailable.code, InteractionRequiredAuthErrorMessage.native_account_unavailable.desc);
+ };
+ return InteractionRequiredAuthError;
+}(AuthError));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var CacheRecord = /** @class */ (function () {
+ function CacheRecord(accountEntity, idTokenEntity, accessTokenEntity, refreshTokenEntity, appMetadataEntity) {
+ this.account = accountEntity || null;
+ this.idToken = idTokenEntity || null;
+ this.accessToken = accessTokenEntity || null;
+ this.refreshToken = refreshTokenEntity || null;
+ this.appMetadata = appMetadataEntity || null;
+ }
+ return CacheRecord;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Class which provides helpers for OAuth 2.0 protocol specific values
+ */
+var ProtocolUtils = /** @class */ (function () {
+ function ProtocolUtils() {
+ }
+ /**
+ * Appends user state with random guid, or returns random guid.
+ * @param userState
+ * @param randomGuid
+ */
+ ProtocolUtils.setRequestState = function (cryptoObj, userState, meta) {
+ var libraryState = ProtocolUtils.generateLibraryState(cryptoObj, meta);
+ return !StringUtils.isEmpty(userState) ? "" + libraryState + Constants.RESOURCE_DELIM + userState : libraryState;
+ };
+ /**
+ * Generates the state value used by the common library.
+ * @param randomGuid
+ * @param cryptoObj
+ */
+ ProtocolUtils.generateLibraryState = function (cryptoObj, meta) {
+ if (!cryptoObj) {
+ throw ClientAuthError.createNoCryptoObjectError("generateLibraryState");
+ }
+ // Create a state object containing a unique id and the timestamp of the request creation
+ var stateObj = {
+ id: cryptoObj.createNewGuid()
+ };
+ if (meta) {
+ stateObj.meta = meta;
+ }
+ var stateString = JSON.stringify(stateObj);
+ return cryptoObj.base64Encode(stateString);
+ };
+ /**
+ * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
+ * @param state
+ * @param cryptoObj
+ */
+ ProtocolUtils.parseRequestState = function (cryptoObj, state) {
+ if (!cryptoObj) {
+ throw ClientAuthError.createNoCryptoObjectError("parseRequestState");
+ }
+ if (StringUtils.isEmpty(state)) {
+ throw ClientAuthError.createInvalidStateError(state, "Null, undefined or empty state");
+ }
+ try {
+ // Split the state between library state and user passed state and decode them separately
+ var splitState = state.split(Constants.RESOURCE_DELIM);
+ var libraryState = splitState[0];
+ var userState = splitState.length > 1 ? splitState.slice(1).join(Constants.RESOURCE_DELIM) : Constants.EMPTY_STRING;
+ var libraryStateString = cryptoObj.base64Decode(libraryState);
+ var libraryStateObj = JSON.parse(libraryStateString);
+ return {
+ userRequestState: !StringUtils.isEmpty(userState) ? userState : Constants.EMPTY_STRING,
+ libraryState: libraryStateObj
+ };
+ }
+ catch (e) {
+ throw ClientAuthError.createInvalidStateError(state, e);
+ }
+ };
+ return ProtocolUtils;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Url object class which can perform various transformations on url strings.
+ */
+var UrlString = /** @class */ (function () {
+ function UrlString(url) {
+ this._urlString = url;
+ if (StringUtils.isEmpty(this._urlString)) {
+ // Throws error if url is empty
+ throw ClientConfigurationError.createUrlEmptyError();
+ }
+ if (StringUtils.isEmpty(this.getHash())) {
+ this._urlString = UrlString.canonicalizeUri(url);
+ }
+ }
+ Object.defineProperty(UrlString.prototype, "urlString", {
+ get: function () {
+ return this._urlString;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Ensure urls are lower case and end with a / character.
+ * @param url
+ */
+ UrlString.canonicalizeUri = function (url) {
+ if (url) {
+ var lowerCaseUrl = url.toLowerCase();
+ if (StringUtils.endsWith(lowerCaseUrl, "?")) {
+ lowerCaseUrl = lowerCaseUrl.slice(0, -1);
+ }
+ else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
+ lowerCaseUrl = lowerCaseUrl.slice(0, -2);
+ }
+ if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
+ lowerCaseUrl += "/";
+ }
+ return lowerCaseUrl;
+ }
+ return url;
+ };
+ /**
+ * Throws if urlString passed is not a valid authority URI string.
+ */
+ UrlString.prototype.validateAsUri = function () {
+ // Attempts to parse url for uri components
+ var components;
+ try {
+ components = this.getUrlComponents();
+ }
+ catch (e) {
+ throw ClientConfigurationError.createUrlParseError(e);
+ }
+ // Throw error if URI or path segments are not parseable.
+ if (!components.HostNameAndPort || !components.PathSegments) {
+ throw ClientConfigurationError.createUrlParseError("Given url string: " + this.urlString);
+ }
+ // Throw error if uri is insecure.
+ if (!components.Protocol || components.Protocol.toLowerCase() !== "https:") {
+ throw ClientConfigurationError.createInsecureAuthorityUriError(this.urlString);
+ }
+ };
+ /**
+ * Given a url and a query string return the url with provided query string appended
+ * @param url
+ * @param queryString
+ */
+ UrlString.appendQueryString = function (url, queryString) {
+ if (StringUtils.isEmpty(queryString)) {
+ return url;
+ }
+ return url.indexOf("?") < 0 ? url + "?" + queryString : url + "&" + queryString;
+ };
+ /**
+ * Returns a url with the hash removed
+ * @param url
+ */
+ UrlString.removeHashFromUrl = function (url) {
+ return UrlString.canonicalizeUri(url.split("#")[0]);
+ };
+ /**
+ * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
+ * @param href The url
+ * @param tenantId The tenant id to replace
+ */
+ UrlString.prototype.replaceTenantPath = function (tenantId) {
+ var urlObject = this.getUrlComponents();
+ var pathArray = urlObject.PathSegments;
+ if (tenantId && (pathArray.length !== 0 && (pathArray[0] === AADAuthorityConstants.COMMON || pathArray[0] === AADAuthorityConstants.ORGANIZATIONS))) {
+ pathArray[0] = tenantId;
+ }
+ return UrlString.constructAuthorityUriFromObject(urlObject);
+ };
+ /**
+ * Returns the anchor part(#) of the URL
+ */
+ UrlString.prototype.getHash = function () {
+ return UrlString.parseHash(this.urlString);
+ };
+ /**
+ * Parses out the components from a url string.
+ * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
+ */
+ UrlString.prototype.getUrlComponents = function () {
+ // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
+ var regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
+ // If url string does not match regEx, we throw an error
+ var match = this.urlString.match(regEx);
+ if (!match) {
+ throw ClientConfigurationError.createUrlParseError("Given url string: " + this.urlString);
+ }
+ // Url component object
+ var urlComponents = {
+ Protocol: match[1],
+ HostNameAndPort: match[4],
+ AbsolutePath: match[5],
+ QueryString: match[7]
+ };
+ var pathSegments = urlComponents.AbsolutePath.split("/");
+ pathSegments = pathSegments.filter(function (val) { return val && val.length > 0; }); // remove empty elements
+ urlComponents.PathSegments = pathSegments;
+ if (!StringUtils.isEmpty(urlComponents.QueryString) && urlComponents.QueryString.endsWith("/")) {
+ urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1);
+ }
+ return urlComponents;
+ };
+ UrlString.getDomainFromUrl = function (url) {
+ var regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
+ var match = url.match(regEx);
+ if (!match) {
+ throw ClientConfigurationError.createUrlParseError("Given url string: " + url);
+ }
+ return match[2];
+ };
+ UrlString.getAbsoluteUrl = function (relativeUrl, baseUrl) {
+ if (relativeUrl[0] === Constants.FORWARD_SLASH) {
+ var url = new UrlString(baseUrl);
+ var baseComponents = url.getUrlComponents();
+ return baseComponents.Protocol + "//" + baseComponents.HostNameAndPort + relativeUrl;
+ }
+ return relativeUrl;
+ };
+ /**
+ * Parses hash string from given string. Returns empty string if no hash symbol is found.
+ * @param hashString
+ */
+ UrlString.parseHash = function (hashString) {
+ var hashIndex1 = hashString.indexOf("#");
+ var hashIndex2 = hashString.indexOf("#/");
+ if (hashIndex2 > -1) {
+ return hashString.substring(hashIndex2 + 2);
+ }
+ else if (hashIndex1 > -1) {
+ return hashString.substring(hashIndex1 + 1);
+ }
+ return Constants.EMPTY_STRING;
+ };
+ /**
+ * Parses query string from given string. Returns empty string if no query symbol is found.
+ * @param queryString
+ */
+ UrlString.parseQueryString = function (queryString) {
+ var queryIndex1 = queryString.indexOf("?");
+ var queryIndex2 = queryString.indexOf("/?");
+ if (queryIndex2 > -1) {
+ return queryString.substring(queryIndex2 + 2);
+ }
+ else if (queryIndex1 > -1) {
+ return queryString.substring(queryIndex1 + 1);
+ }
+ return Constants.EMPTY_STRING;
+ };
+ UrlString.constructAuthorityUriFromObject = function (urlObject) {
+ return new UrlString(urlObject.Protocol + "//" + urlObject.HostNameAndPort + "/" + urlObject.PathSegments.join("/"));
+ };
+ /**
+ * Returns URL hash as server auth code response object.
+ */
+ UrlString.getDeserializedHash = function (hash) {
+ // Check if given hash is empty
+ if (StringUtils.isEmpty(hash)) {
+ return {};
+ }
+ // Strip the # symbol if present
+ var parsedHash = UrlString.parseHash(hash);
+ // If # symbol was not present, above will return empty string, so give original hash value
+ var deserializedHash = StringUtils.queryStringToObject(StringUtils.isEmpty(parsedHash) ? hash : parsedHash);
+ // Check if deserialization didn't work
+ if (!deserializedHash) {
+ throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedHash));
+ }
+ return deserializedHash;
+ };
+ /**
+ * Returns URL query string as server auth code response object.
+ */
+ UrlString.getDeserializedQueryString = function (query) {
+ // Check if given query is empty
+ if (StringUtils.isEmpty(query)) {
+ return {};
+ }
+ // Strip the ? symbol if present
+ var parsedQueryString = UrlString.parseQueryString(query);
+ // If ? symbol was not present, above will return empty string, so give original query value
+ var deserializedQueryString = StringUtils.queryStringToObject(StringUtils.isEmpty(parsedQueryString) ? query : parsedQueryString);
+ // Check if deserialization didn't work
+ if (!deserializedQueryString) {
+ throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedQueryString));
+ }
+ return deserializedQueryString;
+ };
+ /**
+ * Check if the hash of the URL string contains known properties
+ */
+ UrlString.hashContainsKnownProperties = function (hash) {
+ if (StringUtils.isEmpty(hash) || hash.indexOf("=") < 0) {
+ // Hash doesn't contain key/value pairs
+ return false;
+ }
+ var parameters = UrlString.getDeserializedHash(hash);
+ return !!(parameters.code ||
+ parameters.error_description ||
+ parameters.error ||
+ parameters.state);
+ };
+ return UrlString;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Enumeration of operations that are instrumented by have their performance measured by the PerformanceClient.
+ *
+ * @export
+ * @enum {number}
+ */
+exports.PerformanceEvents = void 0;
+(function (PerformanceEvents) {
+ /**
+ * acquireTokenByCode API (msal-browser and msal-node).
+ * Used to acquire tokens by trading an authorization code against the token endpoint.
+ */
+ PerformanceEvents["AcquireTokenByCode"] = "acquireTokenByCode";
+ /**
+ * acquireTokenByRefreshToken API (msal-browser and msal-node).
+ * Used to renew an access token using a refresh token against the token endpoint.
+ */
+ PerformanceEvents["AcquireTokenByRefreshToken"] = "acquireTokenByRefreshToken";
+ /**
+ * acquireTokenSilent API (msal-browser and msal-node).
+ * Used to silently acquire a new access token (from the cache or the network).
+ */
+ PerformanceEvents["AcquireTokenSilent"] = "acquireTokenSilent";
+ /**
+ * acquireTokenSilentAsync (msal-browser).
+ * Internal API for acquireTokenSilent.
+ */
+ PerformanceEvents["AcquireTokenSilentAsync"] = "acquireTokenSilentAsync";
+ /**
+ * acquireTokenPopup (msal-browser).
+ * Used to acquire a new access token interactively through pop ups
+ */
+ PerformanceEvents["AcquireTokenPopup"] = "acquireTokenPopup";
+ /**
+ * getPublicKeyThumbprint API in CryptoOpts class (msal-browser).
+ * Used to generate a public/private keypair and generate a public key thumbprint for pop requests.
+ */
+ PerformanceEvents["CryptoOptsGetPublicKeyThumbprint"] = "cryptoOptsGetPublicKeyThumbprint";
+ /**
+ * signJwt API in CryptoOpts class (msal-browser).
+ * Used to signed a pop token.
+ */
+ PerformanceEvents["CryptoOptsSignJwt"] = "cryptoOptsSignJwt";
+ /**
+ * acquireToken API in the SilentCacheClient class (msal-browser).
+ * Used to read access tokens from the cache.
+ */
+ PerformanceEvents["SilentCacheClientAcquireToken"] = "silentCacheClientAcquireToken";
+ /**
+ * acquireToken API in the SilentIframeClient class (msal-browser).
+ * Used to acquire a new set of tokens from the authorize endpoint in a hidden iframe.
+ */
+ PerformanceEvents["SilentIframeClientAcquireToken"] = "silentIframeClientAcquireToken";
+ /**
+ * acquireToken API in SilentRereshClient (msal-browser).
+ * Used to acquire a new set of tokens from the token endpoint using a refresh token.
+ */
+ PerformanceEvents["SilentRefreshClientAcquireToken"] = "silentRefreshClientAcquireToken";
+ /**
+ * ssoSilent API (msal-browser).
+ * Used to silently acquire an authorization code and set of tokens using a hidden iframe.
+ */
+ PerformanceEvents["SsoSilent"] = "ssoSilent";
+ /**
+ * getDiscoveredAuthority API in StandardInteractionClient class (msal-browser).
+ * Used to load authority metadata for a request.
+ */
+ PerformanceEvents["StandardInteractionClientGetDiscoveredAuthority"] = "standardInteractionClientGetDiscoveredAuthority";
+ /**
+ * acquireToken APIs in msal-browser.
+ * Used to make an /authorize endpoint call with native brokering enabled.
+ */
+ PerformanceEvents["FetchAccountIdWithNativeBroker"] = "fetchAccountIdWithNativeBroker";
+ /**
+ * acquireToken API in NativeInteractionClient class (msal-browser).
+ * Used to acquire a token from Native component when native brokering is enabled.
+ */
+ PerformanceEvents["NativeInteractionClientAcquireToken"] = "nativeInteractionClientAcquireToken";
+ /**
+ * Time spent creating default headers for requests to token endpoint
+ */
+ PerformanceEvents["BaseClientCreateTokenRequestHeaders"] = "baseClientCreateTokenRequestHeaders";
+ /**
+ * Used to measure the time taken for completing embedded-broker handshake (PW-Broker).
+ */
+ PerformanceEvents["BrokerHandhshake"] = "brokerHandshake";
+ /**
+ * acquireTokenByRefreshToken API in BrokerClientApplication (PW-Broker) .
+ */
+ PerformanceEvents["AcquireTokenByRefreshTokenInBroker"] = "acquireTokenByRefreshTokenInBroker";
+ /**
+ * Time taken for token acquisition by broker
+ */
+ PerformanceEvents["AcquireTokenByBroker"] = "acquireTokenByBroker";
+ /**
+ * Time spent on the network for refresh token acquisition
+ */
+ PerformanceEvents["RefreshTokenClientExecuteTokenRequest"] = "refreshTokenClientExecuteTokenRequest";
+ /**
+ * Time taken for acquiring refresh token , records RT size
+ */
+ PerformanceEvents["RefreshTokenClientAcquireToken"] = "refreshTokenClientAcquireToken";
+ /**
+ * Time taken for acquiring cached refresh token
+ */
+ PerformanceEvents["RefreshTokenClientAcquireTokenWithCachedRefreshToken"] = "refreshTokenClientAcquireTokenWithCachedRefreshToken";
+ /**
+ * acquireTokenByRefreshToken API in RefreshTokenClient (msal-common).
+ */
+ PerformanceEvents["RefreshTokenClientAcquireTokenByRefreshToken"] = "refreshTokenClientAcquireTokenByRefreshToken";
+ /**
+ * Helper function to create token request body in RefreshTokenClient (msal-common).
+ */
+ PerformanceEvents["RefreshTokenClientCreateTokenRequestBody"] = "refreshTokenClientCreateTokenRequestBody";
+ /**
+ * acquireTokenFromCache (msal-browser).
+ * Internal API for acquiring token from cache
+ */
+ PerformanceEvents["AcquireTokenFromCache"] = "acquireTokenFromCache";
+ /**
+ * acquireTokenBySilentIframe (msal-browser).
+ * Internal API for acquiring token by silent Iframe
+ */
+ PerformanceEvents["AcquireTokenBySilentIframe"] = "acquireTokenBySilentIframe";
+ /**
+ * Internal API for initializing base request in BaseInteractionClient (msal-browser)
+ */
+ PerformanceEvents["InitializeBaseRequest"] = "initializeBaseRequest";
+ /**
+ * Internal API for initializing silent request in SilentCacheClient (msal-browser)
+ */
+ PerformanceEvents["InitializeSilentRequest"] = "initializeSilentRequest";
+ PerformanceEvents["InitializeClientApplication"] = "initializeClientApplication";
+ /**
+ * Helper function in SilentIframeClient class (msal-browser).
+ */
+ PerformanceEvents["SilentIframeClientTokenHelper"] = "silentIframeClientTokenHelper";
+ /**
+ * SilentHandler
+ */
+ PerformanceEvents["SilentHandlerInitiateAuthRequest"] = "silentHandlerInitiateAuthRequest";
+ PerformanceEvents["SilentHandlerMonitorIframeForHash"] = "silentHandlerMonitorIframeForHash";
+ PerformanceEvents["SilentHandlerLoadFrame"] = "silentHandlerLoadFrame";
+ /**
+ * Helper functions in StandardInteractionClient class (msal-browser)
+ */
+ PerformanceEvents["StandardInteractionClientCreateAuthCodeClient"] = "standardInteractionClientCreateAuthCodeClient";
+ PerformanceEvents["StandardInteractionClientGetClientConfiguration"] = "standardInteractionClientGetClientConfiguration";
+ PerformanceEvents["StandardInteractionClientInitializeAuthorizationRequest"] = "standardInteractionClientInitializeAuthorizationRequest";
+ PerformanceEvents["StandardInteractionClientInitializeAuthorizationCodeRequest"] = "standardInteractionClientInitializeAuthorizationCodeRequest";
+ /**
+ * getAuthCodeUrl API (msal-browser and msal-node).
+ */
+ PerformanceEvents["GetAuthCodeUrl"] = "getAuthCodeUrl";
+ /**
+ * Functions from InteractionHandler (msal-browser)
+ */
+ PerformanceEvents["HandleCodeResponseFromServer"] = "handleCodeResponseFromServer";
+ PerformanceEvents["HandleCodeResponseFromHash"] = "handleCodeResponseFromHash";
+ PerformanceEvents["UpdateTokenEndpointAuthority"] = "updateTokenEndpointAuthority";
+ /**
+ * APIs in Authorization Code Client (msal-common)
+ */
+ PerformanceEvents["AuthClientAcquireToken"] = "authClientAcquireToken";
+ PerformanceEvents["AuthClientExecuteTokenRequest"] = "authClientExecuteTokenRequest";
+ PerformanceEvents["AuthClientCreateTokenRequestBody"] = "authClientCreateTokenRequestBody";
+ PerformanceEvents["AuthClientCreateQueryString"] = "authClientCreateQueryString";
+ /**
+ * Generate functions in PopTokenGenerator (msal-common)
+ */
+ PerformanceEvents["PopTokenGenerateCnf"] = "popTokenGenerateCnf";
+ PerformanceEvents["PopTokenGenerateKid"] = "popTokenGenerateKid";
+ /**
+ * handleServerTokenResponse API in ResponseHandler (msal-common)
+ */
+ PerformanceEvents["HandleServerTokenResponse"] = "handleServerTokenResponse";
+ /**
+ * Authority functions
+ */
+ PerformanceEvents["AuthorityFactoryCreateDiscoveredInstance"] = "authorityFactoryCreateDiscoveredInstance";
+ PerformanceEvents["AuthorityResolveEndpointsAsync"] = "authorityResolveEndpointsAsync";
+ PerformanceEvents["AuthorityGetCloudDiscoveryMetadataFromNetwork"] = "authorityGetCloudDiscoveryMetadataFromNetwork";
+ PerformanceEvents["AuthorityUpdateCloudDiscoveryMetadata"] = "authorityUpdateCloudDiscoveryMetadata";
+ PerformanceEvents["AuthorityGetEndpointMetadataFromNetwork"] = "authorityGetEndpointMetadataFromNetwork";
+ PerformanceEvents["AuthorityUpdateEndpointMetadata"] = "authorityUpdateEndpointMetadata";
+ PerformanceEvents["AuthorityUpdateMetadataWithRegionalInformation"] = "authorityUpdateMetadataWithRegionalInformation";
+ /**
+ * Region Discovery functions
+ */
+ PerformanceEvents["RegionDiscoveryDetectRegion"] = "regionDiscoveryDetectRegion";
+ PerformanceEvents["RegionDiscoveryGetRegionFromIMDS"] = "regionDiscoveryGetRegionFromIMDS";
+ PerformanceEvents["RegionDiscoveryGetCurrentVersion"] = "regionDiscoveryGetCurrentVersion";
+ PerformanceEvents["AcquireTokenByCodeAsync"] = "acquireTokenByCodeAsync";
+ PerformanceEvents["GetEndpointMetadataFromNetwork"] = "getEndpointMetadataFromNetwork";
+ PerformanceEvents["GetCloudDiscoveryMetadataFromNetworkMeasurement"] = "getCloudDiscoveryMetadataFromNetworkMeasurement";
+ PerformanceEvents["HandleRedirectPromiseMeasurement"] = "handleRedirectPromiseMeasurement";
+ PerformanceEvents["UpdateCloudDiscoveryMetadataMeasurement"] = "updateCloudDiscoveryMetadataMeasurement";
+ PerformanceEvents["UsernamePasswordClientAcquireToken"] = "usernamePasswordClientAcquireToken";
+ PerformanceEvents["NativeMessageHandlerHandshake"] = "nativeMessageHandlerHandshake";
+})(exports.PerformanceEvents || (exports.PerformanceEvents = {}));
+/**
+ * State of the performance event.
+ *
+ * @export
+ * @enum {number}
+ */
+exports.PerformanceEventStatus = void 0;
+(function (PerformanceEventStatus) {
+ PerformanceEventStatus[PerformanceEventStatus["NotStarted"] = 0] = "NotStarted";
+ PerformanceEventStatus[PerformanceEventStatus["InProgress"] = 1] = "InProgress";
+ PerformanceEventStatus[PerformanceEventStatus["Completed"] = 2] = "Completed";
+})(exports.PerformanceEventStatus || (exports.PerformanceEventStatus = {}));
+var IntFields = new Set([
+ "accessTokenSize",
+ "durationMs",
+ "idTokenSize",
+ "matsSilentStatus",
+ "matsHttpStatus",
+ "refreshTokenSize",
+ "queuedTimeMs",
+ "startTimeMs",
+ "status",
+]);
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var KeyLocation;
+(function (KeyLocation) {
+ KeyLocation["SW"] = "sw";
+ KeyLocation["UHW"] = "uhw";
+})(KeyLocation || (KeyLocation = {}));
+var PopTokenGenerator = /** @class */ (function () {
+ function PopTokenGenerator(cryptoUtils, performanceClient) {
+ this.cryptoUtils = cryptoUtils;
+ this.performanceClient = performanceClient;
+ }
+ /**
+ * Generates the req_cnf validated at the RP in the POP protocol for SHR parameters
+ * and returns an object containing the keyid, the full req_cnf string and the req_cnf string hash
+ * @param request
+ * @returns
+ */
+ PopTokenGenerator.prototype.generateCnf = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var reqCnf, reqCnfString, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.PopTokenGenerateCnf, request.correlationId);
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.PopTokenGenerateKid, request.correlationId);
+ return [4 /*yield*/, this.generateKid(request)];
+ case 1:
+ reqCnf = _d.sent();
+ reqCnfString = this.cryptoUtils.base64Encode(JSON.stringify(reqCnf));
+ _c = {
+ kid: reqCnf.kid,
+ reqCnfString: reqCnfString
+ };
+ return [4 /*yield*/, this.cryptoUtils.hashString(reqCnfString)];
+ case 2: return [2 /*return*/, (_c.reqCnfHash = _d.sent(),
+ _c)];
+ }
+ });
+ });
+ };
+ /**
+ * Generates key_id for a SHR token request
+ * @param request
+ * @returns
+ */
+ PopTokenGenerator.prototype.generateKid = function (request) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var kidThumbprint;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.PopTokenGenerateKid, request.correlationId);
+ return [4 /*yield*/, this.cryptoUtils.getPublicKeyThumbprint(request)];
+ case 1:
+ kidThumbprint = _b.sent();
+ return [2 /*return*/, {
+ kid: kidThumbprint,
+ xms_ksl: KeyLocation.SW
+ }];
+ }
+ });
+ });
+ };
+ /**
+ * Signs the POP access_token with the local generated key-pair
+ * @param accessToken
+ * @param request
+ * @returns
+ */
+ PopTokenGenerator.prototype.signPopToken = function (accessToken, keyId, request) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, this.signPayload(accessToken, keyId, request)];
+ });
+ });
+ };
+ /**
+ * Utility function to generate the signed JWT for an access_token
+ * @param payload
+ * @param kid
+ * @param request
+ * @param claims
+ * @returns
+ */
+ PopTokenGenerator.prototype.signPayload = function (payload, keyId, request, claims) {
+ return __awaiter(this, void 0, void 0, function () {
+ var resourceRequestMethod, resourceRequestUri, shrClaims, shrNonce, resourceUrlString, resourceUrlComponents;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ resourceRequestMethod = request.resourceRequestMethod, resourceRequestUri = request.resourceRequestUri, shrClaims = request.shrClaims, shrNonce = request.shrNonce;
+ resourceUrlString = (resourceRequestUri) ? new UrlString(resourceRequestUri) : undefined;
+ resourceUrlComponents = resourceUrlString === null || resourceUrlString === void 0 ? void 0 : resourceUrlString.getUrlComponents();
+ return [4 /*yield*/, this.cryptoUtils.signJwt(__assign({ at: payload, ts: TimeUtils.nowSeconds(), m: resourceRequestMethod === null || resourceRequestMethod === void 0 ? void 0 : resourceRequestMethod.toUpperCase(), u: resourceUrlComponents === null || resourceUrlComponents === void 0 ? void 0 : resourceUrlComponents.HostNameAndPort, nonce: shrNonce || this.cryptoUtils.createNewGuid(), p: resourceUrlComponents === null || resourceUrlComponents === void 0 ? void 0 : resourceUrlComponents.AbsolutePath, q: (resourceUrlComponents === null || resourceUrlComponents === void 0 ? void 0 : resourceUrlComponents.QueryString) ? [[], resourceUrlComponents.QueryString] : undefined, client_claims: shrClaims || undefined }, claims), keyId, request.correlationId)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return PopTokenGenerator;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * APP_METADATA Cache
+ *
+ * Key:Value Schema:
+ *
+ * Key: appmetadata--
+ *
+ * Value:
+ * {
+ * clientId: client ID of the application
+ * environment: entity that issued the token, represented as a full host
+ * familyId: Family ID identifier, '1' represents Microsoft Family
+ * }
+ */
+var AppMetadataEntity = /** @class */ (function () {
+ function AppMetadataEntity() {
+ }
+ /**
+ * Generate AppMetadata Cache Key as per the schema: appmetadata--
+ */
+ AppMetadataEntity.prototype.generateAppMetadataKey = function () {
+ return AppMetadataEntity.generateAppMetadataCacheKey(this.environment, this.clientId);
+ };
+ /**
+ * Generate AppMetadata Cache Key
+ */
+ AppMetadataEntity.generateAppMetadataCacheKey = function (environment, clientId) {
+ var appMetaDataKeyArray = [
+ APP_METADATA,
+ environment,
+ clientId,
+ ];
+ return appMetaDataKeyArray.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
+ };
+ /**
+ * Creates AppMetadataEntity
+ * @param clientId
+ * @param environment
+ * @param familyId
+ */
+ AppMetadataEntity.createAppMetadataEntity = function (clientId, environment, familyId) {
+ var appMetadata = new AppMetadataEntity();
+ appMetadata.clientId = clientId;
+ appMetadata.environment = environment;
+ if (familyId) {
+ appMetadata.familyId = familyId;
+ }
+ return appMetadata;
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ AppMetadataEntity.isAppMetadataEntity = function (key, entity) {
+ if (!entity) {
+ return false;
+ }
+ return (key.indexOf(APP_METADATA) === 0 &&
+ entity.hasOwnProperty("clientId") &&
+ entity.hasOwnProperty("environment"));
+ };
+ return AppMetadataEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class instance helps track the memory changes facilitating
+ * decisions to read from and write to the persistent cache
+ */ var TokenCacheContext = /** @class */ (function () {
+ function TokenCacheContext(tokenCache, hasChanged) {
+ this.cache = tokenCache;
+ this.hasChanged = hasChanged;
+ }
+ Object.defineProperty(TokenCacheContext.prototype, "cacheHasChanged", {
+ /**
+ * boolean which indicates the changes in cache
+ */
+ get: function () {
+ return this.hasChanged;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(TokenCacheContext.prototype, "tokenCache", {
+ /**
+ * function to retrieve the token cache
+ */
+ get: function () {
+ return this.cache;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ return TokenCacheContext;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Class that handles response parsing.
+ */
+var ResponseHandler = /** @class */ (function () {
+ function ResponseHandler(clientId, cacheStorage, cryptoObj, logger, serializableCache, persistencePlugin, performanceClient) {
+ this.clientId = clientId;
+ this.cacheStorage = cacheStorage;
+ this.cryptoObj = cryptoObj;
+ this.logger = logger;
+ this.serializableCache = serializableCache;
+ this.persistencePlugin = persistencePlugin;
+ this.performanceClient = performanceClient;
+ }
+ /**
+ * Function which validates server authorization code response.
+ * @param serverResponseHash
+ * @param cachedState
+ * @param cryptoObj
+ */
+ ResponseHandler.prototype.validateServerAuthorizationCodeResponse = function (serverResponseHash, cachedState, cryptoObj) {
+ if (!serverResponseHash.state || !cachedState) {
+ throw !serverResponseHash.state ? ClientAuthError.createStateNotFoundError("Server State") : ClientAuthError.createStateNotFoundError("Cached State");
+ }
+ if (decodeURIComponent(serverResponseHash.state) !== decodeURIComponent(cachedState)) {
+ throw ClientAuthError.createStateMismatchError();
+ }
+ // Check for error
+ if (serverResponseHash.error || serverResponseHash.error_description || serverResponseHash.suberror) {
+ if (InteractionRequiredAuthError.isInteractionRequiredError(serverResponseHash.error, serverResponseHash.error_description, serverResponseHash.suberror)) {
+ throw new InteractionRequiredAuthError(serverResponseHash.error || Constants.EMPTY_STRING, serverResponseHash.error_description, serverResponseHash.suberror, serverResponseHash.timestamp || Constants.EMPTY_STRING, serverResponseHash.trace_id || Constants.EMPTY_STRING, serverResponseHash.correlation_id || Constants.EMPTY_STRING, serverResponseHash.claims || Constants.EMPTY_STRING);
+ }
+ throw new ServerError(serverResponseHash.error || Constants.EMPTY_STRING, serverResponseHash.error_description, serverResponseHash.suberror);
+ }
+ if (serverResponseHash.client_info) {
+ buildClientInfo(serverResponseHash.client_info, cryptoObj);
+ }
+ };
+ /**
+ * Function which validates server authorization token response.
+ * @param serverResponse
+ */
+ ResponseHandler.prototype.validateTokenResponse = function (serverResponse) {
+ // Check for error
+ if (serverResponse.error || serverResponse.error_description || serverResponse.suberror) {
+ if (InteractionRequiredAuthError.isInteractionRequiredError(serverResponse.error, serverResponse.error_description, serverResponse.suberror)) {
+ throw new InteractionRequiredAuthError(serverResponse.error, serverResponse.error_description, serverResponse.suberror, serverResponse.timestamp || Constants.EMPTY_STRING, serverResponse.trace_id || Constants.EMPTY_STRING, serverResponse.correlation_id || Constants.EMPTY_STRING, serverResponse.claims || Constants.EMPTY_STRING);
+ }
+ var errString = serverResponse.error_codes + " - [" + serverResponse.timestamp + "]: " + serverResponse.error_description + " - Correlation ID: " + serverResponse.correlation_id + " - Trace ID: " + serverResponse.trace_id;
+ throw new ServerError(serverResponse.error, errString, serverResponse.suberror);
+ }
+ };
+ /**
+ * Returns a constructed token response based on given string. Also manages the cache updates and cleanups.
+ * @param serverTokenResponse
+ * @param authority
+ */
+ ResponseHandler.prototype.handleServerTokenResponse = function (serverTokenResponse, authority, reqTimestamp, request, authCodePayload, userAssertionHash, handlingRefreshTokenResponse, forceCacheRefreshTokenResponse, serverRequestId) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var idTokenObj, authTime, requestStateObj, cacheRecord, cacheContext, key, account;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.HandleServerTokenResponse, serverTokenResponse.correlation_id);
+ if (serverTokenResponse.id_token) {
+ idTokenObj = new AuthToken(serverTokenResponse.id_token || Constants.EMPTY_STRING, this.cryptoObj);
+ // token nonce check (TODO: Add a warning if no nonce is given?)
+ if (authCodePayload && !StringUtils.isEmpty(authCodePayload.nonce)) {
+ if (idTokenObj.claims.nonce !== authCodePayload.nonce) {
+ throw ClientAuthError.createNonceMismatchError();
+ }
+ }
+ // token max_age check
+ if (request.maxAge || (request.maxAge === 0)) {
+ authTime = idTokenObj.claims.auth_time;
+ if (!authTime) {
+ throw ClientAuthError.createAuthTimeNotFoundError();
+ }
+ AuthToken.checkMaxAge(authTime, request.maxAge);
+ }
+ }
+ // generate homeAccountId
+ this.homeAccountIdentifier = AccountEntity.generateHomeAccountId(serverTokenResponse.client_info || Constants.EMPTY_STRING, authority.authorityType, this.logger, this.cryptoObj, idTokenObj);
+ if (!!authCodePayload && !!authCodePayload.state) {
+ requestStateObj = ProtocolUtils.parseRequestState(this.cryptoObj, authCodePayload.state);
+ }
+ // Add keyId from request to serverTokenResponse if defined
+ serverTokenResponse.key_id = serverTokenResponse.key_id || request.sshKid || undefined;
+ cacheRecord = this.generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenObj, userAssertionHash, authCodePayload);
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, , 5, 8]);
+ if (!(this.persistencePlugin && this.serializableCache)) return [3 /*break*/, 3];
+ this.logger.verbose("Persistence enabled, calling beforeCacheAccess");
+ cacheContext = new TokenCacheContext(this.serializableCache, true);
+ return [4 /*yield*/, this.persistencePlugin.beforeCacheAccess(cacheContext)];
+ case 2:
+ _b.sent();
+ _b.label = 3;
+ case 3:
+ /*
+ * When saving a refreshed tokens to the cache, it is expected that the account that was used is present in the cache.
+ * If not present, we should return null, as it's the case that another application called removeAccount in between
+ * the calls to getAllAccounts and acquireTokenSilent. We should not overwrite that removal, unless explicitly flagged by
+ * the developer, as in the case of refresh token flow used in ADAL Node to MSAL Node migration.
+ */
+ if (handlingRefreshTokenResponse && !forceCacheRefreshTokenResponse && cacheRecord.account) {
+ key = cacheRecord.account.generateAccountKey();
+ account = this.cacheStorage.getAccount(key);
+ if (!account) {
+ this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
+ return [2 /*return*/, ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, undefined, serverRequestId)];
+ }
+ }
+ return [4 /*yield*/, this.cacheStorage.saveCacheRecord(cacheRecord)];
+ case 4:
+ _b.sent();
+ return [3 /*break*/, 8];
+ case 5:
+ if (!(this.persistencePlugin && this.serializableCache && cacheContext)) return [3 /*break*/, 7];
+ this.logger.verbose("Persistence enabled, calling afterCacheAccess");
+ return [4 /*yield*/, this.persistencePlugin.afterCacheAccess(cacheContext)];
+ case 6:
+ _b.sent();
+ _b.label = 7;
+ case 7: return [7 /*endfinally*/];
+ case 8: return [2 /*return*/, ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, serverTokenResponse, serverRequestId)];
+ }
+ });
+ });
+ };
+ /**
+ * Generates CacheRecord
+ * @param serverTokenResponse
+ * @param idTokenObj
+ * @param authority
+ */
+ ResponseHandler.prototype.generateCacheRecord = function (serverTokenResponse, authority, reqTimestamp, request, idTokenObj, userAssertionHash, authCodePayload) {
+ var env = authority.getPreferredCache();
+ if (StringUtils.isEmpty(env)) {
+ throw ClientAuthError.createInvalidCacheEnvironmentError();
+ }
+ // IdToken: non AAD scenarios can have empty realm
+ var cachedIdToken;
+ var cachedAccount;
+ if (!StringUtils.isEmpty(serverTokenResponse.id_token) && !!idTokenObj) {
+ cachedIdToken = IdTokenEntity.createIdTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.id_token || Constants.EMPTY_STRING, this.clientId, idTokenObj.claims.tid || Constants.EMPTY_STRING);
+ cachedAccount = this.generateAccountEntity(serverTokenResponse, idTokenObj, authority, authCodePayload);
+ }
+ // AccessToken
+ var cachedAccessToken = null;
+ if (!StringUtils.isEmpty(serverTokenResponse.access_token)) {
+ // If scopes not returned in server response, use request scopes
+ var responseScopes = serverTokenResponse.scope ? ScopeSet.fromString(serverTokenResponse.scope) : new ScopeSet(request.scopes || []);
+ /*
+ * Use timestamp calculated before request
+ * Server may return timestamps as strings, parse to numbers if so.
+ */
+ var expiresIn = (typeof serverTokenResponse.expires_in === "string" ? parseInt(serverTokenResponse.expires_in, 10) : serverTokenResponse.expires_in) || 0;
+ var extExpiresIn = (typeof serverTokenResponse.ext_expires_in === "string" ? parseInt(serverTokenResponse.ext_expires_in, 10) : serverTokenResponse.ext_expires_in) || 0;
+ var refreshIn = (typeof serverTokenResponse.refresh_in === "string" ? parseInt(serverTokenResponse.refresh_in, 10) : serverTokenResponse.refresh_in) || undefined;
+ var tokenExpirationSeconds = reqTimestamp + expiresIn;
+ var extendedTokenExpirationSeconds = tokenExpirationSeconds + extExpiresIn;
+ var refreshOnSeconds = refreshIn && refreshIn > 0 ? reqTimestamp + refreshIn : undefined;
+ // non AAD scenarios can have empty realm
+ cachedAccessToken = AccessTokenEntity.createAccessTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.access_token || Constants.EMPTY_STRING, this.clientId, idTokenObj ? idTokenObj.claims.tid || Constants.EMPTY_STRING : authority.tenant, responseScopes.printScopes(), tokenExpirationSeconds, extendedTokenExpirationSeconds, this.cryptoObj, refreshOnSeconds, serverTokenResponse.token_type, userAssertionHash, serverTokenResponse.key_id, request.claims, request.requestedClaimsHash);
+ }
+ // refreshToken
+ var cachedRefreshToken = null;
+ if (!StringUtils.isEmpty(serverTokenResponse.refresh_token)) {
+ cachedRefreshToken = RefreshTokenEntity.createRefreshTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.refresh_token || Constants.EMPTY_STRING, this.clientId, serverTokenResponse.foci, userAssertionHash);
+ }
+ // appMetadata
+ var cachedAppMetadata = null;
+ if (!StringUtils.isEmpty(serverTokenResponse.foci)) {
+ cachedAppMetadata = AppMetadataEntity.createAppMetadataEntity(this.clientId, env, serverTokenResponse.foci);
+ }
+ return new CacheRecord(cachedAccount, cachedIdToken, cachedAccessToken, cachedRefreshToken, cachedAppMetadata);
+ };
+ /**
+ * Generate Account
+ * @param serverTokenResponse
+ * @param idToken
+ * @param authority
+ */
+ ResponseHandler.prototype.generateAccountEntity = function (serverTokenResponse, idToken, authority, authCodePayload) {
+ var authorityType = authority.authorityType;
+ var cloudGraphHostName = authCodePayload ? authCodePayload.cloud_graph_host_name : Constants.EMPTY_STRING;
+ var msGraphhost = authCodePayload ? authCodePayload.msgraph_host : Constants.EMPTY_STRING;
+ // ADFS does not require client_info in the response
+ if (authorityType === exports.AuthorityType.Adfs) {
+ this.logger.verbose("Authority type is ADFS, creating ADFS account");
+ return AccountEntity.createGenericAccount(this.homeAccountIdentifier, idToken, authority, cloudGraphHostName, msGraphhost);
+ }
+ // This fallback applies to B2C as well as they fall under an AAD account type.
+ if (StringUtils.isEmpty(serverTokenResponse.client_info) && authority.protocolMode === "AAD") {
+ throw ClientAuthError.createClientInfoEmptyError();
+ }
+ return serverTokenResponse.client_info ?
+ AccountEntity.createAccount(serverTokenResponse.client_info, this.homeAccountIdentifier, idToken, authority, cloudGraphHostName, msGraphhost) :
+ AccountEntity.createGenericAccount(this.homeAccountIdentifier, idToken, authority, cloudGraphHostName, msGraphhost);
+ };
+ /**
+ * Creates an @AuthenticationResult from @CacheRecord , @IdToken , and a boolean that states whether or not the result is from cache.
+ *
+ * Optionally takes a state string that is set as-is in the response.
+ *
+ * @param cacheRecord
+ * @param idTokenObj
+ * @param fromTokenCache
+ * @param stateString
+ */
+ ResponseHandler.generateAuthenticationResult = function (cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenObj, requestState, serverTokenResponse, requestId) {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var accessToken, responseScopes, expiresOn, extExpiresOn, familyId, popTokenGenerator, _d, secret, keyId, uid, tid;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ accessToken = Constants.EMPTY_STRING;
+ responseScopes = [];
+ expiresOn = null;
+ familyId = Constants.EMPTY_STRING;
+ if (!cacheRecord.accessToken) return [3 /*break*/, 4];
+ if (!(cacheRecord.accessToken.tokenType === exports.AuthenticationScheme.POP)) return [3 /*break*/, 2];
+ popTokenGenerator = new PopTokenGenerator(cryptoObj);
+ _d = cacheRecord.accessToken, secret = _d.secret, keyId = _d.keyId;
+ if (!keyId) {
+ throw ClientAuthError.createKeyIdMissingError();
+ }
+ return [4 /*yield*/, popTokenGenerator.signPopToken(secret, keyId, request)];
+ case 1:
+ accessToken = _e.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ accessToken = cacheRecord.accessToken.secret;
+ _e.label = 3;
+ case 3:
+ responseScopes = ScopeSet.fromString(cacheRecord.accessToken.target).asArray();
+ expiresOn = new Date(Number(cacheRecord.accessToken.expiresOn) * 1000);
+ extExpiresOn = new Date(Number(cacheRecord.accessToken.extendedExpiresOn) * 1000);
+ _e.label = 4;
+ case 4:
+ if (cacheRecord.appMetadata) {
+ familyId = cacheRecord.appMetadata.familyId === THE_FAMILY_ID ? THE_FAMILY_ID : Constants.EMPTY_STRING;
+ }
+ uid = (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.oid) || (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.sub) || Constants.EMPTY_STRING;
+ tid = (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.tid) || Constants.EMPTY_STRING;
+ // for hybrid + native bridge enablement, send back the native account Id
+ if ((serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_accountid) && !!cacheRecord.account) {
+ cacheRecord.account.nativeAccountId = serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_accountid;
+ }
+ return [2 /*return*/, {
+ authority: authority.canonicalAuthority,
+ uniqueId: uid,
+ tenantId: tid,
+ scopes: responseScopes,
+ account: cacheRecord.account ? cacheRecord.account.getAccountInfo() : null,
+ idToken: idTokenObj ? idTokenObj.rawToken : Constants.EMPTY_STRING,
+ idTokenClaims: idTokenObj ? idTokenObj.claims : {},
+ accessToken: accessToken,
+ fromCache: fromTokenCache,
+ expiresOn: expiresOn,
+ correlationId: request.correlationId,
+ requestId: requestId || Constants.EMPTY_STRING,
+ extExpiresOn: extExpiresOn,
+ familyId: familyId,
+ tokenType: ((_a = cacheRecord.accessToken) === null || _a === void 0 ? void 0 : _a.tokenType) || Constants.EMPTY_STRING,
+ state: requestState ? requestState.userRequestState : Constants.EMPTY_STRING,
+ cloudGraphHostName: ((_b = cacheRecord.account) === null || _b === void 0 ? void 0 : _b.cloudGraphHostName) || Constants.EMPTY_STRING,
+ msGraphHost: ((_c = cacheRecord.account) === null || _c === void 0 ? void 0 : _c.msGraphHost) || Constants.EMPTY_STRING,
+ code: serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_code,
+ fromNativeBroker: false,
+ }];
+ }
+ });
+ });
+ };
+ return ResponseHandler;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Oauth2.0 Authorization Code client
+ */
+var AuthorizationCodeClient = /** @class */ (function (_super) {
+ __extends(AuthorizationCodeClient, _super);
+ function AuthorizationCodeClient(configuration, performanceClient) {
+ var _this = _super.call(this, configuration, performanceClient) || this;
+ // Flag to indicate if client is for hybrid spa auth code redemption
+ _this.includeRedirectUri = true;
+ return _this;
+ }
+ /**
+ * Creates the URL of the authorization request letting the user input credentials and consent to the
+ * application. The URL target the /authorize endpoint of the authority configured in the
+ * application object.
+ *
+ * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI
+ * sent in the request and should contain an authorization code, which can then be used to acquire tokens via
+ * acquireToken(AuthorizationCodeRequest)
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.getAuthCodeUrl = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var queryString;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.GetAuthCodeUrl, request.correlationId);
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
+ return [4 /*yield*/, this.createAuthCodeUrlQueryString(request)];
+ case 1:
+ queryString = _c.sent();
+ return [2 /*return*/, UrlString.appendQueryString(this.authority.authorizationEndpoint, queryString)];
+ }
+ });
+ });
+ };
+ /**
+ * API to acquire a token in exchange of 'authorization_code` acquired by the user in the first leg of the
+ * authorization_code_grant
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.acquireToken = function (request, authCodePayload) {
+ var _a, _b, _c, _d, _e, _f;
+ return __awaiter(this, void 0, void 0, function () {
+ var atsMeasurement, reqTimestamp, response, requestId, httpVerAuthority, responseHandler;
+ var _this = this;
+ return __generator(this, function (_g) {
+ switch (_g.label) {
+ case 0:
+ if (!request || !request.code) {
+ throw ClientAuthError.createTokenRequestCannotBeMadeError();
+ }
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthClientAcquireToken, request.correlationId);
+ atsMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement("AuthCodeClientAcquireToken", request.correlationId);
+ this.logger.info("in acquireToken call in auth-code client");
+ reqTimestamp = TimeUtils.nowSeconds();
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
+ return [4 /*yield*/, this.executeTokenRequest(this.authority, request)];
+ case 1:
+ response = _g.sent();
+ requestId = (_d = response.headers) === null || _d === void 0 ? void 0 : _d[exports.HeaderNames.X_MS_REQUEST_ID];
+ httpVerAuthority = (_e = response.headers) === null || _e === void 0 ? void 0 : _e[exports.HeaderNames.X_MS_HTTP_VERSION];
+ if (httpVerAuthority) {
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.addStaticFields({
+ httpVerAuthority: httpVerAuthority
+ });
+ }
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin, this.performanceClient);
+ // Validate response. This function throws a server error if an error is returned by the server.
+ responseHandler.validateTokenResponse(response.body);
+ (_f = this.performanceClient) === null || _f === void 0 ? void 0 : _f.setPreQueueTime(exports.PerformanceEvents.HandleServerTokenResponse, request.correlationId);
+ return [2 /*return*/, responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, authCodePayload, undefined, undefined, undefined, requestId).then(function (result) {
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.endMeasurement({
+ success: true
+ });
+ return result;
+ })
+ .catch(function (error) {
+ _this.logger.verbose("Error in fetching token in ACC", request.correlationId);
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.endMeasurement({
+ errorCode: error.errorCode,
+ subErrorCode: error.subError,
+ success: false
+ });
+ throw error;
+ })];
+ }
+ });
+ });
+ };
+ /**
+ * Handles the hash fragment response from public client code request. Returns a code response used by
+ * the client to exchange for a token in acquireToken.
+ * @param hashFragment
+ */
+ AuthorizationCodeClient.prototype.handleFragmentResponse = function (hashFragment, cachedState) {
+ // Handle responses.
+ var responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, null, null);
+ // Deserialize hash fragment response parameters.
+ var hashUrlString = new UrlString(hashFragment);
+ // Deserialize hash fragment response parameters.
+ var serverParams = UrlString.getDeserializedHash(hashUrlString.getHash());
+ // Get code response
+ responseHandler.validateServerAuthorizationCodeResponse(serverParams, cachedState, this.cryptoUtils);
+ // throw when there is no auth code in the response
+ if (!serverParams.code) {
+ throw ClientAuthError.createNoAuthCodeInServerResponseError();
+ }
+ return __assign(__assign({}, serverParams), {
+ // Code param is optional in ServerAuthorizationCodeResponse but required in AuthorizationCodePaylod
+ code: serverParams.code });
+ };
+ /**
+ * Used to log out the current user, and redirect the user to the postLogoutRedirectUri.
+ * Default behaviour is to redirect the user to `window.location.href`.
+ * @param authorityUri
+ */
+ AuthorizationCodeClient.prototype.getLogoutUri = function (logoutRequest) {
+ // Throw error if logoutRequest is null/undefined
+ if (!logoutRequest) {
+ throw ClientConfigurationError.createEmptyLogoutRequestError();
+ }
+ var queryString = this.createLogoutUrlQueryString(logoutRequest);
+ // Construct logout URI
+ return UrlString.appendQueryString(this.authority.endSessionEndpoint, queryString);
+ };
+ /**
+ * Executes POST request to token endpoint
+ * @param authority
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.executeTokenRequest = function (authority, request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var queryParametersString, endpoint, requestBody, ccsCredential, clientInfo, headers, thumbprint;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
+ return [4 /*yield*/, this.createTokenRequestBody(request)];
+ case 1:
+ requestBody = _c.sent();
+ ccsCredential = undefined;
+ if (request.clientInfo) {
+ try {
+ clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
+ ccsCredential = {
+ credential: "" + clientInfo.uid + Separators.CLIENT_INFO_SEPARATOR + clientInfo.utid,
+ type: exports.CcsCredentialType.HOME_ACCOUNT_ID
+ };
+ }
+ catch (e) {
+ this.logger.verbose("Could not parse client info for CCS Header: " + e);
+ }
+ }
+ headers = this.createTokenRequestHeaders(ccsCredential || request.ccsCredential);
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: authority.canonicalAuthority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ return [2 /*return*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)];
+ }
+ });
+ });
+ };
+ /**
+ * Generates a map for all the params to be sent to the service
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.createTokenRequestBody = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var parameterBuilder, clientAssertion, popTokenGenerator, reqCnfData, correlationId, ccsCred, clientInfo, clientInfo;
+ var _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
+ parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ /*
+ * For hybrid spa flow, there will be a code but no verifier
+ * In this scenario, don't include redirect uri as auth code will not be bound to redirect URI
+ */
+ if (!this.includeRedirectUri) {
+ // Just validate
+ RequestValidator.validateRedirectUri(request.redirectUri);
+ }
+ else {
+ // Validate and include redirect uri
+ parameterBuilder.addRedirectUri(request.redirectUri);
+ }
+ // Add scope array, parameter builder will add default scopes and dedupe
+ parameterBuilder.addScopes(request.scopes);
+ // add code: user set, not validated
+ parameterBuilder.addAuthorizationCode(request.code);
+ // Add library metadata
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ parameterBuilder.addThrottling();
+ if (this.serverTelemetryManager) {
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
+ }
+ // add code_verifier if passed
+ if (request.codeVerifier) {
+ parameterBuilder.addCodeVerifier(request.codeVerifier);
+ }
+ if (this.config.clientCredentials.clientSecret) {
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
+ }
+ if (this.config.clientCredentials.clientAssertion) {
+ clientAssertion = this.config.clientCredentials.clientAssertion;
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
+ }
+ parameterBuilder.addGrantType(GrantType.AUTHORIZATION_CODE_GRANT);
+ parameterBuilder.addClientInfo();
+ if (!(request.authenticationScheme === exports.AuthenticationScheme.POP)) return [3 /*break*/, 2];
+ popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient);
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.PopTokenGenerateCnf, request.correlationId);
+ return [4 /*yield*/, popTokenGenerator.generateCnf(request)];
+ case 1:
+ reqCnfData = _d.sent();
+ // SPA PoP requires full Base64Url encoded req_cnf string (unhashed)
+ parameterBuilder.addPopToken(reqCnfData.reqCnfString);
+ return [3 /*break*/, 3];
+ case 2:
+ if (request.authenticationScheme === exports.AuthenticationScheme.SSH) {
+ if (request.sshJwk) {
+ parameterBuilder.addSshJwk(request.sshJwk);
+ }
+ else {
+ throw ClientConfigurationError.createMissingSshJwkError();
+ }
+ }
+ _d.label = 3;
+ case 3:
+ correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ parameterBuilder.addCorrelationId(correlationId);
+ if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ ccsCred = undefined;
+ if (request.clientInfo) {
+ try {
+ clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
+ ccsCred = {
+ credential: "" + clientInfo.uid + Separators.CLIENT_INFO_SEPARATOR + clientInfo.utid,
+ type: exports.CcsCredentialType.HOME_ACCOUNT_ID
+ };
+ }
+ catch (e) {
+ this.logger.verbose("Could not parse client info for CCS Header: " + e);
+ }
+ }
+ else {
+ ccsCred = request.ccsCredential;
+ }
+ // Adds these as parameters in the request instead of headers to prevent CORS preflight request
+ if (this.config.systemOptions.preventCorsPreflight && ccsCred) {
+ switch (ccsCred.type) {
+ case exports.CcsCredentialType.HOME_ACCOUNT_ID:
+ try {
+ clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
+ parameterBuilder.addCcsOid(clientInfo);
+ }
+ catch (e) {
+ this.logger.verbose("Could not parse home account ID for CCS Header: " + e);
+ }
+ break;
+ case exports.CcsCredentialType.UPN:
+ parameterBuilder.addCcsUpn(ccsCred.credential);
+ break;
+ }
+ }
+ if (request.tokenBodyParameters) {
+ parameterBuilder.addExtraQueryParameters(request.tokenBodyParameters);
+ }
+ // Add hybrid spa parameters if not already provided
+ if (request.enableSpaAuthorizationCode && (!request.tokenBodyParameters || !request.tokenBodyParameters[exports.AADServerParamKeys.RETURN_SPA_CODE])) {
+ parameterBuilder.addExtraQueryParameters((_c = {},
+ _c[exports.AADServerParamKeys.RETURN_SPA_CODE] = "1",
+ _c));
+ }
+ return [2 /*return*/, parameterBuilder.createQueryString()];
+ }
+ });
+ });
+ };
+ /**
+ * This API validates the `AuthorizationCodeUrlRequest` and creates a URL
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.createAuthCodeUrlQueryString = function (request) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var parameterBuilder, requestScopes, correlationId, accountSid, accountLoginHintClaim, clientInfo, clientInfo, clientInfo, popTokenGenerator, reqCnfData;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
+ parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ requestScopes = __spreadArrays(request.scopes || [], request.extraScopesToConsent || []);
+ parameterBuilder.addScopes(requestScopes);
+ // validate the redirectUri (to be a non null value)
+ parameterBuilder.addRedirectUri(request.redirectUri);
+ correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ parameterBuilder.addCorrelationId(correlationId);
+ // add response_mode. If not passed in it defaults to query.
+ parameterBuilder.addResponseMode(request.responseMode);
+ // add response_type = code
+ parameterBuilder.addResponseTypeCode();
+ // add library info parameters
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ // add client_info=1
+ parameterBuilder.addClientInfo();
+ if (request.codeChallenge && request.codeChallengeMethod) {
+ parameterBuilder.addCodeChallengeParams(request.codeChallenge, request.codeChallengeMethod);
+ }
+ if (request.prompt) {
+ parameterBuilder.addPrompt(request.prompt);
+ }
+ if (request.domainHint) {
+ parameterBuilder.addDomainHint(request.domainHint);
+ }
+ // Add sid or loginHint with preference for login_hint claim (in request) -> sid -> loginHint (upn/email) -> username of AccountInfo object
+ if (request.prompt !== PromptValue.SELECT_ACCOUNT) {
+ // AAD will throw if prompt=select_account is passed with an account hint
+ if (request.sid && request.prompt === PromptValue.NONE) {
+ // SessionID is only used in silent calls
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from request");
+ parameterBuilder.addSid(request.sid);
+ }
+ else if (request.account) {
+ accountSid = this.extractAccountSid(request.account);
+ accountLoginHintClaim = this.extractLoginHint(request.account);
+ // If login_hint claim is present, use it over sid/username
+ if (accountLoginHintClaim) {
+ this.logger.verbose("createAuthCodeUrlQueryString: login_hint claim present on account");
+ parameterBuilder.addLoginHint(accountLoginHintClaim);
+ try {
+ clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
+ parameterBuilder.addCcsOid(clientInfo);
+ }
+ catch (e) {
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
+ }
+ }
+ else if (accountSid && request.prompt === PromptValue.NONE) {
+ /*
+ * If account and loginHint are provided, we will check account first for sid before adding loginHint
+ * SessionId is only used in silent calls
+ */
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from account");
+ parameterBuilder.addSid(accountSid);
+ try {
+ clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
+ parameterBuilder.addCcsOid(clientInfo);
+ }
+ catch (e) {
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
+ }
+ }
+ else if (request.loginHint) {
+ this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from request");
+ parameterBuilder.addLoginHint(request.loginHint);
+ parameterBuilder.addCcsUpn(request.loginHint);
+ }
+ else if (request.account.username) {
+ // Fallback to account username if provided
+ this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from account");
+ parameterBuilder.addLoginHint(request.account.username);
+ try {
+ clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
+ parameterBuilder.addCcsOid(clientInfo);
+ }
+ catch (e) {
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
+ }
+ }
+ }
+ else if (request.loginHint) {
+ this.logger.verbose("createAuthCodeUrlQueryString: No account, adding login_hint from request");
+ parameterBuilder.addLoginHint(request.loginHint);
+ parameterBuilder.addCcsUpn(request.loginHint);
+ }
+ }
+ else {
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is select_account, ignoring account hints");
+ }
+ if (request.nonce) {
+ parameterBuilder.addNonce(request.nonce);
+ }
+ if (request.state) {
+ parameterBuilder.addState(request.state);
+ }
+ if (!StringUtils.isEmpty(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ if (request.extraQueryParameters) {
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
+ }
+ if (!request.nativeBroker) return [3 /*break*/, 2];
+ // signal ests that this is a WAM call
+ parameterBuilder.addNativeBroker();
+ if (!(request.authenticationScheme === exports.AuthenticationScheme.POP)) return [3 /*break*/, 2];
+ popTokenGenerator = new PopTokenGenerator(this.cryptoUtils);
+ return [4 /*yield*/, popTokenGenerator.generateCnf(request)];
+ case 1:
+ reqCnfData = _b.sent();
+ parameterBuilder.addPopToken(reqCnfData.reqCnfString);
+ _b.label = 2;
+ case 2: return [2 /*return*/, parameterBuilder.createQueryString()];
+ }
+ });
+ });
+ };
+ /**
+ * This API validates the `EndSessionRequest` and creates a URL
+ * @param request
+ */
+ AuthorizationCodeClient.prototype.createLogoutUrlQueryString = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ if (request.postLogoutRedirectUri) {
+ parameterBuilder.addPostLogoutRedirectUri(request.postLogoutRedirectUri);
+ }
+ if (request.correlationId) {
+ parameterBuilder.addCorrelationId(request.correlationId);
+ }
+ if (request.idTokenHint) {
+ parameterBuilder.addIdTokenHint(request.idTokenHint);
+ }
+ if (request.state) {
+ parameterBuilder.addState(request.state);
+ }
+ if (request.logoutHint) {
+ parameterBuilder.addLogoutHint(request.logoutHint);
+ }
+ if (request.extraQueryParameters) {
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ /**
+ * Helper to get sid from account. Returns null if idTokenClaims are not present or sid is not present.
+ * @param account
+ */
+ AuthorizationCodeClient.prototype.extractAccountSid = function (account) {
+ var _a;
+ return ((_a = account.idTokenClaims) === null || _a === void 0 ? void 0 : _a.sid) || null;
+ };
+ AuthorizationCodeClient.prototype.extractLoginHint = function (account) {
+ var _a;
+ return ((_a = account.idTokenClaims) === null || _a === void 0 ? void 0 : _a.login_hint) || null;
+ };
+ return AuthorizationCodeClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * OAuth2.0 Device code client
+ */
+var DeviceCodeClient = /** @class */ (function (_super) {
+ __extends(DeviceCodeClient, _super);
+ function DeviceCodeClient(configuration) {
+ return _super.call(this, configuration) || this;
+ }
+ /**
+ * Gets device code from device code endpoint, calls back to with device code response, and
+ * polls token endpoint to exchange device code for tokens
+ * @param request
+ */
+ DeviceCodeClient.prototype.acquireToken = function (request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var deviceCodeResponse, reqTimestamp, response, responseHandler;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.getDeviceCode(request)];
+ case 1:
+ deviceCodeResponse = _a.sent();
+ request.deviceCodeCallback(deviceCodeResponse);
+ reqTimestamp = TimeUtils.nowSeconds();
+ return [4 /*yield*/, this.acquireTokenWithDeviceCode(request, deviceCodeResponse)];
+ case 2:
+ response = _a.sent();
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
+ // Validate response. This function throws a server error if an error is returned by the server.
+ responseHandler.validateTokenResponse(response);
+ return [4 /*yield*/, responseHandler.handleServerTokenResponse(response, this.authority, reqTimestamp, request)];
+ case 3: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ /**
+ * Creates device code request and executes http GET
+ * @param request
+ */
+ DeviceCodeClient.prototype.getDeviceCode = function (request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var queryParametersString, endpoint, queryString, headers, thumbprint;
+ return __generator(this, function (_a) {
+ queryParametersString = this.createExtraQueryParameters(request);
+ endpoint = UrlString.appendQueryString(this.authority.deviceCodeEndpoint, queryParametersString);
+ queryString = this.createQueryString(request);
+ headers = this.createTokenRequestHeaders();
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: request.authority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ return [2 /*return*/, this.executePostRequestToDeviceCodeEndpoint(endpoint, queryString, headers, thumbprint)];
+ });
+ });
+ };
+ /**
+ * Creates query string for the device code request
+ * @param request
+ */
+ DeviceCodeClient.prototype.createExtraQueryParameters = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ if (request.extraQueryParameters) {
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ /**
+ * Executes POST request to device code endpoint
+ * @param deviceCodeEndpoint
+ * @param queryString
+ * @param headers
+ */
+ DeviceCodeClient.prototype.executePostRequestToDeviceCodeEndpoint = function (deviceCodeEndpoint, queryString, headers, thumbprint) {
+ return __awaiter(this, void 0, void 0, function () {
+ var _a, userCode, deviceCode, verificationUri, expiresIn, interval, message;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0: return [4 /*yield*/, this.networkManager.sendPostRequest(thumbprint, deviceCodeEndpoint, {
+ body: queryString,
+ headers: headers
+ })];
+ case 1:
+ _a = (_b.sent()).body, userCode = _a.user_code, deviceCode = _a.device_code, verificationUri = _a.verification_uri, expiresIn = _a.expires_in, interval = _a.interval, message = _a.message;
+ return [2 /*return*/, {
+ userCode: userCode,
+ deviceCode: deviceCode,
+ verificationUri: verificationUri,
+ expiresIn: expiresIn,
+ interval: interval,
+ message: message
+ }];
+ }
+ });
+ });
+ };
+ /**
+ * Create device code endpoint query parameters and returns string
+ */
+ DeviceCodeClient.prototype.createQueryString = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addScopes(request.scopes);
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ if (request.extraQueryParameters) {
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
+ }
+ if (!StringUtils.isEmpty(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ /**
+ * Breaks the polling with specific conditions.
+ * @param request CommonDeviceCodeRequest
+ * @param deviceCodeResponse DeviceCodeResponse
+ */
+ DeviceCodeClient.prototype.continuePolling = function (deviceCodeExpirationTime, userSpecifiedTimeout, userSpecifiedCancelFlag) {
+ if (userSpecifiedCancelFlag) {
+ this.logger.error("Token request cancelled by setting DeviceCodeRequest.cancel = true");
+ throw ClientAuthError.createDeviceCodeCancelledError();
+ }
+ else if (userSpecifiedTimeout && userSpecifiedTimeout < deviceCodeExpirationTime && TimeUtils.nowSeconds() > userSpecifiedTimeout) {
+ this.logger.error("User defined timeout for device code polling reached. The timeout was set for " + userSpecifiedTimeout);
+ throw ClientAuthError.createUserTimeoutReachedError();
+ }
+ else if (TimeUtils.nowSeconds() > deviceCodeExpirationTime) {
+ if (userSpecifiedTimeout) {
+ this.logger.verbose("User specified timeout ignored as the device code has expired before the timeout elapsed. The user specified timeout was set for " + userSpecifiedTimeout);
+ }
+ this.logger.error("Device code expired. Expiration time of device code was " + deviceCodeExpirationTime);
+ throw ClientAuthError.createDeviceCodeExpiredError();
+ }
+ return true;
+ };
+ /**
+ * Creates token request with device code response and polls token endpoint at interval set by the device code
+ * response
+ * @param request
+ * @param deviceCodeResponse
+ */
+ DeviceCodeClient.prototype.acquireTokenWithDeviceCode = function (request, deviceCodeResponse) {
+ return __awaiter(this, void 0, void 0, function () {
+ var queryParametersString, endpoint, requestBody, headers, userSpecifiedTimeout, deviceCodeExpirationTime, pollingIntervalMilli, thumbprint, response;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(this.authority.tokenEndpoint, queryParametersString);
+ requestBody = this.createTokenRequestBody(request, deviceCodeResponse);
+ headers = this.createTokenRequestHeaders();
+ userSpecifiedTimeout = request.timeout ? TimeUtils.nowSeconds() + request.timeout : undefined;
+ deviceCodeExpirationTime = TimeUtils.nowSeconds() + deviceCodeResponse.expiresIn;
+ pollingIntervalMilli = deviceCodeResponse.interval * 1000;
+ _a.label = 1;
+ case 1:
+ if (!this.continuePolling(deviceCodeExpirationTime, userSpecifiedTimeout, request.cancel)) return [3 /*break*/, 8];
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: request.authority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ return [4 /*yield*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)];
+ case 2:
+ response = _a.sent();
+ if (!(response.body && response.body.error)) return [3 /*break*/, 6];
+ if (!(response.body.error === Constants.AUTHORIZATION_PENDING)) return [3 /*break*/, 4];
+ this.logger.info("Authorization pending. Continue polling.");
+ return [4 /*yield*/, TimeUtils.delay(pollingIntervalMilli)];
+ case 3:
+ _a.sent();
+ return [3 /*break*/, 5];
+ case 4:
+ // for any other error, throw
+ this.logger.info("Unexpected error in polling from the server");
+ throw ServerError.createPostRequestFailed(response.body.error);
+ case 5: return [3 /*break*/, 7];
+ case 6:
+ this.logger.verbose("Authorization completed successfully. Polling stopped.");
+ return [2 /*return*/, response.body];
+ case 7: return [3 /*break*/, 1];
+ case 8:
+ /*
+ * The above code should've thrown by this point, but to satisfy TypeScript,
+ * and in the rare case the conditionals in continuePolling() may not catch everything...
+ */
+ this.logger.error("Polling stopped for unknown reasons.");
+ throw ClientAuthError.createDeviceCodeUnknownError();
+ }
+ });
+ });
+ };
+ /**
+ * Creates query parameters and converts to string.
+ * @param request
+ * @param deviceCodeResponse
+ */
+ DeviceCodeClient.prototype.createTokenRequestBody = function (request, deviceCodeResponse) {
+ var requestParameters = new RequestParameterBuilder();
+ requestParameters.addScopes(request.scopes);
+ requestParameters.addClientId(this.config.authOptions.clientId);
+ requestParameters.addGrantType(GrantType.DEVICE_CODE_GRANT);
+ requestParameters.addDeviceCode(deviceCodeResponse.deviceCode);
+ var correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ requestParameters.addCorrelationId(correlationId);
+ requestParameters.addClientInfo();
+ requestParameters.addLibraryInfo(this.config.libraryInfo);
+ requestParameters.addApplicationTelemetry(this.config.telemetry.application);
+ requestParameters.addThrottling();
+ if (this.serverTelemetryManager) {
+ requestParameters.addServerTelemetry(this.serverTelemetryManager);
+ }
+ if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ requestParameters.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ return requestParameters.createQueryString();
+ };
+ return DeviceCodeClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * OAuth2.0 refresh token client
+ */
+var RefreshTokenClient = /** @class */ (function (_super) {
+ __extends(RefreshTokenClient, _super);
+ function RefreshTokenClient(configuration, performanceClient) {
+ return _super.call(this, configuration, performanceClient) || this;
+ }
+ RefreshTokenClient.prototype.acquireToken = function (request) {
+ var _a, _b, _c, _d, _e, _f, _g;
+ return __awaiter(this, void 0, void 0, function () {
+ var atsMeasurement, reqTimestamp, response, httpVerToken, requestId, responseHandler;
+ var _this = this;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireToken, request.correlationId);
+ atsMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireToken, request.correlationId);
+ this.logger.verbose("RefreshTokenClientAcquireToken called", request.correlationId);
+ reqTimestamp = TimeUtils.nowSeconds();
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientExecuteTokenRequest, request.correlationId);
+ return [4 /*yield*/, this.executeTokenRequest(request, this.authority)];
+ case 1:
+ response = _h.sent();
+ httpVerToken = (_d = response.headers) === null || _d === void 0 ? void 0 : _d[exports.HeaderNames.X_MS_HTTP_VERSION];
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.addStaticFields({
+ refreshTokenSize: ((_e = response.body.refresh_token) === null || _e === void 0 ? void 0 : _e.length) || 0,
+ });
+ if (httpVerToken) {
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.addStaticFields({
+ httpVerToken: httpVerToken,
+ });
+ }
+ requestId = (_f = response.headers) === null || _f === void 0 ? void 0 : _f[exports.HeaderNames.X_MS_REQUEST_ID];
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
+ responseHandler.validateTokenResponse(response.body);
+ (_g = this.performanceClient) === null || _g === void 0 ? void 0 : _g.setPreQueueTime(exports.PerformanceEvents.HandleServerTokenResponse, request.correlationId);
+ return [2 /*return*/, responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, undefined, undefined, true, request.forceCache, requestId).then(function (result) {
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.endMeasurement({
+ success: true
+ });
+ return result;
+ })
+ .catch(function (error) {
+ _this.logger.verbose("Error in fetching refresh token", request.correlationId);
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.endMeasurement({
+ errorCode: error.errorCode,
+ subErrorCode: error.subError,
+ success: false
+ });
+ throw error;
+ })];
+ }
+ });
+ });
+ };
+ /**
+ * Gets cached refresh token and attaches to request, then calls acquireToken API
+ * @param request
+ */
+ RefreshTokenClient.prototype.acquireTokenByRefreshToken = function (request) {
+ var _a, _b, _c, _d;
+ return __awaiter(this, void 0, void 0, function () {
+ var isFOCI, noFamilyRTInCache, clientMismatchErrorWithFamilyRT;
+ return __generator(this, function (_e) {
+ // Cannot renew token if no request object is given.
+ if (!request) {
+ throw ClientConfigurationError.createEmptyTokenRequestError();
+ }
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireTokenByRefreshToken, request.correlationId);
+ // We currently do not support silent flow for account === null use cases; This will be revisited for confidential flow usecases
+ if (!request.account) {
+ throw ClientAuthError.createNoAccountInSilentRequestError();
+ }
+ isFOCI = this.cacheManager.isAppMetadataFOCI(request.account.environment);
+ // if the app is part of the family, retrive a Family refresh token if present and make a refreshTokenRequest
+ if (isFOCI) {
+ try {
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
+ return [2 /*return*/, this.acquireTokenWithCachedRefreshToken(request, true)];
+ }
+ catch (e) {
+ noFamilyRTInCache = e instanceof InteractionRequiredAuthError && e.errorCode === InteractionRequiredAuthErrorMessage.noTokensFoundError.code;
+ clientMismatchErrorWithFamilyRT = e instanceof ServerError && e.errorCode === Errors.INVALID_GRANT_ERROR && e.subError === Errors.CLIENT_MISMATCH_ERROR;
+ // if family Refresh Token (FRT) cache acquisition fails or if client_mismatch error is seen with FRT, reattempt with application Refresh Token (ART)
+ if (noFamilyRTInCache || clientMismatchErrorWithFamilyRT) {
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
+ return [2 /*return*/, this.acquireTokenWithCachedRefreshToken(request, false)];
+ // throw in all other cases
+ }
+ else {
+ throw e;
+ }
+ }
+ }
+ // fall back to application refresh token acquisition
+ (_d = this.performanceClient) === null || _d === void 0 ? void 0 : _d.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
+ return [2 /*return*/, this.acquireTokenWithCachedRefreshToken(request, false)];
+ });
+ });
+ };
+ /**
+ * makes a network call to acquire tokens by exchanging RefreshToken available in userCache; throws if refresh token is not cached
+ * @param request
+ */
+ RefreshTokenClient.prototype.acquireTokenWithCachedRefreshToken = function (request, foci) {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var atsMeasurement, refreshToken, refreshTokenRequest;
+ return __generator(this, function (_d) {
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
+ atsMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
+ this.logger.verbose("RefreshTokenClientAcquireTokenWithCachedRefreshToken called", request.correlationId);
+ refreshToken = this.cacheManager.getRefreshToken(request.account, foci);
+ if (!refreshToken) {
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.discardMeasurement();
+ throw InteractionRequiredAuthError.createNoTokensFoundError();
+ }
+ // attach cached RT size to the current measurement
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.endMeasurement({
+ success: true
+ });
+ refreshTokenRequest = __assign(__assign({}, request), { refreshToken: refreshToken.secret, authenticationScheme: request.authenticationScheme || exports.AuthenticationScheme.BEARER, ccsCredential: {
+ credential: request.account.homeAccountId,
+ type: exports.CcsCredentialType.HOME_ACCOUNT_ID
+ } });
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientAcquireToken, request.correlationId);
+ return [2 /*return*/, this.acquireToken(refreshTokenRequest)];
+ });
+ });
+ };
+ /**
+ * Constructs the network message and makes a NW call to the underlying secure token service
+ * @param request
+ * @param authority
+ */
+ RefreshTokenClient.prototype.executeTokenRequest = function (request, authority) {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var acquireTokenMeasurement, queryParametersString, endpoint, requestBody, headers, thumbprint;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientExecuteTokenRequest, request.correlationId);
+ acquireTokenMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement(exports.PerformanceEvents.RefreshTokenClientExecuteTokenRequest, request.correlationId);
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RefreshTokenClientCreateTokenRequestBody, request.correlationId);
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
+ return [4 /*yield*/, this.createTokenRequestBody(request)];
+ case 1:
+ requestBody = _d.sent();
+ headers = this.createTokenRequestHeaders(request.ccsCredential);
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: authority.canonicalAuthority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ return [2 /*return*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)
+ .then(function (result) {
+ acquireTokenMeasurement === null || acquireTokenMeasurement === void 0 ? void 0 : acquireTokenMeasurement.endMeasurement({
+ success: true
+ });
+ return result;
+ })
+ .catch(function (error) {
+ acquireTokenMeasurement === null || acquireTokenMeasurement === void 0 ? void 0 : acquireTokenMeasurement.endMeasurement({
+ success: false
+ });
+ throw error;
+ })];
+ }
+ });
+ });
+ };
+ /**
+ * Helper function to create the token request body
+ * @param request
+ */
+ RefreshTokenClient.prototype.createTokenRequestBody = function (request) {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var correlationId, acquireTokenMeasurement, parameterBuilder, clientAssertion, popTokenGenerator, reqCnfData, clientInfo;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientCreateTokenRequestBody, request.correlationId);
+ correlationId = request.correlationId;
+ acquireTokenMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement(exports.PerformanceEvents.BaseClientCreateTokenRequestHeaders, correlationId);
+ parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ parameterBuilder.addScopes(request.scopes);
+ parameterBuilder.addGrantType(GrantType.REFRESH_TOKEN_GRANT);
+ parameterBuilder.addClientInfo();
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ parameterBuilder.addThrottling();
+ if (this.serverTelemetryManager) {
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
+ }
+ parameterBuilder.addCorrelationId(correlationId);
+ parameterBuilder.addRefreshToken(request.refreshToken);
+ if (this.config.clientCredentials.clientSecret) {
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
+ }
+ if (this.config.clientCredentials.clientAssertion) {
+ clientAssertion = this.config.clientCredentials.clientAssertion;
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
+ }
+ if (!(request.authenticationScheme === exports.AuthenticationScheme.POP)) return [3 /*break*/, 2];
+ popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient);
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.PopTokenGenerateCnf, request.correlationId);
+ return [4 /*yield*/, popTokenGenerator.generateCnf(request)];
+ case 1:
+ reqCnfData = _d.sent();
+ // SPA PoP requires full Base64Url encoded req_cnf string (unhashed)
+ parameterBuilder.addPopToken(reqCnfData.reqCnfString);
+ return [3 /*break*/, 3];
+ case 2:
+ if (request.authenticationScheme === exports.AuthenticationScheme.SSH) {
+ if (request.sshJwk) {
+ parameterBuilder.addSshJwk(request.sshJwk);
+ }
+ else {
+ acquireTokenMeasurement === null || acquireTokenMeasurement === void 0 ? void 0 : acquireTokenMeasurement.endMeasurement({
+ success: false
+ });
+ throw ClientConfigurationError.createMissingSshJwkError();
+ }
+ }
+ _d.label = 3;
+ case 3:
+ if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ if (this.config.systemOptions.preventCorsPreflight && request.ccsCredential) {
+ switch (request.ccsCredential.type) {
+ case exports.CcsCredentialType.HOME_ACCOUNT_ID:
+ try {
+ clientInfo = buildClientInfoFromHomeAccountId(request.ccsCredential.credential);
+ parameterBuilder.addCcsOid(clientInfo);
+ }
+ catch (e) {
+ this.logger.verbose("Could not parse home account ID for CCS Header: " + e);
+ }
+ break;
+ case exports.CcsCredentialType.UPN:
+ parameterBuilder.addCcsUpn(request.ccsCredential.credential);
+ break;
+ }
+ }
+ acquireTokenMeasurement === null || acquireTokenMeasurement === void 0 ? void 0 : acquireTokenMeasurement.endMeasurement({
+ success: true
+ });
+ return [2 /*return*/, parameterBuilder.createQueryString()];
+ }
+ });
+ });
+ };
+ return RefreshTokenClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * OAuth2.0 client credential grant
+ */
+var ClientCredentialClient = /** @class */ (function (_super) {
+ __extends(ClientCredentialClient, _super);
+ function ClientCredentialClient(configuration, appTokenProvider) {
+ var _this = _super.call(this, configuration) || this;
+ _this.appTokenProvider = appTokenProvider;
+ return _this;
+ }
+ /**
+ * Public API to acquire a token with ClientCredential Flow for Confidential clients
+ * @param request
+ */
+ ClientCredentialClient.prototype.acquireToken = function (request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var cachedAuthenticationResult;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ this.scopeSet = new ScopeSet(request.scopes || []);
+ if (!request.skipCache) return [3 /*break*/, 2];
+ return [4 /*yield*/, this.executeTokenRequest(request, this.authority)];
+ case 1: return [2 /*return*/, _a.sent()];
+ case 2: return [4 /*yield*/, this.getCachedAuthenticationResult(request)];
+ case 3:
+ cachedAuthenticationResult = _a.sent();
+ if (!cachedAuthenticationResult) return [3 /*break*/, 4];
+ return [2 /*return*/, cachedAuthenticationResult];
+ case 4: return [4 /*yield*/, this.executeTokenRequest(request, this.authority)];
+ case 5: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ /**
+ * looks up cache if the tokens are cached already
+ */
+ ClientCredentialClient.prototype.getCachedAuthenticationResult = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var cachedAccessToken;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ cachedAccessToken = this.readAccessTokenFromCache();
+ if (!cachedAccessToken) {
+ (_a = this.serverTelemetryManager) === null || _a === void 0 ? void 0 : _a.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN);
+ return [2 /*return*/, null];
+ }
+ if (TimeUtils.isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) {
+ (_b = this.serverTelemetryManager) === null || _b === void 0 ? void 0 : _b.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED);
+ return [2 /*return*/, null];
+ }
+ return [4 /*yield*/, ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, {
+ account: null,
+ idToken: null,
+ accessToken: cachedAccessToken,
+ refreshToken: null,
+ appMetadata: null
+ }, true, request)];
+ case 1: return [2 /*return*/, _c.sent()];
+ }
+ });
+ });
+ };
+ /**
+ * Reads access token from the cache
+ */
+ ClientCredentialClient.prototype.readAccessTokenFromCache = function () {
+ var accessTokenFilter = {
+ homeAccountId: Constants.EMPTY_STRING,
+ environment: this.authority.canonicalAuthorityUrlComponents.HostNameAndPort,
+ credentialType: exports.CredentialType.ACCESS_TOKEN,
+ clientId: this.config.authOptions.clientId,
+ realm: this.authority.tenant,
+ target: ScopeSet.createSearchScopes(this.scopeSet.asArray())
+ };
+ var accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter);
+ if (accessTokens.length < 1) {
+ return null;
+ }
+ else if (accessTokens.length > 1) {
+ throw ClientAuthError.createMultipleMatchingTokensInCacheError();
+ }
+ return accessTokens[0];
+ };
+ /**
+ * Makes a network call to request the token from the service
+ * @param request
+ * @param authority
+ */
+ ClientCredentialClient.prototype.executeTokenRequest = function (request, authority) {
+ return __awaiter(this, void 0, void 0, function () {
+ var serverTokenResponse, reqTimestamp, appTokenPropviderParameters, appTokenProviderResult, queryParametersString, endpoint, requestBody, headers, thumbprint, response, responseHandler, tokenResponse;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ if (!this.appTokenProvider) return [3 /*break*/, 2];
+ this.logger.info("Using appTokenProvider extensibility.");
+ appTokenPropviderParameters = {
+ correlationId: request.correlationId,
+ tenantId: this.config.authOptions.authority.tenant,
+ scopes: request.scopes,
+ claims: request.claims,
+ };
+ reqTimestamp = TimeUtils.nowSeconds();
+ return [4 /*yield*/, this.appTokenProvider(appTokenPropviderParameters)];
+ case 1:
+ appTokenProviderResult = _a.sent();
+ serverTokenResponse = {
+ access_token: appTokenProviderResult.accessToken,
+ expires_in: appTokenProviderResult.expiresInSeconds,
+ refresh_in: appTokenProviderResult.refreshInSeconds,
+ token_type: exports.AuthenticationScheme.BEARER
+ };
+ return [3 /*break*/, 4];
+ case 2:
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
+ requestBody = this.createTokenRequestBody(request);
+ headers = this.createTokenRequestHeaders();
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: request.authority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ reqTimestamp = TimeUtils.nowSeconds();
+ return [4 /*yield*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)];
+ case 3:
+ response = _a.sent();
+ serverTokenResponse = response.body;
+ _a.label = 4;
+ case 4:
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
+ responseHandler.validateTokenResponse(serverTokenResponse);
+ return [4 /*yield*/, responseHandler.handleServerTokenResponse(serverTokenResponse, this.authority, reqTimestamp, request)];
+ case 5:
+ tokenResponse = _a.sent();
+ return [2 /*return*/, tokenResponse];
+ }
+ });
+ });
+ };
+ /**
+ * generate the request to the server in the acceptable format
+ * @param request
+ */
+ ClientCredentialClient.prototype.createTokenRequestBody = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ parameterBuilder.addScopes(request.scopes, false);
+ parameterBuilder.addGrantType(GrantType.CLIENT_CREDENTIALS_GRANT);
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ parameterBuilder.addThrottling();
+ if (this.serverTelemetryManager) {
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
+ }
+ var correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ parameterBuilder.addCorrelationId(correlationId);
+ if (this.config.clientCredentials.clientSecret) {
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
+ }
+ // Use clientAssertion from request, fallback to client assertion in base configuration
+ var clientAssertion = request.clientAssertion || this.config.clientCredentials.clientAssertion;
+ if (clientAssertion) {
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
+ }
+ if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ return ClientCredentialClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * On-Behalf-Of client
+ */
+var OnBehalfOfClient = /** @class */ (function (_super) {
+ __extends(OnBehalfOfClient, _super);
+ function OnBehalfOfClient(configuration) {
+ return _super.call(this, configuration) || this;
+ }
+ /**
+ * Public API to acquire tokens with on behalf of flow
+ * @param request
+ */
+ OnBehalfOfClient.prototype.acquireToken = function (request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ this.scopeSet = new ScopeSet(request.scopes || []);
+ // generate the user_assertion_hash for OBOAssertion
+ _a = this;
+ return [4 /*yield*/, this.cryptoUtils.hashString(request.oboAssertion)];
+ case 1:
+ // generate the user_assertion_hash for OBOAssertion
+ _a.userAssertionHash = _b.sent();
+ if (!request.skipCache) return [3 /*break*/, 3];
+ return [4 /*yield*/, this.executeTokenRequest(request, this.authority, this.userAssertionHash)];
+ case 2: return [2 /*return*/, _b.sent()];
+ case 3:
+ _b.trys.push([3, 5, , 7]);
+ return [4 /*yield*/, this.getCachedAuthenticationResult(request)];
+ case 4: return [2 /*return*/, _b.sent()];
+ case 5:
+ _b.sent();
+ return [4 /*yield*/, this.executeTokenRequest(request, this.authority, this.userAssertionHash)];
+ case 6:
+ // Any failure falls back to interactive request, once we implement distributed cache, we plan to handle `createRefreshRequiredError` to refresh using the RT
+ return [2 /*return*/, _b.sent()];
+ case 7: return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * look up cache for tokens
+ * Find idtoken in the cache
+ * Find accessToken based on user assertion and account info in the cache
+ * Please note we are not yet supported OBO tokens refreshed with long lived RT. User will have to send a new assertion if the current access token expires
+ * This is to prevent security issues when the assertion changes over time, however, longlived RT helps retaining the session
+ * @param request
+ */
+ OnBehalfOfClient.prototype.getCachedAuthenticationResult = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var cachedAccessToken, cachedIdToken, idTokenObject, cachedAccount, localAccountId, accountInfo;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ cachedAccessToken = this.readAccessTokenFromCacheForOBO(this.config.authOptions.clientId, request);
+ if (!cachedAccessToken) {
+ // Must refresh due to non-existent access_token.
+ (_a = this.serverTelemetryManager) === null || _a === void 0 ? void 0 : _a.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN);
+ this.logger.info("SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ else if (TimeUtils.isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) {
+ // Access token expired, will need to renewed
+ (_b = this.serverTelemetryManager) === null || _b === void 0 ? void 0 : _b.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED);
+ this.logger.info("OnbehalfofFlow:getCachedAuthenticationResult - Cached access token is expired or will expire within " + this.config.systemOptions.tokenRenewalOffsetSeconds + " seconds.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ cachedIdToken = this.readIdTokenFromCacheForOBO(cachedAccessToken.homeAccountId);
+ cachedAccount = null;
+ if (cachedIdToken) {
+ idTokenObject = new AuthToken(cachedIdToken.secret, this.config.cryptoInterface);
+ localAccountId = idTokenObject.claims.oid ? idTokenObject.claims.oid : idTokenObject.claims.sub;
+ accountInfo = {
+ homeAccountId: cachedIdToken.homeAccountId,
+ environment: cachedIdToken.environment,
+ tenantId: cachedIdToken.realm,
+ username: Constants.EMPTY_STRING,
+ localAccountId: localAccountId || Constants.EMPTY_STRING
+ };
+ cachedAccount = this.cacheManager.readAccountFromCache(accountInfo);
+ }
+ // increment telemetry cache hit counter
+ if (this.config.serverTelemetryManager) {
+ this.config.serverTelemetryManager.incrementCacheHits();
+ }
+ return [4 /*yield*/, ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, {
+ account: cachedAccount,
+ accessToken: cachedAccessToken,
+ idToken: cachedIdToken,
+ refreshToken: null,
+ appMetadata: null
+ }, true, request, idTokenObject)];
+ case 1: return [2 /*return*/, _c.sent()];
+ }
+ });
+ });
+ };
+ /**
+ * read idtoken from cache, this is a specific implementation for OBO as the requirements differ from a generic lookup in the cacheManager
+ * Certain use cases of OBO flow do not expect an idToken in the cache/or from the service
+ * @param request
+ */
+ OnBehalfOfClient.prototype.readIdTokenFromCacheForOBO = function (atHomeAccountId) {
+ var idTokenFilter = {
+ homeAccountId: atHomeAccountId,
+ environment: this.authority.canonicalAuthorityUrlComponents.HostNameAndPort,
+ credentialType: exports.CredentialType.ID_TOKEN,
+ clientId: this.config.authOptions.clientId,
+ realm: this.authority.tenant
+ };
+ var idTokens = this.cacheManager.getIdTokensByFilter(idTokenFilter);
+ // When acquiring a token on behalf of an application, there might not be an id token in the cache
+ if (idTokens.length < 1) {
+ return null;
+ }
+ return idTokens[0];
+ };
+ /**
+ * Fetches the cached access token based on incoming assertion
+ * @param clientId
+ * @param request
+ * @param userAssertionHash
+ */
+ OnBehalfOfClient.prototype.readAccessTokenFromCacheForOBO = function (clientId, request) {
+ var authScheme = request.authenticationScheme || exports.AuthenticationScheme.BEARER;
+ /*
+ * Distinguish between Bearer and PoP/SSH token cache types
+ * Cast to lowercase to handle "bearer" from ADFS
+ */
+ var credentialType = (authScheme && authScheme.toLowerCase() !== exports.AuthenticationScheme.BEARER.toLowerCase()) ? exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : exports.CredentialType.ACCESS_TOKEN;
+ var accessTokenFilter = {
+ credentialType: credentialType,
+ clientId: clientId,
+ target: ScopeSet.createSearchScopes(this.scopeSet.asArray()),
+ tokenType: authScheme,
+ keyId: request.sshKid,
+ requestedClaimsHash: request.requestedClaimsHash,
+ userAssertionHash: this.userAssertionHash
+ };
+ var accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter);
+ var numAccessTokens = accessTokens.length;
+ if (numAccessTokens < 1) {
+ return null;
+ }
+ else if (numAccessTokens > 1) {
+ throw ClientAuthError.createMultipleMatchingTokensInCacheError();
+ }
+ return accessTokens[0];
+ };
+ /**
+ * Make a network call to the server requesting credentials
+ * @param request
+ * @param authority
+ */
+ OnBehalfOfClient.prototype.executeTokenRequest = function (request, authority, userAssertionHash) {
+ return __awaiter(this, void 0, void 0, function () {
+ var queryParametersString, endpoint, requestBody, headers, thumbprint, reqTimestamp, response, responseHandler, tokenResponse;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
+ requestBody = this.createTokenRequestBody(request);
+ headers = this.createTokenRequestHeaders();
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: request.authority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ reqTimestamp = TimeUtils.nowSeconds();
+ return [4 /*yield*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)];
+ case 1:
+ response = _a.sent();
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
+ responseHandler.validateTokenResponse(response.body);
+ return [4 /*yield*/, responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, undefined, userAssertionHash)];
+ case 2:
+ tokenResponse = _a.sent();
+ return [2 /*return*/, tokenResponse];
+ }
+ });
+ });
+ };
+ /**
+ * generate a server request in accepable format
+ * @param request
+ */
+ OnBehalfOfClient.prototype.createTokenRequestBody = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ parameterBuilder.addScopes(request.scopes);
+ parameterBuilder.addGrantType(GrantType.JWT_BEARER);
+ parameterBuilder.addClientInfo();
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ parameterBuilder.addThrottling();
+ if (this.serverTelemetryManager) {
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
+ }
+ var correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ parameterBuilder.addCorrelationId(correlationId);
+ parameterBuilder.addRequestTokenUse(exports.AADServerParamKeys.ON_BEHALF_OF);
+ parameterBuilder.addOboAssertion(request.oboAssertion);
+ if (this.config.clientCredentials.clientSecret) {
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
+ }
+ if (this.config.clientCredentials.clientAssertion) {
+ var clientAssertion = this.config.clientCredentials.clientAssertion;
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
+ }
+ if (request.claims || (this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0)) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ return OnBehalfOfClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var SilentFlowClient = /** @class */ (function (_super) {
+ __extends(SilentFlowClient, _super);
+ function SilentFlowClient(configuration, performanceClient) {
+ return _super.call(this, configuration, performanceClient) || this;
+ }
+ /**
+ * Retrieves a token from cache if it is still valid, or uses the cached refresh token to renew
+ * the given token and returns the renewed token
+ * @param request
+ */
+ SilentFlowClient.prototype.acquireToken = function (request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var e_1, refreshTokenClient;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ _a.trys.push([0, 2, , 3]);
+ return [4 /*yield*/, this.acquireCachedToken(request)];
+ case 1: return [2 /*return*/, _a.sent()];
+ case 2:
+ e_1 = _a.sent();
+ if (e_1 instanceof ClientAuthError && e_1.errorCode === ClientAuthErrorMessage.tokenRefreshRequired.code) {
+ refreshTokenClient = new RefreshTokenClient(this.config, this.performanceClient);
+ return [2 /*return*/, refreshTokenClient.acquireTokenByRefreshToken(request)];
+ }
+ else {
+ throw e_1;
+ }
+ case 3: return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Retrieves token from cache or throws an error if it must be refreshed.
+ * @param request
+ */
+ SilentFlowClient.prototype.acquireCachedToken = function (request) {
+ var _a, _b, _c, _d, _e;
+ return __awaiter(this, void 0, void 0, function () {
+ var environment, cacheRecord;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
+ case 0:
+ // Cannot renew token if no request object is given.
+ if (!request) {
+ throw ClientConfigurationError.createEmptyTokenRequestError();
+ }
+ if (request.forceRefresh) {
+ // Must refresh due to present force_refresh flag.
+ (_a = this.serverTelemetryManager) === null || _a === void 0 ? void 0 : _a.setCacheOutcome(CacheOutcome.FORCE_REFRESH);
+ this.logger.info("SilentFlowClient:acquireCachedToken - Skipping cache because forceRefresh is true.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ else if (!this.config.cacheOptions.claimsBasedCachingEnabled && !StringUtils.isEmptyObj(request.claims)) {
+ // Must refresh due to presence of claims in request preventing cache lookup
+ (_b = this.serverTelemetryManager) === null || _b === void 0 ? void 0 : _b.setCacheOutcome(CacheOutcome.CLAIMS_REQUESTED_CACHE_SKIPPED);
+ this.logger.info("SilentFlowClient:acquireCachedToken - Skipping cache because claims-based caching is disabled and claims were requested.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ // We currently do not support silent flow for account === null use cases; This will be revisited for confidential flow usecases
+ if (!request.account) {
+ throw ClientAuthError.createNoAccountInSilentRequestError();
+ }
+ environment = request.authority || this.authority.getPreferredCache();
+ cacheRecord = this.cacheManager.readCacheRecord(request.account, request, environment);
+ if (!cacheRecord.accessToken) {
+ // Must refresh due to non-existent access_token.
+ (_c = this.serverTelemetryManager) === null || _c === void 0 ? void 0 : _c.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN);
+ this.logger.info("SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ else if (TimeUtils.wasClockTurnedBack(cacheRecord.accessToken.cachedAt) ||
+ TimeUtils.isTokenExpired(cacheRecord.accessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) {
+ // Must refresh due to expired access_token.
+ (_d = this.serverTelemetryManager) === null || _d === void 0 ? void 0 : _d.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED);
+ this.logger.info("SilentFlowClient:acquireCachedToken - Cached access token is expired or will expire within " + this.config.systemOptions.tokenRenewalOffsetSeconds + " seconds.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ else if (cacheRecord.accessToken.refreshOn && TimeUtils.isTokenExpired(cacheRecord.accessToken.refreshOn, 0)) {
+ // Must refresh due to the refresh_in value.
+ (_e = this.serverTelemetryManager) === null || _e === void 0 ? void 0 : _e.setCacheOutcome(CacheOutcome.REFRESH_CACHED_ACCESS_TOKEN);
+ this.logger.info("SilentFlowClient:acquireCachedToken - Cached access token's refreshOn property has been exceeded'.");
+ throw ClientAuthError.createRefreshRequiredError();
+ }
+ if (this.config.serverTelemetryManager) {
+ this.config.serverTelemetryManager.incrementCacheHits();
+ }
+ return [4 /*yield*/, this.generateResultFromCacheRecord(cacheRecord, request)];
+ case 1: return [2 /*return*/, _f.sent()];
+ }
+ });
+ });
+ };
+ /**
+ * Helper function to build response object from the CacheRecord
+ * @param cacheRecord
+ */
+ SilentFlowClient.prototype.generateResultFromCacheRecord = function (cacheRecord, request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var idTokenObj, authTime;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ if (cacheRecord.idToken) {
+ idTokenObj = new AuthToken(cacheRecord.idToken.secret, this.config.cryptoInterface);
+ }
+ // token max_age check
+ if (request.maxAge || (request.maxAge === 0)) {
+ authTime = idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.auth_time;
+ if (!authTime) {
+ throw ClientAuthError.createAuthTimeNotFoundError();
+ }
+ AuthToken.checkMaxAge(authTime, request.maxAge);
+ }
+ return [4 /*yield*/, ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, cacheRecord, true, request, idTokenObj)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return SilentFlowClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Oauth2.0 Password grant client
+ * Note: We are only supporting public clients for password grant and for purely testing purposes
+ */
+var UsernamePasswordClient = /** @class */ (function (_super) {
+ __extends(UsernamePasswordClient, _super);
+ function UsernamePasswordClient(configuration) {
+ return _super.call(this, configuration) || this;
+ }
+ /**
+ * API to acquire a token by passing the username and password to the service in exchage of credentials
+ * password_grant
+ * @param request
+ */
+ UsernamePasswordClient.prototype.acquireToken = function (request) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var atsMeasurement, reqTimestamp, response, httpVerToken, responseHandler, tokenResponse;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ atsMeasurement = (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.startMeasurement("UsernamePasswordClientAcquireToken", request.correlationId);
+ this.logger.info("in acquireToken call in username-password client");
+ reqTimestamp = TimeUtils.nowSeconds();
+ return [4 /*yield*/, this.executeTokenRequest(this.authority, request)];
+ case 1:
+ response = _c.sent();
+ httpVerToken = (_b = response.headers) === null || _b === void 0 ? void 0 : _b[exports.HeaderNames.X_MS_HTTP_VERSION];
+ atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.addStaticFields({
+ httpVerToken: httpVerToken
+ });
+ responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
+ // Validate response. This function throws a server error if an error is returned by the server.
+ responseHandler.validateTokenResponse(response.body);
+ tokenResponse = responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request);
+ return [2 /*return*/, tokenResponse];
+ }
+ });
+ });
+ };
+ /**
+ * Executes POST request to token endpoint
+ * @param authority
+ * @param request
+ */
+ UsernamePasswordClient.prototype.executeTokenRequest = function (authority, request) {
+ return __awaiter(this, void 0, void 0, function () {
+ var queryParametersString, endpoint, requestBody, headers, thumbprint;
+ return __generator(this, function (_a) {
+ queryParametersString = this.createTokenQueryParameters(request);
+ endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
+ requestBody = this.createTokenRequestBody(request);
+ headers = this.createTokenRequestHeaders({
+ credential: request.username,
+ type: exports.CcsCredentialType.UPN
+ });
+ thumbprint = {
+ clientId: this.config.authOptions.clientId,
+ authority: authority.canonicalAuthority,
+ scopes: request.scopes,
+ claims: request.claims,
+ authenticationScheme: request.authenticationScheme,
+ resourceRequestMethod: request.resourceRequestMethod,
+ resourceRequestUri: request.resourceRequestUri,
+ shrClaims: request.shrClaims,
+ sshKid: request.sshKid
+ };
+ return [2 /*return*/, this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)];
+ });
+ });
+ };
+ /**
+ * Generates a map for all the params to be sent to the service
+ * @param request
+ */
+ UsernamePasswordClient.prototype.createTokenRequestBody = function (request) {
+ var parameterBuilder = new RequestParameterBuilder();
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
+ parameterBuilder.addUsername(request.username);
+ parameterBuilder.addPassword(request.password);
+ parameterBuilder.addScopes(request.scopes);
+ parameterBuilder.addResponseTypeForTokenAndIdToken();
+ parameterBuilder.addGrantType(GrantType.RESOURCE_OWNER_PASSWORD_GRANT);
+ parameterBuilder.addClientInfo();
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
+ parameterBuilder.addThrottling();
+ if (this.serverTelemetryManager) {
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
+ }
+ var correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid();
+ parameterBuilder.addCorrelationId(correlationId);
+ if (this.config.clientCredentials.clientSecret) {
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
+ }
+ if (this.config.clientCredentials.clientAssertion) {
+ var clientAssertion = this.config.clientCredentials.clientAssertion;
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
+ }
+ if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) {
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
+ }
+ if (this.config.systemOptions.preventCorsPreflight && request.username) {
+ parameterBuilder.addCcsUpn(request.username);
+ }
+ return parameterBuilder.createQueryString();
+ };
+ return UsernamePasswordClient;
+}(BaseClient));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+function isOpenIdConfigResponse(response) {
+ return (response.hasOwnProperty("authorization_endpoint") &&
+ response.hasOwnProperty("token_endpoint") &&
+ response.hasOwnProperty("issuer") &&
+ response.hasOwnProperty("jwks_uri"));
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var rawMetdataJSON = { "endpointMetadata": { "https://login.microsoftonline.com/common/": { "token_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.com/common/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.com/common/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.com", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pas.windows.net" }, "https://login.chinacloudapi.cn/common/": { "token_endpoint": "https://login.chinacloudapi.cn/common/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.chinacloudapi.cn/common/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.partner.microsoftonline.cn/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://microsoftgraph.chinacloudapi.cn/oidc/userinfo", "authorization_endpoint": "https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.chinacloudapi.cn/common/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.chinacloudapi.cn/common/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.chinacloudapi.cn/common/kerberos", "tenant_region_scope": null, "cloud_instance_name": "partner.microsoftonline.cn", "cloud_graph_host_name": "graph.chinacloudapi.cn", "msgraph_host": "microsoftgraph.chinacloudapi.cn", "rbac_url": "https://pas.chinacloudapi.cn" }, "https://login.microsoftonline.us/common/": { "token_endpoint": "https://login.microsoftonline.us/common/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.us/common/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.us/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.us/common/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.us/common/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.us/common/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.us/common/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.us", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pasff.usgovcloudapi.net" }, "https://login.microsoftonline.com/consumers/": { "token_endpoint": "https://login.microsoftonline.com/consumers/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.com/consumers/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.com/consumers/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.com/consumers/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.com", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pas.windows.net" }, "https://login.chinacloudapi.cn/consumers/": { "token_endpoint": "https://login.chinacloudapi.cn/consumers/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.chinacloudapi.cn/consumers/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.partner.microsoftonline.cn/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://microsoftgraph.chinacloudapi.cn/oidc/userinfo", "authorization_endpoint": "https://login.chinacloudapi.cn/consumers/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.chinacloudapi.cn/consumers/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.chinacloudapi.cn/consumers/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.chinacloudapi.cn/consumers/kerberos", "tenant_region_scope": null, "cloud_instance_name": "partner.microsoftonline.cn", "cloud_graph_host_name": "graph.chinacloudapi.cn", "msgraph_host": "microsoftgraph.chinacloudapi.cn", "rbac_url": "https://pas.chinacloudapi.cn" }, "https://login.microsoftonline.us/consumers/": { "token_endpoint": "https://login.microsoftonline.us/consumers/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.us/consumers/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.us/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.us/consumers/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.us/consumers/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.us/consumers/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.us/consumers/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.us", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pasff.usgovcloudapi.net" }, "https://login.microsoftonline.com/organizations/": { "token_endpoint": "https://login.microsoftonline.com/organizations/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.com/organizations/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.com/organizations/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.com/organizations/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.com", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pas.windows.net" }, "https://login.chinacloudapi.cn/organizations/": { "token_endpoint": "https://login.chinacloudapi.cn/organizations/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.chinacloudapi.cn/organizations/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.partner.microsoftonline.cn/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://microsoftgraph.chinacloudapi.cn/oidc/userinfo", "authorization_endpoint": "https://login.chinacloudapi.cn/organizations/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.chinacloudapi.cn/organizations/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.chinacloudapi.cn/organizations/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.chinacloudapi.cn/organizations/kerberos", "tenant_region_scope": null, "cloud_instance_name": "partner.microsoftonline.cn", "cloud_graph_host_name": "graph.chinacloudapi.cn", "msgraph_host": "microsoftgraph.chinacloudapi.cn", "rbac_url": "https://pas.chinacloudapi.cn" }, "https://login.microsoftonline.us/organizations/": { "token_endpoint": "https://login.microsoftonline.us/organizations/oauth2/v2.0/token", "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.us/organizations/discovery/v2.0/keys", "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.us/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", "authorization_endpoint": "https://login.microsoftonline.us/organizations/oauth2/v2.0/authorize", "device_authorization_endpoint": "https://login.microsoftonline.us/organizations/oauth2/v2.0/devicecode", "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.us/organizations/oauth2/v2.0/logout", "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.us/organizations/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.us", "cloud_graph_host_name": "graph.windows.net", "msgraph_host": "graph.microsoft.com", "rbac_url": "https://pasff.usgovcloudapi.net" } }, "instanceDiscoveryMetadata": { "https://login.microsoftonline.com/common/": { "tenant_discovery_endpoint": "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.chinacloudapi.cn/common/": { "tenant_discovery_endpoint": "https://login.chinacloudapi.cn/common/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.microsoftonline.us/common/": { "tenant_discovery_endpoint": "https://login.microsoftonline.us/common/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.microsoftonline.com/consumers/": { "tenant_discovery_endpoint": "https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.chinacloudapi.cn/consumers/": { "tenant_discovery_endpoint": "https://login.chinacloudapi.cn/consumers/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.microsoftonline.us/consumers/": { "tenant_discovery_endpoint": "https://login.microsoftonline.us/consumers/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.microsoftonline.com/organizations/": { "tenant_discovery_endpoint": "https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.chinacloudapi.cn/organizations/": { "tenant_discovery_endpoint": "https://login.chinacloudapi.cn/organizations/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] }, "https://login.microsoftonline.us/organizations/": { "tenant_discovery_endpoint": "https://login.microsoftonline.us/organizations/v2.0/.well-known/openid-configuration", "api-version": "1.1", "metadata": [{ "preferred_network": "login.microsoftonline.com", "preferred_cache": "login.windows.net", "aliases": ["login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net"] }, { "preferred_network": "login.partner.microsoftonline.cn", "preferred_cache": "login.partner.microsoftonline.cn", "aliases": ["login.partner.microsoftonline.cn", "login.chinacloudapi.cn"] }, { "preferred_network": "login.microsoftonline.de", "preferred_cache": "login.microsoftonline.de", "aliases": ["login.microsoftonline.de"] }, { "preferred_network": "login.microsoftonline.us", "preferred_cache": "login.microsoftonline.us", "aliases": ["login.microsoftonline.us", "login.usgovcloudapi.net"] }, { "preferred_network": "login-us.microsoftonline.com", "preferred_cache": "login-us.microsoftonline.com", "aliases": ["login-us.microsoftonline.com"] }] } } };
+var EndpointMetadata = rawMetdataJSON.endpointMetadata;
+var InstanceDiscoveryMetadata = rawMetdataJSON.instanceDiscoveryMetadata;
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Protocol modes supported by MSAL.
+ */
+exports.ProtocolMode = void 0;
+(function (ProtocolMode) {
+ ProtocolMode["AAD"] = "AAD";
+ ProtocolMode["OIDC"] = "OIDC";
+})(exports.ProtocolMode || (exports.ProtocolMode = {}));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var AuthorityMetadataEntity = /** @class */ (function () {
+ function AuthorityMetadataEntity() {
+ this.expiresAt = TimeUtils.nowSeconds() + AUTHORITY_METADATA_CONSTANTS.REFRESH_TIME_SECONDS;
+ }
+ /**
+ * Update the entity with new aliases, preferred_cache and preferred_network values
+ * @param metadata
+ * @param fromNetwork
+ */
+ AuthorityMetadataEntity.prototype.updateCloudDiscoveryMetadata = function (metadata, fromNetwork) {
+ this.aliases = metadata.aliases;
+ this.preferred_cache = metadata.preferred_cache;
+ this.preferred_network = metadata.preferred_network;
+ this.aliasesFromNetwork = fromNetwork;
+ };
+ /**
+ * Update the entity with new endpoints
+ * @param metadata
+ * @param fromNetwork
+ */
+ AuthorityMetadataEntity.prototype.updateEndpointMetadata = function (metadata, fromNetwork) {
+ this.authorization_endpoint = metadata.authorization_endpoint;
+ this.token_endpoint = metadata.token_endpoint;
+ this.end_session_endpoint = metadata.end_session_endpoint;
+ this.issuer = metadata.issuer;
+ this.endpointsFromNetwork = fromNetwork;
+ this.jwks_uri = metadata.jwks_uri;
+ };
+ /**
+ * Save the authority that was used to create this cache entry
+ * @param authority
+ */
+ AuthorityMetadataEntity.prototype.updateCanonicalAuthority = function (authority) {
+ this.canonical_authority = authority;
+ };
+ /**
+ * Reset the exiresAt value
+ */
+ AuthorityMetadataEntity.prototype.resetExpiresAt = function () {
+ this.expiresAt = TimeUtils.nowSeconds() + AUTHORITY_METADATA_CONSTANTS.REFRESH_TIME_SECONDS;
+ };
+ /**
+ * Returns whether or not the data needs to be refreshed
+ */
+ AuthorityMetadataEntity.prototype.isExpired = function () {
+ return this.expiresAt <= TimeUtils.nowSeconds();
+ };
+ /**
+ * Validates an entity: checks for all expected params
+ * @param entity
+ */
+ AuthorityMetadataEntity.isAuthorityMetadataEntity = function (key, entity) {
+ if (!entity) {
+ return false;
+ }
+ return (key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) === 0 &&
+ entity.hasOwnProperty("aliases") &&
+ entity.hasOwnProperty("preferred_cache") &&
+ entity.hasOwnProperty("preferred_network") &&
+ entity.hasOwnProperty("canonical_authority") &&
+ entity.hasOwnProperty("authorization_endpoint") &&
+ entity.hasOwnProperty("token_endpoint") &&
+ entity.hasOwnProperty("issuer") &&
+ entity.hasOwnProperty("aliasesFromNetwork") &&
+ entity.hasOwnProperty("endpointsFromNetwork") &&
+ entity.hasOwnProperty("expiresAt") &&
+ entity.hasOwnProperty("jwks_uri"));
+ };
+ return AuthorityMetadataEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+function isCloudInstanceDiscoveryResponse(response) {
+ return (response.hasOwnProperty("tenant_discovery_endpoint") &&
+ response.hasOwnProperty("metadata"));
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+function isCloudInstanceDiscoveryErrorResponse(response) {
+ return (response.hasOwnProperty("error") &&
+ response.hasOwnProperty("error_description"));
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var RegionDiscovery = /** @class */ (function () {
+ function RegionDiscovery(networkInterface, performanceClient, correlationId) {
+ this.networkInterface = networkInterface;
+ this.performanceClient = performanceClient;
+ this.correlationId = correlationId;
+ }
+ /**
+ * Detect the region from the application's environment.
+ *
+ * @returns Promise
+ */
+ RegionDiscovery.prototype.detectRegion = function (environmentRegion, regionDiscoveryMetadata) {
+ var _a, _b, _c, _d;
+ return __awaiter(this, void 0, void 0, function () {
+ var autodetectedRegionName, options, localIMDSVersionResponse, currentIMDSVersion, currentIMDSVersionResponse;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RegionDiscoveryDetectRegion, this.correlationId);
+ autodetectedRegionName = environmentRegion;
+ if (!!autodetectedRegionName) return [3 /*break*/, 8];
+ options = RegionDiscovery.IMDS_OPTIONS;
+ _e.label = 1;
+ case 1:
+ _e.trys.push([1, 6, , 7]);
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.correlationId);
+ return [4 /*yield*/, this.getRegionFromIMDS(Constants.IMDS_VERSION, options)];
+ case 2:
+ localIMDSVersionResponse = _e.sent();
+ if (localIMDSVersionResponse.status === ResponseCodes.httpSuccess) {
+ autodetectedRegionName = localIMDSVersionResponse.body;
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS;
+ }
+ if (!(localIMDSVersionResponse.status === ResponseCodes.httpBadRequest)) return [3 /*break*/, 5];
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.correlationId);
+ return [4 /*yield*/, this.getCurrentVersion(options)];
+ case 3:
+ currentIMDSVersion = _e.sent();
+ if (!currentIMDSVersion) {
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION;
+ return [2 /*return*/, null];
+ }
+ (_d = this.performanceClient) === null || _d === void 0 ? void 0 : _d.setPreQueueTime(exports.PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.correlationId);
+ return [4 /*yield*/, this.getRegionFromIMDS(currentIMDSVersion, options)];
+ case 4:
+ currentIMDSVersionResponse = _e.sent();
+ if (currentIMDSVersionResponse.status === ResponseCodes.httpSuccess) {
+ autodetectedRegionName = currentIMDSVersionResponse.body;
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS;
+ }
+ _e.label = 5;
+ case 5: return [3 /*break*/, 7];
+ case 6:
+ _e.sent();
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION;
+ return [2 /*return*/, null];
+ case 7: return [3 /*break*/, 9];
+ case 8:
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.ENVIRONMENT_VARIABLE;
+ _e.label = 9;
+ case 9:
+ // If no region was auto detected from the environment or from the IMDS endpoint, mark the attempt as a FAILED_AUTO_DETECTION
+ if (!autodetectedRegionName) {
+ regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION;
+ }
+ return [2 /*return*/, autodetectedRegionName || null];
+ }
+ });
+ });
+ };
+ /**
+ * Make the call to the IMDS endpoint
+ *
+ * @param imdsEndpointUrl
+ * @returns Promise>
+ */
+ RegionDiscovery.prototype.getRegionFromIMDS = function (version, options) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_b) {
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.correlationId);
+ return [2 /*return*/, this.networkInterface.sendGetRequestAsync(Constants.IMDS_ENDPOINT + "?api-version=" + version + "&format=text", options, Constants.IMDS_TIMEOUT)];
+ });
+ });
+ };
+ /**
+ * Get the most recent version of the IMDS endpoint available
+ *
+ * @returns Promise
+ */
+ RegionDiscovery.prototype.getCurrentVersion = function (options) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var response;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.correlationId);
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, this.networkInterface.sendGetRequestAsync(Constants.IMDS_ENDPOINT + "?format=json", options)];
+ case 2:
+ response = _b.sent();
+ // When IMDS endpoint is called without the api version query param, bad request response comes back with latest version.
+ if (response.status === ResponseCodes.httpBadRequest && response.body && response.body["newest-versions"] && response.body["newest-versions"].length > 0) {
+ return [2 /*return*/, response.body["newest-versions"][0]];
+ }
+ return [2 /*return*/, null];
+ case 3:
+ _b.sent();
+ return [2 /*return*/, null];
+ case 4: return [2 /*return*/];
+ }
+ });
+ });
+ };
+ // Options for the IMDS endpoint request
+ RegionDiscovery.IMDS_OPTIONS = {
+ headers: {
+ Metadata: "true",
+ },
+ };
+ return RegionDiscovery;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * The authority class validates the authority URIs used by the user, and retrieves the OpenID Configuration Data from the
+ * endpoint. It will store the pertinent config data in this object for use during token calls.
+ */
+var Authority = /** @class */ (function () {
+ function Authority(authority, networkInterface, cacheManager, authorityOptions, logger, performanceClient, correlationId) {
+ this.canonicalAuthority = authority;
+ this._canonicalAuthority.validateAsUri();
+ this.networkInterface = networkInterface;
+ this.cacheManager = cacheManager;
+ this.authorityOptions = authorityOptions;
+ this.regionDiscoveryMetadata = { region_used: undefined, region_source: undefined, region_outcome: undefined };
+ this.logger = logger;
+ this.performanceClient = performanceClient;
+ this.correlationId = correlationId;
+ this.regionDiscovery = new RegionDiscovery(networkInterface, this.performanceClient, this.correlationId);
+ }
+ /**
+ * Get {@link AuthorityType}
+ * @param authorityUri {@link IUri}
+ * @private
+ */
+ Authority.prototype.getAuthorityType = function (authorityUri) {
+ // CIAM auth url pattern is being standardized as: .ciamlogin.com
+ if (authorityUri.HostNameAndPort.endsWith(Constants.CIAM_AUTH_URL)) {
+ return exports.AuthorityType.Ciam;
+ }
+ var pathSegments = authorityUri.PathSegments;
+ if (pathSegments.length) {
+ switch (pathSegments[0].toLowerCase()) {
+ case Constants.ADFS:
+ return exports.AuthorityType.Adfs;
+ case Constants.DSTS:
+ return exports.AuthorityType.Dsts;
+ }
+ }
+ return exports.AuthorityType.Default;
+ };
+ Object.defineProperty(Authority.prototype, "authorityType", {
+ // See above for AuthorityType
+ get: function () {
+ return this.getAuthorityType(this.canonicalAuthorityUrlComponents);
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "protocolMode", {
+ /**
+ * ProtocolMode enum representing the way endpoints are constructed.
+ */
+ get: function () {
+ return this.authorityOptions.protocolMode;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "options", {
+ /**
+ * Returns authorityOptions which can be used to reinstantiate a new authority instance
+ */
+ get: function () {
+ return this.authorityOptions;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "canonicalAuthority", {
+ /**
+ * A URL that is the authority set by the developer
+ */
+ get: function () {
+ return this._canonicalAuthority.urlString;
+ },
+ /**
+ * Sets canonical authority.
+ */
+ set: function (url) {
+ this._canonicalAuthority = new UrlString(url);
+ this._canonicalAuthority.validateAsUri();
+ this._canonicalAuthorityUrlComponents = null;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "canonicalAuthorityUrlComponents", {
+ /**
+ * Get authority components.
+ */
+ get: function () {
+ if (!this._canonicalAuthorityUrlComponents) {
+ this._canonicalAuthorityUrlComponents = this._canonicalAuthority.getUrlComponents();
+ }
+ return this._canonicalAuthorityUrlComponents;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "hostnameAndPort", {
+ /**
+ * Get hostname and port i.e. login.microsoftonline.com
+ */
+ get: function () {
+ return this.canonicalAuthorityUrlComponents.HostNameAndPort.toLowerCase();
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "tenant", {
+ /**
+ * Get tenant for authority.
+ */
+ get: function () {
+ return this.canonicalAuthorityUrlComponents.PathSegments[0];
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "authorizationEndpoint", {
+ /**
+ * OAuth /authorize endpoint for requests
+ */
+ get: function () {
+ if (this.discoveryComplete()) {
+ return this.replacePath(this.metadata.authorization_endpoint);
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "tokenEndpoint", {
+ /**
+ * OAuth /token endpoint for requests
+ */
+ get: function () {
+ if (this.discoveryComplete()) {
+ return this.replacePath(this.metadata.token_endpoint);
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "deviceCodeEndpoint", {
+ get: function () {
+ if (this.discoveryComplete()) {
+ return this.replacePath(this.metadata.token_endpoint.replace("/token", "/devicecode"));
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "endSessionEndpoint", {
+ /**
+ * OAuth logout endpoint for requests
+ */
+ get: function () {
+ if (this.discoveryComplete()) {
+ // ROPC policies may not have end_session_endpoint set
+ if (!this.metadata.end_session_endpoint) {
+ throw ClientAuthError.createLogoutNotSupportedError();
+ }
+ return this.replacePath(this.metadata.end_session_endpoint);
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "selfSignedJwtAudience", {
+ /**
+ * OAuth issuer for requests
+ */
+ get: function () {
+ if (this.discoveryComplete()) {
+ return this.replacePath(this.metadata.issuer);
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Authority.prototype, "jwksUri", {
+ /**
+ * Jwks_uri for token signing keys
+ */
+ get: function () {
+ if (this.discoveryComplete()) {
+ return this.replacePath(this.metadata.jwks_uri);
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Returns a flag indicating that tenant name can be replaced in authority {@link IUri}
+ * @param authorityUri {@link IUri}
+ * @private
+ */
+ Authority.prototype.canReplaceTenant = function (authorityUri) {
+ return authorityUri.PathSegments.length === 1
+ && !Authority.reservedTenantDomains.has(authorityUri.PathSegments[0])
+ && this.getAuthorityType(authorityUri) === exports.AuthorityType.Default
+ && this.protocolMode === exports.ProtocolMode.AAD;
+ };
+ /**
+ * Replaces tenant in url path with current tenant. Defaults to common.
+ * @param urlString
+ */
+ Authority.prototype.replaceTenant = function (urlString) {
+ return urlString.replace(/{tenant}|{tenantid}/g, this.tenant);
+ };
+ /**
+ * Replaces path such as tenant or policy with the current tenant or policy.
+ * @param urlString
+ */
+ Authority.prototype.replacePath = function (urlString) {
+ var _this = this;
+ var endpoint = urlString;
+ var cachedAuthorityUrl = new UrlString(this.metadata.canonical_authority);
+ var cachedAuthorityUrlComponents = cachedAuthorityUrl.getUrlComponents();
+ var cachedAuthorityParts = cachedAuthorityUrlComponents.PathSegments;
+ var currentAuthorityParts = this.canonicalAuthorityUrlComponents.PathSegments;
+ currentAuthorityParts.forEach(function (currentPart, index) {
+ var cachedPart = cachedAuthorityParts[index];
+ if (index === 0 && _this.canReplaceTenant(cachedAuthorityUrlComponents)) {
+ var tenantId = (new UrlString(_this.metadata.authorization_endpoint)).getUrlComponents().PathSegments[0];
+ /**
+ * Check if AAD canonical authority contains tenant domain name, for example "testdomain.onmicrosoft.com",
+ * by comparing its first path segment to the corresponding authorization endpoint path segment, which is
+ * always resolved with tenant id by OIDC.
+ */
+ if (cachedPart !== tenantId) {
+ _this.logger.verbose("Replacing tenant domain name " + cachedPart + " with id " + tenantId);
+ cachedPart = tenantId;
+ }
+ }
+ if (currentPart !== cachedPart) {
+ endpoint = endpoint.replace("/" + cachedPart + "/", "/" + currentPart + "/");
+ }
+ });
+ return this.replaceTenant(endpoint);
+ };
+ Object.defineProperty(Authority.prototype, "defaultOpenIdConfigurationEndpoint", {
+ /**
+ * The default open id configuration endpoint for any canonical authority.
+ */
+ get: function () {
+ if (this.authorityType === exports.AuthorityType.Adfs ||
+ this.authorityType === exports.AuthorityType.Dsts ||
+ this.protocolMode === exports.ProtocolMode.OIDC) {
+ return this.canonicalAuthority + ".well-known/openid-configuration";
+ }
+ return this.canonicalAuthority + "v2.0/.well-known/openid-configuration";
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Boolean that returns whethr or not tenant discovery has been completed.
+ */
+ Authority.prototype.discoveryComplete = function () {
+ return !!this.metadata;
+ };
+ /**
+ * Perform endpoint discovery to discover aliases, preferred_cache, preferred_network
+ * and the /authorize, /token and logout endpoints.
+ */
+ Authority.prototype.resolveEndpointsAsync = function () {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var metadataEntity, cloudDiscoverySource, endpointSource, cacheKey;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityResolveEndpointsAsync, this.correlationId);
+ metadataEntity = this.cacheManager.getAuthorityMetadataByAlias(this.hostnameAndPort);
+ if (!metadataEntity) {
+ metadataEntity = new AuthorityMetadataEntity();
+ metadataEntity.updateCanonicalAuthority(this.canonicalAuthority);
+ }
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.AuthorityUpdateCloudDiscoveryMetadata, this.correlationId);
+ return [4 /*yield*/, this.updateCloudDiscoveryMetadata(metadataEntity)];
+ case 1:
+ cloudDiscoverySource = _d.sent();
+ this.canonicalAuthority = this.canonicalAuthority.replace(this.hostnameAndPort, metadataEntity.preferred_network);
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.AuthorityUpdateEndpointMetadata, this.correlationId);
+ return [4 /*yield*/, this.updateEndpointMetadata(metadataEntity)];
+ case 2:
+ endpointSource = _d.sent();
+ if (cloudDiscoverySource !== AuthorityMetadataSource.CACHE && endpointSource !== AuthorityMetadataSource.CACHE) {
+ // Reset the expiration time unless both values came from a successful cache lookup
+ metadataEntity.resetExpiresAt();
+ metadataEntity.updateCanonicalAuthority(this.canonicalAuthority);
+ }
+ cacheKey = this.cacheManager.generateAuthorityMetadataCacheKey(metadataEntity.preferred_cache);
+ this.cacheManager.setAuthorityMetadata(cacheKey, metadataEntity);
+ this.metadata = metadataEntity;
+ return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Update AuthorityMetadataEntity with new endpoints and return where the information came from
+ * @param metadataEntity
+ */
+ Authority.prototype.updateEndpointMetadata = function (metadataEntity) {
+ var _a, _b, _c, _d, _e, _f;
+ return __awaiter(this, void 0, void 0, function () {
+ var metadata, harcodedMetadata;
+ return __generator(this, function (_g) {
+ switch (_g.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityUpdateEndpointMetadata, this.correlationId);
+ metadata = this.getEndpointMetadataFromConfig();
+ if (metadata) {
+ metadataEntity.updateEndpointMetadata(metadata, false);
+ return [2 /*return*/, AuthorityMetadataSource.CONFIG];
+ }
+ if (this.isAuthoritySameType(metadataEntity) && metadataEntity.endpointsFromNetwork && !metadataEntity.isExpired()) {
+ // No need to update
+ return [2 /*return*/, AuthorityMetadataSource.CACHE];
+ }
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.AuthorityGetEndpointMetadataFromNetwork, this.correlationId);
+ return [4 /*yield*/, this.getEndpointMetadataFromNetwork()];
+ case 1:
+ metadata = _g.sent();
+ if (!metadata) return [3 /*break*/, 4];
+ if (!((_c = this.authorityOptions.azureRegionConfiguration) === null || _c === void 0 ? void 0 : _c.azureRegion)) return [3 /*break*/, 3];
+ (_d = this.performanceClient) === null || _d === void 0 ? void 0 : _d.setPreQueueTime(exports.PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.correlationId);
+ return [4 /*yield*/, this.updateMetadataWithRegionalInformation(metadata)];
+ case 2:
+ metadata = _g.sent();
+ _g.label = 3;
+ case 3:
+ metadataEntity.updateEndpointMetadata(metadata, true);
+ return [2 /*return*/, AuthorityMetadataSource.NETWORK];
+ case 4:
+ harcodedMetadata = this.getEndpointMetadataFromHardcodedValues();
+ if (!(harcodedMetadata && !this.authorityOptions.skipAuthorityMetadataCache)) return [3 /*break*/, 7];
+ if (!((_e = this.authorityOptions.azureRegionConfiguration) === null || _e === void 0 ? void 0 : _e.azureRegion)) return [3 /*break*/, 6];
+ (_f = this.performanceClient) === null || _f === void 0 ? void 0 : _f.setPreQueueTime(exports.PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.correlationId);
+ return [4 /*yield*/, this.updateMetadataWithRegionalInformation(harcodedMetadata)];
+ case 5:
+ harcodedMetadata = _g.sent();
+ _g.label = 6;
+ case 6:
+ metadataEntity.updateEndpointMetadata(harcodedMetadata, false);
+ return [2 /*return*/, AuthorityMetadataSource.HARDCODED_VALUES];
+ case 7: throw ClientAuthError.createUnableToGetOpenidConfigError(this.defaultOpenIdConfigurationEndpoint);
+ }
+ });
+ });
+ };
+ /**
+ * Compares the number of url components after the domain to determine if the cached
+ * authority metadata can be used for the requested authority. Protects against same domain different
+ * authority such as login.microsoftonline.com/tenant and login.microsoftonline.com/tfp/tenant/policy
+ * @param metadataEntity
+ */
+ Authority.prototype.isAuthoritySameType = function (metadataEntity) {
+ var cachedAuthorityUrl = new UrlString(metadataEntity.canonical_authority);
+ var cachedParts = cachedAuthorityUrl.getUrlComponents().PathSegments;
+ return cachedParts.length === this.canonicalAuthorityUrlComponents.PathSegments.length;
+ };
+ /**
+ * Parse authorityMetadata config option
+ */
+ Authority.prototype.getEndpointMetadataFromConfig = function () {
+ if (this.authorityOptions.authorityMetadata) {
+ try {
+ return JSON.parse(this.authorityOptions.authorityMetadata);
+ }
+ catch (e) {
+ throw ClientConfigurationError.createInvalidAuthorityMetadataError();
+ }
+ }
+ return null;
+ };
+ /**
+ * Gets OAuth endpoints from the given OpenID configuration endpoint.
+ *
+ * @param hasHardcodedMetadata boolean
+ */
+ Authority.prototype.getEndpointMetadataFromNetwork = function () {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var options, response;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityGetEndpointMetadataFromNetwork, this.correlationId);
+ options = {};
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, this.networkInterface.
+ sendGetRequestAsync(this.defaultOpenIdConfigurationEndpoint, options)];
+ case 2:
+ response = _b.sent();
+ return [2 /*return*/, isOpenIdConfigResponse(response.body) ? response.body : null];
+ case 3:
+ _b.sent();
+ return [2 /*return*/, null];
+ case 4: return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Get OAuth endpoints for common authorities.
+ */
+ Authority.prototype.getEndpointMetadataFromHardcodedValues = function () {
+ if (this.canonicalAuthority in EndpointMetadata) {
+ return EndpointMetadata[this.canonicalAuthority];
+ }
+ return null;
+ };
+ /**
+ * Update the retrieved metadata with regional information.
+ * User selected Azure region will be used if configured.
+ */
+ Authority.prototype.updateMetadataWithRegionalInformation = function (metadata) {
+ var _a, _b, _c, _d;
+ return __awaiter(this, void 0, void 0, function () {
+ var userConfiguredAzureRegion, autodetectedRegionName;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.correlationId);
+ userConfiguredAzureRegion = (_b = this.authorityOptions.azureRegionConfiguration) === null || _b === void 0 ? void 0 : _b.azureRegion;
+ if (!userConfiguredAzureRegion) return [3 /*break*/, 2];
+ if (userConfiguredAzureRegion !== Constants.AZURE_REGION_AUTO_DISCOVER_FLAG) {
+ this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.CONFIGURED_NO_AUTO_DETECTION;
+ this.regionDiscoveryMetadata.region_used = userConfiguredAzureRegion;
+ return [2 /*return*/, Authority.replaceWithRegionalInformation(metadata, userConfiguredAzureRegion)];
+ }
+ (_c = this.performanceClient) === null || _c === void 0 ? void 0 : _c.setPreQueueTime(exports.PerformanceEvents.RegionDiscoveryDetectRegion, this.correlationId);
+ return [4 /*yield*/, this.regionDiscovery.detectRegion((_d = this.authorityOptions.azureRegionConfiguration) === null || _d === void 0 ? void 0 : _d.environmentRegion, this.regionDiscoveryMetadata)];
+ case 1:
+ autodetectedRegionName = _e.sent();
+ if (autodetectedRegionName) {
+ this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_SUCCESSFUL;
+ this.regionDiscoveryMetadata.region_used = autodetectedRegionName;
+ return [2 /*return*/, Authority.replaceWithRegionalInformation(metadata, autodetectedRegionName)];
+ }
+ this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_FAILED;
+ _e.label = 2;
+ case 2: return [2 /*return*/, metadata];
+ }
+ });
+ });
+ };
+ /**
+ * Updates the AuthorityMetadataEntity with new aliases, preferred_network and preferred_cache
+ * and returns where the information was retrieved from
+ * @param metadataEntity
+ * @returns AuthorityMetadataSource
+ */
+ Authority.prototype.updateCloudDiscoveryMetadata = function (metadataEntity) {
+ var _a, _b;
+ return __awaiter(this, void 0, void 0, function () {
+ var metadata, metadataEntityExpired, harcodedMetadata;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityUpdateCloudDiscoveryMetadata, this.correlationId);
+ // attempt to read metadata from the config
+ this.logger.verbose("Attempting to get cloud discovery metadata in the config");
+ this.logger.verbosePii("Known Authorities: " + (this.authorityOptions.knownAuthorities || Constants.NOT_APPLICABLE));
+ this.logger.verbosePii("Authority Metadata: " + (this.authorityOptions.authorityMetadata || Constants.NOT_APPLICABLE));
+ this.logger.verbosePii("Canonical Authority: " + (metadataEntity.canonical_authority || Constants.NOT_APPLICABLE));
+ metadata = this.getCloudDiscoveryMetadataFromConfig();
+ if (metadata) {
+ this.logger.verbose("Found cloud discovery metadata in the config.");
+ metadataEntity.updateCloudDiscoveryMetadata(metadata, false);
+ return [2 /*return*/, AuthorityMetadataSource.CONFIG];
+ }
+ // If the cached metadata came from config but that config was not passed to this instance, we must go to the network
+ this.logger.verbose("Did not find cloud discovery metadata in the config... Attempting to get cloud discovery metadata from the cache.");
+ metadataEntityExpired = metadataEntity.isExpired();
+ if (this.isAuthoritySameType(metadataEntity) && metadataEntity.aliasesFromNetwork && !metadataEntityExpired) {
+ this.logger.verbose("Found metadata in the cache.");
+ // No need to update
+ return [2 /*return*/, AuthorityMetadataSource.CACHE];
+ }
+ else if (metadataEntityExpired) {
+ this.logger.verbose("The metadata entity is expired.");
+ }
+ this.logger.verbose("Did not find cloud discovery metadata in the cache... Attempting to get cloud discovery metadata from the network.");
+ (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.setPreQueueTime(exports.PerformanceEvents.AuthorityGetCloudDiscoveryMetadataFromNetwork, this.correlationId);
+ return [4 /*yield*/, this.getCloudDiscoveryMetadataFromNetwork()];
+ case 1:
+ metadata = _c.sent();
+ if (metadata) {
+ this.logger.verbose("cloud discovery metadata was successfully returned from getCloudDiscoveryMetadataFromNetwork()");
+ metadataEntity.updateCloudDiscoveryMetadata(metadata, true);
+ return [2 /*return*/, AuthorityMetadataSource.NETWORK];
+ }
+ this.logger.verbose("Did not find cloud discovery metadata from the network... Attempting to get cloud discovery metadata from hardcoded values.");
+ harcodedMetadata = this.getCloudDiscoveryMetadataFromHarcodedValues();
+ if (harcodedMetadata && !this.options.skipAuthorityMetadataCache) {
+ this.logger.verbose("Found cloud discovery metadata from hardcoded values.");
+ metadataEntity.updateCloudDiscoveryMetadata(harcodedMetadata, false);
+ return [2 /*return*/, AuthorityMetadataSource.HARDCODED_VALUES];
+ }
+ // Metadata could not be obtained from the config, cache, network or hardcoded values
+ this.logger.error("Did not find cloud discovery metadata from hardcoded values... Metadata could not be obtained from config, cache, network or hardcoded values. Throwing Untrusted Authority Error.");
+ throw ClientConfigurationError.createUntrustedAuthorityError();
+ }
+ });
+ });
+ };
+ /**
+ * Parse cloudDiscoveryMetadata config or check knownAuthorities
+ */
+ Authority.prototype.getCloudDiscoveryMetadataFromConfig = function () {
+ // CIAM does not support cloud discovery metadata
+ if (this.authorityType === exports.AuthorityType.Ciam) {
+ this.logger.verbose("CIAM authorities do not support cloud discovery metadata, generate the aliases from authority host.");
+ return Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort);
+ }
+ // Check if network response was provided in config
+ if (this.authorityOptions.cloudDiscoveryMetadata) {
+ this.logger.verbose("The cloud discovery metadata has been provided as a network response, in the config.");
+ try {
+ this.logger.verbose("Attempting to parse the cloud discovery metadata.");
+ var parsedResponse = JSON.parse(this.authorityOptions.cloudDiscoveryMetadata);
+ var metadata = Authority.getCloudDiscoveryMetadataFromNetworkResponse(parsedResponse.metadata, this.hostnameAndPort);
+ this.logger.verbose("Parsed the cloud discovery metadata.");
+ if (metadata) {
+ this.logger.verbose("There is returnable metadata attached to the parsed cloud discovery metadata.");
+ return metadata;
+ }
+ else {
+ this.logger.verbose("There is no metadata attached to the parsed cloud discovery metadata.");
+ }
+ }
+ catch (e) {
+ this.logger.verbose("Unable to parse the cloud discovery metadata. Throwing Invalid Cloud Discovery Metadata Error.");
+ throw ClientConfigurationError.createInvalidCloudDiscoveryMetadataError();
+ }
+ }
+ // If cloudDiscoveryMetadata is empty or does not contain the host, check knownAuthorities
+ if (this.isInKnownAuthorities()) {
+ this.logger.verbose("The host is included in knownAuthorities. Creating new cloud discovery metadata from the host.");
+ return Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort);
+ }
+ return null;
+ };
+ /**
+ * Called to get metadata from network if CloudDiscoveryMetadata was not populated by config
+ *
+ * @param hasHardcodedMetadata boolean
+ */
+ Authority.prototype.getCloudDiscoveryMetadataFromNetwork = function () {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var instanceDiscoveryEndpoint, options, match, response, typedResponseBody, metadata, error_1, typedError;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.AuthorityGetCloudDiscoveryMetadataFromNetwork, this.correlationId);
+ instanceDiscoveryEndpoint = "" + Constants.AAD_INSTANCE_DISCOVERY_ENDPT + this.canonicalAuthority + "oauth2/v2.0/authorize";
+ options = {};
+ match = null;
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 3, , 4]);
+ return [4 /*yield*/, this.networkInterface.sendGetRequestAsync(instanceDiscoveryEndpoint, options)];
+ case 2:
+ response = _b.sent();
+ typedResponseBody = void 0;
+ metadata = void 0;
+ if (isCloudInstanceDiscoveryResponse(response.body)) {
+ typedResponseBody = response.body;
+ metadata = typedResponseBody.metadata;
+ this.logger.verbosePii("tenant_discovery_endpoint is: " + typedResponseBody.tenant_discovery_endpoint);
+ }
+ else if (isCloudInstanceDiscoveryErrorResponse(response.body)) {
+ this.logger.warning("A CloudInstanceDiscoveryErrorResponse was returned. The cloud instance discovery network request's status code is: " + response.status);
+ typedResponseBody = response.body;
+ if (typedResponseBody.error === Constants.INVALID_INSTANCE) {
+ this.logger.error("The CloudInstanceDiscoveryErrorResponse error is invalid_instance.");
+ return [2 /*return*/, null];
+ }
+ this.logger.warning("The CloudInstanceDiscoveryErrorResponse error is " + typedResponseBody.error);
+ this.logger.warning("The CloudInstanceDiscoveryErrorResponse error description is " + typedResponseBody.error_description);
+ this.logger.warning("Setting the value of the CloudInstanceDiscoveryMetadata (returned from the network) to []");
+ metadata = [];
+ }
+ else {
+ this.logger.error("AAD did not return a CloudInstanceDiscoveryResponse or CloudInstanceDiscoveryErrorResponse");
+ return [2 /*return*/, null];
+ }
+ this.logger.verbose("Attempting to find a match between the developer's authority and the CloudInstanceDiscoveryMetadata returned from the network request.");
+ match = Authority.getCloudDiscoveryMetadataFromNetworkResponse(metadata, this.hostnameAndPort);
+ return [3 /*break*/, 4];
+ case 3:
+ error_1 = _b.sent();
+ if (error_1 instanceof AuthError) {
+ this.logger.error("There was a network error while attempting to get the cloud discovery instance metadata.\nError: " + error_1.errorCode + "\nError Description: " + error_1.errorMessage);
+ }
+ else {
+ typedError = error_1;
+ this.logger.error("A non-MSALJS error was thrown while attempting to get the cloud instance discovery metadata.\nError: " + typedError.name + "\nError Description: " + typedError.message);
+ }
+ return [2 /*return*/, null];
+ case 4:
+ // Custom Domain scenario, host is trusted because Instance Discovery call succeeded
+ if (!match) {
+ this.logger.warning("The developer's authority was not found within the CloudInstanceDiscoveryMetadata returned from the network request.");
+ this.logger.verbose("Creating custom Authority for custom domain scenario.");
+ match = Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort);
+ }
+ return [2 /*return*/, match];
+ }
+ });
+ });
+ };
+ /**
+ * Get cloud discovery metadata for common authorities
+ */
+ Authority.prototype.getCloudDiscoveryMetadataFromHarcodedValues = function () {
+ if (this.canonicalAuthority in InstanceDiscoveryMetadata) {
+ return InstanceDiscoveryMetadata[this.canonicalAuthority];
+ }
+ return null;
+ };
+ /**
+ * Helper function to determine if this host is included in the knownAuthorities config option
+ */
+ Authority.prototype.isInKnownAuthorities = function () {
+ var _this = this;
+ var matches = this.authorityOptions.knownAuthorities.filter(function (authority) {
+ return UrlString.getDomainFromUrl(authority).toLowerCase() === _this.hostnameAndPort;
+ });
+ return matches.length > 0;
+ };
+ /**
+ * helper function to populate the authority based on azureCloudOptions
+ * @param authorityString
+ * @param azureCloudOptions
+ */
+ Authority.generateAuthority = function (authorityString, azureCloudOptions) {
+ var authorityAzureCloudInstance;
+ if (azureCloudOptions && azureCloudOptions.azureCloudInstance !== exports.AzureCloudInstance.None) {
+ var tenant = azureCloudOptions.tenant ? azureCloudOptions.tenant : Constants.DEFAULT_COMMON_TENANT;
+ authorityAzureCloudInstance = azureCloudOptions.azureCloudInstance + "/" + tenant + "/";
+ }
+ return authorityAzureCloudInstance ? authorityAzureCloudInstance : authorityString;
+ };
+ /**
+ * Creates cloud discovery metadata object from a given host
+ * @param host
+ */
+ Authority.createCloudDiscoveryMetadataFromHost = function (host) {
+ return {
+ preferred_network: host,
+ preferred_cache: host,
+ aliases: [host]
+ };
+ };
+ /**
+ * Searches instance discovery network response for the entry that contains the host in the aliases list
+ * @param response
+ * @param authority
+ */
+ Authority.getCloudDiscoveryMetadataFromNetworkResponse = function (response, authority) {
+ for (var i = 0; i < response.length; i++) {
+ var metadata = response[i];
+ if (metadata.aliases.indexOf(authority) > -1) {
+ return metadata;
+ }
+ }
+ return null;
+ };
+ /**
+ * helper function to generate environment from authority object
+ */
+ Authority.prototype.getPreferredCache = function () {
+ if (this.discoveryComplete()) {
+ return this.metadata.preferred_cache;
+ }
+ else {
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError("Discovery incomplete.");
+ }
+ };
+ /**
+ * Returns whether or not the provided host is an alias of this authority instance
+ * @param host
+ */
+ Authority.prototype.isAlias = function (host) {
+ return this.metadata.aliases.indexOf(host) > -1;
+ };
+ /**
+ * Checks whether the provided host is that of a public cloud authority
+ *
+ * @param authority string
+ * @returns bool
+ */
+ Authority.isPublicCloudAuthority = function (host) {
+ return Constants.KNOWN_PUBLIC_CLOUDS.indexOf(host) >= 0;
+ };
+ /**
+ * Rebuild the authority string with the region
+ *
+ * @param host string
+ * @param region string
+ */
+ Authority.buildRegionalAuthorityString = function (host, region, queryString) {
+ // Create and validate a Url string object with the initial authority string
+ var authorityUrlInstance = new UrlString(host);
+ authorityUrlInstance.validateAsUri();
+ var authorityUrlParts = authorityUrlInstance.getUrlComponents();
+ var hostNameAndPort = region + "." + authorityUrlParts.HostNameAndPort;
+ if (this.isPublicCloudAuthority(authorityUrlParts.HostNameAndPort)) {
+ hostNameAndPort = region + "." + Constants.REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX;
+ }
+ // Include the query string portion of the url
+ var url = UrlString.constructAuthorityUriFromObject(__assign(__assign({}, authorityUrlInstance.getUrlComponents()), { HostNameAndPort: hostNameAndPort })).urlString;
+ // Add the query string if a query string was provided
+ if (queryString)
+ return url + "?" + queryString;
+ return url;
+ };
+ /**
+ * Replace the endpoints in the metadata object with their regional equivalents.
+ *
+ * @param metadata OpenIdConfigResponse
+ * @param azureRegion string
+ */
+ Authority.replaceWithRegionalInformation = function (metadata, azureRegion) {
+ metadata.authorization_endpoint = Authority.buildRegionalAuthorityString(metadata.authorization_endpoint, azureRegion);
+ // TODO: Enquire on whether we should leave the query string or remove it before releasing the feature
+ metadata.token_endpoint = Authority.buildRegionalAuthorityString(metadata.token_endpoint, azureRegion, Constants.REGIONAL_AUTH_NON_MSI_QUERY_STRING);
+ if (metadata.end_session_endpoint) {
+ metadata.end_session_endpoint = Authority.buildRegionalAuthorityString(metadata.end_session_endpoint, azureRegion);
+ }
+ return metadata;
+ };
+ /**
+ * Transform CIAM_AUTHORIY as per the below rules:
+ * If no path segments found and it is a CIAM authority (hostname ends with .ciamlogin.com), then transform it
+ *
+ * NOTE: The transformation path should go away once STS supports CIAM with the format: `tenantIdorDomain.ciamlogin.com`
+ * `ciamlogin.com` can also change in the future and we should accommodate the same
+ *
+ * @param authority
+ */
+ Authority.transformCIAMAuthority = function (authority) {
+ var ciamAuthority = authority.endsWith(Constants.FORWARD_SLASH) ? authority : "" + authority + Constants.FORWARD_SLASH;
+ var authorityUrl = new UrlString(authority);
+ var authorityUrlComponents = authorityUrl.getUrlComponents();
+ // check if transformation is needed
+ if (authorityUrlComponents.PathSegments.length === 0 && (authorityUrlComponents.HostNameAndPort.endsWith(Constants.CIAM_AUTH_URL))) {
+ var tenantIdOrDomain = authorityUrlComponents.HostNameAndPort.split(".")[0];
+ ciamAuthority = "" + ciamAuthority + tenantIdOrDomain + Constants.AAD_TENANT_DOMAIN_SUFFIX;
+ }
+ return ciamAuthority;
+ };
+ // Reserved tenant domain names that will not be replaced with tenant id
+ Authority.reservedTenantDomains = (new Set([
+ "{tenant}",
+ "{tenantid}",
+ AADAuthorityConstants.COMMON,
+ AADAuthorityConstants.CONSUMERS,
+ AADAuthorityConstants.ORGANIZATIONS
+ ]));
+ return Authority;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var AuthorityFactory = /** @class */ (function () {
+ function AuthorityFactory() {
+ }
+ /**
+ * Create an authority object of the correct type based on the url
+ * Performs basic authority validation - checks to see if the authority is of a valid type (i.e. aad, b2c, adfs)
+ *
+ * Also performs endpoint discovery.
+ *
+ * @param authorityUri
+ * @param networkClient
+ * @param protocolMode
+ */
+ AuthorityFactory.createDiscoveredInstance = function (authorityUri, networkClient, cacheManager, authorityOptions, logger, performanceClient, correlationId) {
+ return __awaiter(this, void 0, void 0, function () {
+ var authorityUriFinal, acquireTokenAuthority, e_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ performanceClient === null || performanceClient === void 0 ? void 0 : performanceClient.addQueueMeasurement(exports.PerformanceEvents.AuthorityFactoryCreateDiscoveredInstance, correlationId);
+ authorityUriFinal = Authority.transformCIAMAuthority(authorityUri);
+ acquireTokenAuthority = AuthorityFactory.createInstance(authorityUriFinal, networkClient, cacheManager, authorityOptions, logger, performanceClient, correlationId);
+ _a.label = 1;
+ case 1:
+ _a.trys.push([1, 3, , 4]);
+ performanceClient === null || performanceClient === void 0 ? void 0 : performanceClient.setPreQueueTime(exports.PerformanceEvents.AuthorityResolveEndpointsAsync, correlationId);
+ return [4 /*yield*/, acquireTokenAuthority.resolveEndpointsAsync()];
+ case 2:
+ _a.sent();
+ return [2 /*return*/, acquireTokenAuthority];
+ case 3:
+ e_1 = _a.sent();
+ throw ClientAuthError.createEndpointDiscoveryIncompleteError(e_1);
+ case 4: return [2 /*return*/];
+ }
+ });
+ });
+ };
+ /**
+ * Create an authority object of the correct type based on the url
+ * Performs basic authority validation - checks to see if the authority is of a valid type (i.e. aad, b2c, adfs)
+ *
+ * Does not perform endpoint discovery.
+ *
+ * @param authorityUrl
+ * @param networkInterface
+ * @param protocolMode
+ */
+ AuthorityFactory.createInstance = function (authorityUrl, networkInterface, cacheManager, authorityOptions, logger, performanceClient, correlationId) {
+ // Throw error if authority url is empty
+ if (StringUtils.isEmpty(authorityUrl)) {
+ throw ClientConfigurationError.createUrlEmptyError();
+ }
+ return new Authority(authorityUrl, networkInterface, cacheManager, authorityOptions, logger, performanceClient, correlationId);
+ };
+ return AuthorityFactory;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var ServerTelemetryEntity = /** @class */ (function () {
+ function ServerTelemetryEntity() {
+ this.failedRequests = [];
+ this.errors = [];
+ this.cacheHits = 0;
+ }
+ /**
+ * validates if a given cache entry is "Telemetry", parses
+ * @param key
+ * @param entity
+ */
+ ServerTelemetryEntity.isServerTelemetryEntity = function (key, entity) {
+ var validateKey = key.indexOf(SERVER_TELEM_CONSTANTS.CACHE_KEY) === 0;
+ var validateEntity = true;
+ if (entity) {
+ validateEntity =
+ entity.hasOwnProperty("failedRequests") &&
+ entity.hasOwnProperty("errors") &&
+ entity.hasOwnProperty("cacheHits");
+ }
+ return validateKey && validateEntity;
+ };
+ return ServerTelemetryEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var ThrottlingEntity = /** @class */ (function () {
+ function ThrottlingEntity() {
+ }
+ /**
+ * validates if a given cache entry is "Throttling", parses
+ * @param key
+ * @param entity
+ */
+ ThrottlingEntity.isThrottlingEntity = function (key, entity) {
+ var validateKey = false;
+ if (key) {
+ validateKey = key.indexOf(ThrottlingConstants.THROTTLING_PREFIX) === 0;
+ }
+ var validateEntity = true;
+ if (entity) {
+ validateEntity = entity.hasOwnProperty("throttleTime");
+ }
+ return validateKey && validateEntity;
+ };
+ return ThrottlingEntity;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var StubbedNetworkModule = {
+ sendGetRequestAsync: function () {
+ var notImplErr = "Network interface - sendGetRequestAsync() has not been implemented for the Network interface.";
+ return Promise.reject(AuthError.createUnexpectedError(notImplErr));
+ },
+ sendPostRequestAsync: function () {
+ var notImplErr = "Network interface - sendPostRequestAsync() has not been implemented for the Network interface.";
+ return Promise.reject(AuthError.createUnexpectedError(notImplErr));
+ }
+};
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * ClientAuthErrorMessage class containing string constants used by error codes and messages.
+ */
+var JoseHeaderErrorMessage = {
+ missingKidError: {
+ code: "missing_kid_error",
+ desc: "The JOSE Header for the requested JWT, JWS or JWK object requires a keyId to be configured as the 'kid' header claim. No 'kid' value was provided."
+ },
+ missingAlgError: {
+ code: "missing_alg_error",
+ desc: "The JOSE Header for the requested JWT, JWS or JWK object requires an algorithm to be specified as the 'alg' header claim. No 'alg' value was provided."
+ },
+};
+/**
+ * Error thrown when there is an error in the client code running on the browser.
+ */
+var JoseHeaderError = /** @class */ (function (_super) {
+ __extends(JoseHeaderError, _super);
+ function JoseHeaderError(errorCode, errorMessage) {
+ var _this = _super.call(this, errorCode, errorMessage) || this;
+ _this.name = "JoseHeaderError";
+ Object.setPrototypeOf(_this, JoseHeaderError.prototype);
+ return _this;
+ }
+ /**
+ * Creates an error thrown when keyId isn't set on JOSE header.
+ */
+ JoseHeaderError.createMissingKidError = function () {
+ return new JoseHeaderError(JoseHeaderErrorMessage.missingKidError.code, JoseHeaderErrorMessage.missingKidError.desc);
+ };
+ /**
+ * Creates an error thrown when algorithm isn't set on JOSE header.
+ */
+ JoseHeaderError.createMissingAlgError = function () {
+ return new JoseHeaderError(JoseHeaderErrorMessage.missingAlgError.code, JoseHeaderErrorMessage.missingAlgError.desc);
+ };
+ return JoseHeaderError;
+}(AuthError));
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var JoseHeader = /** @class */ (function () {
+ function JoseHeader(options) {
+ this.typ = options.typ;
+ this.alg = options.alg;
+ this.kid = options.kid;
+ }
+ /**
+ * Builds SignedHttpRequest formatted JOSE Header from the
+ * JOSE Header options provided or previously set on the object and returns
+ * the stringified header object.
+ * Throws if keyId or algorithm aren't provided since they are required for Access Token Binding.
+ * @param shrHeaderOptions
+ * @returns
+ */
+ JoseHeader.getShrHeaderString = function (shrHeaderOptions) {
+ // KeyID is required on the SHR header
+ if (!shrHeaderOptions.kid) {
+ throw JoseHeaderError.createMissingKidError();
+ }
+ // Alg is required on the SHR header
+ if (!shrHeaderOptions.alg) {
+ throw JoseHeaderError.createMissingAlgError();
+ }
+ var shrHeader = new JoseHeader({
+ // Access Token PoP headers must have type pop, but the type header can be overriden for special cases
+ typ: shrHeaderOptions.typ || JsonTypes.Pop,
+ kid: shrHeaderOptions.kid,
+ alg: shrHeaderOptions.alg
+ });
+ return JSON.stringify(shrHeader);
+ };
+ return JoseHeader;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This is a helper class that parses supported HTTP response authentication headers to extract and return
+ * header challenge values that can be used outside the basic authorization flows.
+ */
+var AuthenticationHeaderParser = /** @class */ (function () {
+ function AuthenticationHeaderParser(headers) {
+ this.headers = headers;
+ }
+ /**
+ * This method parses the SHR nonce value out of either the Authentication-Info or WWW-Authenticate authentication headers.
+ * @returns
+ */
+ AuthenticationHeaderParser.prototype.getShrNonce = function () {
+ // Attempt to parse nonce from Authentiacation-Info
+ var authenticationInfo = this.headers[exports.HeaderNames.AuthenticationInfo];
+ if (authenticationInfo) {
+ var authenticationInfoChallenges = this.parseChallenges(authenticationInfo);
+ if (authenticationInfoChallenges.nextnonce) {
+ return authenticationInfoChallenges.nextnonce;
+ }
+ throw ClientConfigurationError.createInvalidAuthenticationHeaderError(exports.HeaderNames.AuthenticationInfo, "nextnonce challenge is missing.");
+ }
+ // Attempt to parse nonce from WWW-Authenticate
+ var wwwAuthenticate = this.headers[exports.HeaderNames.WWWAuthenticate];
+ if (wwwAuthenticate) {
+ var wwwAuthenticateChallenges = this.parseChallenges(wwwAuthenticate);
+ if (wwwAuthenticateChallenges.nonce) {
+ return wwwAuthenticateChallenges.nonce;
+ }
+ throw ClientConfigurationError.createInvalidAuthenticationHeaderError(exports.HeaderNames.WWWAuthenticate, "nonce challenge is missing.");
+ }
+ // If neither header is present, throw missing headers error
+ throw ClientConfigurationError.createMissingNonceAuthenticationHeadersError();
+ };
+ /**
+ * Parses an HTTP header's challenge set into a key/value map.
+ * @param header
+ * @returns
+ */
+ AuthenticationHeaderParser.prototype.parseChallenges = function (header) {
+ var schemeSeparator = header.indexOf(" ");
+ var challenges = header.substr(schemeSeparator + 1).split(",");
+ var challengeMap = {};
+ challenges.forEach(function (challenge) {
+ var _a = challenge.split("="), key = _a[0], value = _a[1];
+ // Remove escaped quotation marks (', ") from challenge string to keep only the challenge value
+ challengeMap[key] = unescape(value.replace(/['"]+/g, Constants.EMPTY_STRING));
+ });
+ return challengeMap;
+ };
+ return AuthenticationHeaderParser;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var ServerTelemetryManager = /** @class */ (function () {
+ function ServerTelemetryManager(telemetryRequest, cacheManager) {
+ this.cacheOutcome = CacheOutcome.NO_CACHE_HIT;
+ this.cacheManager = cacheManager;
+ this.apiId = telemetryRequest.apiId;
+ this.correlationId = telemetryRequest.correlationId;
+ this.wrapperSKU = telemetryRequest.wrapperSKU || Constants.EMPTY_STRING;
+ this.wrapperVer = telemetryRequest.wrapperVer || Constants.EMPTY_STRING;
+ this.telemetryCacheKey = SERVER_TELEM_CONSTANTS.CACHE_KEY + Separators.CACHE_KEY_SEPARATOR + telemetryRequest.clientId;
+ }
+ /**
+ * API to add MSER Telemetry to request
+ */
+ ServerTelemetryManager.prototype.generateCurrentRequestHeaderValue = function () {
+ var request = "" + this.apiId + SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR + this.cacheOutcome;
+ var platformFields = [this.wrapperSKU, this.wrapperVer].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
+ var regionDiscoveryFields = this.getRegionDiscoveryFields();
+ var requestWithRegionDiscoveryFields = [request, regionDiscoveryFields].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
+ return [SERVER_TELEM_CONSTANTS.SCHEMA_VERSION, requestWithRegionDiscoveryFields, platformFields].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
+ };
+ /**
+ * API to add MSER Telemetry for the last failed request
+ */
+ ServerTelemetryManager.prototype.generateLastRequestHeaderValue = function () {
+ var lastRequests = this.getLastRequests();
+ var maxErrors = ServerTelemetryManager.maxErrorsToSend(lastRequests);
+ var failedRequests = lastRequests.failedRequests.slice(0, 2 * maxErrors).join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
+ var errors = lastRequests.errors.slice(0, maxErrors).join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
+ var errorCount = lastRequests.errors.length;
+ // Indicate whether this header contains all data or partial data
+ var overflow = maxErrors < errorCount ? SERVER_TELEM_CONSTANTS.OVERFLOW_TRUE : SERVER_TELEM_CONSTANTS.OVERFLOW_FALSE;
+ var platformFields = [errorCount, overflow].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
+ return [SERVER_TELEM_CONSTANTS.SCHEMA_VERSION, lastRequests.cacheHits, failedRequests, errors, platformFields].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
+ };
+ /**
+ * API to cache token failures for MSER data capture
+ * @param error
+ */
+ ServerTelemetryManager.prototype.cacheFailedRequest = function (error) {
+ var lastRequests = this.getLastRequests();
+ if (lastRequests.errors.length >= SERVER_TELEM_CONSTANTS.MAX_CACHED_ERRORS) {
+ // Remove a cached error to make room, first in first out
+ lastRequests.failedRequests.shift(); // apiId
+ lastRequests.failedRequests.shift(); // correlationId
+ lastRequests.errors.shift();
+ }
+ lastRequests.failedRequests.push(this.apiId, this.correlationId);
+ if (!StringUtils.isEmpty(error.subError)) {
+ lastRequests.errors.push(error.subError);
+ }
+ else if (!StringUtils.isEmpty(error.errorCode)) {
+ lastRequests.errors.push(error.errorCode);
+ }
+ else if (!!error && error.toString()) {
+ lastRequests.errors.push(error.toString());
+ }
+ else {
+ lastRequests.errors.push(SERVER_TELEM_CONSTANTS.UNKNOWN_ERROR);
+ }
+ this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests);
+ return;
+ };
+ /**
+ * Update server telemetry cache entry by incrementing cache hit counter
+ */
+ ServerTelemetryManager.prototype.incrementCacheHits = function () {
+ var lastRequests = this.getLastRequests();
+ lastRequests.cacheHits += 1;
+ this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests);
+ return lastRequests.cacheHits;
+ };
+ /**
+ * Get the server telemetry entity from cache or initialize a new one
+ */
+ ServerTelemetryManager.prototype.getLastRequests = function () {
+ var initialValue = new ServerTelemetryEntity();
+ var lastRequests = this.cacheManager.getServerTelemetry(this.telemetryCacheKey);
+ return lastRequests || initialValue;
+ };
+ /**
+ * Remove server telemetry cache entry
+ */
+ ServerTelemetryManager.prototype.clearTelemetryCache = function () {
+ var lastRequests = this.getLastRequests();
+ var numErrorsFlushed = ServerTelemetryManager.maxErrorsToSend(lastRequests);
+ var errorCount = lastRequests.errors.length;
+ if (numErrorsFlushed === errorCount) {
+ // All errors were sent on last request, clear Telemetry cache
+ this.cacheManager.removeItem(this.telemetryCacheKey);
+ }
+ else {
+ // Partial data was flushed to server, construct a new telemetry cache item with errors that were not flushed
+ var serverTelemEntity = new ServerTelemetryEntity();
+ serverTelemEntity.failedRequests = lastRequests.failedRequests.slice(numErrorsFlushed * 2); // failedRequests contains 2 items for each error
+ serverTelemEntity.errors = lastRequests.errors.slice(numErrorsFlushed);
+ this.cacheManager.setServerTelemetry(this.telemetryCacheKey, serverTelemEntity);
+ }
+ };
+ /**
+ * Returns the maximum number of errors that can be flushed to the server in the next network request
+ * @param serverTelemetryEntity
+ */
+ ServerTelemetryManager.maxErrorsToSend = function (serverTelemetryEntity) {
+ var i;
+ var maxErrors = 0;
+ var dataSize = 0;
+ var errorCount = serverTelemetryEntity.errors.length;
+ for (i = 0; i < errorCount; i++) {
+ // failedRequests parameter contains pairs of apiId and correlationId, multiply index by 2 to preserve pairs
+ var apiId = serverTelemetryEntity.failedRequests[2 * i] || Constants.EMPTY_STRING;
+ var correlationId = serverTelemetryEntity.failedRequests[2 * i + 1] || Constants.EMPTY_STRING;
+ var errorCode = serverTelemetryEntity.errors[i] || Constants.EMPTY_STRING;
+ // Count number of characters that would be added to header, each character is 1 byte. Add 3 at the end to account for separators
+ dataSize += apiId.toString().length + correlationId.toString().length + errorCode.length + 3;
+ if (dataSize < SERVER_TELEM_CONSTANTS.MAX_LAST_HEADER_BYTES) {
+ // Adding this entry to the header would still keep header size below the limit
+ maxErrors += 1;
+ }
+ else {
+ break;
+ }
+ }
+ return maxErrors;
+ };
+ /**
+ * Get the region discovery fields
+ *
+ * @returns string
+ */
+ ServerTelemetryManager.prototype.getRegionDiscoveryFields = function () {
+ var regionDiscoveryFields = [];
+ regionDiscoveryFields.push(this.regionUsed || Constants.EMPTY_STRING);
+ regionDiscoveryFields.push(this.regionSource || Constants.EMPTY_STRING);
+ regionDiscoveryFields.push(this.regionOutcome || Constants.EMPTY_STRING);
+ return regionDiscoveryFields.join(",");
+ };
+ /**
+ * Update the region discovery metadata
+ *
+ * @param regionDiscoveryMetadata
+ * @returns void
+ */
+ ServerTelemetryManager.prototype.updateRegionDiscoveryMetadata = function (regionDiscoveryMetadata) {
+ this.regionUsed = regionDiscoveryMetadata.region_used;
+ this.regionSource = regionDiscoveryMetadata.region_source;
+ this.regionOutcome = regionDiscoveryMetadata.region_outcome;
+ };
+ /**
+ * Set cache outcome
+ */
+ ServerTelemetryManager.prototype.setCacheOutcome = function (cacheOutcome) {
+ this.cacheOutcome = cacheOutcome;
+ };
+ return ServerTelemetryManager;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var PerformanceClient = /** @class */ (function () {
+ /**
+ * Creates an instance of PerformanceClient,
+ * an abstract class containing core performance telemetry logic.
+ *
+ * @constructor
+ * @param {string} clientId Client ID of the application
+ * @param {string} authority Authority used by the application
+ * @param {Logger} logger Logger used by the application
+ * @param {string} libraryName Name of the library
+ * @param {string} libraryVersion Version of the library
+ */
+ function PerformanceClient(clientId, authority, logger, libraryName, libraryVersion, applicationTelemetry) {
+ this.authority = authority;
+ this.libraryName = libraryName;
+ this.libraryVersion = libraryVersion;
+ this.applicationTelemetry = applicationTelemetry;
+ this.clientId = clientId;
+ this.logger = logger;
+ this.callbacks = new Map();
+ this.eventsByCorrelationId = new Map();
+ this.queueMeasurements = new Map();
+ this.preQueueTimeByCorrelationId = new Map();
+ }
+ /**
+ * Starts and returns an platform-specific implementation of IPerformanceMeasurement.
+ * Note: this function can be changed to abstract at the next major version bump.
+ *
+ * @param {string} measureName
+ * @param {string} correlationId
+ * @returns {IPerformanceMeasurement}
+ */
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
+ PerformanceClient.prototype.startPerformanceMeasurement = function (measureName, correlationId) {
+ return {};
+ };
+ /**
+ * Starts and returns an platform-specific implementation of IPerformanceMeasurement.
+ * Note: this incorrectly-named function will be removed at the next major version bump.
+ *
+ * @param {string} measureName
+ * @param {string} correlationId
+ * @returns {IPerformanceMeasurement}
+ */
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
+ PerformanceClient.prototype.startPerformanceMeasuremeant = function (measureName, correlationId) {
+ return {};
+ };
+ /**
+ * Get integral fields.
+ * Override to change the set.
+ */
+ PerformanceClient.prototype.getIntFields = function () {
+ return IntFields;
+ };
+ /**
+ * Gets map of pre-queue times by correlation Id
+ *
+ * @param {PerformanceEvents} eventName
+ * @param {string} correlationId
+ * @returns {number}
+ */
+ PerformanceClient.prototype.getPreQueueTime = function (eventName, correlationId) {
+ var preQueueEvent = this.preQueueTimeByCorrelationId.get(correlationId);
+ if (!preQueueEvent) {
+ this.logger.trace("PerformanceClient.getPreQueueTime: no pre-queue times found for correlationId: " + correlationId + ", unable to add queue measurement");
+ return;
+ }
+ else if (preQueueEvent.name !== eventName) {
+ this.logger.trace("PerformanceClient.getPreQueueTime: no pre-queue time found for " + eventName + ", unable to add queue measurement");
+ return;
+ }
+ return preQueueEvent.time;
+ };
+ /**
+ * Calculates the difference between current time and time when function was queued.
+ * Note: It is possible to have 0 as the queue time if the current time and the queued time was the same.
+ *
+ * @param {number} preQueueTime
+ * @param {number} currentTime
+ * @returns {number}
+ */
+ PerformanceClient.prototype.calculateQueuedTime = function (preQueueTime, currentTime) {
+ if (preQueueTime < 1) {
+ this.logger.trace("PerformanceClient: preQueueTime should be a positive integer and not " + preQueueTime);
+ return 0;
+ }
+ if (currentTime < 1) {
+ this.logger.trace("PerformanceClient: currentTime should be a positive integer and not " + currentTime);
+ return 0;
+ }
+ if (currentTime < preQueueTime) {
+ this.logger.trace("PerformanceClient: currentTime is less than preQueueTime, check how time is being retrieved");
+ return 0;
+ }
+ return currentTime - preQueueTime;
+ };
+ /**
+ * Adds queue measurement time to QueueMeasurements array for given correlation ID.
+ *
+ * @param {PerformanceEvents} eventName
+ * @param {?string} correlationId
+ * @param {?number} queueTime
+ * @param {?boolean} manuallyCompleted - indicator for manually completed queue measurements
+ * @returns
+ */
+ PerformanceClient.prototype.addQueueMeasurement = function (eventName, correlationId, queueTime, manuallyCompleted) {
+ if (!correlationId) {
+ this.logger.trace("PerformanceClient.addQueueMeasurement: correlationId not provided for " + eventName + ", cannot add queue measurement");
+ return;
+ }
+ if (queueTime === 0) {
+ // Possible for there to be no queue time after calculation
+ this.logger.trace("PerformanceClient.addQueueMeasurement: queue time provided for " + eventName + " is " + queueTime);
+ }
+ else if (!queueTime) {
+ this.logger.trace("PerformanceClient.addQueueMeasurement: no queue time provided for " + eventName);
+ return;
+ }
+ var queueMeasurement = { eventName: eventName, queueTime: queueTime, manuallyCompleted: manuallyCompleted };
+ // Adds to existing correlation Id if present in queueMeasurements
+ var existingMeasurements = this.queueMeasurements.get(correlationId);
+ if (existingMeasurements) {
+ existingMeasurements.push(queueMeasurement);
+ this.queueMeasurements.set(correlationId, existingMeasurements);
+ }
+ else {
+ // Sets new correlation Id if not present in queueMeasurements
+ this.logger.trace("PerformanceClient.addQueueMeasurement: adding correlationId " + correlationId + " to queue measurements");
+ var measurementArray = [queueMeasurement];
+ this.queueMeasurements.set(correlationId, measurementArray);
+ }
+ // Delete processed pre-queue event.
+ this.preQueueTimeByCorrelationId.delete(correlationId);
+ };
+ /**
+ * Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
+ *
+ * @param {PerformanceEvents} measureName
+ * @param {?string} [correlationId]
+ * @returns {InProgressPerformanceEvent}
+ */
+ PerformanceClient.prototype.startMeasurement = function (measureName, correlationId) {
+ var _this = this;
+ var _a, _b;
+ // Generate a placeholder correlation if the request does not provide one
+ var eventCorrelationId = correlationId || this.generateId();
+ if (!correlationId) {
+ this.logger.info("PerformanceClient: No correlation id provided for " + measureName + ", generating", eventCorrelationId);
+ }
+ // Duplicate code to address spelling error will be removed at the next major version bump.
+ this.logger.trace("PerformanceClient: Performance measurement started for " + measureName, eventCorrelationId);
+ var performanceMeasurement = this.startPerformanceMeasuremeant(measureName, eventCorrelationId);
+ performanceMeasurement.startMeasurement();
+ var inProgressEvent = {
+ eventId: this.generateId(),
+ status: exports.PerformanceEventStatus.InProgress,
+ authority: this.authority,
+ libraryName: this.libraryName,
+ libraryVersion: this.libraryVersion,
+ clientId: this.clientId,
+ name: measureName,
+ startTimeMs: Date.now(),
+ correlationId: eventCorrelationId,
+ appName: (_a = this.applicationTelemetry) === null || _a === void 0 ? void 0 : _a.appName,
+ appVersion: (_b = this.applicationTelemetry) === null || _b === void 0 ? void 0 : _b.appVersion,
+ };
+ // Store in progress events so they can be discarded if not ended properly
+ this.cacheEventByCorrelationId(inProgressEvent);
+ // Return the event and functions the caller can use to properly end/flush the measurement
+ return {
+ endMeasurement: function (event) {
+ return _this.endMeasurement(__assign(__assign({}, inProgressEvent), event), performanceMeasurement);
+ },
+ discardMeasurement: function () {
+ return _this.discardMeasurements(inProgressEvent.correlationId);
+ },
+ addStaticFields: function (fields) {
+ return _this.addStaticFields(fields, inProgressEvent.correlationId);
+ },
+ increment: function (counters) {
+ return _this.increment(counters, inProgressEvent.correlationId);
+ },
+ measurement: performanceMeasurement,
+ event: inProgressEvent
+ };
+ };
+ /**
+ * Stops measuring the performance for an operation. Should only be called directly by PerformanceClient classes,
+ * as consumers should instead use the function returned by startMeasurement.
+ * Adds a new field named as "[event name]DurationMs" for sub-measurements, completes and emits an event
+ * otherwise.
+ *
+ * @param {PerformanceEvent} event
+ * @param {IPerformanceMeasurement} measurement
+ * @returns {(PerformanceEvent | null)}
+ */
+ PerformanceClient.prototype.endMeasurement = function (event, measurement) {
+ var _this = this;
+ var _a, _b;
+ var rootEvent = this.eventsByCorrelationId.get(event.correlationId);
+ if (!rootEvent) {
+ this.logger.trace("PerformanceClient: Measurement not found for " + event.eventId, event.correlationId);
+ return null;
+ }
+ var isRoot = event.eventId === rootEvent.eventId;
+ var queueInfo = {
+ totalQueueTime: 0,
+ totalQueueCount: 0,
+ manuallyCompletedCount: 0
+ };
+ if (isRoot) {
+ queueInfo = this.getQueueInfo(event.correlationId);
+ this.discardCache(rootEvent.correlationId);
+ }
+ else {
+ (_a = rootEvent.incompleteSubMeasurements) === null || _a === void 0 ? void 0 : _a.delete(event.eventId);
+ }
+ measurement === null || measurement === void 0 ? void 0 : measurement.endMeasurement();
+ var durationMs = measurement === null || measurement === void 0 ? void 0 : measurement.flushMeasurement();
+ // null indicates no measurement was taken (e.g. needed performance APIs not present)
+ if (!durationMs) {
+ this.logger.trace("PerformanceClient: Performance measurement not taken", rootEvent.correlationId);
+ return null;
+ }
+ this.logger.trace("PerformanceClient: Performance measurement ended for " + event.name + ": " + durationMs + " ms", event.correlationId);
+ // Add sub-measurement attribute to root event.
+ if (!isRoot) {
+ rootEvent[event.name + "DurationMs"] = Math.floor(durationMs);
+ return __assign({}, rootEvent);
+ }
+ var finalEvent = __assign(__assign({}, rootEvent), event);
+ var incompleteSubsCount = 0;
+ // Incomplete sub-measurements are discarded. They are likely an instrumentation bug that should be fixed.
+ (_b = finalEvent.incompleteSubMeasurements) === null || _b === void 0 ? void 0 : _b.forEach(function (subMeasurement) {
+ _this.logger.trace("PerformanceClient: Incomplete submeasurement " + subMeasurement.name + " found for " + event.name, finalEvent.correlationId);
+ incompleteSubsCount++;
+ });
+ finalEvent.incompleteSubMeasurements = undefined;
+ finalEvent = __assign(__assign({}, finalEvent), { durationMs: Math.round(durationMs), queuedTimeMs: queueInfo.totalQueueTime, queuedCount: queueInfo.totalQueueCount, queuedManuallyCompletedCount: queueInfo.manuallyCompletedCount, status: exports.PerformanceEventStatus.Completed, incompleteSubsCount: incompleteSubsCount });
+ this.truncateIntegralFields(finalEvent, this.getIntFields());
+ this.emitEvents([finalEvent], event.correlationId);
+ return finalEvent;
+ };
+ /**
+ * Saves extra information to be emitted when the measurements are flushed
+ * @param fields
+ * @param correlationId
+ */
+ PerformanceClient.prototype.addStaticFields = function (fields, correlationId) {
+ this.logger.trace("PerformanceClient: Updating static fields");
+ var event = this.eventsByCorrelationId.get(correlationId);
+ if (event) {
+ this.eventsByCorrelationId.set(correlationId, __assign(__assign({}, event), fields));
+ }
+ else {
+ this.logger.trace("PerformanceClient: Event not found for", correlationId);
+ }
+ };
+ /**
+ * Increment counters to be emitted when the measurements are flushed
+ * @param counters {Counters}
+ * @param correlationId {string} correlation identifier
+ */
+ PerformanceClient.prototype.increment = function (counters, correlationId) {
+ this.logger.trace("PerformanceClient: Updating counters");
+ var event = this.eventsByCorrelationId.get(correlationId);
+ if (event) {
+ for (var counter in counters) {
+ if (!event.hasOwnProperty(counter)) {
+ event[counter] = 0;
+ }
+ event[counter] += counters[counter];
+ }
+ }
+ else {
+ this.logger.trace("PerformanceClient: Event not found for", correlationId);
+ }
+ };
+ /**
+ * Upserts event into event cache.
+ * First key is the correlation id, second key is the event id.
+ * Allows for events to be grouped by correlation id,
+ * and to easily allow for properties on them to be updated.
+ *
+ * @private
+ * @param {PerformanceEvent} event
+ */
+ PerformanceClient.prototype.cacheEventByCorrelationId = function (event) {
+ var rootEvent = this.eventsByCorrelationId.get(event.correlationId);
+ if (rootEvent) {
+ this.logger.trace("PerformanceClient: Performance measurement for " + event.name + " added/updated", event.correlationId);
+ rootEvent.incompleteSubMeasurements = rootEvent.incompleteSubMeasurements || new Map();
+ rootEvent.incompleteSubMeasurements.set(event.eventId, { name: event.name, startTimeMs: event.startTimeMs });
+ }
+ else {
+ this.logger.trace("PerformanceClient: Performance measurement for " + event.name + " started", event.correlationId);
+ this.eventsByCorrelationId.set(event.correlationId, __assign({}, event));
+ }
+ };
+ PerformanceClient.prototype.getQueueInfo = function (correlationId) {
+ var queueMeasurementForCorrelationId = this.queueMeasurements.get(correlationId);
+ if (!queueMeasurementForCorrelationId) {
+ this.logger.trace("PerformanceClient: no queue measurements found for for correlationId: " + correlationId);
+ }
+ var totalQueueTime = 0;
+ var totalQueueCount = 0;
+ var manuallyCompletedCount = 0;
+ queueMeasurementForCorrelationId === null || queueMeasurementForCorrelationId === void 0 ? void 0 : queueMeasurementForCorrelationId.forEach(function (measurement) {
+ totalQueueTime += measurement.queueTime;
+ totalQueueCount++;
+ manuallyCompletedCount += measurement.manuallyCompleted ? 1 : 0;
+ });
+ return {
+ totalQueueTime: totalQueueTime,
+ totalQueueCount: totalQueueCount,
+ manuallyCompletedCount: manuallyCompletedCount
+ };
+ };
+ /**
+ * Removes measurements for a given correlation id.
+ *
+ * @param {string} correlationId
+ */
+ PerformanceClient.prototype.discardMeasurements = function (correlationId) {
+ this.logger.trace("PerformanceClient: Performance measurements discarded", correlationId);
+ this.eventsByCorrelationId.delete(correlationId);
+ };
+ /**
+ * Removes cache for a given correlation id.
+ *
+ * @param {string} correlationId correlation identifier
+ */
+ PerformanceClient.prototype.discardCache = function (correlationId) {
+ this.discardMeasurements(correlationId);
+ this.logger.trace("PerformanceClient: QueueMeasurements discarded", correlationId);
+ this.queueMeasurements.delete(correlationId);
+ this.logger.trace("PerformanceClient: Pre-queue times discarded", correlationId);
+ this.preQueueTimeByCorrelationId.delete(correlationId);
+ };
+ /**
+ * Registers a callback function to receive performance events.
+ *
+ * @param {PerformanceCallbackFunction} callback
+ * @returns {string}
+ */
+ PerformanceClient.prototype.addPerformanceCallback = function (callback) {
+ var callbackId = this.generateId();
+ this.callbacks.set(callbackId, callback);
+ this.logger.verbose("PerformanceClient: Performance callback registered with id: " + callbackId);
+ return callbackId;
+ };
+ /**
+ * Removes a callback registered with addPerformanceCallback.
+ *
+ * @param {string} callbackId
+ * @returns {boolean}
+ */
+ PerformanceClient.prototype.removePerformanceCallback = function (callbackId) {
+ var result = this.callbacks.delete(callbackId);
+ if (result) {
+ this.logger.verbose("PerformanceClient: Performance callback " + callbackId + " removed.");
+ }
+ else {
+ this.logger.verbose("PerformanceClient: Performance callback " + callbackId + " not removed.");
+ }
+ return result;
+ };
+ /**
+ * Emits events to all registered callbacks.
+ *
+ * @param {PerformanceEvent[]} events
+ * @param {?string} [correlationId]
+ */
+ PerformanceClient.prototype.emitEvents = function (events, correlationId) {
+ var _this = this;
+ this.logger.verbose("PerformanceClient: Emitting performance events", correlationId);
+ this.callbacks.forEach(function (callback, callbackId) {
+ _this.logger.trace("PerformanceClient: Emitting event to callback " + callbackId, correlationId);
+ callback.apply(null, [events]);
+ });
+ };
+ /**
+ * Enforce truncation of integral fields in performance event.
+ * @param {PerformanceEvent} event performance event to update.
+ * @param {Set} intFields integral fields.
+ */
+ PerformanceClient.prototype.truncateIntegralFields = function (event, intFields) {
+ intFields.forEach(function (key) {
+ if (key in event && typeof event[key] === "number") {
+ event[key] = Math.floor(event[key]);
+ }
+ });
+ };
+ return PerformanceClient;
+}());
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+var StubPerformanceMeasurement = /** @class */ (function () {
+ function StubPerformanceMeasurement() {
+ }
+ /* eslint-disable-next-line @typescript-eslint/no-empty-function */
+ StubPerformanceMeasurement.prototype.startMeasurement = function () { };
+ /* eslint-disable-next-line @typescript-eslint/no-empty-function */
+ StubPerformanceMeasurement.prototype.endMeasurement = function () { };
+ StubPerformanceMeasurement.prototype.flushMeasurement = function () {
+ return null;
+ };
+ return StubPerformanceMeasurement;
+}());
+var StubPerformanceClient = /** @class */ (function (_super) {
+ __extends(StubPerformanceClient, _super);
+ function StubPerformanceClient() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ StubPerformanceClient.prototype.generateId = function () {
+ return "callback-id";
+ };
+ StubPerformanceClient.prototype.startPerformanceMeasuremeant = function () {
+ return new StubPerformanceMeasurement();
+ };
+ StubPerformanceClient.prototype.startPerformanceMeasurement = function () {
+ return new StubPerformanceMeasurement();
+ };
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
+ StubPerformanceClient.prototype.calculateQueuedTime = function (preQueueTime, currentTime) {
+ return 0;
+ };
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
+ StubPerformanceClient.prototype.addQueueMeasurement = function (eventName, correlationId, queueTime) {
+ return;
+ };
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
+ StubPerformanceClient.prototype.setPreQueueTime = function (eventName, correlationId) {
+ return;
+ };
+ return StubPerformanceClient;
+}(PerformanceClient));
+
+exports.AccessTokenEntity = AccessTokenEntity;
+exports.AccountEntity = AccountEntity;
+exports.AppMetadataEntity = AppMetadataEntity;
+exports.AuthError = AuthError;
+exports.AuthErrorMessage = AuthErrorMessage;
+exports.AuthToken = AuthToken;
+exports.AuthenticationHeaderParser = AuthenticationHeaderParser;
+exports.Authority = Authority;
+exports.AuthorityFactory = AuthorityFactory;
+exports.AuthorityMetadataEntity = AuthorityMetadataEntity;
+exports.AuthorizationCodeClient = AuthorizationCodeClient;
+exports.CacheManager = CacheManager;
+exports.CacheRecord = CacheRecord;
+exports.ClientAuthError = ClientAuthError;
+exports.ClientAuthErrorMessage = ClientAuthErrorMessage;
+exports.ClientConfigurationError = ClientConfigurationError;
+exports.ClientConfigurationErrorMessage = ClientConfigurationErrorMessage;
+exports.ClientCredentialClient = ClientCredentialClient;
+exports.CodeChallengeMethodValues = CodeChallengeMethodValues;
+exports.Constants = Constants;
+exports.CredentialEntity = CredentialEntity;
+exports.DEFAULT_CRYPTO_IMPLEMENTATION = DEFAULT_CRYPTO_IMPLEMENTATION;
+exports.DEFAULT_SYSTEM_OPTIONS = DEFAULT_SYSTEM_OPTIONS;
+exports.DefaultStorageClass = DefaultStorageClass;
+exports.DeviceCodeClient = DeviceCodeClient;
+exports.Errors = Errors;
+exports.IdToken = AuthToken;
+exports.IdTokenEntity = IdTokenEntity;
+exports.IntFields = IntFields;
+exports.InteractionRequiredAuthError = InteractionRequiredAuthError;
+exports.InteractionRequiredAuthErrorMessage = InteractionRequiredAuthErrorMessage;
+exports.JoseHeader = JoseHeader;
+exports.Logger = Logger;
+exports.NetworkManager = NetworkManager;
+exports.OIDC_DEFAULT_SCOPES = OIDC_DEFAULT_SCOPES;
+exports.ONE_DAY_IN_MS = ONE_DAY_IN_MS;
+exports.OnBehalfOfClient = OnBehalfOfClient;
+exports.PerformanceClient = PerformanceClient;
+exports.PopTokenGenerator = PopTokenGenerator;
+exports.PromptValue = PromptValue;
+exports.ProtocolUtils = ProtocolUtils;
+exports.RefreshTokenClient = RefreshTokenClient;
+exports.RefreshTokenEntity = RefreshTokenEntity;
+exports.ScopeSet = ScopeSet;
+exports.ServerError = ServerError;
+exports.ServerTelemetryEntity = ServerTelemetryEntity;
+exports.ServerTelemetryManager = ServerTelemetryManager;
+exports.SilentFlowClient = SilentFlowClient;
+exports.StringUtils = StringUtils;
+exports.StubPerformanceClient = StubPerformanceClient;
+exports.StubbedNetworkModule = StubbedNetworkModule;
+exports.THE_FAMILY_ID = THE_FAMILY_ID;
+exports.ThrottlingConstants = ThrottlingConstants;
+exports.ThrottlingEntity = ThrottlingEntity;
+exports.ThrottlingUtils = ThrottlingUtils;
+exports.TimeUtils = TimeUtils;
+exports.TokenCacheContext = TokenCacheContext;
+exports.UrlString = UrlString;
+exports.UsernamePasswordClient = UsernamePasswordClient;
+exports.buildClientInfo = buildClientInfo;
+exports.buildClientInfoFromHomeAccountId = buildClientInfoFromHomeAccountId;
+exports.version = version;
+//# sourceMappingURL=index.cjs.js.map
+
+
+/***/ }),
+
+/***/ 2884:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+
+if (process.env.NODE_ENV === 'production') {
+ module.exports = __nccwpck_require__(9802)
+} else {
+ module.exports = __nccwpck_require__(5674)
+}
+
+
+/***/ }),
+
+/***/ 5674:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var msalCommon = __nccwpck_require__(5728);
+var http = __nccwpck_require__(3685);
+var http__default = _interopDefault(http);
+var https = _interopDefault(__nccwpck_require__(5687));
+var uuid = __nccwpck_require__(5840);
+var crypto = _interopDefault(__nccwpck_require__(6113));
+var jsonwebtoken = __nccwpck_require__(7486);
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * http methods
+ */
+var HttpMethod;
+(function (HttpMethod) {
+ HttpMethod["GET"] = "get";
+ HttpMethod["POST"] = "post";
+})(HttpMethod || (HttpMethod = {}));
+var HttpStatus;
+(function (HttpStatus) {
+ HttpStatus[HttpStatus["SUCCESS_RANGE_START"] = 200] = "SUCCESS_RANGE_START";
+ HttpStatus[HttpStatus["SUCCESS_RANGE_END"] = 299] = "SUCCESS_RANGE_END";
+ HttpStatus[HttpStatus["REDIRECT"] = 302] = "REDIRECT";
+ HttpStatus[HttpStatus["CLIENT_ERROR_RANGE_START"] = 400] = "CLIENT_ERROR_RANGE_START";
+ HttpStatus[HttpStatus["CLIENT_ERROR_RANGE_END"] = 499] = "CLIENT_ERROR_RANGE_END";
+ HttpStatus[HttpStatus["SERVER_ERROR_RANGE_START"] = 500] = "SERVER_ERROR_RANGE_START";
+ HttpStatus[HttpStatus["SERVER_ERROR_RANGE_END"] = 599] = "SERVER_ERROR_RANGE_END";
+})(HttpStatus || (HttpStatus = {}));
+var ProxyStatus;
+(function (ProxyStatus) {
+ ProxyStatus[ProxyStatus["SUCCESS_RANGE_START"] = 200] = "SUCCESS_RANGE_START";
+ ProxyStatus[ProxyStatus["SUCCESS_RANGE_END"] = 299] = "SUCCESS_RANGE_END";
+ ProxyStatus[ProxyStatus["SERVER_ERROR"] = 500] = "SERVER_ERROR";
+})(ProxyStatus || (ProxyStatus = {}));
+/**
+ * Constants used for region discovery
+ */
+const REGION_ENVIRONMENT_VARIABLE = "REGION_NAME";
+/**
+ * Constant used for PKCE
+ */
+const RANDOM_OCTET_SIZE = 32;
+/**
+ * Constants used in PKCE
+ */
+const Hash = {
+ SHA256: "sha256"
+};
+/**
+ * Constants for encoding schemes
+ */
+const CharSet = {
+ CV_CHARSET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
+};
+/**
+ * Constants
+ */
+const Constants = {
+ MSAL_SKU: "msal.js.node",
+ JWT_BEARER_ASSERTION_TYPE: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
+ AUTHORIZATION_PENDING: "authorization_pending",
+ HTTP_PROTOCOL: "http://",
+ LOCALHOST: "localhost"
+};
+/**
+ * API Codes for Telemetry purposes.
+ * Before adding a new code you must claim it in the MSAL Telemetry tracker as these number spaces are shared across all MSALs
+ * 0-99 Silent Flow
+ * 600-699 Device Code Flow
+ * 800-899 Auth Code Flow
+ */
+var ApiId;
+(function (ApiId) {
+ ApiId[ApiId["acquireTokenSilent"] = 62] = "acquireTokenSilent";
+ ApiId[ApiId["acquireTokenByUsernamePassword"] = 371] = "acquireTokenByUsernamePassword";
+ ApiId[ApiId["acquireTokenByDeviceCode"] = 671] = "acquireTokenByDeviceCode";
+ ApiId[ApiId["acquireTokenByClientCredential"] = 771] = "acquireTokenByClientCredential";
+ ApiId[ApiId["acquireTokenByCode"] = 871] = "acquireTokenByCode";
+ ApiId[ApiId["acquireTokenByRefreshToken"] = 872] = "acquireTokenByRefreshToken";
+})(ApiId || (ApiId = {}));
+/**
+ * JWT constants
+ */
+const JwtConstants = {
+ ALGORITHM: "alg",
+ RSA_256: "RS256",
+ X5T: "x5t",
+ X5C: "x5c",
+ AUDIENCE: "aud",
+ EXPIRATION_TIME: "exp",
+ ISSUER: "iss",
+ SUBJECT: "sub",
+ NOT_BEFORE: "nbf",
+ JWT_ID: "jti"
+};
+const LOOPBACK_SERVER_CONSTANTS = {
+ INTERVAL_MS: 100,
+ TIMEOUT_MS: 5000
+};
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class NetworkUtils {
+ static getNetworkResponse(headers, body, statusCode) {
+ return {
+ headers: headers,
+ body: body,
+ status: statusCode
+ };
+ }
+ /*
+ * Utility function that converts a URL object into an ordinary options object as expected by the
+ * http.request and https.request APIs.
+ * https://github.com/nodejs/node/blob/main/lib/internal/url.js#L1090
+ */
+ static urlToHttpOptions(url) {
+ const options = {
+ protocol: url.protocol,
+ hostname: url.hostname && url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname,
+ hash: url.hash,
+ search: url.search,
+ pathname: url.pathname,
+ path: `${url.pathname || ""}${url.search || ""}`,
+ href: url.href
+ };
+ if (url.port !== "") {
+ options.port = Number(url.port);
+ }
+ if (url.username || url.password) {
+ options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`;
+ }
+ return options;
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class implements the API for network requests.
+ */
+class HttpClient {
+ constructor(proxyUrl, customAgentOptions) {
+ this.proxyUrl = proxyUrl || "";
+ this.customAgentOptions = customAgentOptions || {};
+ }
+ /**
+ * Http Get request
+ * @param url
+ * @param options
+ */
+ async sendGetRequestAsync(url, options) {
+ if (this.proxyUrl) {
+ return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.GET, options, this.customAgentOptions);
+ } else {
+ return networkRequestViaHttps(url, HttpMethod.GET, options, this.customAgentOptions);
+ }
+ }
+ /**
+ * Http Post request
+ * @param url
+ * @param options
+ */
+ async sendPostRequestAsync(url, options, cancellationToken) {
+ if (this.proxyUrl) {
+ return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.POST, options, this.customAgentOptions, cancellationToken);
+ } else {
+ return networkRequestViaHttps(url, HttpMethod.POST, options, this.customAgentOptions, cancellationToken);
+ }
+ }
+}
+const networkRequestViaProxy = (destinationUrlString, proxyUrlString, httpMethod, options, agentOptions, timeout) => {
+ const destinationUrl = new URL(destinationUrlString);
+ const proxyUrl = new URL(proxyUrlString);
+ // "method: connect" must be used to establish a connection to the proxy
+ const headers = (options == null ? void 0 : options.headers) || {};
+ const tunnelRequestOptions = {
+ host: proxyUrl.hostname,
+ port: proxyUrl.port,
+ method: "CONNECT",
+ path: destinationUrl.hostname,
+ headers: headers
+ };
+ if (timeout) {
+ tunnelRequestOptions.timeout = timeout;
+ }
+ if (agentOptions && Object.keys(agentOptions).length) {
+ tunnelRequestOptions.agent = new http__default.Agent(agentOptions);
+ }
+ // compose a request string for the socket
+ let postRequestStringContent = "";
+ if (httpMethod === HttpMethod.POST) {
+ const body = (options == null ? void 0 : options.body) || "";
+ postRequestStringContent = "Content-Type: application/x-www-form-urlencoded\r\n" + `Content-Length: ${body.length}\r\n` + `\r\n${body}`;
+ }
+ const outgoingRequestString = `${httpMethod.toUpperCase()} ${destinationUrl.href} HTTP/1.1\r\n` + `Host: ${destinationUrl.host}\r\n` + "Connection: close\r\n" + postRequestStringContent + "\r\n";
+ return new Promise((resolve, reject) => {
+ const request = http__default.request(tunnelRequestOptions);
+ if (tunnelRequestOptions.timeout) {
+ request.on("timeout", () => {
+ request.destroy();
+ reject(new Error("Request time out"));
+ });
+ }
+ request.end();
+ // establish connection to the proxy
+ request.on("connect", (response, socket) => {
+ const proxyStatusCode = (response == null ? void 0 : response.statusCode) || ProxyStatus.SERVER_ERROR;
+ if (proxyStatusCode < ProxyStatus.SUCCESS_RANGE_START || proxyStatusCode > ProxyStatus.SUCCESS_RANGE_END) {
+ request.destroy();
+ socket.destroy();
+ reject(new Error(`Error connecting to proxy. Http status code: ${response.statusCode}. Http status message: ${(response == null ? void 0 : response.statusMessage) || "Unknown"}`));
+ }
+ if (tunnelRequestOptions.timeout) {
+ socket.setTimeout(tunnelRequestOptions.timeout);
+ socket.on("timeout", () => {
+ request.destroy();
+ socket.destroy();
+ reject(new Error("Request time out"));
+ });
+ }
+ // make a request over an HTTP tunnel
+ socket.write(outgoingRequestString);
+ const data = [];
+ socket.on("data", chunk => {
+ data.push(chunk);
+ });
+ socket.on("end", () => {
+ // combine all received buffer streams into one buffer, and then into a string
+ const dataString = Buffer.concat([...data]).toString();
+ // separate each line into it's own entry in an arry
+ const dataStringArray = dataString.split("\r\n");
+ // the first entry will contain the statusCode and statusMessage
+ const httpStatusCode = parseInt(dataStringArray[0].split(" ")[1]);
+ // remove "HTTP/1.1" and the status code to get the status message
+ const statusMessage = dataStringArray[0].split(" ").slice(2).join(" ");
+ // the last entry will contain the body
+ const body = dataStringArray[dataStringArray.length - 1];
+ // everything in between the first and last entries are the headers
+ const headersArray = dataStringArray.slice(1, dataStringArray.length - 2);
+ // build an object out of all the headers
+ const entries = new Map();
+ headersArray.forEach(header => {
+ /**
+ * the header might look like "Content-Length: 1531", but that is just a string
+ * it needs to be converted to a key/value pair
+ * split the string at the first instance of ":"
+ * there may be more than one ":" if the value of the header is supposed to be a JSON object
+ */
+ const headerKeyValue = header.split(new RegExp(/:\s(.*)/s));
+ const headerKey = headerKeyValue[0];
+ let headerValue = headerKeyValue[1];
+ // check if the value of the header is supposed to be a JSON object
+ try {
+ const object = JSON.parse(headerValue);
+ // if it is, then convert it from a string to a JSON object
+ if (object && typeof object === "object") {
+ headerValue = object;
+ }
+ } catch (e) {
+ // otherwise, leave it as a string
+ }
+ entries.set(headerKey, headerValue);
+ });
+ const headers = Object.fromEntries(entries);
+ const parsedHeaders = headers;
+ const networkResponse = NetworkUtils.getNetworkResponse(parsedHeaders, parseBody(httpStatusCode, statusMessage, parsedHeaders, body), httpStatusCode);
+ if ((httpStatusCode < HttpStatus.SUCCESS_RANGE_START || httpStatusCode > HttpStatus.SUCCESS_RANGE_END) &&
+ // do not destroy the request for the device code flow
+ networkResponse.body["error"] !== Constants.AUTHORIZATION_PENDING) {
+ request.destroy();
+ }
+ resolve(networkResponse);
+ });
+ socket.on("error", chunk => {
+ request.destroy();
+ socket.destroy();
+ reject(new Error(chunk.toString()));
+ });
+ });
+ request.on("error", chunk => {
+ request.destroy();
+ reject(new Error(chunk.toString()));
+ });
+ });
+};
+const networkRequestViaHttps = (urlString, httpMethod, options, agentOptions, timeout) => {
+ const isPostRequest = httpMethod === HttpMethod.POST;
+ const body = (options == null ? void 0 : options.body) || "";
+ const url = new URL(urlString);
+ const headers = (options == null ? void 0 : options.headers) || {};
+ const customOptions = {
+ method: httpMethod,
+ headers: headers,
+ ...NetworkUtils.urlToHttpOptions(url)
+ };
+ if (timeout) {
+ customOptions.timeout = timeout;
+ }
+ if (agentOptions && Object.keys(agentOptions).length) {
+ customOptions.agent = new https.Agent(agentOptions);
+ }
+ if (isPostRequest) {
+ // needed for post request to work
+ customOptions.headers = {
+ ...customOptions.headers,
+ "Content-Length": body.length
+ };
+ }
+ return new Promise((resolve, reject) => {
+ const request = https.request(customOptions);
+ if (timeout) {
+ request.on("timeout", () => {
+ request.destroy();
+ reject(new Error("Request time out"));
+ });
+ }
+ if (isPostRequest) {
+ request.write(body);
+ }
+ request.end();
+ request.on("response", response => {
+ const headers = response.headers;
+ const statusCode = response.statusCode;
+ const statusMessage = response.statusMessage;
+ const data = [];
+ response.on("data", chunk => {
+ data.push(chunk);
+ });
+ response.on("end", () => {
+ // combine all received buffer streams into one buffer, and then into a string
+ const body = Buffer.concat([...data]).toString();
+ const parsedHeaders = headers;
+ const networkResponse = NetworkUtils.getNetworkResponse(parsedHeaders, parseBody(statusCode, statusMessage, parsedHeaders, body), statusCode);
+ if ((statusCode < HttpStatus.SUCCESS_RANGE_START || statusCode > HttpStatus.SUCCESS_RANGE_END) &&
+ // do not destroy the request for the device code flow
+ networkResponse.body["error"] !== Constants.AUTHORIZATION_PENDING) {
+ request.destroy();
+ }
+ resolve(networkResponse);
+ });
+ });
+ request.on("error", chunk => {
+ request.destroy();
+ reject(new Error(chunk.toString()));
+ });
+ });
+};
+/**
+ * Check if extra parsing is needed on the repsonse from the server
+ * @param statusCode {number} the status code of the response from the server
+ * @param statusMessage {string | undefined} the status message of the response from the server
+ * @param headers {Record} the headers of the response from the server
+ * @param body {string} the body from the response of the server
+ * @returns {Object} JSON parsed body or error object
+ */
+const parseBody = (statusCode, statusMessage, headers, body) => {
+ /*
+ * Informational responses (100 – 199)
+ * Successful responses (200 – 299)
+ * Redirection messages (300 – 399)
+ * Client error responses (400 – 499)
+ * Server error responses (500 – 599)
+ */
+ let parsedBody;
+ try {
+ parsedBody = JSON.parse(body);
+ } catch (error) {
+ let errorType;
+ let errorDescriptionHelper;
+ if (statusCode >= HttpStatus.CLIENT_ERROR_RANGE_START && statusCode <= HttpStatus.CLIENT_ERROR_RANGE_END) {
+ errorType = "client_error";
+ errorDescriptionHelper = "A client";
+ } else if (statusCode >= HttpStatus.SERVER_ERROR_RANGE_START && statusCode <= HttpStatus.SERVER_ERROR_RANGE_END) {
+ errorType = "server_error";
+ errorDescriptionHelper = "A server";
+ } else {
+ errorType = "unknown_error";
+ errorDescriptionHelper = "An unknown";
+ }
+ parsedBody = {
+ error: errorType,
+ error_description: `${errorDescriptionHelper} error occured.\nHttp status code: ${statusCode}\nHttp status message: ${statusMessage || "Unknown"}\nHeaders: ${JSON.stringify(headers)}`
+ };
+ }
+ return parsedBody;
+};
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+const DEFAULT_AUTH_OPTIONS = {
+ clientId: msalCommon.Constants.EMPTY_STRING,
+ authority: msalCommon.Constants.DEFAULT_AUTHORITY,
+ clientSecret: msalCommon.Constants.EMPTY_STRING,
+ clientAssertion: msalCommon.Constants.EMPTY_STRING,
+ clientCertificate: {
+ thumbprint: msalCommon.Constants.EMPTY_STRING,
+ privateKey: msalCommon.Constants.EMPTY_STRING,
+ x5c: msalCommon.Constants.EMPTY_STRING
+ },
+ knownAuthorities: [],
+ cloudDiscoveryMetadata: msalCommon.Constants.EMPTY_STRING,
+ authorityMetadata: msalCommon.Constants.EMPTY_STRING,
+ clientCapabilities: [],
+ protocolMode: msalCommon.ProtocolMode.AAD,
+ azureCloudOptions: {
+ azureCloudInstance: msalCommon.AzureCloudInstance.None,
+ tenant: msalCommon.Constants.EMPTY_STRING
+ },
+ skipAuthorityMetadataCache: false
+};
+const DEFAULT_CACHE_OPTIONS = {
+ claimsBasedCachingEnabled: true
+};
+const DEFAULT_LOGGER_OPTIONS = {
+ loggerCallback: () => {
+ // allow users to not set logger call back
+ },
+ piiLoggingEnabled: false,
+ logLevel: msalCommon.LogLevel.Info
+};
+const DEFAULT_SYSTEM_OPTIONS = {
+ loggerOptions: DEFAULT_LOGGER_OPTIONS,
+ networkClient: /*#__PURE__*/new HttpClient(),
+ proxyUrl: msalCommon.Constants.EMPTY_STRING,
+ customAgentOptions: {}
+};
+const DEFAULT_TELEMETRY_OPTIONS = {
+ application: {
+ appName: msalCommon.Constants.EMPTY_STRING,
+ appVersion: msalCommon.Constants.EMPTY_STRING
+ }
+};
+/**
+ * Sets the default options when not explicitly configured from app developer
+ *
+ * @param auth - Authentication options
+ * @param cache - Cache options
+ * @param system - System options
+ * @param telemetry - Telemetry options
+ *
+ * @returns Configuration
+ * @public
+ */
+function buildAppConfiguration({
+ auth,
+ broker,
+ cache,
+ system,
+ telemetry
+}) {
+ const systemOptions = {
+ ...DEFAULT_SYSTEM_OPTIONS,
+ networkClient: new HttpClient(system == null ? void 0 : system.proxyUrl, system == null ? void 0 : system.customAgentOptions),
+ loggerOptions: (system == null ? void 0 : system.loggerOptions) || DEFAULT_LOGGER_OPTIONS
+ };
+ return {
+ auth: {
+ ...DEFAULT_AUTH_OPTIONS,
+ ...auth
+ },
+ broker: {
+ ...broker
+ },
+ cache: {
+ ...DEFAULT_CACHE_OPTIONS,
+ ...cache
+ },
+ system: {
+ ...systemOptions,
+ ...system
+ },
+ telemetry: {
+ ...DEFAULT_TELEMETRY_OPTIONS,
+ ...telemetry
+ }
+ };
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class GuidGenerator {
+ /**
+ *
+ * RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers.
+ * uuidv4 generates guids from cryprtographically-string random
+ */
+ generateGuid() {
+ return uuid.v4();
+ }
+ /**
+ * verifies if a string is GUID
+ * @param guid
+ */
+ isGuid(guid) {
+ const regexGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
+ return regexGuid.test(guid);
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class EncodingUtils {
+ /**
+ * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.
+ * 'base64': Base64 encoding.
+ *
+ * @param str text
+ */
+ static base64Encode(str, encoding) {
+ return Buffer.from(str, encoding).toString("base64");
+ }
+ /**
+ * encode a URL
+ * @param str
+ */
+ static base64EncodeUrl(str, encoding) {
+ return EncodingUtils.base64Encode(str, encoding).replace(/=/g, msalCommon.Constants.EMPTY_STRING).replace(/\+/g, "-").replace(/\//g, "_");
+ }
+ /**
+ * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.
+ * 'base64': Base64 encoding.
+ *
+ * @param base64Str Base64 encoded text
+ */
+ static base64Decode(base64Str) {
+ return Buffer.from(base64Str, "base64").toString("utf8");
+ }
+ /**
+ * @param base64Str Base64 encoded Url
+ */
+ static base64DecodeUrl(base64Str) {
+ let str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
+ while (str.length % 4) {
+ str += "=";
+ }
+ return EncodingUtils.base64Decode(str);
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class HashUtils {
+ /**
+ * generate 'SHA256' hash
+ * @param buffer
+ */
+ sha256(buffer) {
+ return crypto.createHash(Hash.SHA256).update(buffer).digest();
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * https://tools.ietf.org/html/rfc7636#page-8
+ */
+class PkceGenerator {
+ constructor() {
+ this.hashUtils = new HashUtils();
+ }
+ /**
+ * generates the codeVerfier and the challenge from the codeVerfier
+ * reference: https://tools.ietf.org/html/rfc7636#section-4.1 and https://tools.ietf.org/html/rfc7636#section-4.2
+ */
+ async generatePkceCodes() {
+ const verifier = this.generateCodeVerifier();
+ const challenge = this.generateCodeChallengeFromVerifier(verifier);
+ return {
+ verifier,
+ challenge
+ };
+ }
+ /**
+ * generates the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.1
+ */
+ generateCodeVerifier() {
+ const charArr = [];
+ const maxNumber = 256 - 256 % CharSet.CV_CHARSET.length;
+ while (charArr.length <= RANDOM_OCTET_SIZE) {
+ const byte = crypto.randomBytes(1)[0];
+ if (byte >= maxNumber) {
+ /*
+ * Ignore this number to maintain randomness.
+ * Including it would result in an unequal distribution of characters after doing the modulo
+ */
+ continue;
+ }
+ const index = byte % CharSet.CV_CHARSET.length;
+ charArr.push(CharSet.CV_CHARSET[index]);
+ }
+ const verifier = charArr.join(msalCommon.Constants.EMPTY_STRING);
+ return EncodingUtils.base64EncodeUrl(verifier);
+ }
+ /**
+ * generate the challenge from the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.2
+ * @param codeVerifier
+ */
+ generateCodeChallengeFromVerifier(codeVerifier) {
+ return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(codeVerifier).toString("base64"), "base64");
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class implements MSAL node's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and
+ * implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).
+ * @public
+ */
+class CryptoProvider {
+ constructor() {
+ // Browser crypto needs to be validated first before any other classes can be set.
+ this.pkceGenerator = new PkceGenerator();
+ this.guidGenerator = new GuidGenerator();
+ this.hashUtils = new HashUtils();
+ }
+ /**
+ * Creates a new random GUID - used to populate state and nonce.
+ * @returns string (GUID)
+ */
+ createNewGuid() {
+ return this.guidGenerator.generateGuid();
+ }
+ /**
+ * Encodes input string to base64.
+ * @param input - string to be encoded
+ */
+ base64Encode(input) {
+ return EncodingUtils.base64Encode(input);
+ }
+ /**
+ * Decodes input string from base64.
+ * @param input - string to be decoded
+ */
+ base64Decode(input) {
+ return EncodingUtils.base64Decode(input);
+ }
+ /**
+ * Generates PKCE codes used in Authorization Code Flow.
+ */
+ generatePkceCodes() {
+ return this.pkceGenerator.generatePkceCodes();
+ }
+ /**
+ * Generates a keypair, stores it and returns a thumbprint - not yet implemented for node
+ */
+ getPublicKeyThumbprint() {
+ throw new Error("Method not implemented.");
+ }
+ /**
+ * Removes cryptographic keypair from key store matching the keyId passed in
+ * @param kid
+ */
+ removeTokenBindingKey() {
+ throw new Error("Method not implemented.");
+ }
+ /**
+ * Removes all cryptographic keys from Keystore
+ */
+ clearKeystore() {
+ throw new Error("Method not implemented.");
+ }
+ /**
+ * Signs the given object as a jwt payload with private key retrieved by given kid - currently not implemented for node
+ */
+ signJwt() {
+ throw new Error("Method not implemented.");
+ }
+ /**
+ * Returns the SHA-256 hash of an input string
+ */
+ async hashString(plainText) {
+ return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(plainText).toString("base64"), "base64");
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class deserializes cache entities read from the file into in memory object types defined internally
+ */
+class Deserializer {
+ /**
+ * Parse the JSON blob in memory and deserialize the content
+ * @param cachedJson
+ */
+ static deserializeJSONBlob(jsonFile) {
+ const deserializedCache = msalCommon.StringUtils.isEmpty(jsonFile) ? {} : JSON.parse(jsonFile);
+ return deserializedCache;
+ }
+ /**
+ * Deserializes accounts to AccountEntity objects
+ * @param accounts
+ */
+ static deserializeAccounts(accounts) {
+ const accountObjects = {};
+ if (accounts) {
+ Object.keys(accounts).map(function (key) {
+ const serializedAcc = accounts[key];
+ const mappedAcc = {
+ homeAccountId: serializedAcc.home_account_id,
+ environment: serializedAcc.environment,
+ realm: serializedAcc.realm,
+ localAccountId: serializedAcc.local_account_id,
+ username: serializedAcc.username,
+ authorityType: serializedAcc.authority_type,
+ name: serializedAcc.name,
+ clientInfo: serializedAcc.client_info,
+ lastModificationTime: serializedAcc.last_modification_time,
+ lastModificationApp: serializedAcc.last_modification_app
+ };
+ const account = new msalCommon.AccountEntity();
+ msalCommon.CacheManager.toObject(account, mappedAcc);
+ accountObjects[key] = account;
+ });
+ }
+ return accountObjects;
+ }
+ /**
+ * Deserializes id tokens to IdTokenEntity objects
+ * @param idTokens
+ */
+ static deserializeIdTokens(idTokens) {
+ const idObjects = {};
+ if (idTokens) {
+ Object.keys(idTokens).map(function (key) {
+ const serializedIdT = idTokens[key];
+ const mappedIdT = {
+ homeAccountId: serializedIdT.home_account_id,
+ environment: serializedIdT.environment,
+ credentialType: serializedIdT.credential_type,
+ clientId: serializedIdT.client_id,
+ secret: serializedIdT.secret,
+ realm: serializedIdT.realm
+ };
+ const idToken = new msalCommon.IdTokenEntity();
+ msalCommon.CacheManager.toObject(idToken, mappedIdT);
+ idObjects[key] = idToken;
+ });
+ }
+ return idObjects;
+ }
+ /**
+ * Deserializes access tokens to AccessTokenEntity objects
+ * @param accessTokens
+ */
+ static deserializeAccessTokens(accessTokens) {
+ const atObjects = {};
+ if (accessTokens) {
+ Object.keys(accessTokens).map(function (key) {
+ const serializedAT = accessTokens[key];
+ const mappedAT = {
+ homeAccountId: serializedAT.home_account_id,
+ environment: serializedAT.environment,
+ credentialType: serializedAT.credential_type,
+ clientId: serializedAT.client_id,
+ secret: serializedAT.secret,
+ realm: serializedAT.realm,
+ target: serializedAT.target,
+ cachedAt: serializedAT.cached_at,
+ expiresOn: serializedAT.expires_on,
+ extendedExpiresOn: serializedAT.extended_expires_on,
+ refreshOn: serializedAT.refresh_on,
+ keyId: serializedAT.key_id,
+ tokenType: serializedAT.token_type,
+ requestedClaims: serializedAT.requestedClaims,
+ requestedClaimsHash: serializedAT.requestedClaimsHash,
+ userAssertionHash: serializedAT.userAssertionHash
+ };
+ const accessToken = new msalCommon.AccessTokenEntity();
+ msalCommon.CacheManager.toObject(accessToken, mappedAT);
+ atObjects[key] = accessToken;
+ });
+ }
+ return atObjects;
+ }
+ /**
+ * Deserializes refresh tokens to RefreshTokenEntity objects
+ * @param refreshTokens
+ */
+ static deserializeRefreshTokens(refreshTokens) {
+ const rtObjects = {};
+ if (refreshTokens) {
+ Object.keys(refreshTokens).map(function (key) {
+ const serializedRT = refreshTokens[key];
+ const mappedRT = {
+ homeAccountId: serializedRT.home_account_id,
+ environment: serializedRT.environment,
+ credentialType: serializedRT.credential_type,
+ clientId: serializedRT.client_id,
+ secret: serializedRT.secret,
+ familyId: serializedRT.family_id,
+ target: serializedRT.target,
+ realm: serializedRT.realm
+ };
+ const refreshToken = new msalCommon.RefreshTokenEntity();
+ msalCommon.CacheManager.toObject(refreshToken, mappedRT);
+ rtObjects[key] = refreshToken;
+ });
+ }
+ return rtObjects;
+ }
+ /**
+ * Deserializes appMetadata to AppMetaData objects
+ * @param appMetadata
+ */
+ static deserializeAppMetadata(appMetadata) {
+ const appMetadataObjects = {};
+ if (appMetadata) {
+ Object.keys(appMetadata).map(function (key) {
+ const serializedAmdt = appMetadata[key];
+ const mappedAmd = {
+ clientId: serializedAmdt.client_id,
+ environment: serializedAmdt.environment,
+ familyId: serializedAmdt.family_id
+ };
+ const amd = new msalCommon.AppMetadataEntity();
+ msalCommon.CacheManager.toObject(amd, mappedAmd);
+ appMetadataObjects[key] = amd;
+ });
+ }
+ return appMetadataObjects;
+ }
+ /**
+ * Deserialize an inMemory Cache
+ * @param jsonCache
+ */
+ static deserializeAllCache(jsonCache) {
+ return {
+ accounts: jsonCache.Account ? this.deserializeAccounts(jsonCache.Account) : {},
+ idTokens: jsonCache.IdToken ? this.deserializeIdTokens(jsonCache.IdToken) : {},
+ accessTokens: jsonCache.AccessToken ? this.deserializeAccessTokens(jsonCache.AccessToken) : {},
+ refreshTokens: jsonCache.RefreshToken ? this.deserializeRefreshTokens(jsonCache.RefreshToken) : {},
+ appMetadata: jsonCache.AppMetadata ? this.deserializeAppMetadata(jsonCache.AppMetadata) : {}
+ };
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class Serializer {
+ /**
+ * serialize the JSON blob
+ * @param data
+ */
+ static serializeJSONBlob(data) {
+ return JSON.stringify(data);
+ }
+ /**
+ * Serialize Accounts
+ * @param accCache
+ */
+ static serializeAccounts(accCache) {
+ const accounts = {};
+ Object.keys(accCache).map(function (key) {
+ const accountEntity = accCache[key];
+ accounts[key] = {
+ home_account_id: accountEntity.homeAccountId,
+ environment: accountEntity.environment,
+ realm: accountEntity.realm,
+ local_account_id: accountEntity.localAccountId,
+ username: accountEntity.username,
+ authority_type: accountEntity.authorityType,
+ name: accountEntity.name,
+ client_info: accountEntity.clientInfo,
+ last_modification_time: accountEntity.lastModificationTime,
+ last_modification_app: accountEntity.lastModificationApp
+ };
+ });
+ return accounts;
+ }
+ /**
+ * Serialize IdTokens
+ * @param idTCache
+ */
+ static serializeIdTokens(idTCache) {
+ const idTokens = {};
+ Object.keys(idTCache).map(function (key) {
+ const idTEntity = idTCache[key];
+ idTokens[key] = {
+ home_account_id: idTEntity.homeAccountId,
+ environment: idTEntity.environment,
+ credential_type: idTEntity.credentialType,
+ client_id: idTEntity.clientId,
+ secret: idTEntity.secret,
+ realm: idTEntity.realm
+ };
+ });
+ return idTokens;
+ }
+ /**
+ * Serializes AccessTokens
+ * @param atCache
+ */
+ static serializeAccessTokens(atCache) {
+ const accessTokens = {};
+ Object.keys(atCache).map(function (key) {
+ const atEntity = atCache[key];
+ accessTokens[key] = {
+ home_account_id: atEntity.homeAccountId,
+ environment: atEntity.environment,
+ credential_type: atEntity.credentialType,
+ client_id: atEntity.clientId,
+ secret: atEntity.secret,
+ realm: atEntity.realm,
+ target: atEntity.target,
+ cached_at: atEntity.cachedAt,
+ expires_on: atEntity.expiresOn,
+ extended_expires_on: atEntity.extendedExpiresOn,
+ refresh_on: atEntity.refreshOn,
+ key_id: atEntity.keyId,
+ token_type: atEntity.tokenType,
+ requestedClaims: atEntity.requestedClaims,
+ requestedClaimsHash: atEntity.requestedClaimsHash,
+ userAssertionHash: atEntity.userAssertionHash
+ };
+ });
+ return accessTokens;
+ }
+ /**
+ * Serialize refreshTokens
+ * @param rtCache
+ */
+ static serializeRefreshTokens(rtCache) {
+ const refreshTokens = {};
+ Object.keys(rtCache).map(function (key) {
+ const rtEntity = rtCache[key];
+ refreshTokens[key] = {
+ home_account_id: rtEntity.homeAccountId,
+ environment: rtEntity.environment,
+ credential_type: rtEntity.credentialType,
+ client_id: rtEntity.clientId,
+ secret: rtEntity.secret,
+ family_id: rtEntity.familyId,
+ target: rtEntity.target,
+ realm: rtEntity.realm
+ };
+ });
+ return refreshTokens;
+ }
+ /**
+ * Serialize amdtCache
+ * @param amdtCache
+ */
+ static serializeAppMetadata(amdtCache) {
+ const appMetadata = {};
+ Object.keys(amdtCache).map(function (key) {
+ const amdtEntity = amdtCache[key];
+ appMetadata[key] = {
+ client_id: amdtEntity.clientId,
+ environment: amdtEntity.environment,
+ family_id: amdtEntity.familyId
+ };
+ });
+ return appMetadata;
+ }
+ /**
+ * Serialize the cache
+ * @param jsonContent
+ */
+ static serializeAllCache(inMemCache) {
+ return {
+ Account: this.serializeAccounts(inMemCache.accounts),
+ IdToken: this.serializeIdTokens(inMemCache.idTokens),
+ AccessToken: this.serializeAccessTokens(inMemCache.accessTokens),
+ RefreshToken: this.serializeRefreshTokens(inMemCache.refreshTokens),
+ AppMetadata: this.serializeAppMetadata(inMemCache.appMetadata)
+ };
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class implements Storage for node, reading cache from user specified storage location or an extension library
+ * @public
+ */
+class NodeStorage extends msalCommon.CacheManager {
+ constructor(logger, clientId, cryptoImpl) {
+ super(clientId, cryptoImpl, logger);
+ this.cache = {};
+ this.changeEmitters = [];
+ this.logger = logger;
+ }
+ /**
+ * Queue up callbacks
+ * @param func - a callback function for cache change indication
+ */
+ registerChangeEmitter(func) {
+ this.changeEmitters.push(func);
+ }
+ /**
+ * Invoke the callback when cache changes
+ */
+ emitChange() {
+ this.changeEmitters.forEach(func => func.call(null));
+ }
+ /**
+ * Converts cacheKVStore to InMemoryCache
+ * @param cache - key value store
+ */
+ cacheToInMemoryCache(cache) {
+ const inMemoryCache = {
+ accounts: {},
+ idTokens: {},
+ accessTokens: {},
+ refreshTokens: {},
+ appMetadata: {}
+ };
+ for (const key in cache) {
+ if (cache[key] instanceof msalCommon.AccountEntity) {
+ inMemoryCache.accounts[key] = cache[key];
+ } else if (cache[key] instanceof msalCommon.IdTokenEntity) {
+ inMemoryCache.idTokens[key] = cache[key];
+ } else if (cache[key] instanceof msalCommon.AccessTokenEntity) {
+ inMemoryCache.accessTokens[key] = cache[key];
+ } else if (cache[key] instanceof msalCommon.RefreshTokenEntity) {
+ inMemoryCache.refreshTokens[key] = cache[key];
+ } else if (cache[key] instanceof msalCommon.AppMetadataEntity) {
+ inMemoryCache.appMetadata[key] = cache[key];
+ } else {
+ continue;
+ }
+ }
+ return inMemoryCache;
+ }
+ /**
+ * converts inMemoryCache to CacheKVStore
+ * @param inMemoryCache - kvstore map for inmemory
+ */
+ inMemoryCacheToCache(inMemoryCache) {
+ // convert in memory cache to a flat Key-Value map
+ let cache = this.getCache();
+ cache = {
+ ...cache,
+ ...inMemoryCache.accounts,
+ ...inMemoryCache.idTokens,
+ ...inMemoryCache.accessTokens,
+ ...inMemoryCache.refreshTokens,
+ ...inMemoryCache.appMetadata
+ };
+ // convert in memory cache to a flat Key-Value map
+ return cache;
+ }
+ /**
+ * gets the current in memory cache for the client
+ */
+ getInMemoryCache() {
+ this.logger.trace("Getting in-memory cache");
+ // convert the cache key value store to inMemoryCache
+ const inMemoryCache = this.cacheToInMemoryCache(this.getCache());
+ return inMemoryCache;
+ }
+ /**
+ * sets the current in memory cache for the client
+ * @param inMemoryCache - key value map in memory
+ */
+ setInMemoryCache(inMemoryCache) {
+ this.logger.trace("Setting in-memory cache");
+ // convert and append the inMemoryCache to cacheKVStore
+ const cache = this.inMemoryCacheToCache(inMemoryCache);
+ this.setCache(cache);
+ this.emitChange();
+ }
+ /**
+ * get the current cache key-value store
+ */
+ getCache() {
+ this.logger.trace("Getting cache key-value store");
+ return this.cache;
+ }
+ /**
+ * sets the current cache (key value store)
+ * @param cacheMap - key value map
+ */
+ setCache(cache) {
+ this.logger.trace("Setting cache key value store");
+ this.cache = cache;
+ // mark change in cache
+ this.emitChange();
+ }
+ /**
+ * Gets cache item with given key.
+ * @param key - lookup key for the cache entry
+ */
+ getItem(key) {
+ this.logger.tracePii(`Item key: ${key}`);
+ // read cache
+ const cache = this.getCache();
+ return cache[key];
+ }
+ /**
+ * Gets cache item with given key-value
+ * @param key - lookup key for the cache entry
+ * @param value - value of the cache entry
+ */
+ setItem(key, value) {
+ this.logger.tracePii(`Item key: ${key}`);
+ // read cache
+ const cache = this.getCache();
+ cache[key] = value;
+ // write to cache
+ this.setCache(cache);
+ }
+ getAccountKeys() {
+ const inMemoryCache = this.getInMemoryCache();
+ const accountKeys = Object.keys(inMemoryCache.accounts);
+ return accountKeys;
+ }
+ getTokenKeys() {
+ const inMemoryCache = this.getInMemoryCache();
+ const tokenKeys = {
+ idToken: Object.keys(inMemoryCache.idTokens),
+ accessToken: Object.keys(inMemoryCache.accessTokens),
+ refreshToken: Object.keys(inMemoryCache.refreshTokens)
+ };
+ return tokenKeys;
+ }
+ /**
+ * fetch the account entity
+ * @param accountKey - lookup key to fetch cache type AccountEntity
+ */
+ getAccount(accountKey) {
+ const account = this.getItem(accountKey);
+ if (msalCommon.AccountEntity.isAccountEntity(account)) {
+ return account;
+ }
+ return null;
+ }
+ /**
+ * set account entity
+ * @param account - cache value to be set of type AccountEntity
+ */
+ setAccount(account) {
+ const accountKey = account.generateAccountKey();
+ this.setItem(accountKey, account);
+ }
+ /**
+ * fetch the idToken credential
+ * @param idTokenKey - lookup key to fetch cache type IdTokenEntity
+ */
+ getIdTokenCredential(idTokenKey) {
+ const idToken = this.getItem(idTokenKey);
+ if (msalCommon.IdTokenEntity.isIdTokenEntity(idToken)) {
+ return idToken;
+ }
+ return null;
+ }
+ /**
+ * set idToken credential
+ * @param idToken - cache value to be set of type IdTokenEntity
+ */
+ setIdTokenCredential(idToken) {
+ const idTokenKey = idToken.generateCredentialKey();
+ this.setItem(idTokenKey, idToken);
+ }
+ /**
+ * fetch the accessToken credential
+ * @param accessTokenKey - lookup key to fetch cache type AccessTokenEntity
+ */
+ getAccessTokenCredential(accessTokenKey) {
+ const accessToken = this.getItem(accessTokenKey);
+ if (msalCommon.AccessTokenEntity.isAccessTokenEntity(accessToken)) {
+ return accessToken;
+ }
+ return null;
+ }
+ /**
+ * set accessToken credential
+ * @param accessToken - cache value to be set of type AccessTokenEntity
+ */
+ setAccessTokenCredential(accessToken) {
+ const accessTokenKey = accessToken.generateCredentialKey();
+ this.setItem(accessTokenKey, accessToken);
+ }
+ /**
+ * fetch the refreshToken credential
+ * @param refreshTokenKey - lookup key to fetch cache type RefreshTokenEntity
+ */
+ getRefreshTokenCredential(refreshTokenKey) {
+ const refreshToken = this.getItem(refreshTokenKey);
+ if (msalCommon.RefreshTokenEntity.isRefreshTokenEntity(refreshToken)) {
+ return refreshToken;
+ }
+ return null;
+ }
+ /**
+ * set refreshToken credential
+ * @param refreshToken - cache value to be set of type RefreshTokenEntity
+ */
+ setRefreshTokenCredential(refreshToken) {
+ const refreshTokenKey = refreshToken.generateCredentialKey();
+ this.setItem(refreshTokenKey, refreshToken);
+ }
+ /**
+ * fetch appMetadata entity from the platform cache
+ * @param appMetadataKey - lookup key to fetch cache type AppMetadataEntity
+ */
+ getAppMetadata(appMetadataKey) {
+ const appMetadata = this.getItem(appMetadataKey);
+ if (msalCommon.AppMetadataEntity.isAppMetadataEntity(appMetadataKey, appMetadata)) {
+ return appMetadata;
+ }
+ return null;
+ }
+ /**
+ * set appMetadata entity to the platform cache
+ * @param appMetadata - cache value to be set of type AppMetadataEntity
+ */
+ setAppMetadata(appMetadata) {
+ const appMetadataKey = appMetadata.generateAppMetadataKey();
+ this.setItem(appMetadataKey, appMetadata);
+ }
+ /**
+ * fetch server telemetry entity from the platform cache
+ * @param serverTelemetrykey - lookup key to fetch cache type ServerTelemetryEntity
+ */
+ getServerTelemetry(serverTelemetrykey) {
+ const serverTelemetryEntity = this.getItem(serverTelemetrykey);
+ if (serverTelemetryEntity && msalCommon.ServerTelemetryEntity.isServerTelemetryEntity(serverTelemetrykey, serverTelemetryEntity)) {
+ return serverTelemetryEntity;
+ }
+ return null;
+ }
+ /**
+ * set server telemetry entity to the platform cache
+ * @param serverTelemetryKey - lookup key to fetch cache type ServerTelemetryEntity
+ * @param serverTelemetry - cache value to be set of type ServerTelemetryEntity
+ */
+ setServerTelemetry(serverTelemetryKey, serverTelemetry) {
+ this.setItem(serverTelemetryKey, serverTelemetry);
+ }
+ /**
+ * fetch authority metadata entity from the platform cache
+ * @param key - lookup key to fetch cache type AuthorityMetadataEntity
+ */
+ getAuthorityMetadata(key) {
+ const authorityMetadataEntity = this.getItem(key);
+ if (authorityMetadataEntity && msalCommon.AuthorityMetadataEntity.isAuthorityMetadataEntity(key, authorityMetadataEntity)) {
+ return authorityMetadataEntity;
+ }
+ return null;
+ }
+ /**
+ * Get all authority metadata keys
+ */
+ getAuthorityMetadataKeys() {
+ return this.getKeys().filter(key => {
+ return this.isAuthorityMetadata(key);
+ });
+ }
+ /**
+ * set authority metadata entity to the platform cache
+ * @param key - lookup key to fetch cache type AuthorityMetadataEntity
+ * @param metadata - cache value to be set of type AuthorityMetadataEntity
+ */
+ setAuthorityMetadata(key, metadata) {
+ this.setItem(key, metadata);
+ }
+ /**
+ * fetch throttling entity from the platform cache
+ * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
+ */
+ getThrottlingCache(throttlingCacheKey) {
+ const throttlingCache = this.getItem(throttlingCacheKey);
+ if (throttlingCache && msalCommon.ThrottlingEntity.isThrottlingEntity(throttlingCacheKey, throttlingCache)) {
+ return throttlingCache;
+ }
+ return null;
+ }
+ /**
+ * set throttling entity to the platform cache
+ * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
+ * @param throttlingCache - cache value to be set of type ThrottlingEntity
+ */
+ setThrottlingCache(throttlingCacheKey, throttlingCache) {
+ this.setItem(throttlingCacheKey, throttlingCache);
+ }
+ /**
+ * Removes the cache item from memory with the given key.
+ * @param key - lookup key to remove a cache entity
+ * @param inMemory - key value map of the cache
+ */
+ removeItem(key) {
+ this.logger.tracePii(`Item key: ${key}`);
+ // read inMemoryCache
+ let result = false;
+ const cache = this.getCache();
+ if (!!cache[key]) {
+ delete cache[key];
+ result = true;
+ }
+ // write to the cache after removal
+ if (result) {
+ this.setCache(cache);
+ this.emitChange();
+ }
+ return result;
+ }
+ /**
+ * Checks whether key is in cache.
+ * @param key - look up key for a cache entity
+ */
+ containsKey(key) {
+ return this.getKeys().includes(key);
+ }
+ /**
+ * Gets all keys in window.
+ */
+ getKeys() {
+ this.logger.trace("Retrieving all cache keys");
+ // read cache
+ const cache = this.getCache();
+ return [...Object.keys(cache)];
+ }
+ /**
+ * Clears all cache entries created by MSAL (except tokens).
+ */
+ async clear() {
+ this.logger.trace("Clearing cache entries created by MSAL");
+ // read inMemoryCache
+ const cacheKeys = this.getKeys();
+ // delete each element
+ cacheKeys.forEach(key => {
+ this.removeItem(key);
+ });
+ this.emitChange();
+ }
+ /**
+ * Initialize in memory cache from an exisiting cache vault
+ * @param cache - blob formatted cache (JSON)
+ */
+ static generateInMemoryCache(cache) {
+ return Deserializer.deserializeAllCache(Deserializer.deserializeJSONBlob(cache));
+ }
+ /**
+ * retrieves the final JSON
+ * @param inMemoryCache - itemised cache read from the JSON
+ */
+ static generateJsonCache(inMemoryCache) {
+ return Serializer.serializeAllCache(inMemoryCache);
+ }
+ /**
+ * Updates a credential's cache key if the current cache key is outdated
+ */
+ updateCredentialCacheKey(currentCacheKey, credential) {
+ const updatedCacheKey = credential.generateCredentialKey();
+ if (currentCacheKey !== updatedCacheKey) {
+ const cacheItem = this.getItem(currentCacheKey);
+ if (cacheItem) {
+ this.removeItem(currentCacheKey);
+ this.setItem(updatedCacheKey, cacheItem);
+ this.logger.verbose(`Updated an outdated ${credential.credentialType} cache key`);
+ return updatedCacheKey;
+ } else {
+ this.logger.error(`Attempted to update an outdated ${credential.credentialType} cache key but no item matching the outdated key was found in storage`);
+ }
+ }
+ return currentCacheKey;
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+const defaultSerializedCache = {
+ Account: {},
+ IdToken: {},
+ AccessToken: {},
+ RefreshToken: {},
+ AppMetadata: {}
+};
+/**
+ * In-memory token cache manager
+ * @public
+ */
+class TokenCache {
+ constructor(storage, logger, cachePlugin) {
+ this.cacheHasChanged = false;
+ this.storage = storage;
+ this.storage.registerChangeEmitter(this.handleChangeEvent.bind(this));
+ if (cachePlugin) {
+ this.persistence = cachePlugin;
+ }
+ this.logger = logger;
+ }
+ /**
+ * Set to true if cache state has changed since last time serialize or writeToPersistence was called
+ */
+ hasChanged() {
+ return this.cacheHasChanged;
+ }
+ /**
+ * Serializes in memory cache to JSON
+ */
+ serialize() {
+ this.logger.trace("Serializing in-memory cache");
+ let finalState = Serializer.serializeAllCache(this.storage.getInMemoryCache());
+ // if cacheSnapshot not null or empty, merge
+ if (!msalCommon.StringUtils.isEmpty(this.cacheSnapshot)) {
+ this.logger.trace("Reading cache snapshot from disk");
+ finalState = this.mergeState(JSON.parse(this.cacheSnapshot), finalState);
+ } else {
+ this.logger.trace("No cache snapshot to merge");
+ }
+ this.cacheHasChanged = false;
+ return JSON.stringify(finalState);
+ }
+ /**
+ * Deserializes JSON to in-memory cache. JSON should be in MSAL cache schema format
+ * @param cache - blob formatted cache
+ */
+ deserialize(cache) {
+ this.logger.trace("Deserializing JSON to in-memory cache");
+ this.cacheSnapshot = cache;
+ if (!msalCommon.StringUtils.isEmpty(this.cacheSnapshot)) {
+ this.logger.trace("Reading cache snapshot from disk");
+ const deserializedCache = Deserializer.deserializeAllCache(this.overlayDefaults(JSON.parse(this.cacheSnapshot)));
+ this.storage.setInMemoryCache(deserializedCache);
+ } else {
+ this.logger.trace("No cache snapshot to deserialize");
+ }
+ }
+ /**
+ * Fetches the cache key-value map
+ */
+ getKVStore() {
+ return this.storage.getCache();
+ }
+ /**
+ * API that retrieves all accounts currently in cache to the user
+ */
+ async getAllAccounts() {
+ this.logger.trace("getAllAccounts called");
+ let cacheContext;
+ try {
+ if (this.persistence) {
+ cacheContext = new msalCommon.TokenCacheContext(this, false);
+ await this.persistence.beforeCacheAccess(cacheContext);
+ }
+ return this.storage.getAllAccounts();
+ } finally {
+ if (this.persistence && cacheContext) {
+ await this.persistence.afterCacheAccess(cacheContext);
+ }
+ }
+ }
+ /**
+ * Returns the signed in account matching homeAccountId.
+ * (the account object is created at the time of successful login)
+ * or null when no matching account is found
+ * @param homeAccountId - unique identifier for an account (uid.utid)
+ */
+ async getAccountByHomeId(homeAccountId) {
+ const allAccounts = await this.getAllAccounts();
+ if (!msalCommon.StringUtils.isEmpty(homeAccountId) && allAccounts && allAccounts.length) {
+ return allAccounts.filter(accountObj => accountObj.homeAccountId === homeAccountId)[0] || null;
+ } else {
+ return null;
+ }
+ }
+ /**
+ * Returns the signed in account matching localAccountId.
+ * (the account object is created at the time of successful login)
+ * or null when no matching account is found
+ * @param localAccountId - unique identifier of an account (sub/obj when homeAccountId cannot be populated)
+ */
+ async getAccountByLocalId(localAccountId) {
+ const allAccounts = await this.getAllAccounts();
+ if (!msalCommon.StringUtils.isEmpty(localAccountId) && allAccounts && allAccounts.length) {
+ return allAccounts.filter(accountObj => accountObj.localAccountId === localAccountId)[0] || null;
+ } else {
+ return null;
+ }
+ }
+ /**
+ * API to remove a specific account and the relevant data from cache
+ * @param account - AccountInfo passed by the user
+ */
+ async removeAccount(account) {
+ this.logger.trace("removeAccount called");
+ let cacheContext;
+ try {
+ if (this.persistence) {
+ cacheContext = new msalCommon.TokenCacheContext(this, true);
+ await this.persistence.beforeCacheAccess(cacheContext);
+ }
+ await this.storage.removeAccount(msalCommon.AccountEntity.generateAccountCacheKey(account));
+ } finally {
+ if (this.persistence && cacheContext) {
+ await this.persistence.afterCacheAccess(cacheContext);
+ }
+ }
+ }
+ /**
+ * Called when the cache has changed state.
+ */
+ handleChangeEvent() {
+ this.cacheHasChanged = true;
+ }
+ /**
+ * Merge in memory cache with the cache snapshot.
+ * @param oldState - cache before changes
+ * @param currentState - current cache state in the library
+ */
+ mergeState(oldState, currentState) {
+ this.logger.trace("Merging in-memory cache with cache snapshot");
+ const stateAfterRemoval = this.mergeRemovals(oldState, currentState);
+ return this.mergeUpdates(stateAfterRemoval, currentState);
+ }
+ /**
+ * Deep update of oldState based on newState values
+ * @param oldState - cache before changes
+ * @param newState - updated cache
+ */
+ mergeUpdates(oldState, newState) {
+ Object.keys(newState).forEach(newKey => {
+ const newValue = newState[newKey];
+ // if oldState does not contain value but newValue does, add it
+ if (!oldState.hasOwnProperty(newKey)) {
+ if (newValue !== null) {
+ oldState[newKey] = newValue;
+ }
+ } else {
+ // both oldState and newState contain the key, do deep update
+ const newValueNotNull = newValue !== null;
+ const newValueIsObject = typeof newValue === "object";
+ const newValueIsNotArray = !Array.isArray(newValue);
+ const oldStateNotUndefinedOrNull = typeof oldState[newKey] !== "undefined" && oldState[newKey] !== null;
+ if (newValueNotNull && newValueIsObject && newValueIsNotArray && oldStateNotUndefinedOrNull) {
+ this.mergeUpdates(oldState[newKey], newValue);
+ } else {
+ oldState[newKey] = newValue;
+ }
+ }
+ });
+ return oldState;
+ }
+ /**
+ * Removes entities in oldState that the were removed from newState. If there are any unknown values in root of
+ * oldState that are not recognized, they are left untouched.
+ * @param oldState - cache before changes
+ * @param newState - updated cache
+ */
+ mergeRemovals(oldState, newState) {
+ this.logger.trace("Remove updated entries in cache");
+ const accounts = oldState.Account ? this.mergeRemovalsDict(oldState.Account, newState.Account) : oldState.Account;
+ const accessTokens = oldState.AccessToken ? this.mergeRemovalsDict(oldState.AccessToken, newState.AccessToken) : oldState.AccessToken;
+ const refreshTokens = oldState.RefreshToken ? this.mergeRemovalsDict(oldState.RefreshToken, newState.RefreshToken) : oldState.RefreshToken;
+ const idTokens = oldState.IdToken ? this.mergeRemovalsDict(oldState.IdToken, newState.IdToken) : oldState.IdToken;
+ const appMetadata = oldState.AppMetadata ? this.mergeRemovalsDict(oldState.AppMetadata, newState.AppMetadata) : oldState.AppMetadata;
+ return {
+ ...oldState,
+ Account: accounts,
+ AccessToken: accessTokens,
+ RefreshToken: refreshTokens,
+ IdToken: idTokens,
+ AppMetadata: appMetadata
+ };
+ }
+ /**
+ * Helper to merge new cache with the old one
+ * @param oldState - cache before changes
+ * @param newState - updated cache
+ */
+ mergeRemovalsDict(oldState, newState) {
+ const finalState = {
+ ...oldState
+ };
+ Object.keys(oldState).forEach(oldKey => {
+ if (!newState || !newState.hasOwnProperty(oldKey)) {
+ delete finalState[oldKey];
+ }
+ });
+ return finalState;
+ }
+ /**
+ * Helper to overlay as a part of cache merge
+ * @param passedInCache - cache read from the blob
+ */
+ overlayDefaults(passedInCache) {
+ this.logger.trace("Overlaying input cache with the default cache");
+ return {
+ Account: {
+ ...defaultSerializedCache.Account,
+ ...passedInCache.Account
+ },
+ IdToken: {
+ ...defaultSerializedCache.IdToken,
+ ...passedInCache.IdToken
+ },
+ AccessToken: {
+ ...defaultSerializedCache.AccessToken,
+ ...passedInCache.AccessToken
+ },
+ RefreshToken: {
+ ...defaultSerializedCache.RefreshToken,
+ ...passedInCache.RefreshToken
+ },
+ AppMetadata: {
+ ...defaultSerializedCache.AppMetadata,
+ ...passedInCache.AppMetadata
+ }
+ };
+ }
+}
+
+/* eslint-disable header/header */
+const name = "@azure/msal-node";
+const version = "1.18.1";
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * NodeAuthErrorMessage class containing string constants used by error codes and messages.
+ */
+const NodeAuthErrorMessage = {
+ invalidLoopbackAddressType: {
+ code: "invalid_loopback_server_address_type",
+ desc: "Loopback server address is not type string. This is unexpected."
+ },
+ unableToLoadRedirectUri: {
+ code: "unable_to_load_redirectUrl",
+ desc: "Loopback server callback was invoked without a url. This is unexpected."
+ },
+ noAuthCodeInResponse: {
+ code: "no_auth_code_in_response",
+ desc: "No auth code found in the server response. Please check your network trace to determine what happened."
+ },
+ noLoopbackServerExists: {
+ code: "no_loopback_server_exists",
+ desc: "No loopback server exists yet."
+ },
+ loopbackServerAlreadyExists: {
+ code: "loopback_server_already_exists",
+ desc: "Loopback server already exists. Cannot create another."
+ },
+ loopbackServerTimeout: {
+ code: "loopback_server_timeout",
+ desc: "Timed out waiting for auth code listener to be registered."
+ },
+ stateNotFoundError: {
+ code: "state_not_found",
+ desc: "State not found. Please verify that the request originated from msal."
+ }
+};
+class NodeAuthError extends msalCommon.AuthError {
+ constructor(errorCode, errorMessage) {
+ super(errorCode, errorMessage);
+ this.name = "NodeAuthError";
+ }
+ /**
+ * Creates an error thrown if loopback server address is of type string.
+ */
+ static createInvalidLoopbackAddressTypeError() {
+ return new NodeAuthError(NodeAuthErrorMessage.invalidLoopbackAddressType.code, `${NodeAuthErrorMessage.invalidLoopbackAddressType.desc}`);
+ }
+ /**
+ * Creates an error thrown if the loopback server is unable to get a url.
+ */
+ static createUnableToLoadRedirectUrlError() {
+ return new NodeAuthError(NodeAuthErrorMessage.unableToLoadRedirectUri.code, `${NodeAuthErrorMessage.unableToLoadRedirectUri.desc}`);
+ }
+ /**
+ * Creates an error thrown if the server response does not contain an auth code.
+ */
+ static createNoAuthCodeInResponseError() {
+ return new NodeAuthError(NodeAuthErrorMessage.noAuthCodeInResponse.code, `${NodeAuthErrorMessage.noAuthCodeInResponse.desc}`);
+ }
+ /**
+ * Creates an error thrown if the loopback server has not been spun up yet.
+ */
+ static createNoLoopbackServerExistsError() {
+ return new NodeAuthError(NodeAuthErrorMessage.noLoopbackServerExists.code, `${NodeAuthErrorMessage.noLoopbackServerExists.desc}`);
+ }
+ /**
+ * Creates an error thrown if a loopback server already exists when attempting to create another one.
+ */
+ static createLoopbackServerAlreadyExistsError() {
+ return new NodeAuthError(NodeAuthErrorMessage.loopbackServerAlreadyExists.code, `${NodeAuthErrorMessage.loopbackServerAlreadyExists.desc}`);
+ }
+ /**
+ * Creates an error thrown if the loopback server times out registering the auth code listener.
+ */
+ static createLoopbackServerTimeoutError() {
+ return new NodeAuthError(NodeAuthErrorMessage.loopbackServerTimeout.code, `${NodeAuthErrorMessage.loopbackServerTimeout.desc}`);
+ }
+ /**
+ * Creates an error thrown when the state is not present.
+ */
+ static createStateNotFoundError() {
+ return new NodeAuthError(NodeAuthErrorMessage.stateNotFoundError.code, NodeAuthErrorMessage.stateNotFoundError.desc);
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Base abstract class for all ClientApplications - public and confidential
+ * @public
+ */
+class ClientApplication {
+ /**
+ * Constructor for the ClientApplication
+ */
+ constructor(configuration) {
+ this.config = buildAppConfiguration(configuration);
+ this.cryptoProvider = new CryptoProvider();
+ this.logger = new msalCommon.Logger(this.config.system.loggerOptions, name, version);
+ this.storage = new NodeStorage(this.logger, this.config.auth.clientId, this.cryptoProvider);
+ this.tokenCache = new TokenCache(this.storage, this.logger, this.config.cache.cachePlugin);
+ }
+ /**
+ * Creates the URL of the authorization request, letting the user input credentials and consent to the
+ * application. The URL targets the /authorize endpoint of the authority configured in the
+ * application object.
+ *
+ * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI
+ * sent in the request and should contain an authorization code, which can then be used to acquire tokens via
+ * `acquireTokenByCode(AuthorizationCodeRequest)`.
+ */
+ async getAuthCodeUrl(request) {
+ this.logger.info("getAuthCodeUrl called", request.correlationId);
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request)),
+ responseMode: request.responseMode || msalCommon.ResponseMode.QUERY,
+ authenticationScheme: msalCommon.AuthenticationScheme.BEARER
+ };
+ const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, undefined, undefined, request.azureCloudOptions);
+ const authorizationCodeClient = new msalCommon.AuthorizationCodeClient(authClientConfig);
+ this.logger.verbose("Auth code client created", validRequest.correlationId);
+ return authorizationCodeClient.getAuthCodeUrl(validRequest);
+ }
+ /**
+ * Acquires a token by exchanging the Authorization Code received from the first step of OAuth2.0
+ * Authorization Code flow.
+ *
+ * `getAuthCodeUrl(AuthorizationCodeUrlRequest)` can be used to create the URL for the first step of OAuth2.0
+ * Authorization Code flow. Ensure that values for redirectUri and scopes in AuthorizationCodeUrlRequest and
+ * AuthorizationCodeRequest are the same.
+ */
+ async acquireTokenByCode(request, authCodePayLoad) {
+ this.logger.info("acquireTokenByCode called");
+ if (request.state && authCodePayLoad) {
+ this.logger.info("acquireTokenByCode - validating state");
+ this.validateState(request.state, authCodePayLoad.state || "");
+ // eslint-disable-next-line no-param-reassign
+ authCodePayLoad = {
+ ...authCodePayLoad,
+ state: ""
+ };
+ }
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request)),
+ authenticationScheme: msalCommon.AuthenticationScheme.BEARER
+ };
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByCode, validRequest.correlationId);
+ try {
+ const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, undefined, request.azureCloudOptions);
+ const authorizationCodeClient = new msalCommon.AuthorizationCodeClient(authClientConfig);
+ this.logger.verbose("Auth code client created", validRequest.correlationId);
+ return authorizationCodeClient.acquireToken(validRequest, authCodePayLoad);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Acquires a token by exchanging the refresh token provided for a new set of tokens.
+ *
+ * This API is provided only for scenarios where you would like to migrate from ADAL to MSAL. Otherwise, it is
+ * recommended that you use `acquireTokenSilent()` for silent scenarios. When using `acquireTokenSilent()`, MSAL will
+ * handle the caching and refreshing of tokens automatically.
+ */
+ async acquireTokenByRefreshToken(request) {
+ this.logger.info("acquireTokenByRefreshToken called", request.correlationId);
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request)),
+ authenticationScheme: msalCommon.AuthenticationScheme.BEARER
+ };
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByRefreshToken, validRequest.correlationId);
+ try {
+ const refreshTokenClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, undefined, request.azureCloudOptions);
+ const refreshTokenClient = new msalCommon.RefreshTokenClient(refreshTokenClientConfig);
+ this.logger.verbose("Refresh token client created", validRequest.correlationId);
+ return refreshTokenClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Acquires a token silently when a user specifies the account the token is requested for.
+ *
+ * This API expects the user to provide an account object and looks into the cache to retrieve the token if present.
+ * There is also an optional "forceRefresh" boolean the user can send to bypass the cache for access_token and id_token.
+ * In case the refresh_token is expired or not found, an error is thrown
+ * and the guidance is for the user to call any interactive token acquisition API (eg: `acquireTokenByCode()`).
+ */
+ async acquireTokenSilent(request) {
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request)),
+ forceRefresh: request.forceRefresh || false
+ };
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent, validRequest.correlationId, validRequest.forceRefresh);
+ try {
+ const silentFlowClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, undefined, request.azureCloudOptions);
+ const silentFlowClient = new msalCommon.SilentFlowClient(silentFlowClientConfig);
+ this.logger.verbose("Silent flow client created", validRequest.correlationId);
+ return silentFlowClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Acquires tokens with password grant by exchanging client applications username and password for credentials
+ *
+ * The latest OAuth 2.0 Security Best Current Practice disallows the password grant entirely.
+ * More details on this recommendation at https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-3.4
+ * Microsoft's documentation and recommendations are at:
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#usernamepassword
+ *
+ * @param request - UsenamePasswordRequest
+ */
+ async acquireTokenByUsernamePassword(request) {
+ this.logger.info("acquireTokenByUsernamePassword called", request.correlationId);
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request))
+ };
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByUsernamePassword, validRequest.correlationId);
+ try {
+ const usernamePasswordClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, undefined, request.azureCloudOptions);
+ const usernamePasswordClient = new msalCommon.UsernamePasswordClient(usernamePasswordClientConfig);
+ this.logger.verbose("Username password client created", validRequest.correlationId);
+ return usernamePasswordClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Gets the token cache for the application.
+ */
+ getTokenCache() {
+ this.logger.info("getTokenCache called");
+ return this.tokenCache;
+ }
+ /**
+ * Validates OIDC state by comparing the user cached state with the state received from the server.
+ *
+ * This API is provided for scenarios where you would use OAuth2.0 state parameter to mitigate against
+ * CSRF attacks.
+ * For more information about state, visit https://datatracker.ietf.org/doc/html/rfc6819#section-3.6.
+ * @param state
+ * @param cachedState
+ */
+ validateState(state, cachedState) {
+ if (!state) {
+ throw NodeAuthError.createStateNotFoundError();
+ }
+ if (state !== cachedState) {
+ throw msalCommon.ClientAuthError.createStateMismatchError();
+ }
+ }
+ /**
+ * Returns the logger instance
+ */
+ getLogger() {
+ return this.logger;
+ }
+ /**
+ * Replaces the default logger set in configurations with new Logger with new configurations
+ * @param logger - Logger instance
+ */
+ setLogger(logger) {
+ this.logger = logger;
+ }
+ /**
+ * Builds the common configuration to be passed to the common component based on the platform configurarion
+ * @param authority - user passed authority in configuration
+ * @param serverTelemetryManager - initializes servertelemetry if passed
+ */
+ async buildOauthClientConfiguration(authority, requestCorrelationId, serverTelemetryManager, azureRegionConfiguration, azureCloudOptions) {
+ this.logger.verbose("buildOauthClientConfiguration called", requestCorrelationId);
+ // precedence - azureCloudInstance + tenant >> authority and request >> config
+ const userAzureCloudOptions = azureCloudOptions ? azureCloudOptions : this.config.auth.azureCloudOptions;
+ // using null assertion operator as we ensure that all config values have default values in buildConfiguration()
+ this.logger.verbose(`building oauth client configuration with the authority: ${authority}`, requestCorrelationId);
+ const discoveredAuthority = await this.createAuthority(authority, azureRegionConfiguration, requestCorrelationId, userAzureCloudOptions);
+ serverTelemetryManager == null ? void 0 : serverTelemetryManager.updateRegionDiscoveryMetadata(discoveredAuthority.regionDiscoveryMetadata);
+ const clientConfiguration = {
+ authOptions: {
+ clientId: this.config.auth.clientId,
+ authority: discoveredAuthority,
+ clientCapabilities: this.config.auth.clientCapabilities
+ },
+ loggerOptions: {
+ logLevel: this.config.system.loggerOptions.logLevel,
+ loggerCallback: this.config.system.loggerOptions.loggerCallback,
+ piiLoggingEnabled: this.config.system.loggerOptions.piiLoggingEnabled,
+ correlationId: requestCorrelationId
+ },
+ cacheOptions: {
+ claimsBasedCachingEnabled: this.config.cache.claimsBasedCachingEnabled
+ },
+ cryptoInterface: this.cryptoProvider,
+ networkInterface: this.config.system.networkClient,
+ storageInterface: this.storage,
+ serverTelemetryManager: serverTelemetryManager,
+ clientCredentials: {
+ clientSecret: this.clientSecret,
+ clientAssertion: this.clientAssertion ? this.getClientAssertion(discoveredAuthority) : undefined
+ },
+ libraryInfo: {
+ sku: Constants.MSAL_SKU,
+ version: version,
+ cpu: process.arch || msalCommon.Constants.EMPTY_STRING,
+ os: process.platform || msalCommon.Constants.EMPTY_STRING
+ },
+ telemetry: this.config.telemetry,
+ persistencePlugin: this.config.cache.cachePlugin,
+ serializableCache: this.tokenCache
+ };
+ return clientConfiguration;
+ }
+ getClientAssertion(authority) {
+ return {
+ assertion: this.clientAssertion.getJwt(this.cryptoProvider, this.config.auth.clientId, authority.tokenEndpoint),
+ assertionType: Constants.JWT_BEARER_ASSERTION_TYPE
+ };
+ }
+ /**
+ * Generates a request with the default scopes & generates a correlationId.
+ * @param authRequest - BaseAuthRequest for initialization
+ */
+ async initializeBaseRequest(authRequest) {
+ this.logger.verbose("initializeRequestScopes called", authRequest.correlationId);
+ // Default authenticationScheme to Bearer, log that POP isn't supported yet
+ if (authRequest.authenticationScheme && authRequest.authenticationScheme === msalCommon.AuthenticationScheme.POP) {
+ this.logger.verbose("Authentication Scheme 'pop' is not supported yet, setting Authentication Scheme to 'Bearer' for request", authRequest.correlationId);
+ }
+ authRequest.authenticationScheme = msalCommon.AuthenticationScheme.BEARER;
+ // Set requested claims hash if claims-based caching is enabled and claims were requested
+ if (this.config.cache.claimsBasedCachingEnabled && authRequest.claims &&
+ // Checks for empty stringified object "{}" which doesn't qualify as requested claims
+ !msalCommon.StringUtils.isEmptyObj(authRequest.claims)) {
+ authRequest.requestedClaimsHash = await this.cryptoProvider.hashString(authRequest.claims);
+ }
+ return {
+ ...authRequest,
+ scopes: [...(authRequest && authRequest.scopes || []), ...msalCommon.OIDC_DEFAULT_SCOPES],
+ correlationId: authRequest && authRequest.correlationId || this.cryptoProvider.createNewGuid(),
+ authority: authRequest.authority || this.config.auth.authority
+ };
+ }
+ /**
+ * Initializes the server telemetry payload
+ * @param apiId - Id for a specific request
+ * @param correlationId - GUID
+ * @param forceRefresh - boolean to indicate network call
+ */
+ initializeServerTelemetryManager(apiId, correlationId, forceRefresh) {
+ const telemetryPayload = {
+ clientId: this.config.auth.clientId,
+ correlationId: correlationId,
+ apiId: apiId,
+ forceRefresh: forceRefresh || false
+ };
+ return new msalCommon.ServerTelemetryManager(telemetryPayload, this.storage);
+ }
+ /**
+ * Create authority instance. If authority not passed in request, default to authority set on the application
+ * object. If no authority set in application object, then default to common authority.
+ * @param authorityString - authority from user configuration
+ */
+ async createAuthority(authorityString, azureRegionConfiguration, requestCorrelationId, azureCloudOptions) {
+ this.logger.verbose("createAuthority called", requestCorrelationId);
+ // build authority string based on auth params - azureCloudInstance is prioritized if provided
+ const authorityUrl = msalCommon.Authority.generateAuthority(authorityString, azureCloudOptions);
+ const authorityOptions = {
+ protocolMode: this.config.auth.protocolMode,
+ knownAuthorities: this.config.auth.knownAuthorities,
+ cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata,
+ authorityMetadata: this.config.auth.authorityMetadata,
+ azureRegionConfiguration,
+ skipAuthorityMetadataCache: this.config.auth.skipAuthorityMetadataCache
+ };
+ return await msalCommon.AuthorityFactory.createDiscoveredInstance(authorityUrl, this.config.system.networkClient, this.storage, authorityOptions, this.logger);
+ }
+ /**
+ * Clear the cache
+ */
+ clearCache() {
+ this.storage.clear();
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class LoopbackClient {
+ /**
+ * Spins up a loopback server which returns the server response when the localhost redirectUri is hit
+ * @param successTemplate
+ * @param errorTemplate
+ * @returns
+ */
+ async listenForAuthCode(successTemplate, errorTemplate) {
+ if (!!this.server) {
+ throw NodeAuthError.createLoopbackServerAlreadyExistsError();
+ }
+ const authCodeListener = new Promise((resolve, reject) => {
+ this.server = http.createServer(async (req, res) => {
+ const url = req.url;
+ if (!url) {
+ res.end(errorTemplate || "Error occurred loading redirectUrl");
+ reject(NodeAuthError.createUnableToLoadRedirectUrlError());
+ return;
+ } else if (url === msalCommon.Constants.FORWARD_SLASH) {
+ res.end(successTemplate || "Auth code was successfully acquired. You can close this window now.");
+ return;
+ }
+ const authCodeResponse = msalCommon.UrlString.getDeserializedQueryString(url);
+ if (authCodeResponse.code) {
+ const redirectUri = await this.getRedirectUri();
+ res.writeHead(HttpStatus.REDIRECT, {
+ location: redirectUri
+ }); // Prevent auth code from being saved in the browser history
+ res.end();
+ }
+ resolve(authCodeResponse);
+ });
+ this.server.listen(0); // Listen on any available port
+ });
+ // Wait for server to be listening
+ await new Promise(resolve => {
+ let ticks = 0;
+ const id = setInterval(() => {
+ if (LOOPBACK_SERVER_CONSTANTS.TIMEOUT_MS / LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS < ticks) {
+ throw NodeAuthError.createLoopbackServerTimeoutError();
+ }
+ if (this.server.listening) {
+ clearInterval(id);
+ resolve();
+ }
+ ticks++;
+ }, LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS);
+ });
+ return authCodeListener;
+ }
+ /**
+ * Get the port that the loopback server is running on
+ * @returns
+ */
+ getRedirectUri() {
+ if (!this.server) {
+ throw NodeAuthError.createNoLoopbackServerExistsError();
+ }
+ const address = this.server.address();
+ if (!address || typeof address === "string" || !address.port) {
+ this.closeServer();
+ throw NodeAuthError.createInvalidLoopbackAddressTypeError();
+ }
+ const port = address && address.port;
+ return `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}:${port}`;
+ }
+ /**
+ * Close the loopback server
+ */
+ closeServer() {
+ if (!!this.server) {
+ this.server.close();
+ }
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class is to be used to acquire tokens for public client applications (desktop, mobile). Public client applications
+ * are not trusted to safely store application secrets, and therefore can only request tokens in the name of an user.
+ * @public
+ */
+class PublicClientApplication extends ClientApplication {
+ /**
+ * Important attributes in the Configuration object for auth are:
+ * - clientID: the application ID of your application. You can obtain one by registering your application with our Application registration portal.
+ * - authority: the authority URL for your application.
+ *
+ * AAD authorities are of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}.
+ * - If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com).
+ * - If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations.
+ * - If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common.
+ * - To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers.
+ *
+ * Azure B2C authorities are of the form https://\{instance\}/\{tenant\}/\{policy\}. Each policy is considered
+ * its own authority. You will have to set the all of the knownAuthorities at the time of the client application
+ * construction.
+ *
+ * ADFS authorities are of the form https://\{instance\}/adfs.
+ */
+ constructor(configuration) {
+ super(configuration);
+ if (this.config.broker.nativeBrokerPlugin) {
+ if (this.config.broker.nativeBrokerPlugin.isBrokerAvailable) {
+ this.nativeBrokerPlugin = this.config.broker.nativeBrokerPlugin;
+ this.nativeBrokerPlugin.setLogger(this.config.system.loggerOptions);
+ } else {
+ this.logger.warning("NativeBroker implementation was provided but the broker is unavailable.");
+ }
+ }
+ }
+ /**
+ * Acquires a token from the authority using OAuth2.0 device code flow.
+ * This flow is designed for devices that do not have access to a browser or have input constraints.
+ * The authorization server issues a DeviceCode object with a verification code, an end-user code,
+ * and the end-user verification URI. The DeviceCode object is provided through a callback, and the end-user should be
+ * instructed to use another device to navigate to the verification URI to input credentials.
+ * Since the client cannot receive incoming requests, it polls the authorization server repeatedly
+ * until the end-user completes input of credentials.
+ */
+ async acquireTokenByDeviceCode(request) {
+ this.logger.info("acquireTokenByDeviceCode called", request.correlationId);
+ const validRequest = Object.assign(request, await this.initializeBaseRequest(request));
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByDeviceCode, validRequest.correlationId);
+ try {
+ const deviceCodeConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, undefined, request.azureCloudOptions);
+ const deviceCodeClient = new msalCommon.DeviceCodeClient(deviceCodeConfig);
+ this.logger.verbose("Device code client created", validRequest.correlationId);
+ return deviceCodeClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Acquires a token interactively via the browser by requesting an authorization code then exchanging it for a token.
+ */
+ async acquireTokenInteractive(request) {
+ const correlationId = request.correlationId || this.cryptoProvider.createNewGuid();
+ this.logger.trace("acquireTokenInteractive called", correlationId);
+ const {
+ openBrowser,
+ successTemplate,
+ errorTemplate,
+ windowHandle,
+ loopbackClient: customLoopbackClient,
+ ...remainingProperties
+ } = request;
+ if (this.nativeBrokerPlugin) {
+ var _remainingProperties$;
+ const brokerRequest = {
+ ...remainingProperties,
+ clientId: this.config.auth.clientId,
+ scopes: request.scopes || msalCommon.OIDC_DEFAULT_SCOPES,
+ redirectUri: `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}`,
+ authority: request.authority || this.config.auth.authority,
+ correlationId: correlationId,
+ extraParameters: {
+ ...remainingProperties.extraQueryParameters,
+ ...remainingProperties.tokenQueryParameters
+ },
+ accountId: (_remainingProperties$ = remainingProperties.account) == null ? void 0 : _remainingProperties$.nativeAccountId
+ };
+ return this.nativeBrokerPlugin.acquireTokenInteractive(brokerRequest, windowHandle);
+ }
+ const {
+ verifier,
+ challenge
+ } = await this.cryptoProvider.generatePkceCodes();
+ const loopbackClient = customLoopbackClient || new LoopbackClient();
+ const authCodeListener = loopbackClient.listenForAuthCode(successTemplate, errorTemplate);
+ const redirectUri = loopbackClient.getRedirectUri();
+ const validRequest = {
+ ...remainingProperties,
+ correlationId: correlationId,
+ scopes: request.scopes || msalCommon.OIDC_DEFAULT_SCOPES,
+ redirectUri: redirectUri,
+ responseMode: msalCommon.ResponseMode.QUERY,
+ codeChallenge: challenge,
+ codeChallengeMethod: msalCommon.CodeChallengeMethodValues.S256
+ };
+ const authCodeUrl = await this.getAuthCodeUrl(validRequest);
+ await openBrowser(authCodeUrl);
+ const authCodeResponse = await authCodeListener.finally(() => {
+ loopbackClient.closeServer();
+ });
+ if (authCodeResponse.error) {
+ throw new msalCommon.ServerError(authCodeResponse.error, authCodeResponse.error_description, authCodeResponse.suberror);
+ } else if (!authCodeResponse.code) {
+ throw NodeAuthError.createNoAuthCodeInResponseError();
+ }
+ const clientInfo = authCodeResponse.client_info;
+ const tokenRequest = {
+ code: authCodeResponse.code,
+ codeVerifier: verifier,
+ clientInfo: clientInfo || msalCommon.Constants.EMPTY_STRING,
+ ...validRequest
+ };
+ return this.acquireTokenByCode(tokenRequest);
+ }
+ /**
+ * Returns a token retrieved either from the cache or by exchanging the refresh token for a fresh access token. If brokering is enabled the token request will be serviced by the broker.
+ * @param request
+ * @returns
+ */
+ async acquireTokenSilent(request) {
+ const correlationId = request.correlationId || this.cryptoProvider.createNewGuid();
+ this.logger.trace("acquireTokenSilent called", correlationId);
+ if (this.nativeBrokerPlugin) {
+ const brokerRequest = {
+ ...request,
+ clientId: this.config.auth.clientId,
+ scopes: request.scopes || msalCommon.OIDC_DEFAULT_SCOPES,
+ redirectUri: `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}`,
+ authority: request.authority || this.config.auth.authority,
+ correlationId: correlationId,
+ extraParameters: request.tokenQueryParameters,
+ accountId: request.account.nativeAccountId,
+ forceRefresh: request.forceRefresh || false
+ };
+ return this.nativeBrokerPlugin.acquireTokenSilent(brokerRequest);
+ }
+ return super.acquireTokenSilent(request);
+ }
+ /**
+ * Removes cache artifacts associated with the given account
+ * @param request
+ * @returns
+ */
+ async signOut(request) {
+ if (this.nativeBrokerPlugin && request.account.nativeAccountId) {
+ const signoutRequest = {
+ clientId: this.config.auth.clientId,
+ accountId: request.account.nativeAccountId,
+ correlationId: request.correlationId || this.cryptoProvider.createNewGuid()
+ };
+ await this.nativeBrokerPlugin.signOut(signoutRequest);
+ }
+ await this.getTokenCache().removeAccount(request.account);
+ }
+ /**
+ * Returns all cached accounts for this application. If brokering is enabled this request will be serviced by the broker.
+ * @returns
+ */
+ async getAllAccounts() {
+ if (this.nativeBrokerPlugin) {
+ const correlationId = this.cryptoProvider.createNewGuid();
+ return this.nativeBrokerPlugin.getAllAccounts(this.config.auth.clientId, correlationId);
+ }
+ return this.getTokenCache().getAllAccounts();
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * Client assertion of type jwt-bearer used in confidential client flows
+ * @public
+ */
+class ClientAssertion {
+ /**
+ * Initialize the ClientAssertion class from the clientAssertion passed by the user
+ * @param assertion - refer https://tools.ietf.org/html/rfc7521
+ */
+ static fromAssertion(assertion) {
+ const clientAssertion = new ClientAssertion();
+ clientAssertion.jwt = assertion;
+ return clientAssertion;
+ }
+ /**
+ * Initialize the ClientAssertion class from the certificate passed by the user
+ * @param thumbprint - identifier of a certificate
+ * @param privateKey - secret key
+ * @param publicCertificate - electronic document provided to prove the ownership of the public key
+ */
+ static fromCertificate(thumbprint, privateKey, publicCertificate) {
+ const clientAssertion = new ClientAssertion();
+ clientAssertion.privateKey = privateKey;
+ clientAssertion.thumbprint = thumbprint;
+ if (publicCertificate) {
+ clientAssertion.publicCertificate = this.parseCertificate(publicCertificate);
+ }
+ return clientAssertion;
+ }
+ /**
+ * Update JWT for certificate based clientAssertion, if passed by the user, uses it as is
+ * @param cryptoProvider - library's crypto helper
+ * @param issuer - iss claim
+ * @param jwtAudience - aud claim
+ */
+ getJwt(cryptoProvider, issuer, jwtAudience) {
+ // if assertion was created from certificate, check if jwt is expired and create new one.
+ if (this.privateKey && this.thumbprint) {
+ if (this.jwt && !this.isExpired() && issuer === this.issuer && jwtAudience === this.jwtAudience) {
+ return this.jwt;
+ }
+ return this.createJwt(cryptoProvider, issuer, jwtAudience);
+ }
+ /*
+ * if assertion was created by caller, then we just append it. It is up to the caller to
+ * ensure that it contains necessary claims and that it is not expired.
+ */
+ if (this.jwt) {
+ return this.jwt;
+ }
+ throw msalCommon.ClientAuthError.createInvalidAssertionError();
+ }
+ /**
+ * JWT format and required claims specified: https://tools.ietf.org/html/rfc7523#section-3
+ */
+ createJwt(cryptoProvider, issuer, jwtAudience) {
+ this.issuer = issuer;
+ this.jwtAudience = jwtAudience;
+ const issuedAt = msalCommon.TimeUtils.nowSeconds();
+ this.expirationTime = issuedAt + 600;
+ const header = {
+ alg: JwtConstants.RSA_256,
+ x5t: EncodingUtils.base64EncodeUrl(this.thumbprint, "hex")
+ };
+ if (this.publicCertificate) {
+ Object.assign(header, {
+ x5c: this.publicCertificate
+ });
+ }
+ const payload = {
+ [JwtConstants.AUDIENCE]: this.jwtAudience,
+ [JwtConstants.EXPIRATION_TIME]: this.expirationTime,
+ [JwtConstants.ISSUER]: this.issuer,
+ [JwtConstants.SUBJECT]: this.issuer,
+ [JwtConstants.NOT_BEFORE]: issuedAt,
+ [JwtConstants.JWT_ID]: cryptoProvider.createNewGuid()
+ };
+ this.jwt = jsonwebtoken.sign(payload, this.privateKey, {
+ header
+ });
+ return this.jwt;
+ }
+ /**
+ * Utility API to check expiration
+ */
+ isExpired() {
+ return this.expirationTime < msalCommon.TimeUtils.nowSeconds();
+ }
+ /**
+ * Extracts the raw certs from a given certificate string and returns them in an array.
+ * @param publicCertificate - electronic document provided to prove the ownership of the public key
+ */
+ static parseCertificate(publicCertificate) {
+ /**
+ * This is regex to identify the certs in a given certificate string.
+ * We want to look for the contents between the BEGIN and END certificate strings, without the associated newlines.
+ * The information in parens "(.+?)" is the capture group to represent the cert we want isolated.
+ * "." means any string character, "+" means match 1 or more times, and "?" means the shortest match.
+ * The "g" at the end of the regex means search the string globally, and the "s" enables the "." to match newlines.
+ */
+ const regexToFindCerts = /-----BEGIN CERTIFICATE-----\r*\n(.+?)\r*\n-----END CERTIFICATE-----/gs;
+ const certs = [];
+ let matches;
+ while ((matches = regexToFindCerts.exec(publicCertificate)) !== null) {
+ // matches[1] represents the first parens capture group in the regex.
+ certs.push(matches[1].replace(/\r*\n/g, msalCommon.Constants.EMPTY_STRING));
+ }
+ return certs;
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+/**
+ * This class is to be used to acquire tokens for confidential client applications (webApp, webAPI). Confidential client applications
+ * will configure application secrets, client certificates/assertions as applicable
+ * @public
+ */
+class ConfidentialClientApplication extends ClientApplication {
+ /**
+ * Constructor for the ConfidentialClientApplication
+ *
+ * Required attributes in the Configuration object are:
+ * - clientID: the application ID of your application. You can obtain one by registering your application with our application registration portal
+ * - authority: the authority URL for your application.
+ * - client credential: Must set either client secret, certificate, or assertion for confidential clients. You can obtain a client secret from the application registration portal.
+ *
+ * In Azure AD, authority is a URL indicating of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}.
+ * If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com).
+ * If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations.
+ * If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common.
+ * To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers.
+ *
+ * In Azure B2C, authority is of the form https://\{instance\}/tfp/\{tenant\}/\{policyName\}/
+ * Full B2C functionality will be available in this library in future versions.
+ *
+ * @param Configuration - configuration object for the MSAL ConfidentialClientApplication instance
+ */
+ constructor(configuration) {
+ super(configuration);
+ this.setClientCredential(this.config);
+ this.appTokenProvider = undefined;
+ }
+ /**
+ * This extensibility point only works for the client_credential flow, i.e. acquireTokenByClientCredential and
+ * is meant for Azure SDK to enhance Managed Identity support.
+ *
+ * @param IAppTokenProvider - Extensibility interface, which allows the app developer to return a token from a custom source.
+ */
+ SetAppTokenProvider(provider) {
+ this.appTokenProvider = provider;
+ }
+ /**
+ * Acquires tokens from the authority for the application (not for an end user).
+ */
+ async acquireTokenByClientCredential(request) {
+ this.logger.info("acquireTokenByClientCredential called", request.correlationId);
+ // If there is a client assertion present in the request, it overrides the one present in the client configuration
+ let clientAssertion;
+ if (request.clientAssertion) {
+ clientAssertion = {
+ assertion: request.clientAssertion,
+ assertionType: Constants.JWT_BEARER_ASSERTION_TYPE
+ };
+ }
+ const baseRequest = await this.initializeBaseRequest(request);
+ // valid base request should not contain oidc scopes in this grant type
+ const validBaseRequest = {
+ ...baseRequest,
+ scopes: baseRequest.scopes.filter(scope => !msalCommon.OIDC_DEFAULT_SCOPES.includes(scope))
+ };
+ const validRequest = {
+ ...request,
+ ...validBaseRequest,
+ clientAssertion
+ };
+ const azureRegionConfiguration = {
+ azureRegion: validRequest.azureRegion,
+ environmentRegion: process.env[REGION_ENVIRONMENT_VARIABLE]
+ };
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByClientCredential, validRequest.correlationId, validRequest.skipCache);
+ try {
+ const clientCredentialConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, azureRegionConfiguration, request.azureCloudOptions);
+ const clientCredentialClient = new msalCommon.ClientCredentialClient(clientCredentialConfig, this.appTokenProvider);
+ this.logger.verbose("Client credential client created", validRequest.correlationId);
+ return clientCredentialClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ serverTelemetryManager.cacheFailedRequest(e);
+ throw e;
+ }
+ }
+ /**
+ * Acquires tokens from the authority for the application.
+ *
+ * Used in scenarios where the current app is a middle-tier service which was called with a token
+ * representing an end user. The current app can use the token (oboAssertion) to request another
+ * token to access downstream web API, on behalf of that user.
+ *
+ * The current middle-tier app has no user interaction to obtain consent.
+ * See how to gain consent upfront for your middle-tier app from this article.
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application
+ */
+ async acquireTokenOnBehalfOf(request) {
+ this.logger.info("acquireTokenOnBehalfOf called", request.correlationId);
+ const validRequest = {
+ ...request,
+ ...(await this.initializeBaseRequest(request))
+ };
+ try {
+ const onBehalfOfConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, undefined, undefined, request.azureCloudOptions);
+ const oboClient = new msalCommon.OnBehalfOfClient(onBehalfOfConfig);
+ this.logger.verbose("On behalf of client created", validRequest.correlationId);
+ return oboClient.acquireToken(validRequest);
+ } catch (e) {
+ if (e instanceof msalCommon.AuthError) {
+ e.setCorrelationId(validRequest.correlationId);
+ }
+ throw e;
+ }
+ }
+ setClientCredential(configuration) {
+ const clientSecretNotEmpty = !msalCommon.StringUtils.isEmpty(configuration.auth.clientSecret);
+ const clientAssertionNotEmpty = !msalCommon.StringUtils.isEmpty(configuration.auth.clientAssertion);
+ const certificate = configuration.auth.clientCertificate || {
+ thumbprint: msalCommon.Constants.EMPTY_STRING,
+ privateKey: msalCommon.Constants.EMPTY_STRING
+ };
+ const certificateNotEmpty = !msalCommon.StringUtils.isEmpty(certificate.thumbprint) || !msalCommon.StringUtils.isEmpty(certificate.privateKey);
+ /*
+ * If app developer configures this callback, they don't need a credential
+ * i.e. AzureSDK can get token from Managed Identity without a cert / secret
+ */
+ if (this.appTokenProvider) {
+ return;
+ }
+ // Check that at most one credential is set on the application
+ if (clientSecretNotEmpty && clientAssertionNotEmpty || clientAssertionNotEmpty && certificateNotEmpty || clientSecretNotEmpty && certificateNotEmpty) {
+ throw msalCommon.ClientAuthError.createInvalidCredentialError();
+ }
+ if (configuration.auth.clientSecret) {
+ this.clientSecret = configuration.auth.clientSecret;
+ return;
+ }
+ if (configuration.auth.clientAssertion) {
+ this.clientAssertion = ClientAssertion.fromAssertion(configuration.auth.clientAssertion);
+ return;
+ }
+ if (!certificateNotEmpty) {
+ throw msalCommon.ClientAuthError.createInvalidCredentialError();
+ } else {
+ var _configuration$auth$c;
+ this.clientAssertion = ClientAssertion.fromCertificate(certificate.thumbprint, certificate.privateKey, (_configuration$auth$c = configuration.auth.clientCertificate) == null ? void 0 : _configuration$auth$c.x5c);
+ }
+ }
+}
+
+/*
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License.
+ */
+class DistributedCachePlugin {
+ constructor(client, partitionManager) {
+ this.client = client;
+ this.partitionManager = partitionManager;
+ }
+ async beforeCacheAccess(cacheContext) {
+ const partitionKey = await this.partitionManager.getKey();
+ const cacheData = await this.client.get(partitionKey);
+ cacheContext.tokenCache.deserialize(cacheData);
+ }
+ async afterCacheAccess(cacheContext) {
+ if (cacheContext.cacheHasChanged) {
+ const kvStore = cacheContext.tokenCache.getKVStore();
+ const accountEntities = Object.values(kvStore).filter(value => msalCommon.AccountEntity.isAccountEntity(value));
+ if (accountEntities.length > 0) {
+ const accountEntity = accountEntities[0];
+ const partitionKey = await this.partitionManager.extractKey(accountEntity);
+ await this.client.set(partitionKey, cacheContext.tokenCache.serialize());
+ }
+ }
+ }
+}
+
+Object.defineProperty(exports, "AuthError", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.AuthError;
+ }
+}));
+Object.defineProperty(exports, "AuthErrorMessage", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.AuthErrorMessage;
+ }
+}));
+Object.defineProperty(exports, "AzureCloudInstance", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.AzureCloudInstance;
+ }
+}));
+Object.defineProperty(exports, "ClientAuthError", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ClientAuthError;
+ }
+}));
+Object.defineProperty(exports, "ClientAuthErrorMessage", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ClientAuthErrorMessage;
+ }
+}));
+Object.defineProperty(exports, "ClientConfigurationError", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ClientConfigurationError;
+ }
+}));
+Object.defineProperty(exports, "ClientConfigurationErrorMessage", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ClientConfigurationErrorMessage;
+ }
+}));
+Object.defineProperty(exports, "InteractionRequiredAuthError", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.InteractionRequiredAuthError;
+ }
+}));
+Object.defineProperty(exports, "InteractionRequiredAuthErrorMessage", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.InteractionRequiredAuthErrorMessage;
+ }
+}));
+Object.defineProperty(exports, "LogLevel", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.LogLevel;
+ }
+}));
+Object.defineProperty(exports, "Logger", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.Logger;
+ }
+}));
+Object.defineProperty(exports, "PromptValue", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.PromptValue;
+ }
+}));
+Object.defineProperty(exports, "ProtocolMode", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ProtocolMode;
+ }
+}));
+Object.defineProperty(exports, "ResponseMode", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ResponseMode;
+ }
+}));
+Object.defineProperty(exports, "ServerError", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.ServerError;
+ }
+}));
+Object.defineProperty(exports, "TokenCacheContext", ({
+ enumerable: true,
+ get: function () {
+ return msalCommon.TokenCacheContext;
+ }
+}));
+exports.ClientApplication = ClientApplication;
+exports.ClientAssertion = ClientAssertion;
+exports.ConfidentialClientApplication = ConfidentialClientApplication;
+exports.CryptoProvider = CryptoProvider;
+exports.DistributedCachePlugin = DistributedCachePlugin;
+exports.NodeStorage = NodeStorage;
+exports.PublicClientApplication = PublicClientApplication;
+exports.TokenCache = TokenCache;
+exports.buildAppConfiguration = buildAppConfiguration;
+exports.version = version;
+//# sourceMappingURL=msal-node.cjs.development.js.map
+
+
+/***/ }),
+
+/***/ 9802:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports, "__esModule", ({value:!0}));var t,r,n,i=__nccwpck_require__(5728),o=__nccwpck_require__(3685),s=e(o),a=e(__nccwpck_require__(5687)),c=__nccwpck_require__(5840),l=e(__nccwpck_require__(6113)),h=__nccwpck_require__(7486);!function(e){e.GET="get",e.POST="post"}(t||(t={})),function(e){e[e.SUCCESS_RANGE_START=200]="SUCCESS_RANGE_START",e[e.SUCCESS_RANGE_END=299]="SUCCESS_RANGE_END",e[e.REDIRECT=302]="REDIRECT",e[e.CLIENT_ERROR_RANGE_START=400]="CLIENT_ERROR_RANGE_START",e[e.CLIENT_ERROR_RANGE_END=499]="CLIENT_ERROR_RANGE_END",e[e.SERVER_ERROR_RANGE_START=500]="SERVER_ERROR_RANGE_START",e[e.SERVER_ERROR_RANGE_END=599]="SERVER_ERROR_RANGE_END"}(r||(r={})),function(e){e[e.SUCCESS_RANGE_START=200]="SUCCESS_RANGE_START",e[e.SUCCESS_RANGE_END=299]="SUCCESS_RANGE_END",e[e.SERVER_ERROR=500]="SERVER_ERROR"}(n||(n={}));const u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";var d;!function(e){e[e.acquireTokenSilent=62]="acquireTokenSilent",e[e.acquireTokenByUsernamePassword=371]="acquireTokenByUsernamePassword",e[e.acquireTokenByDeviceCode=671]="acquireTokenByDeviceCode",e[e.acquireTokenByClientCredential=771]="acquireTokenByClientCredential",e[e.acquireTokenByCode=871]="acquireTokenByCode",e[e.acquireTokenByRefreshToken=872]="acquireTokenByRefreshToken"}(d||(d={}));class g{static getNetworkResponse(e,t,r){return{headers:e,body:t,status:r}}static urlToHttpOptions(e){const t={protocol:e.protocol,hostname:e.hostname&&e.hostname.startsWith("[")?e.hostname.slice(1,-1):e.hostname,hash:e.hash,search:e.search,pathname:e.pathname,path:`${e.pathname||""}${e.search||""}`,href:e.href};return""!==e.port&&(t.port=Number(e.port)),(e.username||e.password)&&(t.auth=`${decodeURIComponent(e.username)}:${decodeURIComponent(e.password)}`),t}}class p{constructor(e,t){this.proxyUrl=e||"",this.customAgentOptions=t||{}}async sendGetRequestAsync(e,r){return this.proxyUrl?y(e,this.proxyUrl,t.GET,r,this.customAgentOptions):m(e,t.GET,r,this.customAgentOptions)}async sendPostRequestAsync(e,r,n){return this.proxyUrl?y(e,this.proxyUrl,t.POST,r,this.customAgentOptions,n):m(e,t.POST,r,this.customAgentOptions,n)}}const y=(e,i,o,a,c,l)=>{const h=new URL(e),u=new URL(i),d={host:u.hostname,port:u.port,method:"CONNECT",path:h.hostname,headers:(null==a?void 0:a.headers)||{}};l&&(d.timeout=l),c&&Object.keys(c).length&&(d.agent=new s.Agent(c));let p="";if(o===t.POST){const e=(null==a?void 0:a.body)||"";p=`Content-Type: application/x-www-form-urlencoded\r\nContent-Length: ${e.length}\r\n\r\n`+e}const y=`${o.toUpperCase()} ${h.href} HTTP/1.1\r\nHost: ${h.host}\r\nConnection: close\r\n`+p+"\r\n";return new Promise((e,t)=>{const i=s.request(d);d.timeout&&i.on("timeout",()=>{i.destroy(),t(new Error("Request time out"))}),i.end(),i.on("connect",(o,s)=>{const a=(null==o?void 0:o.statusCode)||n.SERVER_ERROR;(an.SUCCESS_RANGE_END)&&(i.destroy(),s.destroy(),t(new Error(`Error connecting to proxy. Http status code: ${o.statusCode}. Http status message: ${(null==o?void 0:o.statusMessage)||"Unknown"}`))),d.timeout&&(s.setTimeout(d.timeout),s.on("timeout",()=>{i.destroy(),s.destroy(),t(new Error("Request time out"))})),s.write(y);const c=[];s.on("data",e=>{c.push(e)}),s.on("end",()=>{const t=Buffer.concat([...c]).toString().split("\r\n"),n=parseInt(t[0].split(" ")[1]),o=t[0].split(" ").slice(2).join(" "),s=t[t.length-1],a=t.slice(1,t.length-2),l=new Map;a.forEach(e=>{const t=e.split(new RegExp(/:\s(.*)/s)),r=t[0];let n=t[1];try{const e=JSON.parse(n);e&&"object"==typeof e&&(n=e)}catch(e){}l.set(r,n)});const h=Object.fromEntries(l),u=g.getNetworkResponse(h,C(n,o,h,s),n);(nr.SUCCESS_RANGE_END)&&"authorization_pending"!==u.body.error&&i.destroy(),e(u)}),s.on("error",e=>{i.destroy(),s.destroy(),t(new Error(e.toString()))})}),i.on("error",e=>{i.destroy(),t(new Error(e.toString()))})})},m=(e,n,i,o,s)=>{const c=n===t.POST,l=(null==i?void 0:i.body)||"",h=new URL(e),u={method:n,headers:(null==i?void 0:i.headers)||{},...g.urlToHttpOptions(h)};return s&&(u.timeout=s),o&&Object.keys(o).length&&(u.agent=new a.Agent(o)),c&&(u.headers={...u.headers,"Content-Length":l.length}),new Promise((e,t)=>{const n=a.request(u);s&&n.on("timeout",()=>{n.destroy(),t(new Error("Request time out"))}),c&&n.write(l),n.end(),n.on("response",t=>{const i=t.headers,o=t.statusCode,s=t.statusMessage,a=[];t.on("data",e=>{a.push(e)}),t.on("end",()=>{const t=Buffer.concat([...a]).toString(),c=g.getNetworkResponse(i,C(o,s,i,t),o);(or.SUCCESS_RANGE_END)&&"authorization_pending"!==c.body.error&&n.destroy(),e(c)})}),n.on("error",e=>{n.destroy(),t(new Error(e.toString()))})})},C=(e,t,n,i)=>{let o;try{o=JSON.parse(i)}catch(i){let s,a;e>=r.CLIENT_ERROR_RANGE_START&&e<=r.CLIENT_ERROR_RANGE_END?(s="client_error",a="A client"):e>=r.SERVER_ERROR_RANGE_START&&e<=r.SERVER_ERROR_RANGE_END?(s="server_error",a="A server"):(s="unknown_error",a="An unknown"),o={error:s,error_description:`${a} error occured.\nHttp status code: ${e}\nHttp status message: ${t||"Unknown"}\nHeaders: ${JSON.stringify(n)}`}}return o},f={clientId:i.Constants.EMPTY_STRING,authority:i.Constants.DEFAULT_AUTHORITY,clientSecret:i.Constants.EMPTY_STRING,clientAssertion:i.Constants.EMPTY_STRING,clientCertificate:{thumbprint:i.Constants.EMPTY_STRING,privateKey:i.Constants.EMPTY_STRING,x5c:i.Constants.EMPTY_STRING},knownAuthorities:[],cloudDiscoveryMetadata:i.Constants.EMPTY_STRING,authorityMetadata:i.Constants.EMPTY_STRING,clientCapabilities:[],protocolMode:i.ProtocolMode.AAD,azureCloudOptions:{azureCloudInstance:i.AzureCloudInstance.None,tenant:i.Constants.EMPTY_STRING},skipAuthorityMetadataCache:!1},T={claimsBasedCachingEnabled:!0},A={loggerCallback:()=>{},piiLoggingEnabled:!1,logLevel:i.LogLevel.Info},E={loggerOptions:A,networkClient:new p,proxyUrl:i.Constants.EMPTY_STRING,customAgentOptions:{}},k={application:{appName:i.Constants.EMPTY_STRING,appVersion:i.Constants.EMPTY_STRING}};function R({auth:e,broker:t,cache:r,system:n,telemetry:i}){const o={...E,networkClient:new p(null==n?void 0:n.proxyUrl,null==n?void 0:n.customAgentOptions),loggerOptions:(null==n?void 0:n.loggerOptions)||A};return{auth:{...f,...e},broker:{...t},cache:{...T,...r},system:{...o,...n},telemetry:{...k,...i}}}class I{generateGuid(){return c.v4()}isGuid(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e)}}class v{static base64Encode(e,t){return Buffer.from(e,t).toString("base64")}static base64EncodeUrl(e,t){return v.base64Encode(e,t).replace(/=/g,i.Constants.EMPTY_STRING).replace(/\+/g,"-").replace(/\//g,"_")}static base64Decode(e){return Buffer.from(e,"base64").toString("utf8")}static base64DecodeUrl(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");for(;t.length%4;)t+="=";return v.base64Decode(t)}}class S{sha256(e){return l.createHash("sha256").update(e).digest()}}class w{constructor(){this.hashUtils=new S}async generatePkceCodes(){const e=this.generateCodeVerifier();return{verifier:e,challenge:this.generateCodeChallengeFromVerifier(e)}}generateCodeVerifier(){const e=[],t=256-256%u.length;for(;e.length<=32;){const r=l.randomBytes(1)[0];r>=t||e.push(u[r%u.length])}const r=e.join(i.Constants.EMPTY_STRING);return v.base64EncodeUrl(r)}generateCodeChallengeFromVerifier(e){return v.base64EncodeUrl(this.hashUtils.sha256(e).toString("base64"),"base64")}}class _{constructor(){this.pkceGenerator=new w,this.guidGenerator=new I,this.hashUtils=new S}createNewGuid(){return this.guidGenerator.generateGuid()}base64Encode(e){return v.base64Encode(e)}base64Decode(e){return v.base64Decode(e)}generatePkceCodes(){return this.pkceGenerator.generatePkceCodes()}getPublicKeyThumbprint(){throw new Error("Method not implemented.")}removeTokenBindingKey(){throw new Error("Method not implemented.")}clearKeystore(){throw new Error("Method not implemented.")}signJwt(){throw new Error("Method not implemented.")}async hashString(e){return v.base64EncodeUrl(this.hashUtils.sha256(e).toString("base64"),"base64")}}class b{static deserializeJSONBlob(e){return i.StringUtils.isEmpty(e)?{}:JSON.parse(e)}static deserializeAccounts(e){const t={};return e&&Object.keys(e).map((function(r){const n=e[r],o={homeAccountId:n.home_account_id,environment:n.environment,realm:n.realm,localAccountId:n.local_account_id,username:n.username,authorityType:n.authority_type,name:n.name,clientInfo:n.client_info,lastModificationTime:n.last_modification_time,lastModificationApp:n.last_modification_app},s=new i.AccountEntity;i.CacheManager.toObject(s,o),t[r]=s})),t}static deserializeIdTokens(e){const t={};return e&&Object.keys(e).map((function(r){const n=e[r],o={homeAccountId:n.home_account_id,environment:n.environment,credentialType:n.credential_type,clientId:n.client_id,secret:n.secret,realm:n.realm},s=new i.IdTokenEntity;i.CacheManager.toObject(s,o),t[r]=s})),t}static deserializeAccessTokens(e){const t={};return e&&Object.keys(e).map((function(r){const n=e[r],o={homeAccountId:n.home_account_id,environment:n.environment,credentialType:n.credential_type,clientId:n.client_id,secret:n.secret,realm:n.realm,target:n.target,cachedAt:n.cached_at,expiresOn:n.expires_on,extendedExpiresOn:n.extended_expires_on,refreshOn:n.refresh_on,keyId:n.key_id,tokenType:n.token_type,requestedClaims:n.requestedClaims,requestedClaimsHash:n.requestedClaimsHash,userAssertionHash:n.userAssertionHash},s=new i.AccessTokenEntity;i.CacheManager.toObject(s,o),t[r]=s})),t}static deserializeRefreshTokens(e){const t={};return e&&Object.keys(e).map((function(r){const n=e[r],o={homeAccountId:n.home_account_id,environment:n.environment,credentialType:n.credential_type,clientId:n.client_id,secret:n.secret,familyId:n.family_id,target:n.target,realm:n.realm},s=new i.RefreshTokenEntity;i.CacheManager.toObject(s,o),t[r]=s})),t}static deserializeAppMetadata(e){const t={};return e&&Object.keys(e).map((function(r){const n=e[r],o={clientId:n.client_id,environment:n.environment,familyId:n.family_id},s=new i.AppMetadataEntity;i.CacheManager.toObject(s,o),t[r]=s})),t}static deserializeAllCache(e){return{accounts:e.Account?this.deserializeAccounts(e.Account):{},idTokens:e.IdToken?this.deserializeIdTokens(e.IdToken):{},accessTokens:e.AccessToken?this.deserializeAccessTokens(e.AccessToken):{},refreshTokens:e.RefreshToken?this.deserializeRefreshTokens(e.RefreshToken):{},appMetadata:e.AppMetadata?this.deserializeAppMetadata(e.AppMetadata):{}}}}class O{static serializeJSONBlob(e){return JSON.stringify(e)}static serializeAccounts(e){const t={};return Object.keys(e).map((function(r){const n=e[r];t[r]={home_account_id:n.homeAccountId,environment:n.environment,realm:n.realm,local_account_id:n.localAccountId,username:n.username,authority_type:n.authorityType,name:n.name,client_info:n.clientInfo,last_modification_time:n.lastModificationTime,last_modification_app:n.lastModificationApp}})),t}static serializeIdTokens(e){const t={};return Object.keys(e).map((function(r){const n=e[r];t[r]={home_account_id:n.homeAccountId,environment:n.environment,credential_type:n.credentialType,client_id:n.clientId,secret:n.secret,realm:n.realm}})),t}static serializeAccessTokens(e){const t={};return Object.keys(e).map((function(r){const n=e[r];t[r]={home_account_id:n.homeAccountId,environment:n.environment,credential_type:n.credentialType,client_id:n.clientId,secret:n.secret,realm:n.realm,target:n.target,cached_at:n.cachedAt,expires_on:n.expiresOn,extended_expires_on:n.extendedExpiresOn,refresh_on:n.refreshOn,key_id:n.keyId,token_type:n.tokenType,requestedClaims:n.requestedClaims,requestedClaimsHash:n.requestedClaimsHash,userAssertionHash:n.userAssertionHash}})),t}static serializeRefreshTokens(e){const t={};return Object.keys(e).map((function(r){const n=e[r];t[r]={home_account_id:n.homeAccountId,environment:n.environment,credential_type:n.credentialType,client_id:n.clientId,secret:n.secret,family_id:n.familyId,target:n.target,realm:n.realm}})),t}static serializeAppMetadata(e){const t={};return Object.keys(e).map((function(r){const n=e[r];t[r]={client_id:n.clientId,environment:n.environment,family_id:n.familyId}})),t}static serializeAllCache(e){return{Account:this.serializeAccounts(e.accounts),IdToken:this.serializeIdTokens(e.idTokens),AccessToken:this.serializeAccessTokens(e.accessTokens),RefreshToken:this.serializeRefreshTokens(e.refreshTokens),AppMetadata:this.serializeAppMetadata(e.appMetadata)}}}class M extends i.CacheManager{constructor(e,t,r){super(t,r,e),this.cache={},this.changeEmitters=[],this.logger=e}registerChangeEmitter(e){this.changeEmitters.push(e)}emitChange(){this.changeEmitters.forEach(e=>e.call(null))}cacheToInMemoryCache(e){const t={accounts:{},idTokens:{},accessTokens:{},refreshTokens:{},appMetadata:{}};for(const r in e)if(e[r]instanceof i.AccountEntity)t.accounts[r]=e[r];else if(e[r]instanceof i.IdTokenEntity)t.idTokens[r]=e[r];else if(e[r]instanceof i.AccessTokenEntity)t.accessTokens[r]=e[r];else if(e[r]instanceof i.RefreshTokenEntity)t.refreshTokens[r]=e[r];else{if(!(e[r]instanceof i.AppMetadataEntity))continue;t.appMetadata[r]=e[r]}return t}inMemoryCacheToCache(e){let t=this.getCache();return t={...t,...e.accounts,...e.idTokens,...e.accessTokens,...e.refreshTokens,...e.appMetadata},t}getInMemoryCache(){return this.logger.trace("Getting in-memory cache"),this.cacheToInMemoryCache(this.getCache())}setInMemoryCache(e){this.logger.trace("Setting in-memory cache");const t=this.inMemoryCacheToCache(e);this.setCache(t),this.emitChange()}getCache(){return this.logger.trace("Getting cache key-value store"),this.cache}setCache(e){this.logger.trace("Setting cache key value store"),this.cache=e,this.emitChange()}getItem(e){return this.logger.tracePii("Item key: "+e),this.getCache()[e]}setItem(e,t){this.logger.tracePii("Item key: "+e);const r=this.getCache();r[e]=t,this.setCache(r)}getAccountKeys(){const e=this.getInMemoryCache();return Object.keys(e.accounts)}getTokenKeys(){const e=this.getInMemoryCache();return{idToken:Object.keys(e.idTokens),accessToken:Object.keys(e.accessTokens),refreshToken:Object.keys(e.refreshTokens)}}getAccount(e){const t=this.getItem(e);return i.AccountEntity.isAccountEntity(t)?t:null}setAccount(e){const t=e.generateAccountKey();this.setItem(t,e)}getIdTokenCredential(e){const t=this.getItem(e);return i.IdTokenEntity.isIdTokenEntity(t)?t:null}setIdTokenCredential(e){const t=e.generateCredentialKey();this.setItem(t,e)}getAccessTokenCredential(e){const t=this.getItem(e);return i.AccessTokenEntity.isAccessTokenEntity(t)?t:null}setAccessTokenCredential(e){const t=e.generateCredentialKey();this.setItem(t,e)}getRefreshTokenCredential(e){const t=this.getItem(e);return i.RefreshTokenEntity.isRefreshTokenEntity(t)?t:null}setRefreshTokenCredential(e){const t=e.generateCredentialKey();this.setItem(t,e)}getAppMetadata(e){const t=this.getItem(e);return i.AppMetadataEntity.isAppMetadataEntity(e,t)?t:null}setAppMetadata(e){const t=e.generateAppMetadataKey();this.setItem(t,e)}getServerTelemetry(e){const t=this.getItem(e);return t&&i.ServerTelemetryEntity.isServerTelemetryEntity(e,t)?t:null}setServerTelemetry(e,t){this.setItem(e,t)}getAuthorityMetadata(e){const t=this.getItem(e);return t&&i.AuthorityMetadataEntity.isAuthorityMetadataEntity(e,t)?t:null}getAuthorityMetadataKeys(){return this.getKeys().filter(e=>this.isAuthorityMetadata(e))}setAuthorityMetadata(e,t){this.setItem(e,t)}getThrottlingCache(e){const t=this.getItem(e);return t&&i.ThrottlingEntity.isThrottlingEntity(e,t)?t:null}setThrottlingCache(e,t){this.setItem(e,t)}removeItem(e){this.logger.tracePii("Item key: "+e);let t=!1;const r=this.getCache();return r[e]&&(delete r[e],t=!0),t&&(this.setCache(r),this.emitChange()),t}containsKey(e){return this.getKeys().includes(e)}getKeys(){this.logger.trace("Retrieving all cache keys");const e=this.getCache();return[...Object.keys(e)]}async clear(){this.logger.trace("Clearing cache entries created by MSAL"),this.getKeys().forEach(e=>{this.removeItem(e)}),this.emitChange()}static generateInMemoryCache(e){return b.deserializeAllCache(b.deserializeJSONBlob(e))}static generateJsonCache(e){return O.serializeAllCache(e)}updateCredentialCacheKey(e,t){const r=t.generateCredentialKey();if(e!==r){const n=this.getItem(e);if(n)return this.removeItem(e),this.setItem(r,n),this.logger.verbose(`Updated an outdated ${t.credentialType} cache key`),r;this.logger.error(`Attempted to update an outdated ${t.credentialType} cache key but no item matching the outdated key was found in storage`)}return e}}const P={},N={},q={},U={},x={};class z{constructor(e,t,r){this.cacheHasChanged=!1,this.storage=e,this.storage.registerChangeEmitter(this.handleChangeEvent.bind(this)),r&&(this.persistence=r),this.logger=t}hasChanged(){return this.cacheHasChanged}serialize(){this.logger.trace("Serializing in-memory cache");let e=O.serializeAllCache(this.storage.getInMemoryCache());return i.StringUtils.isEmpty(this.cacheSnapshot)?this.logger.trace("No cache snapshot to merge"):(this.logger.trace("Reading cache snapshot from disk"),e=this.mergeState(JSON.parse(this.cacheSnapshot),e)),this.cacheHasChanged=!1,JSON.stringify(e)}deserialize(e){if(this.logger.trace("Deserializing JSON to in-memory cache"),this.cacheSnapshot=e,i.StringUtils.isEmpty(this.cacheSnapshot))this.logger.trace("No cache snapshot to deserialize");else{this.logger.trace("Reading cache snapshot from disk");const e=b.deserializeAllCache(this.overlayDefaults(JSON.parse(this.cacheSnapshot)));this.storage.setInMemoryCache(e)}}getKVStore(){return this.storage.getCache()}async getAllAccounts(){let e;this.logger.trace("getAllAccounts called");try{return this.persistence&&(e=new i.TokenCacheContext(this,!1),await this.persistence.beforeCacheAccess(e)),this.storage.getAllAccounts()}finally{this.persistence&&e&&await this.persistence.afterCacheAccess(e)}}async getAccountByHomeId(e){const t=await this.getAllAccounts();return!i.StringUtils.isEmpty(e)&&t&&t.length&&t.filter(t=>t.homeAccountId===e)[0]||null}async getAccountByLocalId(e){const t=await this.getAllAccounts();return!i.StringUtils.isEmpty(e)&&t&&t.length&&t.filter(t=>t.localAccountId===e)[0]||null}async removeAccount(e){let t;this.logger.trace("removeAccount called");try{this.persistence&&(t=new i.TokenCacheContext(this,!0),await this.persistence.beforeCacheAccess(t)),await this.storage.removeAccount(i.AccountEntity.generateAccountCacheKey(e))}finally{this.persistence&&t&&await this.persistence.afterCacheAccess(t)}}handleChangeEvent(){this.cacheHasChanged=!0}mergeState(e,t){this.logger.trace("Merging in-memory cache with cache snapshot");const r=this.mergeRemovals(e,t);return this.mergeUpdates(r,t)}mergeUpdates(e,t){return Object.keys(t).forEach(r=>{const n=t[r];if(e.hasOwnProperty(r)){const t=null!==n,i="object"==typeof n,o=!Array.isArray(n),s=null!=e[r];t&&i&&o&&s?this.mergeUpdates(e[r],n):e[r]=n}else null!==n&&(e[r]=n)}),e}mergeRemovals(e,t){this.logger.trace("Remove updated entries in cache");const r=e.Account?this.mergeRemovalsDict(e.Account,t.Account):e.Account,n=e.AccessToken?this.mergeRemovalsDict(e.AccessToken,t.AccessToken):e.AccessToken,i=e.RefreshToken?this.mergeRemovalsDict(e.RefreshToken,t.RefreshToken):e.RefreshToken,o=e.IdToken?this.mergeRemovalsDict(e.IdToken,t.IdToken):e.IdToken,s=e.AppMetadata?this.mergeRemovalsDict(e.AppMetadata,t.AppMetadata):e.AppMetadata;return{...e,Account:r,AccessToken:n,RefreshToken:i,IdToken:o,AppMetadata:s}}mergeRemovalsDict(e,t){const r={...e};return Object.keys(e).forEach(e=>{t&&t.hasOwnProperty(e)||delete r[e]}),r}overlayDefaults(e){return this.logger.trace("Overlaying input cache with the default cache"),{Account:{...P,...e.Account},IdToken:{...N,...e.IdToken},AccessToken:{...q,...e.AccessToken},RefreshToken:{...U,...e.RefreshToken},AppMetadata:{...x,...e.AppMetadata}}}}class B extends i.AuthError{constructor(e,t){super(e,t),this.name="NodeAuthError"}static createInvalidLoopbackAddressTypeError(){return new B("invalid_loopback_server_address_type","Loopback server address is not type string. This is unexpected.")}static createUnableToLoadRedirectUrlError(){return new B("unable_to_load_redirectUrl","Loopback server callback was invoked without a url. This is unexpected.")}static createNoAuthCodeInResponseError(){return new B("no_auth_code_in_response","No auth code found in the server response. Please check your network trace to determine what happened.")}static createNoLoopbackServerExistsError(){return new B("no_loopback_server_exists","No loopback server exists yet.")}static createLoopbackServerAlreadyExistsError(){return new B("loopback_server_already_exists","Loopback server already exists. Cannot create another.")}static createLoopbackServerTimeoutError(){return new B("loopback_server_timeout","Timed out waiting for auth code listener to be registered.")}static createStateNotFoundError(){return new B("state_not_found","State not found. Please verify that the request originated from msal.")}}class G{constructor(e){this.config=R(e),this.cryptoProvider=new _,this.logger=new i.Logger(this.config.system.loggerOptions,"@azure/msal-node","1.18.1"),this.storage=new M(this.logger,this.config.auth.clientId,this.cryptoProvider),this.tokenCache=new z(this.storage,this.logger,this.config.cache.cachePlugin)}async getAuthCodeUrl(e){this.logger.info("getAuthCodeUrl called",e.correlationId);const t={...e,...await this.initializeBaseRequest(e),responseMode:e.responseMode||i.ResponseMode.QUERY,authenticationScheme:i.AuthenticationScheme.BEARER},r=await this.buildOauthClientConfiguration(t.authority,t.correlationId,void 0,void 0,e.azureCloudOptions),n=new i.AuthorizationCodeClient(r);return this.logger.verbose("Auth code client created",t.correlationId),n.getAuthCodeUrl(t)}async acquireTokenByCode(e,t){this.logger.info("acquireTokenByCode called"),e.state&&t&&(this.logger.info("acquireTokenByCode - validating state"),this.validateState(e.state,t.state||""),t={...t,state:""});const r={...e,...await this.initializeBaseRequest(e),authenticationScheme:i.AuthenticationScheme.BEARER},n=this.initializeServerTelemetryManager(d.acquireTokenByCode,r.correlationId);try{const o=await this.buildOauthClientConfiguration(r.authority,r.correlationId,n,void 0,e.azureCloudOptions),s=new i.AuthorizationCodeClient(o);return this.logger.verbose("Auth code client created",r.correlationId),s.acquireToken(r,t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(r.correlationId),n.cacheFailedRequest(e),e}}async acquireTokenByRefreshToken(e){this.logger.info("acquireTokenByRefreshToken called",e.correlationId);const t={...e,...await this.initializeBaseRequest(e),authenticationScheme:i.AuthenticationScheme.BEARER},r=this.initializeServerTelemetryManager(d.acquireTokenByRefreshToken,t.correlationId);try{const n=await this.buildOauthClientConfiguration(t.authority,t.correlationId,r,void 0,e.azureCloudOptions),o=new i.RefreshTokenClient(n);return this.logger.verbose("Refresh token client created",t.correlationId),o.acquireToken(t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(t.correlationId),r.cacheFailedRequest(e),e}}async acquireTokenSilent(e){const t={...e,...await this.initializeBaseRequest(e),forceRefresh:e.forceRefresh||!1},r=this.initializeServerTelemetryManager(d.acquireTokenSilent,t.correlationId,t.forceRefresh);try{const n=await this.buildOauthClientConfiguration(t.authority,t.correlationId,r,void 0,e.azureCloudOptions),o=new i.SilentFlowClient(n);return this.logger.verbose("Silent flow client created",t.correlationId),o.acquireToken(t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(t.correlationId),r.cacheFailedRequest(e),e}}async acquireTokenByUsernamePassword(e){this.logger.info("acquireTokenByUsernamePassword called",e.correlationId);const t={...e,...await this.initializeBaseRequest(e)},r=this.initializeServerTelemetryManager(d.acquireTokenByUsernamePassword,t.correlationId);try{const n=await this.buildOauthClientConfiguration(t.authority,t.correlationId,r,void 0,e.azureCloudOptions),o=new i.UsernamePasswordClient(n);return this.logger.verbose("Username password client created",t.correlationId),o.acquireToken(t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(t.correlationId),r.cacheFailedRequest(e),e}}getTokenCache(){return this.logger.info("getTokenCache called"),this.tokenCache}validateState(e,t){if(!e)throw B.createStateNotFoundError();if(e!==t)throw i.ClientAuthError.createStateMismatchError()}getLogger(){return this.logger}setLogger(e){this.logger=e}async buildOauthClientConfiguration(e,t,r,n,o){this.logger.verbose("buildOauthClientConfiguration called",t);const s=o||this.config.auth.azureCloudOptions;this.logger.verbose("building oauth client configuration with the authority: "+e,t);const a=await this.createAuthority(e,n,t,s);return null==r||r.updateRegionDiscoveryMetadata(a.regionDiscoveryMetadata),{authOptions:{clientId:this.config.auth.clientId,authority:a,clientCapabilities:this.config.auth.clientCapabilities},loggerOptions:{logLevel:this.config.system.loggerOptions.logLevel,loggerCallback:this.config.system.loggerOptions.loggerCallback,piiLoggingEnabled:this.config.system.loggerOptions.piiLoggingEnabled,correlationId:t},cacheOptions:{claimsBasedCachingEnabled:this.config.cache.claimsBasedCachingEnabled},cryptoInterface:this.cryptoProvider,networkInterface:this.config.system.networkClient,storageInterface:this.storage,serverTelemetryManager:r,clientCredentials:{clientSecret:this.clientSecret,clientAssertion:this.clientAssertion?this.getClientAssertion(a):void 0},libraryInfo:{sku:"msal.js.node",version:"1.18.1",cpu:process.arch||i.Constants.EMPTY_STRING,os:process.platform||i.Constants.EMPTY_STRING},telemetry:this.config.telemetry,persistencePlugin:this.config.cache.cachePlugin,serializableCache:this.tokenCache}}getClientAssertion(e){return{assertion:this.clientAssertion.getJwt(this.cryptoProvider,this.config.auth.clientId,e.tokenEndpoint),assertionType:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"}}async initializeBaseRequest(e){return this.logger.verbose("initializeRequestScopes called",e.correlationId),e.authenticationScheme&&e.authenticationScheme===i.AuthenticationScheme.POP&&this.logger.verbose("Authentication Scheme 'pop' is not supported yet, setting Authentication Scheme to 'Bearer' for request",e.correlationId),e.authenticationScheme=i.AuthenticationScheme.BEARER,this.config.cache.claimsBasedCachingEnabled&&e.claims&&!i.StringUtils.isEmptyObj(e.claims)&&(e.requestedClaimsHash=await this.cryptoProvider.hashString(e.claims)),{...e,scopes:[...e&&e.scopes||[],...i.OIDC_DEFAULT_SCOPES],correlationId:e&&e.correlationId||this.cryptoProvider.createNewGuid(),authority:e.authority||this.config.auth.authority}}initializeServerTelemetryManager(e,t,r){return new i.ServerTelemetryManager({clientId:this.config.auth.clientId,correlationId:t,apiId:e,forceRefresh:r||!1},this.storage)}async createAuthority(e,t,r,n){this.logger.verbose("createAuthority called",r);const o=i.Authority.generateAuthority(e,n),s={protocolMode:this.config.auth.protocolMode,knownAuthorities:this.config.auth.knownAuthorities,cloudDiscoveryMetadata:this.config.auth.cloudDiscoveryMetadata,authorityMetadata:this.config.auth.authorityMetadata,azureRegionConfiguration:t,skipAuthorityMetadataCache:this.config.auth.skipAuthorityMetadataCache};return await i.AuthorityFactory.createDiscoveredInstance(o,this.config.system.networkClient,this.storage,s,this.logger)}clearCache(){this.storage.clear()}}class j{async listenForAuthCode(e,t){if(this.server)throw B.createLoopbackServerAlreadyExistsError();const n=new Promise((n,s)=>{this.server=o.createServer(async(o,a)=>{const c=o.url;if(!c)return a.end(t||"Error occurred loading redirectUrl"),void s(B.createUnableToLoadRedirectUrlError());if(c===i.Constants.FORWARD_SLASH)return void a.end(e||"Auth code was successfully acquired. You can close this window now.");const l=i.UrlString.getDeserializedQueryString(c);if(l.code){const e=await this.getRedirectUri();a.writeHead(r.REDIRECT,{location:e}),a.end()}n(l)}),this.server.listen(0)});return await new Promise(e=>{let t=0;const r=setInterval(()=>{if(50!i.OIDC_DEFAULT_SCOPES.includes(e))},o={...e,...n,clientAssertion:t},s={azureRegion:o.azureRegion,environmentRegion:process.env.REGION_NAME},a=this.initializeServerTelemetryManager(d.acquireTokenByClientCredential,o.correlationId,o.skipCache);try{const t=await this.buildOauthClientConfiguration(o.authority,o.correlationId,a,s,e.azureCloudOptions),r=new i.ClientCredentialClient(t,this.appTokenProvider);return this.logger.verbose("Client credential client created",o.correlationId),r.acquireToken(o)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(o.correlationId),a.cacheFailedRequest(e),e}}async acquireTokenOnBehalfOf(e){this.logger.info("acquireTokenOnBehalfOf called",e.correlationId);const t={...e,...await this.initializeBaseRequest(e)};try{const r=await this.buildOauthClientConfiguration(t.authority,t.correlationId,void 0,void 0,e.azureCloudOptions),n=new i.OnBehalfOfClient(r);return this.logger.verbose("On behalf of client created",t.correlationId),n.acquireToken(t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(t.correlationId),e}}setClientCredential(e){const t=!i.StringUtils.isEmpty(e.auth.clientSecret),r=!i.StringUtils.isEmpty(e.auth.clientAssertion),n=e.auth.clientCertificate||{thumbprint:i.Constants.EMPTY_STRING,privateKey:i.Constants.EMPTY_STRING},o=!i.StringUtils.isEmpty(n.thumbprint)||!i.StringUtils.isEmpty(n.privateKey);if(!this.appTokenProvider){if(t&&r||r&&o||t&&o)throw i.ClientAuthError.createInvalidCredentialError();if(e.auth.clientSecret)this.clientSecret=e.auth.clientSecret;else if(e.auth.clientAssertion)this.clientAssertion=D.fromAssertion(e.auth.clientAssertion);else{if(!o)throw i.ClientAuthError.createInvalidCredentialError();var s;this.clientAssertion=D.fromCertificate(n.thumbprint,n.privateKey,null==(s=e.auth.clientCertificate)?void 0:s.x5c)}}}},exports.CryptoProvider=_,exports.DistributedCachePlugin=class{constructor(e,t){this.client=e,this.partitionManager=t}async beforeCacheAccess(e){const t=await this.partitionManager.getKey(),r=await this.client.get(t);e.tokenCache.deserialize(r)}async afterCacheAccess(e){if(e.cacheHasChanged){const t=e.tokenCache.getKVStore(),r=Object.values(t).filter(e=>i.AccountEntity.isAccountEntity(e));if(r.length>0){const t=r[0],n=await this.partitionManager.extractKey(t);await this.client.set(n,e.tokenCache.serialize())}}}},exports.NodeStorage=M,exports.PublicClientApplication=class extends G{constructor(e){super(e),this.config.broker.nativeBrokerPlugin&&(this.config.broker.nativeBrokerPlugin.isBrokerAvailable?(this.nativeBrokerPlugin=this.config.broker.nativeBrokerPlugin,this.nativeBrokerPlugin.setLogger(this.config.system.loggerOptions)):this.logger.warning("NativeBroker implementation was provided but the broker is unavailable."))}async acquireTokenByDeviceCode(e){this.logger.info("acquireTokenByDeviceCode called",e.correlationId);const t=Object.assign(e,await this.initializeBaseRequest(e)),r=this.initializeServerTelemetryManager(d.acquireTokenByDeviceCode,t.correlationId);try{const n=await this.buildOauthClientConfiguration(t.authority,t.correlationId,r,void 0,e.azureCloudOptions),o=new i.DeviceCodeClient(n);return this.logger.verbose("Device code client created",t.correlationId),o.acquireToken(t)}catch(e){throw e instanceof i.AuthError&&e.setCorrelationId(t.correlationId),r.cacheFailedRequest(e),e}}async acquireTokenInteractive(e){const t=e.correlationId||this.cryptoProvider.createNewGuid();this.logger.trace("acquireTokenInteractive called",t);const{openBrowser:r,successTemplate:n,errorTemplate:o,windowHandle:s,loopbackClient:a,...c}=e;if(this.nativeBrokerPlugin){var l;const r={...c,clientId:this.config.auth.clientId,scopes:e.scopes||i.OIDC_DEFAULT_SCOPES,redirectUri:"http://localhost",authority:e.authority||this.config.auth.authority,correlationId:t,extraParameters:{...c.extraQueryParameters,...c.tokenQueryParameters},accountId:null==(l=c.account)?void 0:l.nativeAccountId};return this.nativeBrokerPlugin.acquireTokenInteractive(r,s)}const{verifier:h,challenge:u}=await this.cryptoProvider.generatePkceCodes(),d=a||new j,g=d.listenForAuthCode(n,o),p=d.getRedirectUri(),y={...c,correlationId:t,scopes:e.scopes||i.OIDC_DEFAULT_SCOPES,redirectUri:p,responseMode:i.ResponseMode.QUERY,codeChallenge:u,codeChallengeMethod:i.CodeChallengeMethodValues.S256},m=await this.getAuthCodeUrl(y);await r(m);const C=await g.finally(()=>{d.closeServer()});if(C.error)throw new i.ServerError(C.error,C.error_description,C.suberror);if(!C.code)throw B.createNoAuthCodeInResponseError();const f={code:C.code,codeVerifier:h,clientInfo:C.client_info||i.Constants.EMPTY_STRING,...y};return this.acquireTokenByCode(f)}async acquireTokenSilent(e){const t=e.correlationId||this.cryptoProvider.createNewGuid();if(this.logger.trace("acquireTokenSilent called",t),this.nativeBrokerPlugin){const r={...e,clientId:this.config.auth.clientId,scopes:e.scopes||i.OIDC_DEFAULT_SCOPES,redirectUri:"http://localhost",authority:e.authority||this.config.auth.authority,correlationId:t,extraParameters:e.tokenQueryParameters,accountId:e.account.nativeAccountId,forceRefresh:e.forceRefresh||!1};return this.nativeBrokerPlugin.acquireTokenSilent(r)}return super.acquireTokenSilent(e)}async signOut(e){if(this.nativeBrokerPlugin&&e.account.nativeAccountId){const t={clientId:this.config.auth.clientId,accountId:e.account.nativeAccountId,correlationId:e.correlationId||this.cryptoProvider.createNewGuid()};await this.nativeBrokerPlugin.signOut(t)}await this.getTokenCache().removeAccount(e.account)}async getAllAccounts(){if(this.nativeBrokerPlugin){const e=this.cryptoProvider.createNewGuid();return this.nativeBrokerPlugin.getAllAccounts(this.config.auth.clientId,e)}return this.getTokenCache().getAllAccounts()}},exports.TokenCache=z,exports.buildAppConfiguration=R,exports.version="1.18.1";
+//# sourceMappingURL=msal-node.cjs.production.min.js.map
+
+
+/***/ }),
+
+/***/ 1040:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+function once(emitter, name, { signal } = {}) {
+ return new Promise((resolve, reject) => {
+ function cleanup() {
+ signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', cleanup);
+ emitter.removeListener(name, onEvent);
+ emitter.removeListener('error', onError);
+ }
+ function onEvent(...args) {
+ cleanup();
+ resolve(args);
+ }
+ function onError(err) {
+ cleanup();
+ reject(err);
+ }
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', cleanup);
+ emitter.on(name, onEvent);
+ emitter.on('error', onError);
+ });
+}
+exports["default"] = once;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 9690:
+/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+const events_1 = __nccwpck_require__(2361);
+const debug_1 = __importDefault(__nccwpck_require__(8237));
+const promisify_1 = __importDefault(__nccwpck_require__(6570));
+const debug = debug_1.default('agent-base');
+function isAgent(v) {
+ return Boolean(v) && typeof v.addRequest === 'function';
+}
+function isSecureEndpoint() {
+ const { stack } = new Error();
+ if (typeof stack !== 'string')
+ return false;
+ return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1);
+}
+function createAgent(callback, opts) {
+ return new createAgent.Agent(callback, opts);
+}
+(function (createAgent) {
+ /**
+ * Base `http.Agent` implementation.
+ * No pooling/keep-alive is implemented by default.
+ *
+ * @param {Function} callback
+ * @api public
+ */
+ class Agent extends events_1.EventEmitter {
+ constructor(callback, _opts) {
+ super();
+ let opts = _opts;
+ if (typeof callback === 'function') {
+ this.callback = callback;
+ }
+ else if (callback) {
+ opts = callback;
+ }
+ // Timeout for the socket to be returned from the callback
+ this.timeout = null;
+ if (opts && typeof opts.timeout === 'number') {
+ this.timeout = opts.timeout;
+ }
+ // These aren't actually used by `agent-base`, but are required
+ // for the TypeScript definition files in `@types/node` :/
+ this.maxFreeSockets = 1;
+ this.maxSockets = 1;
+ this.maxTotalSockets = Infinity;
+ this.sockets = {};
+ this.freeSockets = {};
+ this.requests = {};
+ this.options = {};
+ }
+ get defaultPort() {
+ if (typeof this.explicitDefaultPort === 'number') {
+ return this.explicitDefaultPort;
+ }
+ return isSecureEndpoint() ? 443 : 80;
+ }
+ set defaultPort(v) {
+ this.explicitDefaultPort = v;
+ }
+ get protocol() {
+ if (typeof this.explicitProtocol === 'string') {
+ return this.explicitProtocol;
+ }
+ return isSecureEndpoint() ? 'https:' : 'http:';
+ }
+ set protocol(v) {
+ this.explicitProtocol = v;
+ }
+ callback(req, opts, fn) {
+ throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`');
+ }
+ /**
+ * Called by node-core's "_http_client.js" module when creating
+ * a new HTTP request with this Agent instance.
+ *
+ * @api public
+ */
+ addRequest(req, _opts) {
+ const opts = Object.assign({}, _opts);
+ if (typeof opts.secureEndpoint !== 'boolean') {
+ opts.secureEndpoint = isSecureEndpoint();
+ }
+ if (opts.host == null) {
+ opts.host = 'localhost';
+ }
+ if (opts.port == null) {
+ opts.port = opts.secureEndpoint ? 443 : 80;
+ }
+ if (opts.protocol == null) {
+ opts.protocol = opts.secureEndpoint ? 'https:' : 'http:';
+ }
+ if (opts.host && opts.path) {
+ // If both a `host` and `path` are specified then it's most
+ // likely the result of a `url.parse()` call... we need to
+ // remove the `path` portion so that `net.connect()` doesn't
+ // attempt to open that as a unix socket file.
+ delete opts.path;
+ }
+ delete opts.agent;
+ delete opts.hostname;
+ delete opts._defaultAgent;
+ delete opts.defaultPort;
+ delete opts.createConnection;
+ // Hint to use "Connection: close"
+ // XXX: non-documented `http` module API :(
+ req._last = true;
+ req.shouldKeepAlive = false;
+ let timedOut = false;
+ let timeoutId = null;
+ const timeoutMs = opts.timeout || this.timeout;
+ const onerror = (err) => {
+ if (req._hadError)
+ return;
+ req.emit('error', err);
+ // For Safety. Some additional errors might fire later on
+ // and we need to make sure we don't double-fire the error event.
+ req._hadError = true;
+ };
+ const ontimeout = () => {
+ timeoutId = null;
+ timedOut = true;
+ const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`);
+ err.code = 'ETIMEOUT';
+ onerror(err);
+ };
+ const callbackError = (err) => {
+ if (timedOut)
+ return;
+ if (timeoutId !== null) {
+ clearTimeout(timeoutId);
+ timeoutId = null;
+ }
+ onerror(err);
+ };
+ const onsocket = (socket) => {
+ if (timedOut)
+ return;
+ if (timeoutId != null) {
+ clearTimeout(timeoutId);
+ timeoutId = null;
+ }
+ if (isAgent(socket)) {
+ // `socket` is actually an `http.Agent` instance, so
+ // relinquish responsibility for this `req` to the Agent
+ // from here on
+ debug('Callback returned another Agent instance %o', socket.constructor.name);
+ socket.addRequest(req, opts);
+ return;
+ }
+ if (socket) {
+ socket.once('free', () => {
+ this.freeSocket(socket, opts);
+ });
+ req.onSocket(socket);
+ return;
+ }
+ const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``);
+ onerror(err);
+ };
+ if (typeof this.callback !== 'function') {
+ onerror(new Error('`callback` is not defined'));
+ return;
+ }
+ if (!this.promisifiedCallback) {
+ if (this.callback.length >= 3) {
+ debug('Converting legacy callback function to promise');
+ this.promisifiedCallback = promisify_1.default(this.callback);
+ }
+ else {
+ this.promisifiedCallback = this.callback;
+ }
+ }
+ if (typeof timeoutMs === 'number' && timeoutMs > 0) {
+ timeoutId = setTimeout(ontimeout, timeoutMs);
+ }
+ if ('port' in opts && typeof opts.port !== 'number') {
+ opts.port = Number(opts.port);
+ }
+ try {
+ debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`);
+ Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError);
+ }
+ catch (err) {
+ Promise.reject(err).catch(callbackError);
+ }
+ }
+ freeSocket(socket, opts) {
+ debug('Freeing socket %o %o', socket.constructor.name, opts);
+ socket.destroy();
+ }
+ destroy() {
+ debug('Destroying agent %o', this.constructor.name);
+ }
+ }
+ createAgent.Agent = Agent;
+ // So that `instanceof` works correctly
+ createAgent.prototype = createAgent.Agent.prototype;
+})(createAgent || (createAgent = {}));
+module.exports = createAgent;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 6570:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+function promisify(fn) {
+ return function (req, opts) {
+ return new Promise((resolve, reject) => {
+ fn.call(this, req, opts, (err, rtn) => {
+ if (err) {
+ reject(err);
+ }
+ else {
+ resolve(rtn);
+ }
+ });
+ });
+ };
+}
+exports["default"] = promisify;
+//# sourceMappingURL=promisify.js.map
+
+/***/ }),
+
+/***/ 4812:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+module.exports =
+{
+ parallel : __nccwpck_require__(8210),
+ serial : __nccwpck_require__(445),
+ serialOrdered : __nccwpck_require__(3578)
+};
+
+
+/***/ }),
+
+/***/ 1700:
+/***/ ((module) => {
+
+// API
+module.exports = abort;
+
+/**
+ * Aborts leftover active jobs
+ *
+ * @param {object} state - current state object
+ */
+function abort(state)
+{
+ Object.keys(state.jobs).forEach(clean.bind(state));
+
+ // reset leftover jobs
+ state.jobs = {};
+}
+
+/**
+ * Cleans up leftover job by invoking abort function for the provided job id
+ *
+ * @this state
+ * @param {string|number} key - job id to abort
+ */
+function clean(key)
+{
+ if (typeof this.jobs[key] == 'function')
+ {
+ this.jobs[key]();
+ }
+}
+
+
+/***/ }),
+
+/***/ 2794:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var defer = __nccwpck_require__(5295);
+
+// API
+module.exports = async;
+
+/**
+ * Runs provided callback asynchronously
+ * even if callback itself is not
+ *
+ * @param {function} callback - callback to invoke
+ * @returns {function} - augmented callback
+ */
+function async(callback)
+{
+ var isAsync = false;
+
+ // check if async happened
+ defer(function() { isAsync = true; });
+
+ return function async_callback(err, result)
+ {
+ if (isAsync)
+ {
+ callback(err, result);
+ }
+ else
+ {
+ defer(function nextTick_callback()
+ {
+ callback(err, result);
+ });
+ }
+ };
+}
+
+
+/***/ }),
+
+/***/ 5295:
+/***/ ((module) => {
+
+module.exports = defer;
+
+/**
+ * Runs provided function on next iteration of the event loop
+ *
+ * @param {function} fn - function to run
+ */
+function defer(fn)
+{
+ var nextTick = typeof setImmediate == 'function'
+ ? setImmediate
+ : (
+ typeof process == 'object' && typeof process.nextTick == 'function'
+ ? process.nextTick
+ : null
+ );
+
+ if (nextTick)
+ {
+ nextTick(fn);
+ }
+ else
+ {
+ setTimeout(fn, 0);
+ }
+}
+
+
+/***/ }),
+
+/***/ 9023:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var async = __nccwpck_require__(2794)
+ , abort = __nccwpck_require__(1700)
+ ;
+
+// API
+module.exports = iterate;
+
+/**
+ * Iterates over each job object
+ *
+ * @param {array|object} list - array or object (named list) to iterate over
+ * @param {function} iterator - iterator to run
+ * @param {object} state - current job status
+ * @param {function} callback - invoked when all elements processed
+ */
+function iterate(list, iterator, state, callback)
+{
+ // store current index
+ var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;
+
+ state.jobs[key] = runJob(iterator, key, list[key], function(error, output)
+ {
+ // don't repeat yourself
+ // skip secondary callbacks
+ if (!(key in state.jobs))
+ {
+ return;
+ }
+
+ // clean up jobs
+ delete state.jobs[key];
+
+ if (error)
+ {
+ // don't process rest of the results
+ // stop still active jobs
+ // and reset the list
+ abort(state);
+ }
+ else
+ {
+ state.results[key] = output;
+ }
+
+ // return salvaged results
+ callback(error, state.results);
+ });
+}
+
+/**
+ * Runs iterator over provided job element
+ *
+ * @param {function} iterator - iterator to invoke
+ * @param {string|number} key - key/index of the element in the list of jobs
+ * @param {mixed} item - job description
+ * @param {function} callback - invoked after iterator is done with the job
+ * @returns {function|mixed} - job abort function or something else
+ */
+function runJob(iterator, key, item, callback)
+{
+ var aborter;
+
+ // allow shortcut if iterator expects only two arguments
+ if (iterator.length == 2)
+ {
+ aborter = iterator(item, async(callback));
+ }
+ // otherwise go with full three arguments
+ else
+ {
+ aborter = iterator(item, key, async(callback));
+ }
+
+ return aborter;
+}
+
+
+/***/ }),
+
+/***/ 2474:
+/***/ ((module) => {
+
+// API
+module.exports = state;
+
+/**
+ * Creates initial state object
+ * for iteration over list
+ *
+ * @param {array|object} list - list to iterate over
+ * @param {function|null} sortMethod - function to use for keys sort,
+ * or `null` to keep them as is
+ * @returns {object} - initial state object
+ */
+function state(list, sortMethod)
+{
+ var isNamedList = !Array.isArray(list)
+ , initState =
+ {
+ index : 0,
+ keyedList: isNamedList || sortMethod ? Object.keys(list) : null,
+ jobs : {},
+ results : isNamedList ? {} : [],
+ size : isNamedList ? Object.keys(list).length : list.length
+ }
+ ;
+
+ if (sortMethod)
+ {
+ // sort array keys based on it's values
+ // sort object's keys just on own merit
+ initState.keyedList.sort(isNamedList ? sortMethod : function(a, b)
+ {
+ return sortMethod(list[a], list[b]);
+ });
+ }
+
+ return initState;
+}
+
+
+/***/ }),
+
+/***/ 7942:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var abort = __nccwpck_require__(1700)
+ , async = __nccwpck_require__(2794)
+ ;
+
+// API
+module.exports = terminator;
+
+/**
+ * Terminates jobs in the attached state context
+ *
+ * @this AsyncKitState#
+ * @param {function} callback - final callback to invoke after termination
+ */
+function terminator(callback)
+{
+ if (!Object.keys(this.jobs).length)
+ {
+ return;
+ }
+
+ // fast forward iteration index
+ this.index = this.size;
+
+ // abort jobs
+ abort(this);
+
+ // send back results we have so far
+ async(callback)(null, this.results);
+}
+
+
+/***/ }),
+
+/***/ 8210:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var iterate = __nccwpck_require__(9023)
+ , initState = __nccwpck_require__(2474)
+ , terminator = __nccwpck_require__(7942)
+ ;
+
+// Public API
+module.exports = parallel;
+
+/**
+ * Runs iterator over provided array elements in parallel
+ *
+ * @param {array|object} list - array or object (named list) to iterate over
+ * @param {function} iterator - iterator to run
+ * @param {function} callback - invoked when all elements processed
+ * @returns {function} - jobs terminator
+ */
+function parallel(list, iterator, callback)
+{
+ var state = initState(list);
+
+ while (state.index < (state['keyedList'] || list).length)
+ {
+ iterate(list, iterator, state, function(error, result)
+ {
+ if (error)
+ {
+ callback(error, result);
+ return;
+ }
+
+ // looks like it's the last one
+ if (Object.keys(state.jobs).length === 0)
+ {
+ callback(null, state.results);
+ return;
+ }
+ });
+
+ state.index++;
+ }
+
+ return terminator.bind(state, callback);
+}
+
+
+/***/ }),
+
+/***/ 445:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var serialOrdered = __nccwpck_require__(3578);
+
+// Public API
+module.exports = serial;
+
+/**
+ * Runs iterator over provided array elements in series
+ *
+ * @param {array|object} list - array or object (named list) to iterate over
+ * @param {function} iterator - iterator to run
+ * @param {function} callback - invoked when all elements processed
+ * @returns {function} - jobs terminator
+ */
+function serial(list, iterator, callback)
+{
+ return serialOrdered(list, iterator, null, callback);
+}
+
+
+/***/ }),
+
+/***/ 3578:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var iterate = __nccwpck_require__(9023)
+ , initState = __nccwpck_require__(2474)
+ , terminator = __nccwpck_require__(7942)
+ ;
+
+// Public API
+module.exports = serialOrdered;
+// sorting helpers
+module.exports.ascending = ascending;
+module.exports.descending = descending;
+
+/**
+ * Runs iterator over provided sorted array elements in series
+ *
+ * @param {array|object} list - array or object (named list) to iterate over
+ * @param {function} iterator - iterator to run
+ * @param {function} sortMethod - custom sort function
+ * @param {function} callback - invoked when all elements processed
+ * @returns {function} - jobs terminator
+ */
+function serialOrdered(list, iterator, sortMethod, callback)
+{
+ var state = initState(list, sortMethod);
+
+ iterate(list, iterator, state, function iteratorHandler(error, result)
+ {
+ if (error)
+ {
+ callback(error, result);
+ return;
+ }
+
+ state.index++;
+
+ // are we there yet?
+ if (state.index < (state['keyedList'] || list).length)
+ {
+ iterate(list, iterator, state, iteratorHandler);
+ return;
+ }
+
+ // done here
+ callback(null, state.results);
+ });
+
+ return terminator.bind(state, callback);
+}
+
+/*
+ * -- Sort methods
+ */
+
+/**
+ * sort helper to sort array elements in ascending order
+ *
+ * @param {mixed} a - an item to compare
+ * @param {mixed} b - an item to compare
+ * @returns {number} - comparison result
+ */
+function ascending(a, b)
+{
+ return a < b ? -1 : a > b ? 1 : 0;
+}
+
+/**
+ * sort helper to sort array elements in descending order
+ *
+ * @param {mixed} a - an item to compare
+ * @param {mixed} b - an item to compare
+ * @returns {number} - comparison result
+ */
+function descending(a, b)
+{
+ return -1 * ascending(a, b);
+}
+
+
+/***/ }),
+
+/***/ 837:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+__exportStar(__nccwpck_require__(6837), exports);
+__exportStar(__nccwpck_require__(9300), exports);
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 6837:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.Bicep = void 0;
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+const os_1 = __importDefault(__nccwpck_require__(2037));
+const install_1 = __nccwpck_require__(1599);
+const jsonrpc_1 = __nccwpck_require__(7957);
+/**
+ * Helper class to install and interact with the Bicep CLI.
+ */
+class Bicep {
+ constructor(connection) {
+ this.connection = connection;
+ }
+ /**
+ * Initializes the Bicep library with a connection to the Bicep CLI.
+ *
+ * @param bicepPath The path to the Bicep CLI. You can point this to an existing install, or use `Bicep.install()` to obtain this path.
+ * @returns A `Bicep` instance.
+ */
+ static async initialize(bicepPath) {
+ const connection = await (0, jsonrpc_1.openConnection)(bicepPath);
+ return new Bicep(connection);
+ }
+ /**
+ * Returns the Bicep CLI download URL.
+ *
+ * @param version The version of the Bicep CLI to download. Defaults to the latest version.
+ * @param platform The platform to download for. Defaults to `os.platform()`.
+ * @param arch The architecture to download for. Defaults to `os.arch()`.
+ * @returns The download URL.
+ */
+ static async getDownloadUrl(version, platform, arch) {
+ platform !== null && platform !== void 0 ? platform : (platform = os_1.default.platform());
+ arch !== null && arch !== void 0 ? arch : (arch = os_1.default.arch());
+ return await (0, install_1.getBicepCliDownloadUrl)(platform, arch, version);
+ }
+ /**
+ * Downloads the Bicep CLI to the specified path.
+ *
+ * @param basePath The file system path to download the Bicep CLI to. This path must already exist.
+ * @param version The version of the Bicep CLI to download. Defaults to the latest version.
+ * @param platform The platform to download for. Defaults to `os.platform()`.
+ * @param arch The architecture to download for. Defaults to `os.arch()`.
+ * @returns The path to the Bicep CLI.
+ */
+ static async install(basePath, version, platform, arch) {
+ platform !== null && platform !== void 0 ? platform : (platform = os_1.default.platform());
+ arch !== null && arch !== void 0 ? arch : (arch = os_1.default.arch());
+ return await (0, install_1.installBicepCliWithArch)(basePath, platform, arch, version);
+ }
+ /**
+ * Compiles a Bicep file.
+ *
+ * @param request The compilation request.
+ * @returns The compilation response.
+ */
+ async compile(request) {
+ return await this.connection.sendRequest(jsonrpc_1.compileRequestType, request);
+ }
+ /**
+ * Validates a Bicep file against Azure.
+ *
+ * @param request The validate request.
+ * @returns The validate response.
+ */
+ async validate(request) {
+ return await this.connection.sendRequest(jsonrpc_1.validateRequestType, request);
+ }
+ /**
+ * Disposes of the connection to the Bicep CLI. This MUST be called after usage to avoid leaving the process running.
+ */
+ dispose() {
+ this.connection.dispose();
+ }
+}
+exports.Bicep = Bicep;
+//# sourceMappingURL=bicep.js.map
+
+/***/ }),
+
+/***/ 1599:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.installBicepCliWithArch = exports.getBicepCliDownloadUrl = void 0;
+const path_1 = __importDefault(__nccwpck_require__(1017));
+const promises_1 = __importDefault(__nccwpck_require__(3292));
+const node_fetch_1 = __importDefault(__nccwpck_require__(467));
+const downloadBaseUrl = 'https://downloads.bicep.azure.com';
+const latestReleaseUrl = `${downloadBaseUrl}/releases/latest`;
+const downloadUrl = (tag, artifact) => `${downloadBaseUrl}/${tag}/${artifact}`;
+async function getLatestRelease() {
+ const response = await (0, node_fetch_1.default)(latestReleaseUrl);
+ if (!response.ok) {
+ throw `Failed to find latest release of Bicep CLI. Status code: ${response.status}`;
+ }
+ const body = await response.json();
+ return body['tag_name'];
+}
+function getDownloadUrlForTag(osPlat, osArch, tagName) {
+ switch (`${osPlat}_${osArch}`.toLowerCase()) {
+ case 'win32_x64': return downloadUrl(tagName, 'bicep-win-x64.exe');
+ case 'win32_arm64': return downloadUrl(tagName, 'bicep-win-arm64.exe');
+ case 'linux_x64': return downloadUrl(tagName, 'bicep-linux-x64');
+ case 'linux_arm64': return downloadUrl(tagName, 'bicep-linux-arm64');
+ case 'darwin_x64': return downloadUrl(tagName, 'bicep-osx-x64');
+ case 'darwin_arm64': return downloadUrl(tagName, 'bicep-osx-arm64');
+ default: throw `Bicep CLI is not available for platform ${osPlat} and architecture ${osArch}`;
+ }
+}
+async function getBicepCliDownloadUrl(platform, arch, version) {
+ const tagName = version ? `v${version}` : await getLatestRelease();
+ return getDownloadUrlForTag(platform, arch, tagName);
+}
+exports.getBicepCliDownloadUrl = getBicepCliDownloadUrl;
+async function installBicepCliWithArch(basePath, platform, arch, version) {
+ const targetFile = platform === 'win32' ? 'bicep.exe' : 'bicep';
+ const downloadUrl = await getBicepCliDownloadUrl(platform, arch, version);
+ const response = await (0, node_fetch_1.default)(downloadUrl);
+ if (!response.ok) {
+ throw `Failed to download Bicep CLI. Status code: ${response.status}`;
+ }
+ const buffer = await response.arrayBuffer();
+ const toolPath = path_1.default.join(basePath, targetFile);
+ await promises_1.default.writeFile(toolPath, Buffer.from(buffer));
+ await promises_1.default.chmod(toolPath, 0o755);
+ return toolPath;
+}
+exports.installBicepCliWithArch = installBicepCliWithArch;
+//# sourceMappingURL=install.js.map
+
+/***/ }),
+
+/***/ 7957:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.openConnection = exports.validateRequestType = exports.compileRequestType = void 0;
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+const path_1 = __importDefault(__nccwpck_require__(1017));
+const os_1 = __importDefault(__nccwpck_require__(2037));
+const child_process_1 = __nccwpck_require__(2081);
+const crypto_1 = __nccwpck_require__(6113);
+const net_1 = __nccwpck_require__(1808);
+const node_1 = __nccwpck_require__(9827);
+exports.compileRequestType = new node_1.RequestType("bicep/compile");
+exports.validateRequestType = new node_1.RequestType("bicep/validate");
+function tryGetVersionNumberError(bicepPath) {
+ const result = (0, child_process_1.spawnSync)(bicepPath, ["--version"], { encoding: "utf-8" });
+ if (result.status !== 0) {
+ return `Failed to obtain valid Bicep version from '${bicepPath} --version'`;
+ }
+ const versionMatch = result.stdout.match(/Bicep CLI version ([^ ]+) /);
+ if (!versionMatch) {
+ return `Failed to obtain valid Bicep version from '${bicepPath} --version'`;
+ }
+ const minimumVersion = '0.24.24';
+ const actualVersion = versionMatch[1];
+ const compareResult = actualVersion.localeCompare(minimumVersion, undefined, { numeric: true, sensitivity: 'base' });
+ if (compareResult < 0) {
+ return `A minimum Bicep version of ${minimumVersion} is required. Detected version ${actualVersion} from '${bicepPath} --version'`;
+ }
+ return;
+}
+function generateRandomPipeName() {
+ const randomSuffix = (0, crypto_1.randomBytes)(21).toString("hex");
+ if (process.platform === "win32") {
+ return `\\\\.\\pipe\\bicep-${randomSuffix}-sock`;
+ }
+ return path_1.default.join(os_1.default.tmpdir(), `bicep-${randomSuffix}.sock`);
+}
+function connectClientPipe(pipeName, process) {
+ return new Promise((resolve, reject) => {
+ const onProcessExit = () => {
+ server.close();
+ reject();
+ };
+ const server = (0, net_1.createServer)(socket => {
+ process.removeListener('exit', onProcessExit);
+ server.close();
+ resolve([
+ new node_1.SocketMessageReader(socket, 'utf-8'),
+ new node_1.SocketMessageWriter(socket, 'utf-8')
+ ]);
+ });
+ process.on('exit', onProcessExit);
+ server.on('error', reject);
+ server.listen(pipeName, () => server.removeListener('error', reject));
+ });
+}
+async function openConnection(bicepPath) {
+ const pipePath = generateRandomPipeName();
+ const process = (0, child_process_1.spawn)(bicepPath, ["jsonrpc", "--pipe", pipePath]);
+ let stderr = '';
+ process.stderr.on("data", (x) => stderr += x.toString());
+ const processExitedEarly = new Promise((_, reject) => process.on("exit", () => {
+ const error = tryGetVersionNumberError(bicepPath);
+ if (error) {
+ reject(error);
+ }
+ else {
+ reject(`Failed to invoke '${bicepPath} jsonrpc'. Error: ${stderr}`);
+ }
+ }));
+ const transportConnected = connectClientPipe(pipePath, process);
+ const result = await Promise.race([
+ transportConnected,
+ processExitedEarly,
+ ]);
+ const [reader, writer] = result;
+ const connection = (0, node_1.createMessageConnection)(reader, writer, console);
+ connection.onDispose(() => process.kill());
+ process.on("exit", () => connection.dispose());
+ connection.listen();
+ return connection;
+}
+exports.openConnection = openConnection;
+//# sourceMappingURL=jsonrpc.js.map
+
+/***/ }),
+
+/***/ 9300:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+//# sourceMappingURL=types.js.map
+
+/***/ }),
+
+/***/ 9239:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true */
+
+var Buffer = (__nccwpck_require__(4300).Buffer); // browserify
+var SlowBuffer = (__nccwpck_require__(4300).SlowBuffer);
+
+module.exports = bufferEq;
+
+function bufferEq(a, b) {
+
+ // shortcutting on type is necessary for correctness
+ if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+ return false;
+ }
+
+ // buffer sizes should be well-known information, so despite this
+ // shortcutting, it doesn't leak any information about the *contents* of the
+ // buffers.
+ if (a.length !== b.length) {
+ return false;
+ }
+
+ var c = 0;
+ for (var i = 0; i < a.length; i++) {
+ /*jshint bitwise:false */
+ c |= a[i] ^ b[i]; // XOR
+ }
+ return c === 0;
+}
+
+bufferEq.install = function() {
+ Buffer.prototype.equal = SlowBuffer.prototype.equal = function equal(that) {
+ return bufferEq(this, that);
+ };
+};
+
+var origBufEqual = Buffer.prototype.equal;
+var origSlowBufEqual = SlowBuffer.prototype.equal;
+bufferEq.restore = function() {
+ Buffer.prototype.equal = origBufEqual;
+ SlowBuffer.prototype.equal = origSlowBufEqual;
+};
+
+
+/***/ }),
+
+/***/ 5443:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var util = __nccwpck_require__(3837);
+var Stream = (__nccwpck_require__(2781).Stream);
+var DelayedStream = __nccwpck_require__(8611);
+
+module.exports = CombinedStream;
+function CombinedStream() {
+ this.writable = false;
+ this.readable = true;
+ this.dataSize = 0;
+ this.maxDataSize = 2 * 1024 * 1024;
+ this.pauseStreams = true;
+
+ this._released = false;
+ this._streams = [];
+ this._currentStream = null;
+ this._insideLoop = false;
+ this._pendingNext = false;
+}
+util.inherits(CombinedStream, Stream);
+
+CombinedStream.create = function(options) {
+ var combinedStream = new this();
+
+ options = options || {};
+ for (var option in options) {
+ combinedStream[option] = options[option];
+ }
+
+ return combinedStream;
+};
+
+CombinedStream.isStreamLike = function(stream) {
+ return (typeof stream !== 'function')
+ && (typeof stream !== 'string')
+ && (typeof stream !== 'boolean')
+ && (typeof stream !== 'number')
+ && (!Buffer.isBuffer(stream));
+};
+
+CombinedStream.prototype.append = function(stream) {
+ var isStreamLike = CombinedStream.isStreamLike(stream);
+
+ if (isStreamLike) {
+ if (!(stream instanceof DelayedStream)) {
+ var newStream = DelayedStream.create(stream, {
+ maxDataSize: Infinity,
+ pauseStream: this.pauseStreams,
+ });
+ stream.on('data', this._checkDataSize.bind(this));
+ stream = newStream;
+ }
+
+ this._handleErrors(stream);
+
+ if (this.pauseStreams) {
+ stream.pause();
+ }
+ }
+
+ this._streams.push(stream);
+ return this;
+};
+
+CombinedStream.prototype.pipe = function(dest, options) {
+ Stream.prototype.pipe.call(this, dest, options);
+ this.resume();
+ return dest;
+};
+
+CombinedStream.prototype._getNext = function() {
+ this._currentStream = null;
+
+ if (this._insideLoop) {
+ this._pendingNext = true;
+ return; // defer call
+ }
+
+ this._insideLoop = true;
+ try {
+ do {
+ this._pendingNext = false;
+ this._realGetNext();
+ } while (this._pendingNext);
+ } finally {
+ this._insideLoop = false;
+ }
+};
+
+CombinedStream.prototype._realGetNext = function() {
+ var stream = this._streams.shift();
+
+
+ if (typeof stream == 'undefined') {
+ this.end();
+ return;
+ }
+
+ if (typeof stream !== 'function') {
+ this._pipeNext(stream);
+ return;
+ }
+
+ var getStream = stream;
+ getStream(function(stream) {
+ var isStreamLike = CombinedStream.isStreamLike(stream);
+ if (isStreamLike) {
+ stream.on('data', this._checkDataSize.bind(this));
+ this._handleErrors(stream);
+ }
+
+ this._pipeNext(stream);
+ }.bind(this));
+};
+
+CombinedStream.prototype._pipeNext = function(stream) {
+ this._currentStream = stream;
+
+ var isStreamLike = CombinedStream.isStreamLike(stream);
+ if (isStreamLike) {
+ stream.on('end', this._getNext.bind(this));
+ stream.pipe(this, {end: false});
+ return;
+ }
+
+ var value = stream;
+ this.write(value);
+ this._getNext();
+};
+
+CombinedStream.prototype._handleErrors = function(stream) {
+ var self = this;
+ stream.on('error', function(err) {
+ self._emitError(err);
+ });
+};
+
+CombinedStream.prototype.write = function(data) {
+ this.emit('data', data);
+};
+
+CombinedStream.prototype.pause = function() {
+ if (!this.pauseStreams) {
+ return;
+ }
+
+ if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause();
+ this.emit('pause');
+};
+
+CombinedStream.prototype.resume = function() {
+ if (!this._released) {
+ this._released = true;
+ this.writable = true;
+ this._getNext();
+ }
+
+ if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume();
+ this.emit('resume');
+};
+
+CombinedStream.prototype.end = function() {
+ this._reset();
+ this.emit('end');
+};
+
+CombinedStream.prototype.destroy = function() {
+ this._reset();
+ this.emit('close');
+};
+
+CombinedStream.prototype._reset = function() {
+ this.writable = false;
+ this._streams = [];
+ this._currentStream = null;
+};
+
+CombinedStream.prototype._checkDataSize = function() {
+ this._updateDataSize();
+ if (this.dataSize <= this.maxDataSize) {
+ return;
+ }
+
+ var message =
+ 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.';
+ this._emitError(new Error(message));
+};
+
+CombinedStream.prototype._updateDataSize = function() {
+ this.dataSize = 0;
+
+ var self = this;
+ this._streams.forEach(function(stream) {
+ if (!stream.dataSize) {
+ return;
+ }
+
+ self.dataSize += stream.dataSize;
+ });
+
+ if (this._currentStream && this._currentStream.dataSize) {
+ this.dataSize += this._currentStream.dataSize;
+ }
+};
+
+CombinedStream.prototype._emitError = function(err) {
+ this._reset();
+ this.emit('error', err);
+};
+
+
+/***/ }),
+
+/***/ 8222:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+/* eslint-env browser */
+
+/**
+ * This is the web browser implementation of `debug()`.
+ */
+
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.storage = localstorage();
+exports.destroy = (() => {
+ let warned = false;
+
+ return () => {
+ if (!warned) {
+ warned = true;
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+ }
+ };
+})();
+
+/**
+ * Colors.
+ */
+
+exports.colors = [
+ '#0000CC',
+ '#0000FF',
+ '#0033CC',
+ '#0033FF',
+ '#0066CC',
+ '#0066FF',
+ '#0099CC',
+ '#0099FF',
+ '#00CC00',
+ '#00CC33',
+ '#00CC66',
+ '#00CC99',
+ '#00CCCC',
+ '#00CCFF',
+ '#3300CC',
+ '#3300FF',
+ '#3333CC',
+ '#3333FF',
+ '#3366CC',
+ '#3366FF',
+ '#3399CC',
+ '#3399FF',
+ '#33CC00',
+ '#33CC33',
+ '#33CC66',
+ '#33CC99',
+ '#33CCCC',
+ '#33CCFF',
+ '#6600CC',
+ '#6600FF',
+ '#6633CC',
+ '#6633FF',
+ '#66CC00',
+ '#66CC33',
+ '#9900CC',
+ '#9900FF',
+ '#9933CC',
+ '#9933FF',
+ '#99CC00',
+ '#99CC33',
+ '#CC0000',
+ '#CC0033',
+ '#CC0066',
+ '#CC0099',
+ '#CC00CC',
+ '#CC00FF',
+ '#CC3300',
+ '#CC3333',
+ '#CC3366',
+ '#CC3399',
+ '#CC33CC',
+ '#CC33FF',
+ '#CC6600',
+ '#CC6633',
+ '#CC9900',
+ '#CC9933',
+ '#CCCC00',
+ '#CCCC33',
+ '#FF0000',
+ '#FF0033',
+ '#FF0066',
+ '#FF0099',
+ '#FF00CC',
+ '#FF00FF',
+ '#FF3300',
+ '#FF3333',
+ '#FF3366',
+ '#FF3399',
+ '#FF33CC',
+ '#FF33FF',
+ '#FF6600',
+ '#FF6633',
+ '#FF9900',
+ '#FF9933',
+ '#FFCC00',
+ '#FFCC33'
+];
+
+/**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+// eslint-disable-next-line complexity
+function useColors() {
+ // NB: In an Electron preload script, document will be defined but not fully
+ // initialized. Since we know we're in Chrome, we'll just detect this case
+ // explicitly
+ if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
+ return true;
+ }
+
+ // Internet Explorer and Edge do not support colors.
+ if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
+ return false;
+ }
+
+ // Is webkit? http://stackoverflow.com/a/16459606/376773
+ // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+ return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
+ // Is firebug? http://stackoverflow.com/a/398120/376773
+ (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
+ // Is firefox >= v31?
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
+ // Double check webkit in userAgent just in case we are in a worker
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
+}
+
+/**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs(args) {
+ args[0] = (this.useColors ? '%c' : '') +
+ this.namespace +
+ (this.useColors ? ' %c' : ' ') +
+ args[0] +
+ (this.useColors ? '%c ' : ' ') +
+ '+' + module.exports.humanize(this.diff);
+
+ if (!this.useColors) {
+ return;
+ }
+
+ const c = 'color: ' + this.color;
+ args.splice(1, 0, c, 'color: inherit');
+
+ // The final "%c" is somewhat tricky, because there could be other
+ // arguments passed either before or after the %c, so we need to
+ // figure out the correct index to insert the CSS into
+ let index = 0;
+ let lastC = 0;
+ args[0].replace(/%[a-zA-Z%]/g, match => {
+ if (match === '%%') {
+ return;
+ }
+ index++;
+ if (match === '%c') {
+ // We only are interested in the *last* %c
+ // (the user may have provided their own)
+ lastC = index;
+ }
+ });
+
+ args.splice(lastC, 0, c);
+}
+
+/**
+ * Invokes `console.debug()` when available.
+ * No-op when `console.debug` is not a "function".
+ * If `console.debug` is not available, falls back
+ * to `console.log`.
+ *
+ * @api public
+ */
+exports.log = console.debug || console.log || (() => {});
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+function save(namespaces) {
+ try {
+ if (namespaces) {
+ exports.storage.setItem('debug', namespaces);
+ } else {
+ exports.storage.removeItem('debug');
+ }
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+function load() {
+ let r;
+ try {
+ r = exports.storage.getItem('debug');
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+
+ // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
+ if (!r && typeof process !== 'undefined' && 'env' in process) {
+ r = process.env.DEBUG;
+ }
+
+ return r;
+}
+
+/**
+ * Localstorage attempts to return the localstorage.
+ *
+ * This is necessary because safari throws
+ * when a user disables cookies/localstorage
+ * and you attempt to access it.
+ *
+ * @return {LocalStorage}
+ * @api private
+ */
+
+function localstorage() {
+ try {
+ // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
+ // The Browser also has localStorage in the global context.
+ return localStorage;
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+}
+
+module.exports = __nccwpck_require__(6243)(exports);
+
+const {formatters} = module.exports;
+
+/**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+formatters.j = function (v) {
+ try {
+ return JSON.stringify(v);
+ } catch (error) {
+ return '[UnexpectedJSONParseError]: ' + error.message;
+ }
+};
+
+
+/***/ }),
+
+/***/ 6243:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+
+/**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ */
+
+function setup(env) {
+ createDebug.debug = createDebug;
+ createDebug.default = createDebug;
+ createDebug.coerce = coerce;
+ createDebug.disable = disable;
+ createDebug.enable = enable;
+ createDebug.enabled = enabled;
+ createDebug.humanize = __nccwpck_require__(900);
+ createDebug.destroy = destroy;
+
+ Object.keys(env).forEach(key => {
+ createDebug[key] = env[key];
+ });
+
+ /**
+ * The currently active debug mode names, and names to skip.
+ */
+
+ createDebug.names = [];
+ createDebug.skips = [];
+
+ /**
+ * Map of special "%n" handling functions, for the debug "format" argument.
+ *
+ * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
+ */
+ createDebug.formatters = {};
+
+ /**
+ * Selects a color for a debug namespace
+ * @param {String} namespace The namespace string for the debug instance to be colored
+ * @return {Number|String} An ANSI color code for the given namespace
+ * @api private
+ */
+ function selectColor(namespace) {
+ let hash = 0;
+
+ for (let i = 0; i < namespace.length; i++) {
+ hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
+ hash |= 0; // Convert to 32bit integer
+ }
+
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
+ }
+ createDebug.selectColor = selectColor;
+
+ /**
+ * Create a debugger with the given `namespace`.
+ *
+ * @param {String} namespace
+ * @return {Function}
+ * @api public
+ */
+ function createDebug(namespace) {
+ let prevTime;
+ let enableOverride = null;
+ let namespacesCache;
+ let enabledCache;
+
+ function debug(...args) {
+ // Disabled?
+ if (!debug.enabled) {
+ return;
+ }
+
+ const self = debug;
+
+ // Set `diff` timestamp
+ const curr = Number(new Date());
+ const ms = curr - (prevTime || curr);
+ self.diff = ms;
+ self.prev = prevTime;
+ self.curr = curr;
+ prevTime = curr;
+
+ args[0] = createDebug.coerce(args[0]);
+
+ if (typeof args[0] !== 'string') {
+ // Anything else let's inspect with %O
+ args.unshift('%O');
+ }
+
+ // Apply any `formatters` transformations
+ let index = 0;
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
+ // If we encounter an escaped % then don't increase the array index
+ if (match === '%%') {
+ return '%';
+ }
+ index++;
+ const formatter = createDebug.formatters[format];
+ if (typeof formatter === 'function') {
+ const val = args[index];
+ match = formatter.call(self, val);
+
+ // Now we need to remove `args[index]` since it's inlined in the `format`
+ args.splice(index, 1);
+ index--;
+ }
+ return match;
+ });
+
+ // Apply env-specific formatting (colors, etc.)
+ createDebug.formatArgs.call(self, args);
+
+ const logFn = self.log || createDebug.log;
+ logFn.apply(self, args);
+ }
+
+ debug.namespace = namespace;
+ debug.useColors = createDebug.useColors();
+ debug.color = createDebug.selectColor(namespace);
+ debug.extend = extend;
+ debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
+
+ Object.defineProperty(debug, 'enabled', {
+ enumerable: true,
+ configurable: false,
+ get: () => {
+ if (enableOverride !== null) {
+ return enableOverride;
+ }
+ if (namespacesCache !== createDebug.namespaces) {
+ namespacesCache = createDebug.namespaces;
+ enabledCache = createDebug.enabled(namespace);
+ }
+
+ return enabledCache;
+ },
+ set: v => {
+ enableOverride = v;
+ }
+ });
+
+ // Env-specific initialization logic for debug instances
+ if (typeof createDebug.init === 'function') {
+ createDebug.init(debug);
+ }
+
+ return debug;
+ }
+
+ function extend(namespace, delimiter) {
+ const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
+ newDebug.log = this.log;
+ return newDebug;
+ }
+
+ /**
+ * Enables a debug mode by namespaces. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} namespaces
+ * @api public
+ */
+ function enable(namespaces) {
+ createDebug.save(namespaces);
+ createDebug.namespaces = namespaces;
+
+ createDebug.names = [];
+ createDebug.skips = [];
+
+ let i;
+ const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
+ const len = split.length;
+
+ for (i = 0; i < len; i++) {
+ if (!split[i]) {
+ // ignore empty strings
+ continue;
+ }
+
+ namespaces = split[i].replace(/\*/g, '.*?');
+
+ if (namespaces[0] === '-') {
+ createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
+ } else {
+ createDebug.names.push(new RegExp('^' + namespaces + '$'));
+ }
+ }
+ }
+
+ /**
+ * Disable debug output.
+ *
+ * @return {String} namespaces
+ * @api public
+ */
+ function disable() {
+ const namespaces = [
+ ...createDebug.names.map(toNamespace),
+ ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
+ ].join(',');
+ createDebug.enable('');
+ return namespaces;
+ }
+
+ /**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+ function enabled(name) {
+ if (name[name.length - 1] === '*') {
+ return true;
+ }
+
+ let i;
+ let len;
+
+ for (i = 0, len = createDebug.skips.length; i < len; i++) {
+ if (createDebug.skips[i].test(name)) {
+ return false;
+ }
+ }
+
+ for (i = 0, len = createDebug.names.length; i < len; i++) {
+ if (createDebug.names[i].test(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert regexp to namespace
+ *
+ * @param {RegExp} regxep
+ * @return {String} namespace
+ * @api private
+ */
+ function toNamespace(regexp) {
+ return regexp.toString()
+ .substring(2, regexp.toString().length - 2)
+ .replace(/\.\*\?$/, '*');
+ }
+
+ /**
+ * Coerce `val`.
+ *
+ * @param {Mixed} val
+ * @return {Mixed}
+ * @api private
+ */
+ function coerce(val) {
+ if (val instanceof Error) {
+ return val.stack || val.message;
+ }
+ return val;
+ }
+
+ /**
+ * XXX DO NOT USE. This is a temporary stub function.
+ * XXX It WILL be removed in the next major release.
+ */
+ function destroy() {
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+ }
+
+ createDebug.enable(createDebug.load());
+
+ return createDebug;
+}
+
+module.exports = setup;
+
+
+/***/ }),
+
+/***/ 8237:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/**
+ * Detect Electron renderer / nwjs process, which is node, but we should
+ * treat as a browser.
+ */
+
+if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
+ module.exports = __nccwpck_require__(8222);
+} else {
+ module.exports = __nccwpck_require__(4874);
+}
+
+
+/***/ }),
+
+/***/ 4874:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+/**
+ * Module dependencies.
+ */
+
+const tty = __nccwpck_require__(6224);
+const util = __nccwpck_require__(3837);
+
+/**
+ * This is the Node.js implementation of `debug()`.
+ */
+
+exports.init = init;
+exports.log = log;
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.destroy = util.deprecate(
+ () => {},
+ 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
+);
+
+/**
+ * Colors.
+ */
+
+exports.colors = [6, 2, 3, 4, 5, 1];
+
+try {
+ // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
+ // eslint-disable-next-line import/no-extraneous-dependencies
+ const supportsColor = __nccwpck_require__(9318);
+
+ if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
+ exports.colors = [
+ 20,
+ 21,
+ 26,
+ 27,
+ 32,
+ 33,
+ 38,
+ 39,
+ 40,
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 56,
+ 57,
+ 62,
+ 63,
+ 68,
+ 69,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 92,
+ 93,
+ 98,
+ 99,
+ 112,
+ 113,
+ 128,
+ 129,
+ 134,
+ 135,
+ 148,
+ 149,
+ 160,
+ 161,
+ 162,
+ 163,
+ 164,
+ 165,
+ 166,
+ 167,
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 178,
+ 179,
+ 184,
+ 185,
+ 196,
+ 197,
+ 198,
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 209,
+ 214,
+ 215,
+ 220,
+ 221
+ ];
+ }
+} catch (error) {
+ // Swallow - we only care if `supports-color` is available; it doesn't have to be.
+}
+
+/**
+ * Build up the default `inspectOpts` object from the environment variables.
+ *
+ * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
+ */
+
+exports.inspectOpts = Object.keys(process.env).filter(key => {
+ return /^debug_/i.test(key);
+}).reduce((obj, key) => {
+ // Camel-case
+ const prop = key
+ .substring(6)
+ .toLowerCase()
+ .replace(/_([a-z])/g, (_, k) => {
+ return k.toUpperCase();
+ });
+
+ // Coerce string value into JS value
+ let val = process.env[key];
+ if (/^(yes|on|true|enabled)$/i.test(val)) {
+ val = true;
+ } else if (/^(no|off|false|disabled)$/i.test(val)) {
+ val = false;
+ } else if (val === 'null') {
+ val = null;
+ } else {
+ val = Number(val);
+ }
+
+ obj[prop] = val;
+ return obj;
+}, {});
+
+/**
+ * Is stdout a TTY? Colored output is enabled when `true`.
+ */
+
+function useColors() {
+ return 'colors' in exports.inspectOpts ?
+ Boolean(exports.inspectOpts.colors) :
+ tty.isatty(process.stderr.fd);
+}
+
+/**
+ * Adds ANSI color escape codes if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs(args) {
+ const {namespace: name, useColors} = this;
+
+ if (useColors) {
+ const c = this.color;
+ const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
+ const prefix = ` ${colorCode};1m${name} \u001B[0m`;
+
+ args[0] = prefix + args[0].split('\n').join('\n' + prefix);
+ args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
+ } else {
+ args[0] = getDate() + name + ' ' + args[0];
+ }
+}
+
+function getDate() {
+ if (exports.inspectOpts.hideDate) {
+ return '';
+ }
+ return new Date().toISOString() + ' ';
+}
+
+/**
+ * Invokes `util.format()` with the specified arguments and writes to stderr.
+ */
+
+function log(...args) {
+ return process.stderr.write(util.format(...args) + '\n');
+}
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+function save(namespaces) {
+ if (namespaces) {
+ process.env.DEBUG = namespaces;
+ } else {
+ // If you set a process.env field to null or undefined, it gets cast to the
+ // string 'null' or 'undefined'. Just delete instead.
+ delete process.env.DEBUG;
+ }
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+function load() {
+ return process.env.DEBUG;
+}
+
+/**
+ * Init logic for `debug` instances.
+ *
+ * Create a new `inspectOpts` object in case `useColors` is set
+ * differently for a particular `debug` instance.
+ */
+
+function init(debug) {
+ debug.inspectOpts = {};
+
+ const keys = Object.keys(exports.inspectOpts);
+ for (let i = 0; i < keys.length; i++) {
+ debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
+ }
+}
+
+module.exports = __nccwpck_require__(6243)(exports);
+
+const {formatters} = module.exports;
+
+/**
+ * Map %o to `util.inspect()`, all on a single line.
+ */
+
+formatters.o = function (v) {
+ this.inspectOpts.colors = this.useColors;
+ return util.inspect(v, this.inspectOpts)
+ .split('\n')
+ .map(str => str.trim())
+ .join(' ');
+};
+
+/**
+ * Map %O to `util.inspect()`, allowing multiple lines if needed.
+ */
+
+formatters.O = function (v) {
+ this.inspectOpts.colors = this.useColors;
+ return util.inspect(v, this.inspectOpts);
+};
+
+
+/***/ }),
+
+/***/ 961:
+/***/ ((module) => {
+
+"use strict";
+
+module.exports = (object, propertyName, fn) => {
+ const define = value => Object.defineProperty(object, propertyName, {value, enumerable: true, writable: true});
+
+ Object.defineProperty(object, propertyName, {
+ configurable: true,
+ enumerable: true,
+ get() {
+ const result = fn();
+ define(result);
+ return result;
+ },
+ set(value) {
+ define(value);
+ }
+ });
+
+ return object;
+};
+
+
+/***/ }),
+
+/***/ 8611:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var Stream = (__nccwpck_require__(2781).Stream);
+var util = __nccwpck_require__(3837);
+
+module.exports = DelayedStream;
+function DelayedStream() {
+ this.source = null;
+ this.dataSize = 0;
+ this.maxDataSize = 1024 * 1024;
+ this.pauseStream = true;
+
+ this._maxDataSizeExceeded = false;
+ this._released = false;
+ this._bufferedEvents = [];
+}
+util.inherits(DelayedStream, Stream);
+
+DelayedStream.create = function(source, options) {
+ var delayedStream = new this();
+
+ options = options || {};
+ for (var option in options) {
+ delayedStream[option] = options[option];
+ }
+
+ delayedStream.source = source;
+
+ var realEmit = source.emit;
+ source.emit = function() {
+ delayedStream._handleEmit(arguments);
+ return realEmit.apply(source, arguments);
+ };
+
+ source.on('error', function() {});
+ if (delayedStream.pauseStream) {
+ source.pause();
+ }
+
+ return delayedStream;
+};
+
+Object.defineProperty(DelayedStream.prototype, 'readable', {
+ configurable: true,
+ enumerable: true,
+ get: function() {
+ return this.source.readable;
+ }
+});
+
+DelayedStream.prototype.setEncoding = function() {
+ return this.source.setEncoding.apply(this.source, arguments);
+};
+
+DelayedStream.prototype.resume = function() {
+ if (!this._released) {
+ this.release();
+ }
+
+ this.source.resume();
+};
+
+DelayedStream.prototype.pause = function() {
+ this.source.pause();
+};
+
+DelayedStream.prototype.release = function() {
+ this._released = true;
+
+ this._bufferedEvents.forEach(function(args) {
+ this.emit.apply(this, args);
+ }.bind(this));
+ this._bufferedEvents = [];
+};
+
+DelayedStream.prototype.pipe = function() {
+ var r = Stream.prototype.pipe.apply(this, arguments);
+ this.resume();
+ return r;
+};
+
+DelayedStream.prototype._handleEmit = function(args) {
+ if (this._released) {
+ this.emit.apply(this, args);
+ return;
+ }
+
+ if (args[0] === 'data') {
+ this.dataSize += args[1].length;
+ this._checkIfMaxDataSizeExceeded();
+ }
+
+ this._bufferedEvents.push(args);
+};
+
+DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
+ if (this._maxDataSizeExceeded) {
+ return;
+ }
+
+ if (this.dataSize <= this.maxDataSize) {
+ return;
+ }
+
+ this._maxDataSizeExceeded = true;
+ var message =
+ 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
+ this.emit('error', new Error(message));
+};
+
+
+/***/ }),
+
+/***/ 1728:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var Buffer = (__nccwpck_require__(1867).Buffer);
+
+var getParamBytesForAlg = __nccwpck_require__(528);
+
+var MAX_OCTET = 0x80,
+ CLASS_UNIVERSAL = 0,
+ PRIMITIVE_BIT = 0x20,
+ TAG_SEQ = 0x10,
+ TAG_INT = 0x02,
+ ENCODED_TAG_SEQ = (TAG_SEQ | PRIMITIVE_BIT) | (CLASS_UNIVERSAL << 6),
+ ENCODED_TAG_INT = TAG_INT | (CLASS_UNIVERSAL << 6);
+
+function base64Url(base64) {
+ return base64
+ .replace(/=/g, '')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_');
+}
+
+function signatureAsBuffer(signature) {
+ if (Buffer.isBuffer(signature)) {
+ return signature;
+ } else if ('string' === typeof signature) {
+ return Buffer.from(signature, 'base64');
+ }
+
+ throw new TypeError('ECDSA signature must be a Base64 string or a Buffer');
+}
+
+function derToJose(signature, alg) {
+ signature = signatureAsBuffer(signature);
+ var paramBytes = getParamBytesForAlg(alg);
+
+ // the DER encoded param should at most be the param size, plus a padding
+ // zero, since due to being a signed integer
+ var maxEncodedParamLength = paramBytes + 1;
+
+ var inputLength = signature.length;
+
+ var offset = 0;
+ if (signature[offset++] !== ENCODED_TAG_SEQ) {
+ throw new Error('Could not find expected "seq"');
+ }
+
+ var seqLength = signature[offset++];
+ if (seqLength === (MAX_OCTET | 1)) {
+ seqLength = signature[offset++];
+ }
+
+ if (inputLength - offset < seqLength) {
+ throw new Error('"seq" specified length of "' + seqLength + '", only "' + (inputLength - offset) + '" remaining');
+ }
+
+ if (signature[offset++] !== ENCODED_TAG_INT) {
+ throw new Error('Could not find expected "int" for "r"');
+ }
+
+ var rLength = signature[offset++];
+
+ if (inputLength - offset - 2 < rLength) {
+ throw new Error('"r" specified length of "' + rLength + '", only "' + (inputLength - offset - 2) + '" available');
+ }
+
+ if (maxEncodedParamLength < rLength) {
+ throw new Error('"r" specified length of "' + rLength + '", max of "' + maxEncodedParamLength + '" is acceptable');
+ }
+
+ var rOffset = offset;
+ offset += rLength;
+
+ if (signature[offset++] !== ENCODED_TAG_INT) {
+ throw new Error('Could not find expected "int" for "s"');
+ }
+
+ var sLength = signature[offset++];
+
+ if (inputLength - offset !== sLength) {
+ throw new Error('"s" specified length of "' + sLength + '", expected "' + (inputLength - offset) + '"');
+ }
+
+ if (maxEncodedParamLength < sLength) {
+ throw new Error('"s" specified length of "' + sLength + '", max of "' + maxEncodedParamLength + '" is acceptable');
+ }
+
+ var sOffset = offset;
+ offset += sLength;
+
+ if (offset !== inputLength) {
+ throw new Error('Expected to consume entire buffer, but "' + (inputLength - offset) + '" bytes remain');
+ }
+
+ var rPadding = paramBytes - rLength,
+ sPadding = paramBytes - sLength;
+
+ var dst = Buffer.allocUnsafe(rPadding + rLength + sPadding + sLength);
+
+ for (offset = 0; offset < rPadding; ++offset) {
+ dst[offset] = 0;
+ }
+ signature.copy(dst, offset, rOffset + Math.max(-rPadding, 0), rOffset + rLength);
+
+ offset = paramBytes;
+
+ for (var o = offset; offset < o + sPadding; ++offset) {
+ dst[offset] = 0;
+ }
+ signature.copy(dst, offset, sOffset + Math.max(-sPadding, 0), sOffset + sLength);
+
+ dst = dst.toString('base64');
+ dst = base64Url(dst);
+
+ return dst;
+}
+
+function countPadding(buf, start, stop) {
+ var padding = 0;
+ while (start + padding < stop && buf[start + padding] === 0) {
+ ++padding;
+ }
+
+ var needsSign = buf[start + padding] >= MAX_OCTET;
+ if (needsSign) {
+ --padding;
+ }
+
+ return padding;
+}
+
+function joseToDer(signature, alg) {
+ signature = signatureAsBuffer(signature);
+ var paramBytes = getParamBytesForAlg(alg);
+
+ var signatureBytes = signature.length;
+ if (signatureBytes !== paramBytes * 2) {
+ throw new TypeError('"' + alg + '" signatures must be "' + paramBytes * 2 + '" bytes, saw "' + signatureBytes + '"');
+ }
+
+ var rPadding = countPadding(signature, 0, paramBytes);
+ var sPadding = countPadding(signature, paramBytes, signature.length);
+ var rLength = paramBytes - rPadding;
+ var sLength = paramBytes - sPadding;
+
+ var rsBytes = 1 + 1 + rLength + 1 + 1 + sLength;
+
+ var shortLength = rsBytes < MAX_OCTET;
+
+ var dst = Buffer.allocUnsafe((shortLength ? 2 : 3) + rsBytes);
+
+ var offset = 0;
+ dst[offset++] = ENCODED_TAG_SEQ;
+ if (shortLength) {
+ // Bit 8 has value "0"
+ // bits 7-1 give the length.
+ dst[offset++] = rsBytes;
+ } else {
+ // Bit 8 of first octet has value "1"
+ // bits 7-1 give the number of additional length octets.
+ dst[offset++] = MAX_OCTET | 1;
+ // length, base 256
+ dst[offset++] = rsBytes & 0xff;
+ }
+ dst[offset++] = ENCODED_TAG_INT;
+ dst[offset++] = rLength;
+ if (rPadding < 0) {
+ dst[offset++] = 0;
+ offset += signature.copy(dst, offset, 0, paramBytes);
+ } else {
+ offset += signature.copy(dst, offset, rPadding, paramBytes);
+ }
+ dst[offset++] = ENCODED_TAG_INT;
+ dst[offset++] = sLength;
+ if (sPadding < 0) {
+ dst[offset++] = 0;
+ signature.copy(dst, offset, paramBytes);
+ } else {
+ signature.copy(dst, offset, paramBytes + sPadding);
+ }
+
+ return dst;
+}
+
+module.exports = {
+ derToJose: derToJose,
+ joseToDer: joseToDer
+};
+
+
+/***/ }),
+
+/***/ 528:
+/***/ ((module) => {
+
+"use strict";
+
+
+function getParamSize(keySize) {
+ var result = ((keySize / 8) | 0) + (keySize % 8 === 0 ? 0 : 1);
+ return result;
+}
+
+var paramBytesForAlg = {
+ ES256: getParamSize(256),
+ ES384: getParamSize(384),
+ ES512: getParamSize(521)
+};
+
+function getParamBytesForAlg(alg) {
+ var paramBytes = paramBytesForAlg[alg];
+ if (paramBytes) {
+ return paramBytes;
+ }
+
+ throw new Error('Unknown algorithm "' + alg + '"');
+}
+
+module.exports = getParamBytesForAlg;
+
+
+/***/ }),
+
+/***/ 4334:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var CombinedStream = __nccwpck_require__(5443);
+var util = __nccwpck_require__(3837);
+var path = __nccwpck_require__(1017);
+var http = __nccwpck_require__(3685);
+var https = __nccwpck_require__(5687);
+var parseUrl = (__nccwpck_require__(7310).parse);
+var fs = __nccwpck_require__(7147);
+var Stream = (__nccwpck_require__(2781).Stream);
+var mime = __nccwpck_require__(3583);
+var asynckit = __nccwpck_require__(4812);
+var populate = __nccwpck_require__(7142);
+
+// Public API
+module.exports = FormData;
+
+// make it a Stream
+util.inherits(FormData, CombinedStream);
+
+/**
+ * Create readable "multipart/form-data" streams.
+ * Can be used to submit forms
+ * and file uploads to other web applications.
+ *
+ * @constructor
+ * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream
+ */
+function FormData(options) {
+ if (!(this instanceof FormData)) {
+ return new FormData(options);
+ }
+
+ this._overheadLength = 0;
+ this._valueLength = 0;
+ this._valuesToMeasure = [];
+
+ CombinedStream.call(this);
+
+ options = options || {};
+ for (var option in options) {
+ this[option] = options[option];
+ }
+}
+
+FormData.LINE_BREAK = '\r\n';
+FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
+
+FormData.prototype.append = function(field, value, options) {
+
+ options = options || {};
+
+ // allow filename as single option
+ if (typeof options == 'string') {
+ options = {filename: options};
+ }
+
+ var append = CombinedStream.prototype.append.bind(this);
+
+ // all that streamy business can't handle numbers
+ if (typeof value == 'number') {
+ value = '' + value;
+ }
+
+ // https://github.com/felixge/node-form-data/issues/38
+ if (util.isArray(value)) {
+ // Please convert your array into string
+ // the way web server expects it
+ this._error(new Error('Arrays are not supported.'));
+ return;
+ }
+
+ var header = this._multiPartHeader(field, value, options);
+ var footer = this._multiPartFooter();
+
+ append(header);
+ append(value);
+ append(footer);
+
+ // pass along options.knownLength
+ this._trackLength(header, value, options);
+};
+
+FormData.prototype._trackLength = function(header, value, options) {
+ var valueLength = 0;
+
+ // used w/ getLengthSync(), when length is known.
+ // e.g. for streaming directly from a remote server,
+ // w/ a known file a size, and not wanting to wait for
+ // incoming file to finish to get its size.
+ if (options.knownLength != null) {
+ valueLength += +options.knownLength;
+ } else if (Buffer.isBuffer(value)) {
+ valueLength = value.length;
+ } else if (typeof value === 'string') {
+ valueLength = Buffer.byteLength(value);
+ }
+
+ this._valueLength += valueLength;
+
+ // @check why add CRLF? does this account for custom/multiple CRLFs?
+ this._overheadLength +=
+ Buffer.byteLength(header) +
+ FormData.LINE_BREAK.length;
+
+ // empty or either doesn't have path or not an http response or not a stream
+ if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) {
+ return;
+ }
+
+ // no need to bother with the length
+ if (!options.knownLength) {
+ this._valuesToMeasure.push(value);
+ }
+};
+
+FormData.prototype._lengthRetriever = function(value, callback) {
+
+ if (value.hasOwnProperty('fd')) {
+
+ // take read range into a account
+ // `end` = Infinity –> read file till the end
+ //
+ // TODO: Looks like there is bug in Node fs.createReadStream
+ // it doesn't respect `end` options without `start` options
+ // Fix it when node fixes it.
+ // https://github.com/joyent/node/issues/7819
+ if (value.end != undefined && value.end != Infinity && value.start != undefined) {
+
+ // when end specified
+ // no need to calculate range
+ // inclusive, starts with 0
+ callback(null, value.end + 1 - (value.start ? value.start : 0));
+
+ // not that fast snoopy
+ } else {
+ // still need to fetch file size from fs
+ fs.stat(value.path, function(err, stat) {
+
+ var fileSize;
+
+ if (err) {
+ callback(err);
+ return;
+ }
+
+ // update final size based on the range options
+ fileSize = stat.size - (value.start ? value.start : 0);
+ callback(null, fileSize);
+ });
+ }
+
+ // or http response
+ } else if (value.hasOwnProperty('httpVersion')) {
+ callback(null, +value.headers['content-length']);
+
+ // or request stream http://github.com/mikeal/request
+ } else if (value.hasOwnProperty('httpModule')) {
+ // wait till response come back
+ value.on('response', function(response) {
+ value.pause();
+ callback(null, +response.headers['content-length']);
+ });
+ value.resume();
+
+ // something else
+ } else {
+ callback('Unknown stream');
+ }
+};
+
+FormData.prototype._multiPartHeader = function(field, value, options) {
+ // custom header specified (as string)?
+ // it becomes responsible for boundary
+ // (e.g. to handle extra CRLFs on .NET servers)
+ if (typeof options.header == 'string') {
+ return options.header;
+ }
+
+ var contentDisposition = this._getContentDisposition(value, options);
+ var contentType = this._getContentType(value, options);
+
+ var contents = '';
+ var headers = {
+ // add custom disposition as third element or keep it two elements if not
+ 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
+ // if no content type. allow it to be empty array
+ 'Content-Type': [].concat(contentType || [])
+ };
+
+ // allow custom headers.
+ if (typeof options.header == 'object') {
+ populate(headers, options.header);
+ }
+
+ var header;
+ for (var prop in headers) {
+ if (!headers.hasOwnProperty(prop)) continue;
+ header = headers[prop];
+
+ // skip nullish headers.
+ if (header == null) {
+ continue;
+ }
+
+ // convert all headers to arrays.
+ if (!Array.isArray(header)) {
+ header = [header];
+ }
+
+ // add non-empty headers.
+ if (header.length) {
+ contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;
+ }
+ }
+
+ return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
+};
+
+FormData.prototype._getContentDisposition = function(value, options) {
+
+ var filename
+ , contentDisposition
+ ;
+
+ if (typeof options.filepath === 'string') {
+ // custom filepath for relative paths
+ filename = path.normalize(options.filepath).replace(/\\/g, '/');
+ } else if (options.filename || value.name || value.path) {
+ // custom filename take precedence
+ // formidable and the browser add a name property
+ // fs- and request- streams have path property
+ filename = path.basename(options.filename || value.name || value.path);
+ } else if (value.readable && value.hasOwnProperty('httpVersion')) {
+ // or try http response
+ filename = path.basename(value.client._httpMessage.path || '');
+ }
+
+ if (filename) {
+ contentDisposition = 'filename="' + filename + '"';
+ }
+
+ return contentDisposition;
+};
+
+FormData.prototype._getContentType = function(value, options) {
+
+ // use custom content-type above all
+ var contentType = options.contentType;
+
+ // or try `name` from formidable, browser
+ if (!contentType && value.name) {
+ contentType = mime.lookup(value.name);
+ }
+
+ // or try `path` from fs-, request- streams
+ if (!contentType && value.path) {
+ contentType = mime.lookup(value.path);
+ }
+
+ // or if it's http-reponse
+ if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) {
+ contentType = value.headers['content-type'];
+ }
+
+ // or guess it from the filepath or filename
+ if (!contentType && (options.filepath || options.filename)) {
+ contentType = mime.lookup(options.filepath || options.filename);
+ }
+
+ // fallback to the default content type if `value` is not simple value
+ if (!contentType && typeof value == 'object') {
+ contentType = FormData.DEFAULT_CONTENT_TYPE;
+ }
+
+ return contentType;
+};
+
+FormData.prototype._multiPartFooter = function() {
+ return function(next) {
+ var footer = FormData.LINE_BREAK;
+
+ var lastPart = (this._streams.length === 0);
+ if (lastPart) {
+ footer += this._lastBoundary();
+ }
+
+ next(footer);
+ }.bind(this);
+};
+
+FormData.prototype._lastBoundary = function() {
+ return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;
+};
+
+FormData.prototype.getHeaders = function(userHeaders) {
+ var header;
+ var formHeaders = {
+ 'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
+ };
+
+ for (header in userHeaders) {
+ if (userHeaders.hasOwnProperty(header)) {
+ formHeaders[header.toLowerCase()] = userHeaders[header];
+ }
+ }
+
+ return formHeaders;
+};
+
+FormData.prototype.setBoundary = function(boundary) {
+ this._boundary = boundary;
+};
+
+FormData.prototype.getBoundary = function() {
+ if (!this._boundary) {
+ this._generateBoundary();
+ }
+
+ return this._boundary;
+};
+
+FormData.prototype.getBuffer = function() {
+ var dataBuffer = new Buffer.alloc( 0 );
+ var boundary = this.getBoundary();
+
+ // Create the form content. Add Line breaks to the end of data.
+ for (var i = 0, len = this._streams.length; i < len; i++) {
+ if (typeof this._streams[i] !== 'function') {
+
+ // Add content to the buffer.
+ if(Buffer.isBuffer(this._streams[i])) {
+ dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]);
+ }else {
+ dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]);
+ }
+
+ // Add break after content.
+ if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) {
+ dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] );
+ }
+ }
+ }
+
+ // Add the footer and return the Buffer object.
+ return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] );
+};
+
+FormData.prototype._generateBoundary = function() {
+ // This generates a 50 character boundary similar to those used by Firefox.
+ // They are optimized for boyer-moore parsing.
+ var boundary = '--------------------------';
+ for (var i = 0; i < 24; i++) {
+ boundary += Math.floor(Math.random() * 10).toString(16);
+ }
+
+ this._boundary = boundary;
+};
+
+// Note: getLengthSync DOESN'T calculate streams length
+// As workaround one can calculate file size manually
+// and add it as knownLength option
+FormData.prototype.getLengthSync = function() {
+ var knownLength = this._overheadLength + this._valueLength;
+
+ // Don't get confused, there are 3 "internal" streams for each keyval pair
+ // so it basically checks if there is any value added to the form
+ if (this._streams.length) {
+ knownLength += this._lastBoundary().length;
+ }
+
+ // https://github.com/form-data/form-data/issues/40
+ if (!this.hasKnownLength()) {
+ // Some async length retrievers are present
+ // therefore synchronous length calculation is false.
+ // Please use getLength(callback) to get proper length
+ this._error(new Error('Cannot calculate proper length in synchronous way.'));
+ }
+
+ return knownLength;
+};
+
+// Public API to check if length of added values is known
+// https://github.com/form-data/form-data/issues/196
+// https://github.com/form-data/form-data/issues/262
+FormData.prototype.hasKnownLength = function() {
+ var hasKnownLength = true;
+
+ if (this._valuesToMeasure.length) {
+ hasKnownLength = false;
+ }
+
+ return hasKnownLength;
+};
+
+FormData.prototype.getLength = function(cb) {
+ var knownLength = this._overheadLength + this._valueLength;
+
+ if (this._streams.length) {
+ knownLength += this._lastBoundary().length;
+ }
+
+ if (!this._valuesToMeasure.length) {
+ process.nextTick(cb.bind(this, null, knownLength));
+ return;
+ }
+
+ asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {
+ if (err) {
+ cb(err);
+ return;
+ }
+
+ values.forEach(function(length) {
+ knownLength += length;
+ });
+
+ cb(null, knownLength);
+ });
+};
+
+FormData.prototype.submit = function(params, cb) {
+ var request
+ , options
+ , defaults = {method: 'post'}
+ ;
+
+ // parse provided url if it's string
+ // or treat it as options object
+ if (typeof params == 'string') {
+
+ params = parseUrl(params);
+ options = populate({
+ port: params.port,
+ path: params.pathname,
+ host: params.hostname,
+ protocol: params.protocol
+ }, defaults);
+
+ // use custom params
+ } else {
+
+ options = populate(params, defaults);
+ // if no port provided use default one
+ if (!options.port) {
+ options.port = options.protocol == 'https:' ? 443 : 80;
+ }
+ }
+
+ // put that good code in getHeaders to some use
+ options.headers = this.getHeaders(params.headers);
+
+ // https if specified, fallback to http in any other case
+ if (options.protocol == 'https:') {
+ request = https.request(options);
+ } else {
+ request = http.request(options);
+ }
+
+ // get content length and fire away
+ this.getLength(function(err, length) {
+ if (err && err !== 'Unknown stream') {
+ this._error(err);
+ return;
+ }
+
+ // add content length
+ if (length) {
+ request.setHeader('Content-Length', length);
+ }
+
+ this.pipe(request);
+ if (cb) {
+ var onResponse;
+
+ var callback = function (error, responce) {
+ request.removeListener('error', callback);
+ request.removeListener('response', onResponse);
+
+ return cb.call(this, error, responce);
+ };
+
+ onResponse = callback.bind(this, null);
+
+ request.on('error', callback);
+ request.on('response', onResponse);
+ }
+ }.bind(this));
+
+ return request;
+};
+
+FormData.prototype._error = function(err) {
+ if (!this.error) {
+ this.error = err;
+ this.pause();
+ this.emit('error', err);
+ }
+};
+
+FormData.prototype.toString = function () {
+ return '[object FormData]';
+};
+
+
+/***/ }),
+
+/***/ 7142:
+/***/ ((module) => {
+
+// populates missing values
+module.exports = function(dst, src) {
+
+ Object.keys(src).forEach(function(prop)
+ {
+ dst[prop] = dst[prop] || src[prop];
+ });
+
+ return dst;
+};
+
+
+/***/ }),
+
+/***/ 1621:
+/***/ ((module) => {
+
+"use strict";
+
+
+module.exports = (flag, argv = process.argv) => {
+ const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
+ const position = argv.indexOf(prefix + flag);
+ const terminatorPosition = argv.indexOf('--');
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
+};
+
+
+/***/ }),
+
+/***/ 7492:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ 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) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const net_1 = __importDefault(__nccwpck_require__(1808));
+const tls_1 = __importDefault(__nccwpck_require__(4404));
+const url_1 = __importDefault(__nccwpck_require__(7310));
+const debug_1 = __importDefault(__nccwpck_require__(8237));
+const once_1 = __importDefault(__nccwpck_require__(1040));
+const agent_base_1 = __nccwpck_require__(9690);
+const debug = (0, debug_1.default)('http-proxy-agent');
+function isHTTPS(protocol) {
+ return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false;
+}
+/**
+ * The `HttpProxyAgent` implements an HTTP Agent subclass that connects
+ * to the specified "HTTP proxy server" in order to proxy HTTP requests.
+ *
+ * @api public
+ */
+class HttpProxyAgent extends agent_base_1.Agent {
+ constructor(_opts) {
+ let opts;
+ if (typeof _opts === 'string') {
+ opts = url_1.default.parse(_opts);
+ }
+ else {
+ opts = _opts;
+ }
+ if (!opts) {
+ throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!');
+ }
+ debug('Creating new HttpProxyAgent instance: %o', opts);
+ super(opts);
+ const proxy = Object.assign({}, opts);
+ // If `true`, then connect to the proxy server over TLS.
+ // Defaults to `false`.
+ this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol);
+ // Prefer `hostname` over `host`, and set the `port` if needed.
+ proxy.host = proxy.hostname || proxy.host;
+ if (typeof proxy.port === 'string') {
+ proxy.port = parseInt(proxy.port, 10);
+ }
+ if (!proxy.port && proxy.host) {
+ proxy.port = this.secureProxy ? 443 : 80;
+ }
+ if (proxy.host && proxy.path) {
+ // If both a `host` and `path` are specified then it's most likely
+ // the result of a `url.parse()` call... we need to remove the
+ // `path` portion so that `net.connect()` doesn't attempt to open
+ // that as a Unix socket file.
+ delete proxy.path;
+ delete proxy.pathname;
+ }
+ this.proxy = proxy;
+ }
+ /**
+ * Called when the node-core HTTP client library is creating a
+ * new HTTP request.
+ *
+ * @api protected
+ */
+ callback(req, opts) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const { proxy, secureProxy } = this;
+ const parsed = url_1.default.parse(req.path);
+ if (!parsed.protocol) {
+ parsed.protocol = 'http:';
+ }
+ if (!parsed.hostname) {
+ parsed.hostname = opts.hostname || opts.host || null;
+ }
+ if (parsed.port == null && typeof opts.port) {
+ parsed.port = String(opts.port);
+ }
+ if (parsed.port === '80') {
+ // if port is 80, then we can remove the port so that the
+ // ":80" portion is not on the produced URL
+ parsed.port = '';
+ }
+ // Change the `http.ClientRequest` instance's "path" field
+ // to the absolute path of the URL that will be requested.
+ req.path = url_1.default.format(parsed);
+ // Inject the `Proxy-Authorization` header if necessary.
+ if (proxy.auth) {
+ req.setHeader('Proxy-Authorization', `Basic ${Buffer.from(proxy.auth).toString('base64')}`);
+ }
+ // Create a socket connection to the proxy server.
+ let socket;
+ if (secureProxy) {
+ debug('Creating `tls.Socket`: %o', proxy);
+ socket = tls_1.default.connect(proxy);
+ }
+ else {
+ debug('Creating `net.Socket`: %o', proxy);
+ socket = net_1.default.connect(proxy);
+ }
+ // At this point, the http ClientRequest's internal `_header` field
+ // might have already been set. If this is the case then we'll need
+ // to re-generate the string since we just changed the `req.path`.
+ if (req._header) {
+ let first;
+ let endOfHeaders;
+ debug('Regenerating stored HTTP header string for request');
+ req._header = null;
+ req._implicitHeader();
+ if (req.output && req.output.length > 0) {
+ // Node < 12
+ debug('Patching connection write() output buffer with updated header');
+ first = req.output[0];
+ endOfHeaders = first.indexOf('\r\n\r\n') + 4;
+ req.output[0] = req._header + first.substring(endOfHeaders);
+ debug('Output buffer: %o', req.output);
+ }
+ else if (req.outputData && req.outputData.length > 0) {
+ // Node >= 12
+ debug('Patching connection write() output buffer with updated header');
+ first = req.outputData[0].data;
+ endOfHeaders = first.indexOf('\r\n\r\n') + 4;
+ req.outputData[0].data =
+ req._header + first.substring(endOfHeaders);
+ debug('Output buffer: %o', req.outputData[0].data);
+ }
+ }
+ // Wait for the socket's `connect` event, so that this `callback()`
+ // function throws instead of the `http` request machinery. This is
+ // important for i.e. `PacProxyAgent` which determines a failed proxy
+ // connection via the `callback()` function throwing.
+ yield (0, once_1.default)(socket, 'connect');
+ return socket;
+ });
+ }
+}
+exports["default"] = HttpProxyAgent;
+//# sourceMappingURL=agent.js.map
+
+/***/ }),
+
+/***/ 3764:
+/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+const agent_1 = __importDefault(__nccwpck_require__(7492));
+function createHttpProxyAgent(opts) {
+ return new agent_1.default(opts);
+}
+(function (createHttpProxyAgent) {
+ createHttpProxyAgent.HttpProxyAgent = agent_1.default;
+ createHttpProxyAgent.prototype = agent_1.default.prototype;
+})(createHttpProxyAgent || (createHttpProxyAgent = {}));
+module.exports = createHttpProxyAgent;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 5098:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ 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) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const net_1 = __importDefault(__nccwpck_require__(1808));
+const tls_1 = __importDefault(__nccwpck_require__(4404));
+const url_1 = __importDefault(__nccwpck_require__(7310));
+const assert_1 = __importDefault(__nccwpck_require__(9491));
+const debug_1 = __importDefault(__nccwpck_require__(8237));
+const agent_base_1 = __nccwpck_require__(9690);
+const parse_proxy_response_1 = __importDefault(__nccwpck_require__(595));
+const debug = debug_1.default('https-proxy-agent:agent');
+/**
+ * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to
+ * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
+ *
+ * Outgoing HTTP requests are first tunneled through the proxy server using the
+ * `CONNECT` HTTP request method to establish a connection to the proxy server,
+ * and then the proxy server connects to the destination target and issues the
+ * HTTP request from the proxy server.
+ *
+ * `https:` requests have their socket connection upgraded to TLS once
+ * the connection to the proxy server has been established.
+ *
+ * @api public
+ */
+class HttpsProxyAgent extends agent_base_1.Agent {
+ constructor(_opts) {
+ let opts;
+ if (typeof _opts === 'string') {
+ opts = url_1.default.parse(_opts);
+ }
+ else {
+ opts = _opts;
+ }
+ if (!opts) {
+ throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!');
+ }
+ debug('creating new HttpsProxyAgent instance: %o', opts);
+ super(opts);
+ const proxy = Object.assign({}, opts);
+ // If `true`, then connect to the proxy server over TLS.
+ // Defaults to `false`.
+ this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol);
+ // Prefer `hostname` over `host`, and set the `port` if needed.
+ proxy.host = proxy.hostname || proxy.host;
+ if (typeof proxy.port === 'string') {
+ proxy.port = parseInt(proxy.port, 10);
+ }
+ if (!proxy.port && proxy.host) {
+ proxy.port = this.secureProxy ? 443 : 80;
+ }
+ // ALPN is supported by Node.js >= v5.
+ // attempt to negotiate http/1.1 for proxy servers that support http/2
+ if (this.secureProxy && !('ALPNProtocols' in proxy)) {
+ proxy.ALPNProtocols = ['http 1.1'];
+ }
+ if (proxy.host && proxy.path) {
+ // If both a `host` and `path` are specified then it's most likely
+ // the result of a `url.parse()` call... we need to remove the
+ // `path` portion so that `net.connect()` doesn't attempt to open
+ // that as a Unix socket file.
+ delete proxy.path;
+ delete proxy.pathname;
+ }
+ this.proxy = proxy;
+ }
+ /**
+ * Called when the node-core HTTP client library is creating a
+ * new HTTP request.
+ *
+ * @api protected
+ */
+ callback(req, opts) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const { proxy, secureProxy } = this;
+ // Create a socket connection to the proxy server.
+ let socket;
+ if (secureProxy) {
+ debug('Creating `tls.Socket`: %o', proxy);
+ socket = tls_1.default.connect(proxy);
+ }
+ else {
+ debug('Creating `net.Socket`: %o', proxy);
+ socket = net_1.default.connect(proxy);
+ }
+ const headers = Object.assign({}, proxy.headers);
+ const hostname = `${opts.host}:${opts.port}`;
+ let payload = `CONNECT ${hostname} HTTP/1.1\r\n`;
+ // Inject the `Proxy-Authorization` header if necessary.
+ if (proxy.auth) {
+ headers['Proxy-Authorization'] = `Basic ${Buffer.from(proxy.auth).toString('base64')}`;
+ }
+ // The `Host` header should only include the port
+ // number when it is not the default port.
+ let { host, port, secureEndpoint } = opts;
+ if (!isDefaultPort(port, secureEndpoint)) {
+ host += `:${port}`;
+ }
+ headers.Host = host;
+ headers.Connection = 'close';
+ for (const name of Object.keys(headers)) {
+ payload += `${name}: ${headers[name]}\r\n`;
+ }
+ const proxyResponsePromise = parse_proxy_response_1.default(socket);
+ socket.write(`${payload}\r\n`);
+ const { statusCode, buffered } = yield proxyResponsePromise;
+ if (statusCode === 200) {
+ req.once('socket', resume);
+ if (opts.secureEndpoint) {
+ // The proxy is connecting to a TLS server, so upgrade
+ // this socket connection to a TLS connection.
+ debug('Upgrading socket connection to TLS');
+ const servername = opts.servername || opts.host;
+ return tls_1.default.connect(Object.assign(Object.assign({}, omit(opts, 'host', 'hostname', 'path', 'port')), { socket,
+ servername }));
+ }
+ return socket;
+ }
+ // Some other status code that's not 200... need to re-play the HTTP
+ // header "data" events onto the socket once the HTTP machinery is
+ // attached so that the node core `http` can parse and handle the
+ // error status code.
+ // Close the original socket, and a new "fake" socket is returned
+ // instead, so that the proxy doesn't get the HTTP request
+ // written to it (which may contain `Authorization` headers or other
+ // sensitive data).
+ //
+ // See: https://hackerone.com/reports/541502
+ socket.destroy();
+ const fakeSocket = new net_1.default.Socket({ writable: false });
+ fakeSocket.readable = true;
+ // Need to wait for the "socket" event to re-play the "data" events.
+ req.once('socket', (s) => {
+ debug('replaying proxy buffer for failed request');
+ assert_1.default(s.listenerCount('data') > 0);
+ // Replay the "buffered" Buffer onto the fake `socket`, since at
+ // this point the HTTP module machinery has been hooked up for
+ // the user.
+ s.push(buffered);
+ s.push(null);
+ });
+ return fakeSocket;
+ });
+ }
+}
+exports["default"] = HttpsProxyAgent;
+function resume(socket) {
+ socket.resume();
+}
+function isDefaultPort(port, secure) {
+ return Boolean((!secure && port === 80) || (secure && port === 443));
+}
+function isHTTPS(protocol) {
+ return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false;
+}
+function omit(obj, ...keys) {
+ const ret = {};
+ let key;
+ for (key in obj) {
+ if (!keys.includes(key)) {
+ ret[key] = obj[key];
+ }
+ }
+ return ret;
+}
+//# sourceMappingURL=agent.js.map
+
+/***/ }),
+
+/***/ 7219:
+/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+const agent_1 = __importDefault(__nccwpck_require__(5098));
+function createHttpsProxyAgent(opts) {
+ return new agent_1.default(opts);
+}
+(function (createHttpsProxyAgent) {
+ createHttpsProxyAgent.HttpsProxyAgent = agent_1.default;
+ createHttpsProxyAgent.prototype = agent_1.default.prototype;
+})(createHttpsProxyAgent || (createHttpsProxyAgent = {}));
+module.exports = createHttpsProxyAgent;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 595:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const debug_1 = __importDefault(__nccwpck_require__(8237));
+const debug = debug_1.default('https-proxy-agent:parse-proxy-response');
+function parseProxyResponse(socket) {
+ return new Promise((resolve, reject) => {
+ // we need to buffer any HTTP traffic that happens with the proxy before we get
+ // the CONNECT response, so that if the response is anything other than an "200"
+ // response code, then we can re-play the "data" events on the socket once the
+ // HTTP parser is hooked up...
+ let buffersLength = 0;
+ const buffers = [];
+ function read() {
+ const b = socket.read();
+ if (b)
+ ondata(b);
+ else
+ socket.once('readable', read);
+ }
+ function cleanup() {
+ socket.removeListener('end', onend);
+ socket.removeListener('error', onerror);
+ socket.removeListener('close', onclose);
+ socket.removeListener('readable', read);
+ }
+ function onclose(err) {
+ debug('onclose had error %o', err);
+ }
+ function onend() {
+ debug('onend');
+ }
+ function onerror(err) {
+ cleanup();
+ debug('onerror %o', err);
+ reject(err);
+ }
+ function ondata(b) {
+ buffers.push(b);
+ buffersLength += b.length;
+ const buffered = Buffer.concat(buffers, buffersLength);
+ const endOfHeaders = buffered.indexOf('\r\n\r\n');
+ if (endOfHeaders === -1) {
+ // keep buffering
+ debug('have not received end of HTTP headers yet...');
+ read();
+ return;
+ }
+ const firstLine = buffered.toString('ascii', 0, buffered.indexOf('\r\n'));
+ const statusCode = +firstLine.split(' ')[1];
+ debug('got proxy server response: %o', firstLine);
+ resolve({
+ statusCode,
+ buffered
+ });
+ }
+ socket.on('error', onerror);
+ socket.on('close', onclose);
+ socket.on('end', onend);
+ read();
+ });
+}
+exports["default"] = parseProxyResponse;
+//# sourceMappingURL=parse-proxy-response.js.map
+
+/***/ }),
+
+/***/ 8768:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+
+const fs = __nccwpck_require__(7147);
+
+let isDocker;
+
+function hasDockerEnv() {
+ try {
+ fs.statSync('/.dockerenv');
+ return true;
+ } catch (_) {
+ return false;
+ }
+}
+
+function hasDockerCGroup() {
+ try {
+ return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
+ } catch (_) {
+ return false;
+ }
+}
+
+module.exports = () => {
+ if (isDocker === undefined) {
+ isDocker = hasDockerEnv() || hasDockerCGroup();
+ }
+
+ return isDocker;
+};
+
+
+/***/ }),
+
+/***/ 2559:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+
+const os = __nccwpck_require__(2037);
+const fs = __nccwpck_require__(7147);
+const isDocker = __nccwpck_require__(8768);
+
+const isWsl = () => {
+ if (process.platform !== 'linux') {
+ return false;
+ }
+
+ if (os.release().toLowerCase().includes('microsoft')) {
+ if (isDocker()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ try {
+ return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
+ !isDocker() : false;
+ } catch (_) {
+ return false;
+ }
+};
+
+if (process.env.__IS_WSL_TEST__) {
+ module.exports = isWsl;
+} else {
+ module.exports = isWsl();
+}
+
+
+/***/ }),
+
+/***/ 3359:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var jws = __nccwpck_require__(2597);
+
+module.exports = function (jwt, options) {
+ options = options || {};
+ var decoded = jws.decode(jwt, options);
+ if (!decoded) { return null; }
+ var payload = decoded.payload;
+
+ //try parse the payload
+ if(typeof payload === 'string') {
+ try {
+ var obj = JSON.parse(payload);
+ if(obj !== null && typeof obj === 'object') {
+ payload = obj;
+ }
+ } catch (e) { }
+ }
+
+ //return header if `complete` option is enabled. header includes claims
+ //such as `kid` and `alg` used to select the key within a JWKS needed to
+ //verify the signature
+ if (options.complete === true) {
+ return {
+ header: decoded.header,
+ payload: payload,
+ signature: decoded.signature
+ };
+ }
+ return payload;
+};
+
+
+/***/ }),
+
+/***/ 7486:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+module.exports = {
+ decode: __nccwpck_require__(3359),
+ verify: __nccwpck_require__(2327),
+ sign: __nccwpck_require__(2022),
+ JsonWebTokenError: __nccwpck_require__(405),
+ NotBeforeError: __nccwpck_require__(4383),
+ TokenExpiredError: __nccwpck_require__(6637),
+};
+
+
+/***/ }),
+
+/***/ 405:
+/***/ ((module) => {
+
+var JsonWebTokenError = function (message, error) {
+ Error.call(this, message);
+ if(Error.captureStackTrace) {
+ Error.captureStackTrace(this, this.constructor);
+ }
+ this.name = 'JsonWebTokenError';
+ this.message = message;
+ if (error) this.inner = error;
+};
+
+JsonWebTokenError.prototype = Object.create(Error.prototype);
+JsonWebTokenError.prototype.constructor = JsonWebTokenError;
+
+module.exports = JsonWebTokenError;
+
+
+/***/ }),
+
+/***/ 4383:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var JsonWebTokenError = __nccwpck_require__(405);
+
+var NotBeforeError = function (message, date) {
+ JsonWebTokenError.call(this, message);
+ this.name = 'NotBeforeError';
+ this.date = date;
+};
+
+NotBeforeError.prototype = Object.create(JsonWebTokenError.prototype);
+
+NotBeforeError.prototype.constructor = NotBeforeError;
+
+module.exports = NotBeforeError;
+
+/***/ }),
+
+/***/ 6637:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var JsonWebTokenError = __nccwpck_require__(405);
+
+var TokenExpiredError = function (message, expiredAt) {
+ JsonWebTokenError.call(this, message);
+ this.name = 'TokenExpiredError';
+ this.expiredAt = expiredAt;
+};
+
+TokenExpiredError.prototype = Object.create(JsonWebTokenError.prototype);
+
+TokenExpiredError.prototype.constructor = TokenExpiredError;
+
+module.exports = TokenExpiredError;
+
+/***/ }),
+
+/***/ 7622:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+const semver = __nccwpck_require__(1383);
+
+module.exports = semver.satisfies(process.version, '>=15.7.0');
+
+
+/***/ }),
+
+/***/ 9085:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var semver = __nccwpck_require__(1383);
+
+module.exports = semver.satisfies(process.version, '^6.12.0 || >=8.0.0');
+
+
+/***/ }),
+
+/***/ 5170:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+const semver = __nccwpck_require__(1383);
+
+module.exports = semver.satisfies(process.version, '>=16.9.0');
+
+
+/***/ }),
+
+/***/ 6098:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var ms = __nccwpck_require__(900);
+
+module.exports = function (time, iat) {
+ var timestamp = iat || Math.floor(Date.now() / 1000);
+
+ if (typeof time === 'string') {
+ var milliseconds = ms(time);
+ if (typeof milliseconds === 'undefined') {
+ return;
+ }
+ return Math.floor(timestamp + milliseconds / 1000);
+ } else if (typeof time === 'number') {
+ return timestamp + time;
+ } else {
+ return;
+ }
+
+};
+
+/***/ }),
+
+/***/ 7596:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+const ASYMMETRIC_KEY_DETAILS_SUPPORTED = __nccwpck_require__(7622);
+const RSA_PSS_KEY_DETAILS_SUPPORTED = __nccwpck_require__(5170);
+
+const allowedAlgorithmsForKeys = {
+ 'ec': ['ES256', 'ES384', 'ES512'],
+ 'rsa': ['RS256', 'PS256', 'RS384', 'PS384', 'RS512', 'PS512'],
+ 'rsa-pss': ['PS256', 'PS384', 'PS512']
+};
+
+const allowedCurves = {
+ ES256: 'prime256v1',
+ ES384: 'secp384r1',
+ ES512: 'secp521r1',
+};
+
+module.exports = function(algorithm, key) {
+ if (!algorithm || !key) return;
+
+ const keyType = key.asymmetricKeyType;
+ if (!keyType) return;
+
+ const allowedAlgorithms = allowedAlgorithmsForKeys[keyType];
+
+ if (!allowedAlgorithms) {
+ throw new Error(`Unknown key type "${keyType}".`);
+ }
+
+ if (!allowedAlgorithms.includes(algorithm)) {
+ throw new Error(`"alg" parameter for "${keyType}" key type must be one of: ${allowedAlgorithms.join(', ')}.`)
+ }
+
+ /*
+ * Ignore the next block from test coverage because it gets executed
+ * conditionally depending on the Node version. Not ignoring it would
+ * prevent us from reaching the target % of coverage for versions of
+ * Node under 15.7.0.
+ */
+ /* istanbul ignore next */
+ if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) {
+ switch (keyType) {
+ case 'ec':
+ const keyCurve = key.asymmetricKeyDetails.namedCurve;
+ const allowedCurve = allowedCurves[algorithm];
+
+ if (keyCurve !== allowedCurve) {
+ throw new Error(`"alg" parameter "${algorithm}" requires curve "${allowedCurve}".`);
+ }
+ break;
+
+ case 'rsa-pss':
+ if (RSA_PSS_KEY_DETAILS_SUPPORTED) {
+ const length = parseInt(algorithm.slice(-3), 10);
+ const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails;
+
+ if (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm) {
+ throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${algorithm}.`);
+ }
+
+ if (saltLength !== undefined && saltLength > length >> 3) {
+ throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${algorithm}.`)
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+/***/ }),
+
+/***/ 2321:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var bufferEqual = __nccwpck_require__(9239);
+var Buffer = (__nccwpck_require__(1867).Buffer);
+var crypto = __nccwpck_require__(6113);
+var formatEcdsa = __nccwpck_require__(1728);
+var util = __nccwpck_require__(3837);
+
+var MSG_INVALID_ALGORITHM = '"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".'
+var MSG_INVALID_SECRET = 'secret must be a string or buffer';
+var MSG_INVALID_VERIFIER_KEY = 'key must be a string or a buffer';
+var MSG_INVALID_SIGNER_KEY = 'key must be a string, a buffer or an object';
+
+var supportsKeyObjects = typeof crypto.createPublicKey === 'function';
+if (supportsKeyObjects) {
+ MSG_INVALID_VERIFIER_KEY += ' or a KeyObject';
+ MSG_INVALID_SECRET += 'or a KeyObject';
+}
+
+function checkIsPublicKey(key) {
+ if (Buffer.isBuffer(key)) {
+ return;
+ }
+
+ if (typeof key === 'string') {
+ return;
+ }
+
+ if (!supportsKeyObjects) {
+ throw typeError(MSG_INVALID_VERIFIER_KEY);
+ }
+
+ if (typeof key !== 'object') {
+ throw typeError(MSG_INVALID_VERIFIER_KEY);
+ }
+
+ if (typeof key.type !== 'string') {
+ throw typeError(MSG_INVALID_VERIFIER_KEY);
+ }
+
+ if (typeof key.asymmetricKeyType !== 'string') {
+ throw typeError(MSG_INVALID_VERIFIER_KEY);
+ }
+
+ if (typeof key.export !== 'function') {
+ throw typeError(MSG_INVALID_VERIFIER_KEY);
+ }
+};
+
+function checkIsPrivateKey(key) {
+ if (Buffer.isBuffer(key)) {
+ return;
+ }
+
+ if (typeof key === 'string') {
+ return;
+ }
+
+ if (typeof key === 'object') {
+ return;
+ }
+
+ throw typeError(MSG_INVALID_SIGNER_KEY);
+};
+
+function checkIsSecretKey(key) {
+ if (Buffer.isBuffer(key)) {
+ return;
+ }
+
+ if (typeof key === 'string') {
+ return key;
+ }
+
+ if (!supportsKeyObjects) {
+ throw typeError(MSG_INVALID_SECRET);
+ }
+
+ if (typeof key !== 'object') {
+ throw typeError(MSG_INVALID_SECRET);
+ }
+
+ if (key.type !== 'secret') {
+ throw typeError(MSG_INVALID_SECRET);
+ }
+
+ if (typeof key.export !== 'function') {
+ throw typeError(MSG_INVALID_SECRET);
+ }
+}
+
+function fromBase64(base64) {
+ return base64
+ .replace(/=/g, '')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_');
+}
+
+function toBase64(base64url) {
+ base64url = base64url.toString();
+
+ var padding = 4 - base64url.length % 4;
+ if (padding !== 4) {
+ for (var i = 0; i < padding; ++i) {
+ base64url += '=';
+ }
+ }
+
+ return base64url
+ .replace(/\-/g, '+')
+ .replace(/_/g, '/');
+}
+
+function typeError(template) {
+ var args = [].slice.call(arguments, 1);
+ var errMsg = util.format.bind(util, template).apply(null, args);
+ return new TypeError(errMsg);
+}
+
+function bufferOrString(obj) {
+ return Buffer.isBuffer(obj) || typeof obj === 'string';
+}
+
+function normalizeInput(thing) {
+ if (!bufferOrString(thing))
+ thing = JSON.stringify(thing);
+ return thing;
+}
+
+function createHmacSigner(bits) {
+ return function sign(thing, secret) {
+ checkIsSecretKey(secret);
+ thing = normalizeInput(thing);
+ var hmac = crypto.createHmac('sha' + bits, secret);
+ var sig = (hmac.update(thing), hmac.digest('base64'))
+ return fromBase64(sig);
+ }
+}
+
+function createHmacVerifier(bits) {
+ return function verify(thing, signature, secret) {
+ var computedSig = createHmacSigner(bits)(thing, secret);
+ return bufferEqual(Buffer.from(signature), Buffer.from(computedSig));
+ }
+}
+
+function createKeySigner(bits) {
+ return function sign(thing, privateKey) {
+ checkIsPrivateKey(privateKey);
+ thing = normalizeInput(thing);
+ // Even though we are specifying "RSA" here, this works with ECDSA
+ // keys as well.
+ var signer = crypto.createSign('RSA-SHA' + bits);
+ var sig = (signer.update(thing), signer.sign(privateKey, 'base64'));
+ return fromBase64(sig);
+ }
+}
+
+function createKeyVerifier(bits) {
+ return function verify(thing, signature, publicKey) {
+ checkIsPublicKey(publicKey);
+ thing = normalizeInput(thing);
+ signature = toBase64(signature);
+ var verifier = crypto.createVerify('RSA-SHA' + bits);
+ verifier.update(thing);
+ return verifier.verify(publicKey, signature, 'base64');
+ }
+}
+
+function createPSSKeySigner(bits) {
+ return function sign(thing, privateKey) {
+ checkIsPrivateKey(privateKey);
+ thing = normalizeInput(thing);
+ var signer = crypto.createSign('RSA-SHA' + bits);
+ var sig = (signer.update(thing), signer.sign({
+ key: privateKey,
+ padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
+ saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
+ }, 'base64'));
+ return fromBase64(sig);
+ }
+}
+
+function createPSSKeyVerifier(bits) {
+ return function verify(thing, signature, publicKey) {
+ checkIsPublicKey(publicKey);
+ thing = normalizeInput(thing);
+ signature = toBase64(signature);
+ var verifier = crypto.createVerify('RSA-SHA' + bits);
+ verifier.update(thing);
+ return verifier.verify({
+ key: publicKey,
+ padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
+ saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
+ }, signature, 'base64');
+ }
+}
+
+function createECDSASigner(bits) {
+ var inner = createKeySigner(bits);
+ return function sign() {
+ var signature = inner.apply(null, arguments);
+ signature = formatEcdsa.derToJose(signature, 'ES' + bits);
+ return signature;
+ };
+}
+
+function createECDSAVerifer(bits) {
+ var inner = createKeyVerifier(bits);
+ return function verify(thing, signature, publicKey) {
+ signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64');
+ var result = inner(thing, signature, publicKey);
+ return result;
+ };
+}
+
+function createNoneSigner() {
+ return function sign() {
+ return '';
+ }
+}
+
+function createNoneVerifier() {
+ return function verify(thing, signature) {
+ return signature === '';
+ }
+}
+
+module.exports = function jwa(algorithm) {
+ var signerFactories = {
+ hs: createHmacSigner,
+ rs: createKeySigner,
+ ps: createPSSKeySigner,
+ es: createECDSASigner,
+ none: createNoneSigner,
+ }
+ var verifierFactories = {
+ hs: createHmacVerifier,
+ rs: createKeyVerifier,
+ ps: createPSSKeyVerifier,
+ es: createECDSAVerifer,
+ none: createNoneVerifier,
+ }
+ var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i);
+ if (!match)
+ throw typeError(MSG_INVALID_ALGORITHM, algorithm);
+ var algo = (match[1] || match[3]).toLowerCase();
+ var bits = match[2];
+
+ return {
+ sign: signerFactories[algo](bits),
+ verify: verifierFactories[algo](bits),
+ }
+};
+
+
+/***/ }),
+
+/***/ 2597:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+/*global exports*/
+var SignStream = __nccwpck_require__(5070);
+var VerifyStream = __nccwpck_require__(3974);
+
+var ALGORITHMS = [
+ 'HS256', 'HS384', 'HS512',
+ 'RS256', 'RS384', 'RS512',
+ 'PS256', 'PS384', 'PS512',
+ 'ES256', 'ES384', 'ES512'
+];
+
+exports.ALGORITHMS = ALGORITHMS;
+exports.sign = SignStream.sign;
+exports.verify = VerifyStream.verify;
+exports.decode = VerifyStream.decode;
+exports.isValid = VerifyStream.isValid;
+exports.createSign = function createSign(opts) {
+ return new SignStream(opts);
+};
+exports.createVerify = function createVerify(opts) {
+ return new VerifyStream(opts);
+};
+
+
+/***/ }),
+
+/***/ 704:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/*global module, process*/
+var Buffer = (__nccwpck_require__(1867).Buffer);
+var Stream = __nccwpck_require__(2781);
+var util = __nccwpck_require__(3837);
+
+function DataStream(data) {
+ this.buffer = null;
+ this.writable = true;
+ this.readable = true;
+
+ // No input
+ if (!data) {
+ this.buffer = Buffer.alloc(0);
+ return this;
+ }
+
+ // Stream
+ if (typeof data.pipe === 'function') {
+ this.buffer = Buffer.alloc(0);
+ data.pipe(this);
+ return this;
+ }
+
+ // Buffer or String
+ // or Object (assumedly a passworded key)
+ if (data.length || typeof data === 'object') {
+ this.buffer = data;
+ this.writable = false;
+ process.nextTick(function () {
+ this.emit('end', data);
+ this.readable = false;
+ this.emit('close');
+ }.bind(this));
+ return this;
+ }
+
+ throw new TypeError('Unexpected data type ('+ typeof data + ')');
+}
+util.inherits(DataStream, Stream);
+
+DataStream.prototype.write = function write(data) {
+ this.buffer = Buffer.concat([this.buffer, Buffer.from(data)]);
+ this.emit('data', data);
+};
+
+DataStream.prototype.end = function end(data) {
+ if (data)
+ this.write(data);
+ this.emit('end', data);
+ this.emit('close');
+ this.writable = false;
+ this.readable = false;
+};
+
+module.exports = DataStream;
+
+
+/***/ }),
+
+/***/ 5070:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/*global module*/
+var Buffer = (__nccwpck_require__(1867).Buffer);
+var DataStream = __nccwpck_require__(704);
+var jwa = __nccwpck_require__(2321);
+var Stream = __nccwpck_require__(2781);
+var toString = __nccwpck_require__(6206);
+var util = __nccwpck_require__(3837);
+
+function base64url(string, encoding) {
+ return Buffer
+ .from(string, encoding)
+ .toString('base64')
+ .replace(/=/g, '')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_');
+}
+
+function jwsSecuredInput(header, payload, encoding) {
+ encoding = encoding || 'utf8';
+ var encodedHeader = base64url(toString(header), 'binary');
+ var encodedPayload = base64url(toString(payload), encoding);
+ return util.format('%s.%s', encodedHeader, encodedPayload);
+}
+
+function jwsSign(opts) {
+ var header = opts.header;
+ var payload = opts.payload;
+ var secretOrKey = opts.secret || opts.privateKey;
+ var encoding = opts.encoding;
+ var algo = jwa(header.alg);
+ var securedInput = jwsSecuredInput(header, payload, encoding);
+ var signature = algo.sign(securedInput, secretOrKey);
+ return util.format('%s.%s', securedInput, signature);
+}
+
+function SignStream(opts) {
+ var secret = opts.secret||opts.privateKey||opts.key;
+ var secretStream = new DataStream(secret);
+ this.readable = true;
+ this.header = opts.header;
+ this.encoding = opts.encoding;
+ this.secret = this.privateKey = this.key = secretStream;
+ this.payload = new DataStream(opts.payload);
+ this.secret.once('close', function () {
+ if (!this.payload.writable && this.readable)
+ this.sign();
+ }.bind(this));
+
+ this.payload.once('close', function () {
+ if (!this.secret.writable && this.readable)
+ this.sign();
+ }.bind(this));
+}
+util.inherits(SignStream, Stream);
+
+SignStream.prototype.sign = function sign() {
+ try {
+ var signature = jwsSign({
+ header: this.header,
+ payload: this.payload.buffer,
+ secret: this.secret.buffer,
+ encoding: this.encoding
+ });
+ this.emit('done', signature);
+ this.emit('data', signature);
+ this.emit('end');
+ this.readable = false;
+ return signature;
+ } catch (e) {
+ this.readable = false;
+ this.emit('error', e);
+ this.emit('close');
+ }
+};
+
+SignStream.sign = jwsSign;
+
+module.exports = SignStream;
+
+
+/***/ }),
+
+/***/ 6206:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/*global module*/
+var Buffer = (__nccwpck_require__(4300).Buffer);
+
+module.exports = function toString(obj) {
+ if (typeof obj === 'string')
+ return obj;
+ if (typeof obj === 'number' || Buffer.isBuffer(obj))
+ return obj.toString();
+ return JSON.stringify(obj);
+};
+
+
+/***/ }),
+
+/***/ 3974:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/*global module*/
+var Buffer = (__nccwpck_require__(1867).Buffer);
+var DataStream = __nccwpck_require__(704);
+var jwa = __nccwpck_require__(2321);
+var Stream = __nccwpck_require__(2781);
+var toString = __nccwpck_require__(6206);
+var util = __nccwpck_require__(3837);
+var JWS_REGEX = /^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/;
+
+function isObject(thing) {
+ return Object.prototype.toString.call(thing) === '[object Object]';
+}
+
+function safeJsonParse(thing) {
+ if (isObject(thing))
+ return thing;
+ try { return JSON.parse(thing); }
+ catch (e) { return undefined; }
+}
+
+function headerFromJWS(jwsSig) {
+ var encodedHeader = jwsSig.split('.', 1)[0];
+ return safeJsonParse(Buffer.from(encodedHeader, 'base64').toString('binary'));
+}
+
+function securedInputFromJWS(jwsSig) {
+ return jwsSig.split('.', 2).join('.');
+}
+
+function signatureFromJWS(jwsSig) {
+ return jwsSig.split('.')[2];
+}
+
+function payloadFromJWS(jwsSig, encoding) {
+ encoding = encoding || 'utf8';
+ var payload = jwsSig.split('.')[1];
+ return Buffer.from(payload, 'base64').toString(encoding);
+}
+
+function isValidJws(string) {
+ return JWS_REGEX.test(string) && !!headerFromJWS(string);
+}
+
+function jwsVerify(jwsSig, algorithm, secretOrKey) {
+ if (!algorithm) {
+ var err = new Error("Missing algorithm parameter for jws.verify");
+ err.code = "MISSING_ALGORITHM";
+ throw err;
+ }
+ jwsSig = toString(jwsSig);
+ var signature = signatureFromJWS(jwsSig);
+ var securedInput = securedInputFromJWS(jwsSig);
+ var algo = jwa(algorithm);
+ return algo.verify(securedInput, signature, secretOrKey);
+}
+
+function jwsDecode(jwsSig, opts) {
+ opts = opts || {};
+ jwsSig = toString(jwsSig);
+
+ if (!isValidJws(jwsSig))
+ return null;
+
+ var header = headerFromJWS(jwsSig);
+
+ if (!header)
+ return null;
+
+ var payload = payloadFromJWS(jwsSig);
+ if (header.typ === 'JWT' || opts.json)
+ payload = JSON.parse(payload, opts.encoding);
+
+ return {
+ header: header,
+ payload: payload,
+ signature: signatureFromJWS(jwsSig)
+ };
+}
+
+function VerifyStream(opts) {
+ opts = opts || {};
+ var secretOrKey = opts.secret||opts.publicKey||opts.key;
+ var secretStream = new DataStream(secretOrKey);
+ this.readable = true;
+ this.algorithm = opts.algorithm;
+ this.encoding = opts.encoding;
+ this.secret = this.publicKey = this.key = secretStream;
+ this.signature = new DataStream(opts.signature);
+ this.secret.once('close', function () {
+ if (!this.signature.writable && this.readable)
+ this.verify();
+ }.bind(this));
+
+ this.signature.once('close', function () {
+ if (!this.secret.writable && this.readable)
+ this.verify();
+ }.bind(this));
+}
+util.inherits(VerifyStream, Stream);
+VerifyStream.prototype.verify = function verify() {
+ try {
+ var valid = jwsVerify(this.signature.buffer, this.algorithm, this.key.buffer);
+ var obj = jwsDecode(this.signature.buffer, this.encoding);
+ this.emit('done', valid, obj);
+ this.emit('data', valid);
+ this.emit('end');
+ this.readable = false;
+ return valid;
+ } catch (e) {
+ this.readable = false;
+ this.emit('error', e);
+ this.emit('close');
+ }
+};
+
+VerifyStream.decode = jwsDecode;
+VerifyStream.isValid = isValidJws;
+VerifyStream.verify = jwsVerify;
+
+module.exports = VerifyStream;
+
+
+/***/ }),
+
+/***/ 2022:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+const timespan = __nccwpck_require__(6098);
+const PS_SUPPORTED = __nccwpck_require__(9085);
+const validateAsymmetricKey = __nccwpck_require__(7596);
+const jws = __nccwpck_require__(2597);
+const {includes, isBoolean, isInteger, isNumber, isPlainObject, isString, once} = __nccwpck_require__(250)
+const { KeyObject, createSecretKey, createPrivateKey } = __nccwpck_require__(6113)
+
+const SUPPORTED_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'none'];
+if (PS_SUPPORTED) {
+ SUPPORTED_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512');
+}
+
+const sign_options_schema = {
+ expiresIn: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"expiresIn" should be a number of seconds or string representing a timespan' },
+ notBefore: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"notBefore" should be a number of seconds or string representing a timespan' },
+ audience: { isValid: function(value) { return isString(value) || Array.isArray(value); }, message: '"audience" must be a string or array' },
+ algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' },
+ header: { isValid: isPlainObject, message: '"header" must be an object' },
+ encoding: { isValid: isString, message: '"encoding" must be a string' },
+ issuer: { isValid: isString, message: '"issuer" must be a string' },
+ subject: { isValid: isString, message: '"subject" must be a string' },
+ jwtid: { isValid: isString, message: '"jwtid" must be a string' },
+ noTimestamp: { isValid: isBoolean, message: '"noTimestamp" must be a boolean' },
+ keyid: { isValid: isString, message: '"keyid" must be a string' },
+ mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' },
+ allowInsecureKeySizes: { isValid: isBoolean, message: '"allowInsecureKeySizes" must be a boolean'},
+ allowInvalidAsymmetricKeyTypes: { isValid: isBoolean, message: '"allowInvalidAsymmetricKeyTypes" must be a boolean'}
+};
+
+const registered_claims_schema = {
+ iat: { isValid: isNumber, message: '"iat" should be a number of seconds' },
+ exp: { isValid: isNumber, message: '"exp" should be a number of seconds' },
+ nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' }
+};
+
+function validate(schema, allowUnknown, object, parameterName) {
+ if (!isPlainObject(object)) {
+ throw new Error('Expected "' + parameterName + '" to be a plain object.');
+ }
+ Object.keys(object)
+ .forEach(function(key) {
+ const validator = schema[key];
+ if (!validator) {
+ if (!allowUnknown) {
+ throw new Error('"' + key + '" is not allowed in "' + parameterName + '"');
+ }
+ return;
+ }
+ if (!validator.isValid(object[key])) {
+ throw new Error(validator.message);
+ }
+ });
+}
+
+function validateOptions(options) {
+ return validate(sign_options_schema, false, options, 'options');
+}
+
+function validatePayload(payload) {
+ return validate(registered_claims_schema, true, payload, 'payload');
+}
+
+const options_to_payload = {
+ 'audience': 'aud',
+ 'issuer': 'iss',
+ 'subject': 'sub',
+ 'jwtid': 'jti'
+};
+
+const options_for_objects = [
+ 'expiresIn',
+ 'notBefore',
+ 'noTimestamp',
+ 'audience',
+ 'issuer',
+ 'subject',
+ 'jwtid',
+];
+
+module.exports = function (payload, secretOrPrivateKey, options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ } else {
+ options = options || {};
+ }
+
+ const isObjectPayload = typeof payload === 'object' &&
+ !Buffer.isBuffer(payload);
+
+ const header = Object.assign({
+ alg: options.algorithm || 'HS256',
+ typ: isObjectPayload ? 'JWT' : undefined,
+ kid: options.keyid
+ }, options.header);
+
+ function failure(err) {
+ if (callback) {
+ return callback(err);
+ }
+ throw err;
+ }
+
+ if (!secretOrPrivateKey && options.algorithm !== 'none') {
+ return failure(new Error('secretOrPrivateKey must have a value'));
+ }
+
+ if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) {
+ try {
+ secretOrPrivateKey = createPrivateKey(secretOrPrivateKey)
+ } catch (_) {
+ try {
+ secretOrPrivateKey = createSecretKey(typeof secretOrPrivateKey === 'string' ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey)
+ } catch (_) {
+ return failure(new Error('secretOrPrivateKey is not valid key material'));
+ }
+ }
+ }
+
+ if (header.alg.startsWith('HS') && secretOrPrivateKey.type !== 'secret') {
+ return failure(new Error((`secretOrPrivateKey must be a symmetric key when using ${header.alg}`)))
+ } else if (/^(?:RS|PS|ES)/.test(header.alg)) {
+ if (secretOrPrivateKey.type !== 'private') {
+ return failure(new Error((`secretOrPrivateKey must be an asymmetric key when using ${header.alg}`)))
+ }
+ if (!options.allowInsecureKeySizes &&
+ !header.alg.startsWith('ES') &&
+ secretOrPrivateKey.asymmetricKeyDetails !== undefined && //KeyObject.asymmetricKeyDetails is supported in Node 15+
+ secretOrPrivateKey.asymmetricKeyDetails.modulusLength < 2048) {
+ return failure(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`));
+ }
+ }
+
+ if (typeof payload === 'undefined') {
+ return failure(new Error('payload is required'));
+ } else if (isObjectPayload) {
+ try {
+ validatePayload(payload);
+ }
+ catch (error) {
+ return failure(error);
+ }
+ if (!options.mutatePayload) {
+ payload = Object.assign({},payload);
+ }
+ } else {
+ const invalid_options = options_for_objects.filter(function (opt) {
+ return typeof options[opt] !== 'undefined';
+ });
+
+ if (invalid_options.length > 0) {
+ return failure(new Error('invalid ' + invalid_options.join(',') + ' option for ' + (typeof payload ) + ' payload'));
+ }
+ }
+
+ if (typeof payload.exp !== 'undefined' && typeof options.expiresIn !== 'undefined') {
+ return failure(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.'));
+ }
+
+ if (typeof payload.nbf !== 'undefined' && typeof options.notBefore !== 'undefined') {
+ return failure(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.'));
+ }
+
+ try {
+ validateOptions(options);
+ }
+ catch (error) {
+ return failure(error);
+ }
+
+ if (!options.allowInvalidAsymmetricKeyTypes) {
+ try {
+ validateAsymmetricKey(header.alg, secretOrPrivateKey);
+ } catch (error) {
+ return failure(error);
+ }
+ }
+
+ const timestamp = payload.iat || Math.floor(Date.now() / 1000);
+
+ if (options.noTimestamp) {
+ delete payload.iat;
+ } else if (isObjectPayload) {
+ payload.iat = timestamp;
+ }
+
+ if (typeof options.notBefore !== 'undefined') {
+ try {
+ payload.nbf = timespan(options.notBefore, timestamp);
+ }
+ catch (err) {
+ return failure(err);
+ }
+ if (typeof payload.nbf === 'undefined') {
+ return failure(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
+ }
+ }
+
+ if (typeof options.expiresIn !== 'undefined' && typeof payload === 'object') {
+ try {
+ payload.exp = timespan(options.expiresIn, timestamp);
+ }
+ catch (err) {
+ return failure(err);
+ }
+ if (typeof payload.exp === 'undefined') {
+ return failure(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
+ }
+ }
+
+ Object.keys(options_to_payload).forEach(function (key) {
+ const claim = options_to_payload[key];
+ if (typeof options[key] !== 'undefined') {
+ if (typeof payload[claim] !== 'undefined') {
+ return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.'));
+ }
+ payload[claim] = options[key];
+ }
+ });
+
+ const encoding = options.encoding || 'utf8';
+
+ if (typeof callback === 'function') {
+ callback = callback && once(callback);
+
+ jws.createSign({
+ header: header,
+ privateKey: secretOrPrivateKey,
+ payload: payload,
+ encoding: encoding
+ }).once('error', callback)
+ .once('done', function (signature) {
+ // TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
+ if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
+ return callback(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`))
+ }
+ callback(null, signature);
+ });
+ } else {
+ let signature = jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding});
+ // TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
+ if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
+ throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)
+ }
+ return signature
+ }
+};
+
+
+/***/ }),
+
+/***/ 2327:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+const JsonWebTokenError = __nccwpck_require__(405);
+const NotBeforeError = __nccwpck_require__(4383);
+const TokenExpiredError = __nccwpck_require__(6637);
+const decode = __nccwpck_require__(3359);
+const timespan = __nccwpck_require__(6098);
+const validateAsymmetricKey = __nccwpck_require__(7596);
+const PS_SUPPORTED = __nccwpck_require__(9085);
+const jws = __nccwpck_require__(2597);
+const {KeyObject, createSecretKey, createPublicKey} = __nccwpck_require__(6113);
+
+const PUB_KEY_ALGS = ['RS256', 'RS384', 'RS512'];
+const EC_KEY_ALGS = ['ES256', 'ES384', 'ES512'];
+const RSA_KEY_ALGS = ['RS256', 'RS384', 'RS512'];
+const HS_ALGS = ['HS256', 'HS384', 'HS512'];
+
+if (PS_SUPPORTED) {
+ PUB_KEY_ALGS.splice(PUB_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512');
+ RSA_KEY_ALGS.splice(RSA_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512');
+}
+
+module.exports = function (jwtString, secretOrPublicKey, options, callback) {
+ if ((typeof options === 'function') && !callback) {
+ callback = options;
+ options = {};
+ }
+
+ if (!options) {
+ options = {};
+ }
+
+ //clone this object since we are going to mutate it.
+ options = Object.assign({}, options);
+
+ let done;
+
+ if (callback) {
+ done = callback;
+ } else {
+ done = function(err, data) {
+ if (err) throw err;
+ return data;
+ };
+ }
+
+ if (options.clockTimestamp && typeof options.clockTimestamp !== 'number') {
+ return done(new JsonWebTokenError('clockTimestamp must be a number'));
+ }
+
+ if (options.nonce !== undefined && (typeof options.nonce !== 'string' || options.nonce.trim() === '')) {
+ return done(new JsonWebTokenError('nonce must be a non-empty string'));
+ }
+
+ if (options.allowInvalidAsymmetricKeyTypes !== undefined && typeof options.allowInvalidAsymmetricKeyTypes !== 'boolean') {
+ return done(new JsonWebTokenError('allowInvalidAsymmetricKeyTypes must be a boolean'));
+ }
+
+ const clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000);
+
+ if (!jwtString){
+ return done(new JsonWebTokenError('jwt must be provided'));
+ }
+
+ if (typeof jwtString !== 'string') {
+ return done(new JsonWebTokenError('jwt must be a string'));
+ }
+
+ const parts = jwtString.split('.');
+
+ if (parts.length !== 3){
+ return done(new JsonWebTokenError('jwt malformed'));
+ }
+
+ let decodedToken;
+
+ try {
+ decodedToken = decode(jwtString, { complete: true });
+ } catch(err) {
+ return done(err);
+ }
+
+ if (!decodedToken) {
+ return done(new JsonWebTokenError('invalid token'));
+ }
+
+ const header = decodedToken.header;
+ let getSecret;
+
+ if(typeof secretOrPublicKey === 'function') {
+ if(!callback) {
+ return done(new JsonWebTokenError('verify must be called asynchronous if secret or public key is provided as a callback'));
+ }
+
+ getSecret = secretOrPublicKey;
+ }
+ else {
+ getSecret = function(header, secretCallback) {
+ return secretCallback(null, secretOrPublicKey);
+ };
+ }
+
+ return getSecret(header, function(err, secretOrPublicKey) {
+ if(err) {
+ return done(new JsonWebTokenError('error in secret or public key callback: ' + err.message));
+ }
+
+ const hasSignature = parts[2].trim() !== '';
+
+ if (!hasSignature && secretOrPublicKey){
+ return done(new JsonWebTokenError('jwt signature is required'));
+ }
+
+ if (hasSignature && !secretOrPublicKey) {
+ return done(new JsonWebTokenError('secret or public key must be provided'));
+ }
+
+ if (!hasSignature && !options.algorithms) {
+ return done(new JsonWebTokenError('please specify "none" in "algorithms" to verify unsigned tokens'));
+ }
+
+ if (secretOrPublicKey != null && !(secretOrPublicKey instanceof KeyObject)) {
+ try {
+ secretOrPublicKey = createPublicKey(secretOrPublicKey);
+ } catch (_) {
+ try {
+ secretOrPublicKey = createSecretKey(typeof secretOrPublicKey === 'string' ? Buffer.from(secretOrPublicKey) : secretOrPublicKey);
+ } catch (_) {
+ return done(new JsonWebTokenError('secretOrPublicKey is not valid key material'))
+ }
+ }
+ }
+
+ if (!options.algorithms) {
+ if (secretOrPublicKey.type === 'secret') {
+ options.algorithms = HS_ALGS;
+ } else if (['rsa', 'rsa-pss'].includes(secretOrPublicKey.asymmetricKeyType)) {
+ options.algorithms = RSA_KEY_ALGS
+ } else if (secretOrPublicKey.asymmetricKeyType === 'ec') {
+ options.algorithms = EC_KEY_ALGS
+ } else {
+ options.algorithms = PUB_KEY_ALGS
+ }
+ }
+
+ if (options.algorithms.indexOf(decodedToken.header.alg) === -1) {
+ return done(new JsonWebTokenError('invalid algorithm'));
+ }
+
+ if (header.alg.startsWith('HS') && secretOrPublicKey.type !== 'secret') {
+ return done(new JsonWebTokenError((`secretOrPublicKey must be a symmetric key when using ${header.alg}`)))
+ } else if (/^(?:RS|PS|ES)/.test(header.alg) && secretOrPublicKey.type !== 'public') {
+ return done(new JsonWebTokenError((`secretOrPublicKey must be an asymmetric key when using ${header.alg}`)))
+ }
+
+ if (!options.allowInvalidAsymmetricKeyTypes) {
+ try {
+ validateAsymmetricKey(header.alg, secretOrPublicKey);
+ } catch (e) {
+ return done(e);
+ }
+ }
+
+ let valid;
+
+ try {
+ valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey);
+ } catch (e) {
+ return done(e);
+ }
+
+ if (!valid) {
+ return done(new JsonWebTokenError('invalid signature'));
+ }
+
+ const payload = decodedToken.payload;
+
+ if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) {
+ if (typeof payload.nbf !== 'number') {
+ return done(new JsonWebTokenError('invalid nbf value'));
+ }
+ if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) {
+ return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
+ }
+ }
+
+ if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) {
+ if (typeof payload.exp !== 'number') {
+ return done(new JsonWebTokenError('invalid exp value'));
+ }
+ if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) {
+ return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000)));
+ }
+ }
+
+ if (options.audience) {
+ const audiences = Array.isArray(options.audience) ? options.audience : [options.audience];
+ const target = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
+
+ const match = target.some(function (targetAudience) {
+ return audiences.some(function (audience) {
+ return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience;
+ });
+ });
+
+ if (!match) {
+ return done(new JsonWebTokenError('jwt audience invalid. expected: ' + audiences.join(' or ')));
+ }
+ }
+
+ if (options.issuer) {
+ const invalid_issuer =
+ (typeof options.issuer === 'string' && payload.iss !== options.issuer) ||
+ (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1);
+
+ if (invalid_issuer) {
+ return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer));
+ }
+ }
+
+ if (options.subject) {
+ if (payload.sub !== options.subject) {
+ return done(new JsonWebTokenError('jwt subject invalid. expected: ' + options.subject));
+ }
+ }
+
+ if (options.jwtid) {
+ if (payload.jti !== options.jwtid) {
+ return done(new JsonWebTokenError('jwt jwtid invalid. expected: ' + options.jwtid));
+ }
+ }
+
+ if (options.nonce) {
+ if (payload.nonce !== options.nonce) {
+ return done(new JsonWebTokenError('jwt nonce invalid. expected: ' + options.nonce));
+ }
+ }
+
+ if (options.maxAge) {
+ if (typeof payload.iat !== 'number') {
+ return done(new JsonWebTokenError('iat required when maxAge is specified'));
+ }
+
+ const maxAgeTimestamp = timespan(options.maxAge, payload.iat);
+ if (typeof maxAgeTimestamp === 'undefined') {
+ return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
+ }
+ if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) {
+ return done(new TokenExpiredError('maxAge exceeded', new Date(maxAgeTimestamp * 1000)));
+ }
+ }
+
+ if (options.complete === true) {
+ const signature = decodedToken.signature;
+
+ return done(null, {
+ header: header,
+ payload: payload,
+ signature: signature
+ });
+ }
+
+ return done(null, payload);
+ });
+};
+
+
+/***/ }),
+
+/***/ 250:
+/***/ (function(module, exports, __nccwpck_require__) {
+
+/* module decorator */ module = __nccwpck_require__.nmd(module);
+/**
+ * @license
+ * Lodash
+ * Copyright OpenJS Foundation and other contributors
+ * Released under MIT license
+ * Based on Underscore.js 1.8.3
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ */
+;(function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used as the semantic version number. */
+ var VERSION = '4.17.21';
+
+ /** Used as the size to enable large array optimizations. */
+ var LARGE_ARRAY_SIZE = 200;
+
+ /** Error message constants. */
+ var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
+ FUNC_ERROR_TEXT = 'Expected a function',
+ INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /** Used as the maximum memoize cache size. */
+ var MAX_MEMOIZE_SIZE = 500;
+
+ /** Used as the internal argument placeholder. */
+ var PLACEHOLDER = '__lodash_placeholder__';
+
+ /** Used to compose bitmasks for cloning. */
+ var CLONE_DEEP_FLAG = 1,
+ CLONE_FLAT_FLAG = 2,
+ CLONE_SYMBOLS_FLAG = 4;
+
+ /** Used to compose bitmasks for value comparisons. */
+ var COMPARE_PARTIAL_FLAG = 1,
+ COMPARE_UNORDERED_FLAG = 2;
+
+ /** Used to compose bitmasks for function metadata. */
+ var WRAP_BIND_FLAG = 1,
+ WRAP_BIND_KEY_FLAG = 2,
+ WRAP_CURRY_BOUND_FLAG = 4,
+ WRAP_CURRY_FLAG = 8,
+ WRAP_CURRY_RIGHT_FLAG = 16,
+ WRAP_PARTIAL_FLAG = 32,
+ WRAP_PARTIAL_RIGHT_FLAG = 64,
+ WRAP_ARY_FLAG = 128,
+ WRAP_REARG_FLAG = 256,
+ WRAP_FLIP_FLAG = 512;
+
+ /** Used as default options for `_.truncate`. */
+ var DEFAULT_TRUNC_LENGTH = 30,
+ DEFAULT_TRUNC_OMISSION = '...';
+
+ /** Used to detect hot functions by number of calls within a span of milliseconds. */
+ var HOT_COUNT = 800,
+ HOT_SPAN = 16;
+
+ /** Used to indicate the type of lazy iteratees. */
+ var LAZY_FILTER_FLAG = 1,
+ LAZY_MAP_FLAG = 2,
+ LAZY_WHILE_FLAG = 3;
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY = 1 / 0,
+ MAX_SAFE_INTEGER = 9007199254740991,
+ MAX_INTEGER = 1.7976931348623157e+308,
+ NAN = 0 / 0;
+
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295,
+ MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
+ HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
+ /** Used to associate wrap methods with their bit flags. */
+ var wrapFlags = [
+ ['ary', WRAP_ARY_FLAG],
+ ['bind', WRAP_BIND_FLAG],
+ ['bindKey', WRAP_BIND_KEY_FLAG],
+ ['curry', WRAP_CURRY_FLAG],
+ ['curryRight', WRAP_CURRY_RIGHT_FLAG],
+ ['flip', WRAP_FLIP_FLAG],
+ ['partial', WRAP_PARTIAL_FLAG],
+ ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
+ ['rearg', WRAP_REARG_FLAG]
+ ];
+
+ /** `Object#toString` result references. */
+ var argsTag = '[object Arguments]',
+ arrayTag = '[object Array]',
+ asyncTag = '[object AsyncFunction]',
+ boolTag = '[object Boolean]',
+ dateTag = '[object Date]',
+ domExcTag = '[object DOMException]',
+ errorTag = '[object Error]',
+ funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]',
+ mapTag = '[object Map]',
+ numberTag = '[object Number]',
+ nullTag = '[object Null]',
+ objectTag = '[object Object]',
+ promiseTag = '[object Promise]',
+ proxyTag = '[object Proxy]',
+ regexpTag = '[object RegExp]',
+ setTag = '[object Set]',
+ stringTag = '[object String]',
+ symbolTag = '[object Symbol]',
+ undefinedTag = '[object Undefined]',
+ weakMapTag = '[object WeakMap]',
+ weakSetTag = '[object WeakSet]';
+
+ var arrayBufferTag = '[object ArrayBuffer]',
+ dataViewTag = '[object DataView]',
+ float32Tag = '[object Float32Array]',
+ float64Tag = '[object Float64Array]',
+ int8Tag = '[object Int8Array]',
+ int16Tag = '[object Int16Array]',
+ int32Tag = '[object Int32Array]',
+ uint8Tag = '[object Uint8Array]',
+ uint8ClampedTag = '[object Uint8ClampedArray]',
+ uint16Tag = '[object Uint16Array]',
+ uint32Tag = '[object Uint32Array]';
+
+ /** Used to match empty string literals in compiled template source. */
+ var reEmptyStringLeading = /\b__p \+= '';/g,
+ reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
+ reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
+
+ /** Used to match HTML entities and HTML characters. */
+ var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
+ reUnescapedHtml = /[&<>"']/g,
+ reHasEscapedHtml = RegExp(reEscapedHtml.source),
+ reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+ /** Used to match template delimiters. */
+ var reEscape = /<%-([\s\S]+?)%>/g,
+ reEvaluate = /<%([\s\S]+?)%>/g,
+ reInterpolate = /<%=([\s\S]+?)%>/g;
+
+ /** Used to match property names within property paths. */
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
+ reIsPlainProp = /^\w*$/,
+ rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
+
+ /**
+ * Used to match `RegExp`
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+ */
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
+ reHasRegExpChar = RegExp(reRegExpChar.source);
+
+ /** Used to match leading whitespace. */
+ var reTrimStart = /^\s+/;
+
+ /** Used to match a single whitespace character. */
+ var reWhitespace = /\s/;
+
+ /** Used to match wrap detail comments. */
+ var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
+ reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
+ reSplitDetails = /,? & /;
+
+ /** Used to match words composed of alphanumeric characters. */
+ var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
+
+ /**
+ * Used to validate the `validate` option in `_.template` variable.
+ *
+ * Forbids characters which could potentially change the meaning of the function argument definition:
+ * - "()," (modification of function parameters)
+ * - "=" (default value)
+ * - "[]{}" (destructuring of function parameters)
+ * - "/" (beginning of a comment)
+ * - whitespace
+ */
+ var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
+
+ /** Used to match backslashes in property paths. */
+ var reEscapeChar = /\\(\\)?/g;
+
+ /**
+ * Used to match
+ * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
+ */
+ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
+
+ /** Used to match `RegExp` flags from their coerced string values. */
+ var reFlags = /\w*$/;
+
+ /** Used to detect bad signed hexadecimal string values. */
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+ /** Used to detect binary string values. */
+ var reIsBinary = /^0b[01]+$/i;
+
+ /** Used to detect host constructors (Safari). */
+ var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+ /** Used to detect octal string values. */
+ var reIsOctal = /^0o[0-7]+$/i;
+
+ /** Used to detect unsigned integer values. */
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+ /** Used to match Latin Unicode letters (excluding mathematical operators). */
+ var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
+
+ /** Used to ensure capturing order of template delimiters. */
+ var reNoMatch = /($^)/;
+
+ /** Used to match unescaped characters in compiled string literals. */
+ var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboMarksRange = '\\u0300-\\u036f',
+ reComboHalfMarksRange = '\\ufe20-\\ufe2f',
+ rsComboSymbolsRange = '\\u20d0-\\u20ff',
+ rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
+ rsDingbatRange = '\\u2700-\\u27bf',
+ rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
+ rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
+ rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
+ rsPunctuationRange = '\\u2000-\\u206f',
+ rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
+ rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
+ rsVarRange = '\\ufe0e\\ufe0f',
+ rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
+
+ /** Used to compose unicode capture groups. */
+ var rsApos = "['\u2019]",
+ rsAstral = '[' + rsAstralRange + ']',
+ rsBreak = '[' + rsBreakRange + ']',
+ rsCombo = '[' + rsComboRange + ']',
+ rsDigits = '\\d+',
+ rsDingbat = '[' + rsDingbatRange + ']',
+ rsLower = '[' + rsLowerRange + ']',
+ rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsUpper = '[' + rsUpperRange + ']',
+ rsZWJ = '\\u200d';
+
+ /** Used to compose unicode regexes. */
+ var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
+ rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
+ rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
+ rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
+ reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
+ rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
+ rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+ /** Used to match apostrophes. */
+ var reApos = RegExp(rsApos, 'g');
+
+ /**
+ * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+ * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+ */
+ var reComboMark = RegExp(rsCombo, 'g');
+
+ /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+ var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+
+ /** Used to match complex or compound words. */
+ var reUnicodeWord = RegExp([
+ rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+ rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
+ rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
+ rsUpper + '+' + rsOptContrUpper,
+ rsOrdUpper,
+ rsOrdLower,
+ rsDigits,
+ rsEmoji
+ ].join('|'), 'g');
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /** Used to detect strings that need a more robust regexp to match words. */
+ var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
+
+ /** Used to assign default `context` object properties. */
+ var contextProps = [
+ 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
+ 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
+ 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
+ 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
+ '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
+ ];
+
+ /** Used to make template sourceURLs easier to identify. */
+ var templateCounter = -1;
+
+ /** Used to identify `toStringTag` values of typed arrays. */
+ var typedArrayTags = {};
+ typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+ typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+ typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+ typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+ typedArrayTags[uint32Tag] = true;
+ typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+ typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+ typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
+ typedArrayTags[errorTag] = typedArrayTags[funcTag] =
+ typedArrayTags[mapTag] = typedArrayTags[numberTag] =
+ typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
+ typedArrayTags[setTag] = typedArrayTags[stringTag] =
+ typedArrayTags[weakMapTag] = false;
+
+ /** Used to identify `toStringTag` values supported by `_.clone`. */
+ var cloneableTags = {};
+ cloneableTags[argsTag] = cloneableTags[arrayTag] =
+ cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
+ cloneableTags[boolTag] = cloneableTags[dateTag] =
+ cloneableTags[float32Tag] = cloneableTags[float64Tag] =
+ cloneableTags[int8Tag] = cloneableTags[int16Tag] =
+ cloneableTags[int32Tag] = cloneableTags[mapTag] =
+ cloneableTags[numberTag] = cloneableTags[objectTag] =
+ cloneableTags[regexpTag] = cloneableTags[setTag] =
+ cloneableTags[stringTag] = cloneableTags[symbolTag] =
+ cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+ cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+ cloneableTags[errorTag] = cloneableTags[funcTag] =
+ cloneableTags[weakMapTag] = false;
+
+ /** Used to map Latin Unicode letters to basic Latin letters. */
+ var deburredLetters = {
+ // Latin-1 Supplement block.
+ '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
+ '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
+ '\xc7': 'C', '\xe7': 'c',
+ '\xd0': 'D', '\xf0': 'd',
+ '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
+ '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
+ '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
+ '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
+ '\xd1': 'N', '\xf1': 'n',
+ '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
+ '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
+ '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
+ '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
+ '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
+ '\xc6': 'Ae', '\xe6': 'ae',
+ '\xde': 'Th', '\xfe': 'th',
+ '\xdf': 'ss',
+ // Latin Extended-A block.
+ '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
+ '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
+ '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
+ '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
+ '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
+ '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
+ '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
+ '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
+ '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
+ '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
+ '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
+ '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
+ '\u0134': 'J', '\u0135': 'j',
+ '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
+ '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
+ '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
+ '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
+ '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
+ '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
+ '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
+ '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
+ '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
+ '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
+ '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
+ '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
+ '\u0163': 't', '\u0165': 't', '\u0167': 't',
+ '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
+ '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
+ '\u0174': 'W', '\u0175': 'w',
+ '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
+ '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
+ '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
+ '\u0132': 'IJ', '\u0133': 'ij',
+ '\u0152': 'Oe', '\u0153': 'oe',
+ '\u0149': "'n", '\u017f': 's'
+ };
+
+ /** Used to map characters to HTML entities. */
+ var htmlEscapes = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
+ };
+
+ /** Used to map HTML entities to characters. */
+ var htmlUnescapes = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ ''': "'"
+ };
+
+ /** Used to escape characters for inclusion in compiled string literals. */
+ var stringEscapes = {
+ '\\': '\\',
+ "'": "'",
+ '\n': 'n',
+ '\r': 'r',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseFloat = parseFloat,
+ freeParseInt = parseInt;
+
+ /** Detect free variable `global` from Node.js. */
+ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
+
+ /** Detect free variable `self`. */
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
+
+ /** Used as a reference to the global object. */
+ var root = freeGlobal || freeSelf || Function('return this')();
+
+ /** Detect free variable `exports`. */
+ var freeExports = true && exports && !exports.nodeType && exports;
+
+ /** Detect free variable `module`. */
+ var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
+
+ /** Detect the popular CommonJS extension `module.exports`. */
+ var moduleExports = freeModule && freeModule.exports === freeExports;
+
+ /** Detect free variable `process` from Node.js. */
+ var freeProcess = moduleExports && freeGlobal.process;
+
+ /** Used to access faster Node.js helpers. */
+ var nodeUtil = (function() {
+ try {
+ // Use `util.types` for Node.js 10+.
+ var types = freeModule && freeModule.require && freeModule.require('util').types;
+
+ if (types) {
+ return types;
+ }
+
+ // Legacy `process.binding('util')` for Node.js < 10.
+ return freeProcess && freeProcess.binding && freeProcess.binding('util');
+ } catch (e) {}
+ }());
+
+ /* Node.js helper references. */
+ var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
+ nodeIsDate = nodeUtil && nodeUtil.isDate,
+ nodeIsMap = nodeUtil && nodeUtil.isMap,
+ nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
+ nodeIsSet = nodeUtil && nodeUtil.isSet,
+ nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply(func, thisArg, args) {
+ switch (args.length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
+ }
+ return func.apply(thisArg, args);
+ }
+
+ /**
+ * A specialized version of `baseAggregator` for arrays.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */
+ function arrayAggregator(array, setter, iteratee, accumulator) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ while (++index < length) {
+ var value = array[index];
+ setter(accumulator, value, iteratee(value), array);
+ }
+ return accumulator;
+ }
+
+ /**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.forEachRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEachRight(array, iteratee) {
+ var length = array == null ? 0 : array.length;
+
+ while (length--) {
+ if (iteratee(array[length], length, array) === false) {
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`.
+ */
+ function arrayEvery(array, predicate) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ while (++index < length) {
+ if (!predicate(array[index], index, array)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * A specialized version of `_.filter` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */
+ function arrayFilter(array, predicate) {
+ var index = -1,
+ length = array == null ? 0 : array.length,
+ resIndex = 0,
+ result = [];
+
+ while (++index < length) {
+ var value = array[index];
+ if (predicate(value, index, array)) {
+ result[resIndex++] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A specialized version of `_.includes` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludes(array, value) {
+ var length = array == null ? 0 : array.length;
+ return !!length && baseIndexOf(array, value, 0) > -1;
+ }
+
+ /**
+ * This function is like `arrayIncludes` except that it accepts a comparator.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludesWith(array, value, comparator) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ while (++index < length) {
+ if (comparator(value, array[index])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function arrayMap(array, iteratee) {
+ var index = -1,
+ length = array == null ? 0 : array.length,
+ result = Array(length);
+
+ while (++index < length) {
+ result[index] = iteratee(array[index], index, array);
+ }
+ return result;
+ }
+
+ /**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayPush(array, values) {
+ var index = -1,
+ length = values.length,
+ offset = array.length;
+
+ while (++index < length) {
+ array[offset + index] = values[index];
+ }
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.reduce` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as
+ * the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+ function arrayReduce(array, iteratee, accumulator, initAccum) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ if (initAccum && length) {
+ accumulator = array[++index];
+ }
+ while (++index < length) {
+ accumulator = iteratee(accumulator, array[index], index, array);
+ }
+ return accumulator;
+ }
+
+ /**
+ * A specialized version of `_.reduceRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as
+ * the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+ function arrayReduceRight(array, iteratee, accumulator, initAccum) {
+ var length = array == null ? 0 : array.length;
+ if (initAccum && length) {
+ accumulator = array[--length];
+ }
+ while (length--) {
+ accumulator = iteratee(accumulator, array[length], length, array);
+ }
+ return accumulator;
+ }
+
+ /**
+ * A specialized version of `_.some` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ */
+ function arraySome(array, predicate) {
+ var index = -1,
+ length = array == null ? 0 : array.length;
+
+ while (++index < length) {
+ if (predicate(array[index], index, array)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the size of an ASCII `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */
+ var asciiSize = baseProperty('length');
+
+ /**
+ * Converts an ASCII `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function asciiToArray(string) {
+ return string.split('');
+ }
+
+ /**
+ * Splits an ASCII `string` into an array of its words.
+ *
+ * @private
+ * @param {string} The string to inspect.
+ * @returns {Array} Returns the words of `string`.
+ */
+ function asciiWords(string) {
+ return string.match(reAsciiWord) || [];
+ }
+
+ /**
+ * The base implementation of methods like `_.findKey` and `_.findLastKey`,
+ * without support for iteratee shorthands, which iterates over `collection`
+ * using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+ function baseFindKey(collection, predicate, eachFunc) {
+ var result;
+ eachFunc(collection, function(value, key, collection) {
+ if (predicate(value, key, collection)) {
+ result = key;
+ return false;
+ }
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseFindIndex(array, predicate, fromIndex, fromRight) {
+ var length = array.length,
+ index = fromIndex + (fromRight ? 1 : -1);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ if (predicate(array[index], index, array)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseIndexOf(array, value, fromIndex) {
+ return value === value
+ ? strictIndexOf(array, value, fromIndex)
+ : baseFindIndex(array, baseIsNaN, fromIndex);
+ }
+
+ /**
+ * This function is like `baseIndexOf` except that it accepts a comparator.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseIndexOfWith(array, value, fromIndex, comparator) {
+ var index = fromIndex - 1,
+ length = array.length;
+
+ while (++index < length) {
+ if (comparator(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * The base implementation of `_.isNaN` without support for number objects.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ */
+ function baseIsNaN(value) {
+ return value !== value;
+ }
+
+ /**
+ * The base implementation of `_.mean` and `_.meanBy` without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {number} Returns the mean.
+ */
+ function baseMean(array, iteratee) {
+ var length = array == null ? 0 : array.length;
+ return length ? (baseSum(array, iteratee) / length) : NAN;
+ }
+
+ /**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */
+ function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+ }
+
+ /**
+ * The base implementation of `_.propertyOf` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Function} Returns the new accessor function.
+ */
+ function basePropertyOf(object) {
+ return function(key) {
+ return object == null ? undefined : object[key];
+ };
+ }
+
+ /**
+ * The base implementation of `_.reduce` and `_.reduceRight`, without support
+ * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} accumulator The initial value.
+ * @param {boolean} initAccum Specify using the first or last element of
+ * `collection` as the initial value.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the accumulated value.
+ */
+ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
+ eachFunc(collection, function(value, index, collection) {
+ accumulator = initAccum
+ ? (initAccum = false, value)
+ : iteratee(accumulator, value, index, collection);
+ });
+ return accumulator;
+ }
+
+ /**
+ * The base implementation of `_.sortBy` which uses `comparer` to define the
+ * sort order of `array` and replaces criteria objects with their corresponding
+ * values.
+ *
+ * @private
+ * @param {Array} array The array to sort.
+ * @param {Function} comparer The function to define sort order.
+ * @returns {Array} Returns `array`.
+ */
+ function baseSortBy(array, comparer) {
+ var length = array.length;
+
+ array.sort(comparer);
+ while (length--) {
+ array[length] = array[length].value;
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of `_.sum` and `_.sumBy` without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {number} Returns the sum.
+ */
+ function baseSum(array, iteratee) {
+ var result,
+ index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var current = iteratee(array[index]);
+ if (current !== undefined) {
+ result = result === undefined ? current : (result + current);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
+ * of key-value pairs for `object` corresponding to the property names of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the key-value pairs.
+ */
+ function baseToPairs(object, props) {
+ return arrayMap(props, function(key) {
+ return [key, object[key]];
+ });
+ }
+
+ /**
+ * The base implementation of `_.trim`.
+ *
+ * @private
+ * @param {string} string The string to trim.
+ * @returns {string} Returns the trimmed string.
+ */
+ function baseTrim(string) {
+ return string
+ ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
+ : string;
+ }
+
+ /**
+ * The base implementation of `_.unary` without support for storing metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ */
+ function baseUnary(func) {
+ return function(value) {
+ return func(value);
+ };
+ }
+
+ /**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */
+ function baseValues(object, props) {
+ return arrayMap(props, function(key) {
+ return object[key];
+ });
+ }
+
+ /**
+ * Checks if a `cache` value for `key` exists.
+ *
+ * @private
+ * @param {Object} cache The cache to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function cacheHas(cache, key) {
+ return cache.has(key);
+ }
+
+ /**
+ * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the first unmatched string symbol.
+ */
+ function charsStartIndex(strSymbols, chrSymbols) {
+ var index = -1,
+ length = strSymbols.length;
+
+ while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ /**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the last unmatched string symbol.
+ */
+ function charsEndIndex(strSymbols, chrSymbols) {
+ var index = strSymbols.length;
+
+ while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ /**
+ * Gets the number of `placeholder` occurrences in `array`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} placeholder The placeholder to search for.
+ * @returns {number} Returns the placeholder count.
+ */
+ function countHolders(array, placeholder) {
+ var length = array.length,
+ result = 0;
+
+ while (length--) {
+ if (array[length] === placeholder) {
+ ++result;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
+ * letters to basic Latin letters.
+ *
+ * @private
+ * @param {string} letter The matched letter to deburr.
+ * @returns {string} Returns the deburred letter.
+ */
+ var deburrLetter = basePropertyOf(deburredLetters);
+
+ /**
+ * Used by `_.escape` to convert characters to HTML entities.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */
+ var escapeHtmlChar = basePropertyOf(htmlEscapes);
+
+ /**
+ * Used by `_.template` to escape characters for inclusion in compiled string literals.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */
+ function escapeStringChar(chr) {
+ return '\\' + stringEscapes[chr];
+ }
+
+ /**
+ * Gets the value at `key` of `object`.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */
+ function getValue(object, key) {
+ return object == null ? undefined : object[key];
+ }
+
+ /**
+ * Checks if `string` contains Unicode symbols.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {boolean} Returns `true` if a symbol is found, else `false`.
+ */
+ function hasUnicode(string) {
+ return reHasUnicode.test(string);
+ }
+
+ /**
+ * Checks if `string` contains a word composed of Unicode symbols.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {boolean} Returns `true` if a word is found, else `false`.
+ */
+ function hasUnicodeWord(string) {
+ return reHasUnicodeWord.test(string);
+ }
+
+ /**
+ * Converts `iterator` to an array.
+ *
+ * @private
+ * @param {Object} iterator The iterator to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function iteratorToArray(iterator) {
+ var data,
+ result = [];
+
+ while (!(data = iterator.next()).done) {
+ result.push(data.value);
+ }
+ return result;
+ }
+
+ /**
+ * Converts `map` to its key-value pairs.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the key-value pairs.
+ */
+ function mapToArray(map) {
+ var index = -1,
+ result = Array(map.size);
+
+ map.forEach(function(value, key) {
+ result[++index] = [key, value];
+ });
+ return result;
+ }
+
+ /**
+ * Creates a unary function that invokes `func` with its argument transformed.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {Function} transform The argument transform.
+ * @returns {Function} Returns the new function.
+ */
+ function overArg(func, transform) {
+ return function(arg) {
+ return func(transform(arg));
+ };
+ }
+
+ /**
+ * Replaces all `placeholder` elements in `array` with an internal placeholder
+ * and returns an array of their indexes.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {*} placeholder The placeholder to replace.
+ * @returns {Array} Returns the new array of placeholder indexes.
+ */
+ function replaceHolders(array, placeholder) {
+ var index = -1,
+ length = array.length,
+ resIndex = 0,
+ result = [];
+
+ while (++index < length) {
+ var value = array[index];
+ if (value === placeholder || value === PLACEHOLDER) {
+ array[index] = PLACEHOLDER;
+ result[resIndex++] = index;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Converts `set` to an array of its values.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the values.
+ */
+ function setToArray(set) {
+ var index = -1,
+ result = Array(set.size);
+
+ set.forEach(function(value) {
+ result[++index] = value;
+ });
+ return result;
+ }
+
+ /**
+ * Converts `set` to its value-value pairs.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the value-value pairs.
+ */
+ function setToPairs(set) {
+ var index = -1,
+ result = Array(set.size);
+
+ set.forEach(function(value) {
+ result[++index] = [value, value];
+ });
+ return result;
+ }
+
+ /**
+ * A specialized version of `_.indexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function strictIndexOf(array, value, fromIndex) {
+ var index = fromIndex - 1,
+ length = array.length;
+
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * A specialized version of `_.lastIndexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function strictLastIndexOf(array, value, fromIndex) {
+ var index = fromIndex + 1;
+ while (index--) {
+ if (array[index] === value) {
+ return index;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * Gets the number of symbols in `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the string size.
+ */
+ function stringSize(string) {
+ return hasUnicode(string)
+ ? unicodeSize(string)
+ : asciiSize(string);
+ }
+
+ /**
+ * Converts `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function stringToArray(string) {
+ return hasUnicode(string)
+ ? unicodeToArray(string)
+ : asciiToArray(string);
+ }
+
+ /**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
+ * character of `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the index of the last non-whitespace character.
+ */
+ function trimmedEndIndex(string) {
+ var index = string.length;
+
+ while (index-- && reWhitespace.test(string.charAt(index))) {}
+ return index;
+ }
+
+ /**
+ * Used by `_.unescape` to convert HTML entities to characters.
+ *
+ * @private
+ * @param {string} chr The matched character to unescape.
+ * @returns {string} Returns the unescaped character.
+ */
+ var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
+
+ /**
+ * Gets the size of a Unicode `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */
+ function unicodeSize(string) {
+ var result = reUnicode.lastIndex = 0;
+ while (reUnicode.test(string)) {
+ ++result;
+ }
+ return result;
+ }
+
+ /**
+ * Converts a Unicode `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function unicodeToArray(string) {
+ return string.match(reUnicode) || [];
+ }
+
+ /**
+ * Splits a Unicode `string` into an array of its words.
+ *
+ * @private
+ * @param {string} The string to inspect.
+ * @returns {Array} Returns the words of `string`.
+ */
+ function unicodeWords(string) {
+ return string.match(reUnicodeWord) || [];
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Create a new pristine `lodash` function using the `context` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Util
+ * @param {Object} [context=root] The context object.
+ * @returns {Function} Returns a new `lodash` function.
+ * @example
+ *
+ * _.mixin({ 'foo': _.constant('foo') });
+ *
+ * var lodash = _.runInContext();
+ * lodash.mixin({ 'bar': lodash.constant('bar') });
+ *
+ * _.isFunction(_.foo);
+ * // => true
+ * _.isFunction(_.bar);
+ * // => false
+ *
+ * lodash.isFunction(lodash.foo);
+ * // => false
+ * lodash.isFunction(lodash.bar);
+ * // => true
+ *
+ * // Create a suped-up `defer` in Node.js.
+ * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+ */
+ var runInContext = (function runInContext(context) {
+ context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
+
+ /** Built-in constructor references. */
+ var Array = context.Array,
+ Date = context.Date,
+ Error = context.Error,
+ Function = context.Function,
+ Math = context.Math,
+ Object = context.Object,
+ RegExp = context.RegExp,
+ String = context.String,
+ TypeError = context.TypeError;
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype,
+ funcProto = Function.prototype,
+ objectProto = Object.prototype;
+
+ /** Used to detect overreaching core-js shims. */
+ var coreJsData = context['__core-js_shared__'];
+
+ /** Used to resolve the decompiled source of functions. */
+ var funcToString = funcProto.toString;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /** Used to generate unique IDs. */
+ var idCounter = 0;
+
+ /** Used to detect methods masquerading as native. */
+ var maskSrcKey = (function() {
+ var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
+ return uid ? ('Symbol(src)_1.' + uid) : '';
+ }());
+
+ /**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var nativeObjectToString = objectProto.toString;
+
+ /** Used to infer the `Object` constructor. */
+ var objectCtorString = funcToString.call(Object);
+
+ /** Used to restore the original `_` reference in `_.noConflict`. */
+ var oldDash = root._;
+
+ /** Used to detect if a method is native. */
+ var reIsNative = RegExp('^' +
+ funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+ );
+
+ /** Built-in value references. */
+ var Buffer = moduleExports ? context.Buffer : undefined,
+ Symbol = context.Symbol,
+ Uint8Array = context.Uint8Array,
+ allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
+ getPrototype = overArg(Object.getPrototypeOf, Object),
+ objectCreate = Object.create,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
+ splice = arrayProto.splice,
+ spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
+ symIterator = Symbol ? Symbol.iterator : undefined,
+ symToStringTag = Symbol ? Symbol.toStringTag : undefined;
+
+ var defineProperty = (function() {
+ try {
+ var func = getNative(Object, 'defineProperty');
+ func({}, '', {});
+ return func;
+ } catch (e) {}
+ }());
+
+ /** Mocked built-ins. */
+ var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
+ ctxNow = Date && Date.now !== root.Date.now && Date.now,
+ ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil,
+ nativeFloor = Math.floor,
+ nativeGetSymbols = Object.getOwnPropertySymbols,
+ nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
+ nativeIsFinite = context.isFinite,
+ nativeJoin = arrayProto.join,
+ nativeKeys = overArg(Object.keys, Object),
+ nativeMax = Math.max,
+ nativeMin = Math.min,
+ nativeNow = Date.now,
+ nativeParseInt = context.parseInt,
+ nativeRandom = Math.random,
+ nativeReverse = arrayProto.reverse;
+
+ /* Built-in method references that are verified to be native. */
+ var DataView = getNative(context, 'DataView'),
+ Map = getNative(context, 'Map'),
+ Promise = getNative(context, 'Promise'),
+ Set = getNative(context, 'Set'),
+ WeakMap = getNative(context, 'WeakMap'),
+ nativeCreate = getNative(Object, 'create');
+
+ /** Used to store function metadata. */
+ var metaMap = WeakMap && new WeakMap;
+
+ /** Used to lookup unminified function names. */
+ var realNames = {};
+
+ /** Used to detect maps, sets, and weakmaps. */
+ var dataViewCtorString = toSource(DataView),
+ mapCtorString = toSource(Map),
+ promiseCtorString = toSource(Promise),
+ setCtorString = toSource(Set),
+ weakMapCtorString = toSource(WeakMap);
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
+ symbolToString = symbolProto ? symbolProto.toString : undefined;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chain sequences. Methods that operate on and return arrays, collections,
+ * and functions can be chained together. Methods that retrieve a single value
+ * or may return a primitive value will automatically end the chain sequence
+ * and return the unwrapped value. Otherwise, the value must be unwrapped
+ * with `_#value`.
+ *
+ * Explicit chain sequences, which must be unwrapped with `_#value`, may be
+ * enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion.
+ * Shortcut fusion is an optimization to merge iteratee calls; this avoids
+ * the creation of intermediate arrays and can greatly reduce the number of
+ * iteratee executions. Sections of a chain sequence qualify for shortcut
+ * fusion if the section is applied to an array and iteratees accept only
+ * one argument. The heuristic for whether a section qualifies for shortcut
+ * fusion is subject to change.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
+ * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
+ * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
+ * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
+ * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
+ * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
+ * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
+ * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
+ * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
+ * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
+ * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
+ * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
+ * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
+ * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
+ * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
+ * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
+ * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
+ * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
+ * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
+ * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
+ * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
+ * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
+ * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
+ * `zipObject`, `zipObjectDeep`, and `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
+ * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
+ * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
+ * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
+ * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
+ * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
+ * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
+ * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
+ * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
+ * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
+ * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
+ * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
+ * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
+ * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
+ * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
+ * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
+ * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
+ * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
+ * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
+ * `upperFirst`, `value`, and `words`
+ *
+ * @name _
+ * @constructor
+ * @category Seq
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // Returns an unwrapped value.
+ * wrapped.reduce(_.add);
+ * // => 6
+ *
+ * // Returns a wrapped value.
+ * var squares = wrapped.map(square);
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+ function lodash(value) {
+ if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+ if (value instanceof LodashWrapper) {
+ return value;
+ }
+ if (hasOwnProperty.call(value, '__wrapped__')) {
+ return wrapperClone(value);
+ }
+ }
+ return new LodashWrapper(value);
+ }
+
+ /**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} proto The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+ var baseCreate = (function() {
+ function object() {}
+ return function(proto) {
+ if (!isObject(proto)) {
+ return {};
+ }
+ if (objectCreate) {
+ return objectCreate(proto);
+ }
+ object.prototype = proto;
+ var result = new object;
+ object.prototype = undefined;
+ return result;
+ };
+ }());
+
+ /**
+ * The function whose prototype chain sequence wrappers inherit from.
+ *
+ * @private
+ */
+ function baseLodash() {
+ // No operation performed.
+ }
+
+ /**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable explicit method chain sequences.
+ */
+ function LodashWrapper(value, chainAll) {
+ this.__wrapped__ = value;
+ this.__actions__ = [];
+ this.__chain__ = !!chainAll;
+ this.__index__ = 0;
+ this.__values__ = undefined;
+ }
+
+ /**
+ * By default, the template delimiters used by lodash are like those in
+ * embedded Ruby (ERB) as well as ES2015 template strings. Change the
+ * following template settings to use alternative delimiters.
+ *
+ * @static
+ * @memberOf _
+ * @type {Object}
+ */
+ lodash.templateSettings = {
+
+ /**
+ * Used to detect `data` property values to be HTML-escaped.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */
+ 'escape': reEscape,
+
+ /**
+ * Used to detect code to be evaluated.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */
+ 'evaluate': reEvaluate,
+
+ /**
+ * Used to detect `data` property values to inject.
+ *
+ * @memberOf _.templateSettings
+ * @type {RegExp}
+ */
+ 'interpolate': reInterpolate,
+
+ /**
+ * Used to reference the data object in the template text.
+ *
+ * @memberOf _.templateSettings
+ * @type {string}
+ */
+ 'variable': '',
+
+ /**
+ * Used to import variables into the compiled template.
+ *
+ * @memberOf _.templateSettings
+ * @type {Object}
+ */
+ 'imports': {
+
+ /**
+ * A reference to the `lodash` function.
+ *
+ * @memberOf _.templateSettings.imports
+ * @type {Function}
+ */
+ '_': lodash
+ }
+ };
+
+ // Ensure wrappers are instances of `baseLodash`.
+ lodash.prototype = baseLodash.prototype;
+ lodash.prototype.constructor = lodash;
+
+ LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+ LodashWrapper.prototype.constructor = LodashWrapper;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+ *
+ * @private
+ * @constructor
+ * @param {*} value The value to wrap.
+ */
+ function LazyWrapper(value) {
+ this.__wrapped__ = value;
+ this.__actions__ = [];
+ this.__dir__ = 1;
+ this.__filtered__ = false;
+ this.__iteratees__ = [];
+ this.__takeCount__ = MAX_ARRAY_LENGTH;
+ this.__views__ = [];
+ }
+
+ /**
+ * Creates a clone of the lazy wrapper object.
+ *
+ * @private
+ * @name clone
+ * @memberOf LazyWrapper
+ * @returns {Object} Returns the cloned `LazyWrapper` object.
+ */
+ function lazyClone() {
+ var result = new LazyWrapper(this.__wrapped__);
+ result.__actions__ = copyArray(this.__actions__);
+ result.__dir__ = this.__dir__;
+ result.__filtered__ = this.__filtered__;
+ result.__iteratees__ = copyArray(this.__iteratees__);
+ result.__takeCount__ = this.__takeCount__;
+ result.__views__ = copyArray(this.__views__);
+ return result;
+ }
+
+ /**
+ * Reverses the direction of lazy iteration.
+ *
+ * @private
+ * @name reverse
+ * @memberOf LazyWrapper
+ * @returns {Object} Returns the new reversed `LazyWrapper` object.
+ */
+ function lazyReverse() {
+ if (this.__filtered__) {
+ var result = new LazyWrapper(this);
+ result.__dir__ = -1;
+ result.__filtered__ = true;
+ } else {
+ result = this.clone();
+ result.__dir__ *= -1;
+ }
+ return result;
+ }
+
+ /**
+ * Extracts the unwrapped value from its lazy wrapper.
+ *
+ * @private
+ * @name value
+ * @memberOf LazyWrapper
+ * @returns {*} Returns the unwrapped value.
+ */
+ function lazyValue() {
+ var array = this.__wrapped__.value(),
+ dir = this.__dir__,
+ isArr = isArray(array),
+ isRight = dir < 0,
+ arrLength = isArr ? array.length : 0,
+ view = getView(0, arrLength, this.__views__),
+ start = view.start,
+ end = view.end,
+ length = end - start,
+ index = isRight ? end : (start - 1),
+ iteratees = this.__iteratees__,
+ iterLength = iteratees.length,
+ resIndex = 0,
+ takeCount = nativeMin(length, this.__takeCount__);
+
+ if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
+ return baseWrapperValue(array, this.__actions__);
+ }
+ var result = [];
+
+ outer:
+ while (length-- && resIndex < takeCount) {
+ index += dir;
+
+ var iterIndex = -1,
+ value = array[index];
+
+ while (++iterIndex < iterLength) {
+ var data = iteratees[iterIndex],
+ iteratee = data.iteratee,
+ type = data.type,
+ computed = iteratee(value);
+
+ if (type == LAZY_MAP_FLAG) {
+ value = computed;
+ } else if (!computed) {
+ if (type == LAZY_FILTER_FLAG) {
+ continue outer;
+ } else {
+ break outer;
+ }
+ }
+ }
+ result[resIndex++] = value;
+ }
+ return result;
+ }
+
+ // Ensure `LazyWrapper` is an instance of `baseLodash`.
+ LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+ LazyWrapper.prototype.constructor = LazyWrapper;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a hash object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+ function Hash(entries) {
+ var index = -1,
+ length = entries == null ? 0 : entries.length;
+
+ this.clear();
+ while (++index < length) {
+ var entry = entries[index];
+ this.set(entry[0], entry[1]);
+ }
+ }
+
+ /**
+ * Removes all key-value entries from the hash.
+ *
+ * @private
+ * @name clear
+ * @memberOf Hash
+ */
+ function hashClear() {
+ this.__data__ = nativeCreate ? nativeCreate(null) : {};
+ this.size = 0;
+ }
+
+ /**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @name delete
+ * @memberOf Hash
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function hashDelete(key) {
+ var result = this.has(key) && delete this.__data__[key];
+ this.size -= result ? 1 : 0;
+ return result;
+ }
+
+ /**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Hash
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function hashGet(key) {
+ var data = this.__data__;
+ if (nativeCreate) {
+ var result = data[key];
+ return result === HASH_UNDEFINED ? undefined : result;
+ }
+ return hasOwnProperty.call(data, key) ? data[key] : undefined;
+ }
+
+ /**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Hash
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function hashHas(key) {
+ var data = this.__data__;
+ return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
+ }
+
+ /**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Hash
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the hash instance.
+ */
+ function hashSet(key, value) {
+ var data = this.__data__;
+ this.size += this.has(key) ? 0 : 1;
+ data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+ return this;
+ }
+
+ // Add methods to `Hash`.
+ Hash.prototype.clear = hashClear;
+ Hash.prototype['delete'] = hashDelete;
+ Hash.prototype.get = hashGet;
+ Hash.prototype.has = hashHas;
+ Hash.prototype.set = hashSet;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates an list cache object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+ function ListCache(entries) {
+ var index = -1,
+ length = entries == null ? 0 : entries.length;
+
+ this.clear();
+ while (++index < length) {
+ var entry = entries[index];
+ this.set(entry[0], entry[1]);
+ }
+ }
+
+ /**
+ * Removes all key-value entries from the list cache.
+ *
+ * @private
+ * @name clear
+ * @memberOf ListCache
+ */
+ function listCacheClear() {
+ this.__data__ = [];
+ this.size = 0;
+ }
+
+ /**
+ * Removes `key` and its value from the list cache.
+ *
+ * @private
+ * @name delete
+ * @memberOf ListCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function listCacheDelete(key) {
+ var data = this.__data__,
+ index = assocIndexOf(data, key);
+
+ if (index < 0) {
+ return false;
+ }
+ var lastIndex = data.length - 1;
+ if (index == lastIndex) {
+ data.pop();
+ } else {
+ splice.call(data, index, 1);
+ }
+ --this.size;
+ return true;
+ }
+
+ /**
+ * Gets the list cache value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf ListCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function listCacheGet(key) {
+ var data = this.__data__,
+ index = assocIndexOf(data, key);
+
+ return index < 0 ? undefined : data[index][1];
+ }
+
+ /**
+ * Checks if a list cache value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf ListCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function listCacheHas(key) {
+ return assocIndexOf(this.__data__, key) > -1;
+ }
+
+ /**
+ * Sets the list cache `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf ListCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the list cache instance.
+ */
+ function listCacheSet(key, value) {
+ var data = this.__data__,
+ index = assocIndexOf(data, key);
+
+ if (index < 0) {
+ ++this.size;
+ data.push([key, value]);
+ } else {
+ data[index][1] = value;
+ }
+ return this;
+ }
+
+ // Add methods to `ListCache`.
+ ListCache.prototype.clear = listCacheClear;
+ ListCache.prototype['delete'] = listCacheDelete;
+ ListCache.prototype.get = listCacheGet;
+ ListCache.prototype.has = listCacheHas;
+ ListCache.prototype.set = listCacheSet;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+ function MapCache(entries) {
+ var index = -1,
+ length = entries == null ? 0 : entries.length;
+
+ this.clear();
+ while (++index < length) {
+ var entry = entries[index];
+ this.set(entry[0], entry[1]);
+ }
+ }
+
+ /**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */
+ function mapCacheClear() {
+ this.size = 0;
+ this.__data__ = {
+ 'hash': new Hash,
+ 'map': new (Map || ListCache),
+ 'string': new Hash
+ };
+ }
+
+ /**
+ * Removes `key` and its value from the map.
+ *
+ * @private
+ * @name delete
+ * @memberOf MapCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function mapCacheDelete(key) {
+ var result = getMapData(this, key)['delete'](key);
+ this.size -= result ? 1 : 0;
+ return result;
+ }
+
+ /**
+ * Gets the map value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf MapCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function mapCacheGet(key) {
+ return getMapData(this, key).get(key);
+ }
+
+ /**
+ * Checks if a map value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf MapCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function mapCacheHas(key) {
+ return getMapData(this, key).has(key);
+ }
+
+ /**
+ * Sets the map `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache instance.
+ */
+ function mapCacheSet(key, value) {
+ var data = getMapData(this, key),
+ size = data.size;
+
+ data.set(key, value);
+ this.size += data.size == size ? 0 : 1;
+ return this;
+ }
+
+ // Add methods to `MapCache`.
+ MapCache.prototype.clear = mapCacheClear;
+ MapCache.prototype['delete'] = mapCacheDelete;
+ MapCache.prototype.get = mapCacheGet;
+ MapCache.prototype.has = mapCacheHas;
+ MapCache.prototype.set = mapCacheSet;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ *
+ * Creates an array cache object to store unique values.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [values] The values to cache.
+ */
+ function SetCache(values) {
+ var index = -1,
+ length = values == null ? 0 : values.length;
+
+ this.__data__ = new MapCache;
+ while (++index < length) {
+ this.add(values[index]);
+ }
+ }
+
+ /**
+ * Adds `value` to the array cache.
+ *
+ * @private
+ * @name add
+ * @memberOf SetCache
+ * @alias push
+ * @param {*} value The value to cache.
+ * @returns {Object} Returns the cache instance.
+ */
+ function setCacheAdd(value) {
+ this.__data__.set(value, HASH_UNDEFINED);
+ return this;
+ }
+
+ /**
+ * Checks if `value` is in the array cache.
+ *
+ * @private
+ * @name has
+ * @memberOf SetCache
+ * @param {*} value The value to search for.
+ * @returns {number} Returns `true` if `value` is found, else `false`.
+ */
+ function setCacheHas(value) {
+ return this.__data__.has(value);
+ }
+
+ // Add methods to `SetCache`.
+ SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
+ SetCache.prototype.has = setCacheHas;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+ function Stack(entries) {
+ var data = this.__data__ = new ListCache(entries);
+ this.size = data.size;
+ }
+
+ /**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+ function stackClear() {
+ this.__data__ = new ListCache;
+ this.size = 0;
+ }
+
+ /**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function stackDelete(key) {
+ var data = this.__data__,
+ result = data['delete'](key);
+
+ this.size = data.size;
+ return result;
+ }
+
+ /**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function stackGet(key) {
+ return this.__data__.get(key);
+ }
+
+ /**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function stackHas(key) {
+ return this.__data__.has(key);
+ }
+
+ /**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache instance.
+ */
+ function stackSet(key, value) {
+ var data = this.__data__;
+ if (data instanceof ListCache) {
+ var pairs = data.__data__;
+ if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
+ pairs.push([key, value]);
+ this.size = ++data.size;
+ return this;
+ }
+ data = this.__data__ = new MapCache(pairs);
+ }
+ data.set(key, value);
+ this.size = data.size;
+ return this;
+ }
+
+ // Add methods to `Stack`.
+ Stack.prototype.clear = stackClear;
+ Stack.prototype['delete'] = stackDelete;
+ Stack.prototype.get = stackGet;
+ Stack.prototype.has = stackHas;
+ Stack.prototype.set = stackSet;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates an array of the enumerable property names of the array-like `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @param {boolean} inherited Specify returning inherited property names.
+ * @returns {Array} Returns the array of property names.
+ */
+ function arrayLikeKeys(value, inherited) {
+ var isArr = isArray(value),
+ isArg = !isArr && isArguments(value),
+ isBuff = !isArr && !isArg && isBuffer(value),
+ isType = !isArr && !isArg && !isBuff && isTypedArray(value),
+ skipIndexes = isArr || isArg || isBuff || isType,
+ result = skipIndexes ? baseTimes(value.length, String) : [],
+ length = result.length;
+
+ for (var key in value) {
+ if ((inherited || hasOwnProperty.call(value, key)) &&
+ !(skipIndexes && (
+ // Safari 9 has enumerable `arguments.length` in strict mode.
+ key == 'length' ||
+ // Node.js 0.10 has enumerable non-index properties on buffers.
+ (isBuff && (key == 'offset' || key == 'parent')) ||
+ // PhantomJS 2 has enumerable non-index properties on typed arrays.
+ (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
+ // Skip index properties.
+ isIndex(key, length)
+ ))) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A specialized version of `_.sample` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to sample.
+ * @returns {*} Returns the random element.
+ */
+ function arraySample(array) {
+ var length = array.length;
+ return length ? array[baseRandom(0, length - 1)] : undefined;
+ }
+
+ /**
+ * A specialized version of `_.sampleSize` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to sample.
+ * @param {number} n The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ */
+ function arraySampleSize(array, n) {
+ return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
+ }
+
+ /**
+ * A specialized version of `_.shuffle` for arrays.
+ *
+ * @private
+ * @param {Array} array The array to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ */
+ function arrayShuffle(array) {
+ return shuffleSelf(copyArray(array));
+ }
+
+ /**
+ * This function is like `assignValue` except that it doesn't assign
+ * `undefined` values.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignMergeValue(object, key, value) {
+ if ((value !== undefined && !eq(object[key], value)) ||
+ (value === undefined && !(key in object))) {
+ baseAssignValue(object, key, value);
+ }
+ }
+
+ /**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignValue(object, key, value) {
+ var objValue = object[key];
+ if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
+ (value === undefined && !(key in object))) {
+ baseAssignValue(object, key, value);
+ }
+ }
+
+ /**
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function assocIndexOf(array, key) {
+ var length = array.length;
+ while (length--) {
+ if (eq(array[length][0], key)) {
+ return length;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Aggregates elements of `collection` on `accumulator` with keys transformed
+ * by `iteratee` and values set by `setter`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */
+ function baseAggregator(collection, setter, iteratee, accumulator) {
+ baseEach(collection, function(value, key, collection) {
+ setter(accumulator, value, iteratee(value), collection);
+ });
+ return accumulator;
+ }
+
+ /**
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+ function baseAssign(object, source) {
+ return object && copyObject(source, keys(source), object);
+ }
+
+ /**
+ * The base implementation of `_.assignIn` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+ function baseAssignIn(object, source) {
+ return object && copyObject(source, keysIn(source), object);
+ }
+
+ /**
+ * The base implementation of `assignValue` and `assignMergeValue` without
+ * value checks.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function baseAssignValue(object, key, value) {
+ if (key == '__proto__' && defineProperty) {
+ defineProperty(object, key, {
+ 'configurable': true,
+ 'enumerable': true,
+ 'value': value,
+ 'writable': true
+ });
+ } else {
+ object[key] = value;
+ }
+ }
+
+ /**
+ * The base implementation of `_.at` without support for individual paths.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Array} Returns the picked elements.
+ */
+ function baseAt(object, paths) {
+ var index = -1,
+ length = paths.length,
+ result = Array(length),
+ skip = object == null;
+
+ while (++index < length) {
+ result[index] = skip ? undefined : get(object, paths[index]);
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.clamp` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ */
+ function baseClamp(number, lower, upper) {
+ if (number === number) {
+ if (upper !== undefined) {
+ number = number <= upper ? number : upper;
+ }
+ if (lower !== undefined) {
+ number = number >= lower ? number : lower;
+ }
+ }
+ return number;
+ }
+
+ /**
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} bitmask The bitmask flags.
+ * 1 - Deep clone
+ * 2 - Flatten inherited properties
+ * 4 - Clone symbols
+ * @param {Function} [customizer] The function to customize cloning.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+ function baseClone(value, bitmask, customizer, key, object, stack) {
+ var result,
+ isDeep = bitmask & CLONE_DEEP_FLAG,
+ isFlat = bitmask & CLONE_FLAT_FLAG,
+ isFull = bitmask & CLONE_SYMBOLS_FLAG;
+
+ if (customizer) {
+ result = object ? customizer(value, key, object, stack) : customizer(value);
+ }
+ if (result !== undefined) {
+ return result;
+ }
+ if (!isObject(value)) {
+ return value;
+ }
+ var isArr = isArray(value);
+ if (isArr) {
+ result = initCloneArray(value);
+ if (!isDeep) {
+ return copyArray(value, result);
+ }
+ } else {
+ var tag = getTag(value),
+ isFunc = tag == funcTag || tag == genTag;
+
+ if (isBuffer(value)) {
+ return cloneBuffer(value, isDeep);
+ }
+ if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+ result = (isFlat || isFunc) ? {} : initCloneObject(value);
+ if (!isDeep) {
+ return isFlat
+ ? copySymbolsIn(value, baseAssignIn(result, value))
+ : copySymbols(value, baseAssign(result, value));
+ }
+ } else {
+ if (!cloneableTags[tag]) {
+ return object ? value : {};
+ }
+ result = initCloneByTag(value, tag, isDeep);
+ }
+ }
+ // Check for circular references and return its corresponding clone.
+ stack || (stack = new Stack);
+ var stacked = stack.get(value);
+ if (stacked) {
+ return stacked;
+ }
+ stack.set(value, result);
+
+ if (isSet(value)) {
+ value.forEach(function(subValue) {
+ result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
+ });
+ } else if (isMap(value)) {
+ value.forEach(function(subValue, key) {
+ result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
+ });
+ }
+
+ var keysFunc = isFull
+ ? (isFlat ? getAllKeysIn : getAllKeys)
+ : (isFlat ? keysIn : keys);
+
+ var props = isArr ? undefined : keysFunc(value);
+ arrayEach(props || value, function(subValue, key) {
+ if (props) {
+ key = subValue;
+ subValue = value[key];
+ }
+ // Recursively populate clone (susceptible to call stack limits).
+ assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.conforms` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new spec function.
+ */
+ function baseConforms(source) {
+ var props = keys(source);
+ return function(object) {
+ return baseConformsTo(object, source, props);
+ };
+ }
+
+ /**
+ * The base implementation of `_.conformsTo` which accepts `props` to check.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+ */
+ function baseConformsTo(object, source, props) {
+ var length = props.length;
+ if (object == null) {
+ return !length;
+ }
+ object = Object(object);
+ while (length--) {
+ var key = props[length],
+ predicate = source[key],
+ value = object[key];
+
+ if ((value === undefined && !(key in object)) || !predicate(value)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * The base implementation of `_.delay` and `_.defer` which accepts `args`
+ * to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {Array} args The arguments to provide to `func`.
+ * @returns {number|Object} Returns the timer id or timeout object.
+ */
+ function baseDelay(func, wait, args) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return setTimeout(function() { func.apply(undefined, args); }, wait);
+ }
+
+ /**
+ * The base implementation of methods like `_.difference` without support
+ * for excluding multiple arrays or iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Array} values The values to exclude.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ */
+ function baseDifference(array, values, iteratee, comparator) {
+ var index = -1,
+ includes = arrayIncludes,
+ isCommon = true,
+ length = array.length,
+ result = [],
+ valuesLength = values.length;
+
+ if (!length) {
+ return result;
+ }
+ if (iteratee) {
+ values = arrayMap(values, baseUnary(iteratee));
+ }
+ if (comparator) {
+ includes = arrayIncludesWith;
+ isCommon = false;
+ }
+ else if (values.length >= LARGE_ARRAY_SIZE) {
+ includes = cacheHas;
+ isCommon = false;
+ values = new SetCache(values);
+ }
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee == null ? value : iteratee(value);
+
+ value = (comparator || value !== 0) ? value : 0;
+ if (isCommon && computed === computed) {
+ var valuesIndex = valuesLength;
+ while (valuesIndex--) {
+ if (values[valuesIndex] === computed) {
+ continue outer;
+ }
+ }
+ result.push(value);
+ }
+ else if (!includes(values, computed, comparator)) {
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */
+ var baseEach = createBaseEach(baseForOwn);
+
+ /**
+ * The base implementation of `_.forEachRight` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */
+ var baseEachRight = createBaseEach(baseForOwnRight, true);
+
+ /**
+ * The base implementation of `_.every` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`
+ */
+ function baseEvery(collection, predicate) {
+ var result = true;
+ baseEach(collection, function(value, index, collection) {
+ result = !!predicate(value, index, collection);
+ return result;
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
+ * @returns {*} Returns the extremum value.
+ */
+ function baseExtremum(array, iteratee, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index],
+ current = iteratee(value);
+
+ if (current != null && (computed === undefined
+ ? (current === current && !isSymbol(current))
+ : comparator(current, computed)
+ )) {
+ var computed = current,
+ result = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.fill` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to fill.
+ * @param {*} value The value to fill `array` with.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns `array`.
+ */
+ function baseFill(array, value, start, end) {
+ var length = array.length;
+
+ start = toInteger(start);
+ if (start < 0) {
+ start = -start > length ? 0 : (length + start);
+ }
+ end = (end === undefined || end > length) ? length : toInteger(end);
+ if (end < 0) {
+ end += length;
+ }
+ end = start > end ? 0 : toLength(end);
+ while (start < end) {
+ array[start++] = value;
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of `_.filter` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */
+ function baseFilter(collection, predicate) {
+ var result = [];
+ baseEach(collection, function(value, index, collection) {
+ if (predicate(value, index, collection)) {
+ result.push(value);
+ }
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.flatten` with support for restricting flattening.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {number} depth The maximum recursion depth.
+ * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
+ * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */
+ function baseFlatten(array, depth, predicate, isStrict, result) {
+ var index = -1,
+ length = array.length;
+
+ predicate || (predicate = isFlattenable);
+ result || (result = []);
+
+ while (++index < length) {
+ var value = array[index];
+ if (depth > 0 && predicate(value)) {
+ if (depth > 1) {
+ // Recursively flatten arrays (susceptible to call stack limits).
+ baseFlatten(value, depth - 1, predicate, isStrict, result);
+ } else {
+ arrayPush(result, value);
+ }
+ } else if (!isStrict) {
+ result[result.length] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseFor = createBaseFor();
+
+ /**
+ * This function is like `baseFor` except that it iterates over properties
+ * in the opposite order.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseForRight = createBaseFor(true);
+
+ /**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys);
+ }
+
+ /**
+ * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwnRight(object, iteratee) {
+ return object && baseForRight(object, iteratee, keys);
+ }
+
+ /**
+ * The base implementation of `_.functions` which creates an array of
+ * `object` function property names filtered from `props`.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Array} props The property names to filter.
+ * @returns {Array} Returns the function names.
+ */
+ function baseFunctions(object, props) {
+ return arrayFilter(props, function(key) {
+ return isFunction(object[key]);
+ });
+ }
+
+ /**
+ * The base implementation of `_.get` without support for default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseGet(object, path) {
+ path = castPath(path, object);
+
+ var index = 0,
+ length = path.length;
+
+ while (object != null && index < length) {
+ object = object[toKey(path[index++])];
+ }
+ return (index && index == length) ? object : undefined;
+ }
+
+ /**
+ * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
+ * `keysFunc` and `symbolsFunc` to get the enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @param {Function} symbolsFunc The function to get the symbols of `object`.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+ function baseGetAllKeys(object, keysFunc, symbolsFunc) {
+ var result = keysFunc(object);
+ return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
+ }
+
+ /**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+ function baseGetTag(value) {
+ if (value == null) {
+ return value === undefined ? undefinedTag : nullTag;
+ }
+ return (symToStringTag && symToStringTag in Object(value))
+ ? getRawTag(value)
+ : objectToString(value);
+ }
+
+ /**
+ * The base implementation of `_.gt` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than `other`,
+ * else `false`.
+ */
+ function baseGt(value, other) {
+ return value > other;
+ }
+
+ /**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHas(object, key) {
+ return object != null && hasOwnProperty.call(object, key);
+ }
+
+ /**
+ * The base implementation of `_.hasIn` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHasIn(object, key) {
+ return object != null && key in Object(object);
+ }
+
+ /**
+ * The base implementation of `_.inRange` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {number} number The number to check.
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ */
+ function baseInRange(number, start, end) {
+ return number >= nativeMin(start, end) && number < nativeMax(start, end);
+ }
+
+ /**
+ * The base implementation of methods like `_.intersection`, without support
+ * for iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ */
+ function baseIntersection(arrays, iteratee, comparator) {
+ var includes = comparator ? arrayIncludesWith : arrayIncludes,
+ length = arrays[0].length,
+ othLength = arrays.length,
+ othIndex = othLength,
+ caches = Array(othLength),
+ maxLength = Infinity,
+ result = [];
+
+ while (othIndex--) {
+ var array = arrays[othIndex];
+ if (othIndex && iteratee) {
+ array = arrayMap(array, baseUnary(iteratee));
+ }
+ maxLength = nativeMin(array.length, maxLength);
+ caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
+ ? new SetCache(othIndex && array)
+ : undefined;
+ }
+ array = arrays[0];
+
+ var index = -1,
+ seen = caches[0];
+
+ outer:
+ while (++index < length && result.length < maxLength) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ value = (comparator || value !== 0) ? value : 0;
+ if (!(seen
+ ? cacheHas(seen, computed)
+ : includes(result, computed, comparator)
+ )) {
+ othIndex = othLength;
+ while (--othIndex) {
+ var cache = caches[othIndex];
+ if (!(cache
+ ? cacheHas(cache, computed)
+ : includes(arrays[othIndex], computed, comparator))
+ ) {
+ continue outer;
+ }
+ }
+ if (seen) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.invert` and `_.invertBy` which inverts
+ * `object` with values transformed by `iteratee` and set by `setter`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform values.
+ * @param {Object} accumulator The initial inverted object.
+ * @returns {Function} Returns `accumulator`.
+ */
+ function baseInverter(object, setter, iteratee, accumulator) {
+ baseForOwn(object, function(value, key, object) {
+ setter(accumulator, iteratee(value), key, object);
+ });
+ return accumulator;
+ }
+
+ /**
+ * The base implementation of `_.invoke` without support for individual
+ * method arguments.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} args The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ */
+ function baseInvoke(object, path, args) {
+ path = castPath(path, object);
+ object = parent(object, path);
+ var func = object == null ? object : object[toKey(last(path))];
+ return func == null ? undefined : apply(func, object, args);
+ }
+
+ /**
+ * The base implementation of `_.isArguments`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ */
+ function baseIsArguments(value) {
+ return isObjectLike(value) && baseGetTag(value) == argsTag;
+ }
+
+ /**
+ * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+ */
+ function baseIsArrayBuffer(value) {
+ return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
+ }
+
+ /**
+ * The base implementation of `_.isDate` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+ */
+ function baseIsDate(value) {
+ return isObjectLike(value) && baseGetTag(value) == dateTag;
+ }
+
+ /**
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {boolean} bitmask The bitmask flags.
+ * 1 - Unordered comparison
+ * 2 - Partial comparison
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */
+ function baseIsEqual(value, other, bitmask, customizer, stack) {
+ if (value === other) {
+ return true;
+ }
+ if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
+ return value !== value && other !== other;
+ }
+ return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
+ }
+
+ /**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
+ var objIsArr = isArray(object),
+ othIsArr = isArray(other),
+ objTag = objIsArr ? arrayTag : getTag(object),
+ othTag = othIsArr ? arrayTag : getTag(other);
+
+ objTag = objTag == argsTag ? objectTag : objTag;
+ othTag = othTag == argsTag ? objectTag : othTag;
+
+ var objIsObj = objTag == objectTag,
+ othIsObj = othTag == objectTag,
+ isSameTag = objTag == othTag;
+
+ if (isSameTag && isBuffer(object)) {
+ if (!isBuffer(other)) {
+ return false;
+ }
+ objIsArr = true;
+ objIsObj = false;
+ }
+ if (isSameTag && !objIsObj) {
+ stack || (stack = new Stack);
+ return (objIsArr || isTypedArray(object))
+ ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
+ : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
+ }
+ if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
+ var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+ othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+ if (objIsWrapped || othIsWrapped) {
+ var objUnwrapped = objIsWrapped ? object.value() : object,
+ othUnwrapped = othIsWrapped ? other.value() : other;
+
+ stack || (stack = new Stack);
+ return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
+ }
+ }
+ if (!isSameTag) {
+ return false;
+ }
+ stack || (stack = new Stack);
+ return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
+ }
+
+ /**
+ * The base implementation of `_.isMap` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ */
+ function baseIsMap(value) {
+ return isObjectLike(value) && getTag(value) == mapTag;
+ }
+
+ /**
+ * The base implementation of `_.isMatch` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Array} matchData The property names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ */
+ function baseIsMatch(object, source, matchData, customizer) {
+ var index = matchData.length,
+ length = index,
+ noCustomizer = !customizer;
+
+ if (object == null) {
+ return !length;
+ }
+ object = Object(object);
+ while (index--) {
+ var data = matchData[index];
+ if ((noCustomizer && data[2])
+ ? data[1] !== object[data[0]]
+ : !(data[0] in object)
+ ) {
+ return false;
+ }
+ }
+ while (++index < length) {
+ data = matchData[index];
+ var key = data[0],
+ objValue = object[key],
+ srcValue = data[1];
+
+ if (noCustomizer && data[2]) {
+ if (objValue === undefined && !(key in object)) {
+ return false;
+ }
+ } else {
+ var stack = new Stack;
+ if (customizer) {
+ var result = customizer(objValue, srcValue, key, object, source, stack);
+ }
+ if (!(result === undefined
+ ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
+ : result
+ )) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * The base implementation of `_.isNative` without bad shim checks.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ * else `false`.
+ */
+ function baseIsNative(value) {
+ if (!isObject(value) || isMasked(value)) {
+ return false;
+ }
+ var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
+ return pattern.test(toSource(value));
+ }
+
+ /**
+ * The base implementation of `_.isRegExp` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+ */
+ function baseIsRegExp(value) {
+ return isObjectLike(value) && baseGetTag(value) == regexpTag;
+ }
+
+ /**
+ * The base implementation of `_.isSet` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ */
+ function baseIsSet(value) {
+ return isObjectLike(value) && getTag(value) == setTag;
+ }
+
+ /**
+ * The base implementation of `_.isTypedArray` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ */
+ function baseIsTypedArray(value) {
+ return isObjectLike(value) &&
+ isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
+ }
+
+ /**
+ * The base implementation of `_.iteratee`.
+ *
+ * @private
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */
+ function baseIteratee(value) {
+ // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
+ // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
+ if (typeof value == 'function') {
+ return value;
+ }
+ if (value == null) {
+ return identity;
+ }
+ if (typeof value == 'object') {
+ return isArray(value)
+ ? baseMatchesProperty(value[0], value[1])
+ : baseMatches(value);
+ }
+ return property(value);
+ }
+
+ /**
+ * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ if (!isPrototype(object)) {
+ return nativeKeys(object);
+ }
+ var result = [];
+ for (var key in Object(object)) {
+ if (hasOwnProperty.call(object, key) && key != 'constructor') {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeysIn(object) {
+ if (!isObject(object)) {
+ return nativeKeysIn(object);
+ }
+ var isProto = isPrototype(object),
+ result = [];
+
+ for (var key in object) {
+ if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.lt` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than `other`,
+ * else `false`.
+ */
+ function baseLt(value, other) {
+ return value < other;
+ }
+
+ /**
+ * The base implementation of `_.map` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function baseMap(collection, iteratee) {
+ var index = -1,
+ result = isArrayLike(collection) ? Array(collection.length) : [];
+
+ baseEach(collection, function(value, key, collection) {
+ result[++index] = iteratee(value, key, collection);
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.matches` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new spec function.
+ */
+ function baseMatches(source) {
+ var matchData = getMatchData(source);
+ if (matchData.length == 1 && matchData[0][2]) {
+ return matchesStrictComparable(matchData[0][0], matchData[0][1]);
+ }
+ return function(object) {
+ return object === source || baseIsMatch(object, source, matchData);
+ };
+ }
+
+ /**
+ * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
+ *
+ * @private
+ * @param {string} path The path of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */
+ function baseMatchesProperty(path, srcValue) {
+ if (isKey(path) && isStrictComparable(srcValue)) {
+ return matchesStrictComparable(toKey(path), srcValue);
+ }
+ return function(object) {
+ var objValue = get(object, path);
+ return (objValue === undefined && objValue === srcValue)
+ ? hasIn(object, path)
+ : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
+ };
+ }
+
+ /**
+ * The base implementation of `_.merge` without support for multiple sources.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} [customizer] The function to customize merged values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ */
+ function baseMerge(object, source, srcIndex, customizer, stack) {
+ if (object === source) {
+ return;
+ }
+ baseFor(source, function(srcValue, key) {
+ stack || (stack = new Stack);
+ if (isObject(srcValue)) {
+ baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
+ }
+ else {
+ var newValue = customizer
+ ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
+ : undefined;
+
+ if (newValue === undefined) {
+ newValue = srcValue;
+ }
+ assignMergeValue(object, key, newValue);
+ }
+ }, keysIn);
+ }
+
+ /**
+ * A specialized version of `baseMerge` for arrays and objects which performs
+ * deep merges and tracks traversed objects enabling objects with circular
+ * references to be merged.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} mergeFunc The function to merge values.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ */
+ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
+ var objValue = safeGet(object, key),
+ srcValue = safeGet(source, key),
+ stacked = stack.get(srcValue);
+
+ if (stacked) {
+ assignMergeValue(object, key, stacked);
+ return;
+ }
+ var newValue = customizer
+ ? customizer(objValue, srcValue, (key + ''), object, source, stack)
+ : undefined;
+
+ var isCommon = newValue === undefined;
+
+ if (isCommon) {
+ var isArr = isArray(srcValue),
+ isBuff = !isArr && isBuffer(srcValue),
+ isTyped = !isArr && !isBuff && isTypedArray(srcValue);
+
+ newValue = srcValue;
+ if (isArr || isBuff || isTyped) {
+ if (isArray(objValue)) {
+ newValue = objValue;
+ }
+ else if (isArrayLikeObject(objValue)) {
+ newValue = copyArray(objValue);
+ }
+ else if (isBuff) {
+ isCommon = false;
+ newValue = cloneBuffer(srcValue, true);
+ }
+ else if (isTyped) {
+ isCommon = false;
+ newValue = cloneTypedArray(srcValue, true);
+ }
+ else {
+ newValue = [];
+ }
+ }
+ else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+ newValue = objValue;
+ if (isArguments(objValue)) {
+ newValue = toPlainObject(objValue);
+ }
+ else if (!isObject(objValue) || isFunction(objValue)) {
+ newValue = initCloneObject(srcValue);
+ }
+ }
+ else {
+ isCommon = false;
+ }
+ }
+ if (isCommon) {
+ // Recursively merge objects and arrays (susceptible to call stack limits).
+ stack.set(srcValue, newValue);
+ mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+ stack['delete'](srcValue);
+ }
+ assignMergeValue(object, key, newValue);
+ }
+
+ /**
+ * The base implementation of `_.nth` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {number} n The index of the element to return.
+ * @returns {*} Returns the nth element of `array`.
+ */
+ function baseNth(array, n) {
+ var length = array.length;
+ if (!length) {
+ return;
+ }
+ n += n < 0 ? length : 0;
+ return isIndex(n, length) ? array[n] : undefined;
+ }
+
+ /**
+ * The base implementation of `_.orderBy` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+ * @param {string[]} orders The sort orders of `iteratees`.
+ * @returns {Array} Returns the new sorted array.
+ */
+ function baseOrderBy(collection, iteratees, orders) {
+ if (iteratees.length) {
+ iteratees = arrayMap(iteratees, function(iteratee) {
+ if (isArray(iteratee)) {
+ return function(value) {
+ return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
+ }
+ }
+ return iteratee;
+ });
+ } else {
+ iteratees = [identity];
+ }
+
+ var index = -1;
+ iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
+
+ var result = baseMap(collection, function(value, key, collection) {
+ var criteria = arrayMap(iteratees, function(iteratee) {
+ return iteratee(value);
+ });
+ return { 'criteria': criteria, 'index': ++index, 'value': value };
+ });
+
+ return baseSortBy(result, function(object, other) {
+ return compareMultiple(object, other, orders);
+ });
+ }
+
+ /**
+ * The base implementation of `_.pick` without support for individual
+ * property identifiers.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Object} Returns the new object.
+ */
+ function basePick(object, paths) {
+ return basePickBy(object, paths, function(value, path) {
+ return hasIn(object, path);
+ });
+ }
+
+ /**
+ * The base implementation of `_.pickBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} paths The property paths to pick.
+ * @param {Function} predicate The function invoked per property.
+ * @returns {Object} Returns the new object.
+ */
+ function basePickBy(object, paths, predicate) {
+ var index = -1,
+ length = paths.length,
+ result = {};
+
+ while (++index < length) {
+ var path = paths[index],
+ value = baseGet(object, path);
+
+ if (predicate(value, path)) {
+ baseSet(result, castPath(path, object), value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A specialized version of `baseProperty` which supports deep paths.
+ *
+ * @private
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */
+ function basePropertyDeep(path) {
+ return function(object) {
+ return baseGet(object, path);
+ };
+ }
+
+ /**
+ * The base implementation of `_.pullAllBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAll(array, values, iteratee, comparator) {
+ var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
+ index = -1,
+ length = values.length,
+ seen = array;
+
+ if (array === values) {
+ values = copyArray(values);
+ }
+ if (iteratee) {
+ seen = arrayMap(array, baseUnary(iteratee));
+ }
+ while (++index < length) {
+ var fromIndex = 0,
+ value = values[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
+ if (seen !== array) {
+ splice.call(seen, fromIndex, 1);
+ }
+ splice.call(array, fromIndex, 1);
+ }
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of `_.pullAt` without support for individual
+ * indexes or capturing the removed elements.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {number[]} indexes The indexes of elements to remove.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAt(array, indexes) {
+ var length = array ? indexes.length : 0,
+ lastIndex = length - 1;
+
+ while (length--) {
+ var index = indexes[length];
+ if (length == lastIndex || index !== previous) {
+ var previous = index;
+ if (isIndex(index)) {
+ splice.call(array, index, 1);
+ } else {
+ baseUnset(array, index);
+ }
+ }
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of `_.random` without support for returning
+ * floating-point numbers.
+ *
+ * @private
+ * @param {number} lower The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the random number.
+ */
+ function baseRandom(lower, upper) {
+ return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
+ }
+
+ /**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the range of numbers.
+ */
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
+
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.repeat` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {string} string The string to repeat.
+ * @param {number} n The number of times to repeat the string.
+ * @returns {string} Returns the repeated string.
+ */
+ function baseRepeat(string, n) {
+ var result = '';
+ if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
+ return result;
+ }
+ // Leverage the exponentiation by squaring algorithm for a faster repeat.
+ // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
+ do {
+ if (n % 2) {
+ result += string;
+ }
+ n = nativeFloor(n / 2);
+ if (n) {
+ string += string;
+ }
+ } while (n);
+
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.rest` which doesn't validate or coerce arguments.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ */
+ function baseRest(func, start) {
+ return setToString(overRest(func, start, identity), func + '');
+ }
+
+ /**
+ * The base implementation of `_.sample`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
+ */
+ function baseSample(collection) {
+ return arraySample(values(collection));
+ }
+
+ /**
+ * The base implementation of `_.sampleSize` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} n The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ */
+ function baseSampleSize(collection, n) {
+ var array = values(collection);
+ return shuffleSelf(array, baseClamp(n, 0, array.length));
+ }
+
+ /**
+ * The base implementation of `_.set`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */
+ function baseSet(object, path, value, customizer) {
+ if (!isObject(object)) {
+ return object;
+ }
+ path = castPath(path, object);
+
+ var index = -1,
+ length = path.length,
+ lastIndex = length - 1,
+ nested = object;
+
+ while (nested != null && ++index < length) {
+ var key = toKey(path[index]),
+ newValue = value;
+
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
+ return object;
+ }
+
+ if (index != lastIndex) {
+ var objValue = nested[key];
+ newValue = customizer ? customizer(objValue, key, nested) : undefined;
+ if (newValue === undefined) {
+ newValue = isObject(objValue)
+ ? objValue
+ : (isIndex(path[index + 1]) ? [] : {});
+ }
+ }
+ assignValue(nested, key, newValue);
+ nested = nested[key];
+ }
+ return object;
+ }
+
+ /**
+ * The base implementation of `setData` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+ var baseSetData = !metaMap ? identity : function(func, data) {
+ metaMap.set(func, data);
+ return func;
+ };
+
+ /**
+ * The base implementation of `setToString` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+ var baseSetToString = !defineProperty ? identity : function(func, string) {
+ return defineProperty(func, 'toString', {
+ 'configurable': true,
+ 'enumerable': false,
+ 'value': constant(string),
+ 'writable': true
+ });
+ };
+
+ /**
+ * The base implementation of `_.shuffle`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ */
+ function baseShuffle(collection) {
+ return shuffleSelf(values(collection));
+ }
+
+ /**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseSlice(array, start, end) {
+ var index = -1,
+ length = array.length;
+
+ if (start < 0) {
+ start = -start > length ? 0 : (length + start);
+ }
+ end = end > length ? length : end;
+ if (end < 0) {
+ end += length;
+ }
+ length = start > end ? 0 : ((end - start) >>> 0);
+ start >>>= 0;
+
+ var result = Array(length);
+ while (++index < length) {
+ result[index] = array[index + start];
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.some` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ */
+ function baseSome(collection, predicate) {
+ var result;
+
+ baseEach(collection, function(value, index, collection) {
+ result = predicate(value, index, collection);
+ return !result;
+ });
+ return !!result;
+ }
+
+ /**
+ * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
+ * performs a binary search of `array` to determine the index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ */
+ function baseSortedIndex(array, value, retHighest) {
+ var low = 0,
+ high = array == null ? low : array.length;
+
+ if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
+ while (low < high) {
+ var mid = (low + high) >>> 1,
+ computed = array[mid];
+
+ if (computed !== null && !isSymbol(computed) &&
+ (retHighest ? (computed <= value) : (computed < value))) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ return high;
+ }
+ return baseSortedIndexBy(array, value, identity, retHighest);
+ }
+
+ /**
+ * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
+ * which invokes `iteratee` for `value` and each element of `array` to compute
+ * their sort ranking. The iteratee is invoked with one argument; (value).
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} iteratee The iteratee invoked per element.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ */
+ function baseSortedIndexBy(array, value, iteratee, retHighest) {
+ var low = 0,
+ high = array == null ? 0 : array.length;
+ if (high === 0) {
+ return 0;
+ }
+
+ value = iteratee(value);
+ var valIsNaN = value !== value,
+ valIsNull = value === null,
+ valIsSymbol = isSymbol(value),
+ valIsUndefined = value === undefined;
+
+ while (low < high) {
+ var mid = nativeFloor((low + high) / 2),
+ computed = iteratee(array[mid]),
+ othIsDefined = computed !== undefined,
+ othIsNull = computed === null,
+ othIsReflexive = computed === computed,
+ othIsSymbol = isSymbol(computed);
+
+ if (valIsNaN) {
+ var setLow = retHighest || othIsReflexive;
+ } else if (valIsUndefined) {
+ setLow = othIsReflexive && (retHighest || othIsDefined);
+ } else if (valIsNull) {
+ setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
+ } else if (valIsSymbol) {
+ setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
+ } else if (othIsNull || othIsSymbol) {
+ setLow = false;
+ } else {
+ setLow = retHighest ? (computed <= value) : (computed < value);
+ }
+ if (setLow) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ return nativeMin(high, MAX_ARRAY_INDEX);
+ }
+
+ /**
+ * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseSortedUniq(array, iteratee) {
+ var index = -1,
+ length = array.length,
+ resIndex = 0,
+ result = [];
+
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (!index || !eq(computed, seen)) {
+ var seen = computed;
+ result[resIndex++] = value === 0 ? 0 : value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.toNumber` which doesn't ensure correct
+ * conversions of binary, hexadecimal, or octal string values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ */
+ function baseToNumber(value) {
+ if (typeof value == 'number') {
+ return value;
+ }
+ if (isSymbol(value)) {
+ return NAN;
+ }
+ return +value;
+ }
+
+ /**
+ * The base implementation of `_.toString` which doesn't convert nullish
+ * values to empty strings.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+ function baseToString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (isArray(value)) {
+ // Recursively convert values (susceptible to call stack limits).
+ return arrayMap(value, baseToString) + '';
+ }
+ if (isSymbol(value)) {
+ return symbolToString ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+ }
+
+ /**
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseUniq(array, iteratee, comparator) {
+ var index = -1,
+ includes = arrayIncludes,
+ length = array.length,
+ isCommon = true,
+ result = [],
+ seen = result;
+
+ if (comparator) {
+ isCommon = false;
+ includes = arrayIncludesWith;
+ }
+ else if (length >= LARGE_ARRAY_SIZE) {
+ var set = iteratee ? null : createSet(array);
+ if (set) {
+ return setToArray(set);
+ }
+ isCommon = false;
+ includes = cacheHas;
+ seen = new SetCache;
+ }
+ else {
+ seen = iteratee ? [] : result;
+ }
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ value = (comparator || value !== 0) ? value : 0;
+ if (isCommon && computed === computed) {
+ var seenIndex = seen.length;
+ while (seenIndex--) {
+ if (seen[seenIndex] === computed) {
+ continue outer;
+ }
+ }
+ if (iteratee) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ else if (!includes(seen, computed, comparator)) {
+ if (seen !== result) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.unset`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The property path to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ */
+ function baseUnset(object, path) {
+ path = castPath(path, object);
+ object = parent(object, path);
+ return object == null || delete object[toKey(last(path))];
+ }
+
+ /**
+ * The base implementation of `_.update`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to update.
+ * @param {Function} updater The function to produce the updated value.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */
+ function baseUpdate(object, path, updater, customizer) {
+ return baseSet(object, path, updater(baseGet(object, path)), customizer);
+ }
+
+ /**
+ * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
+ * without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseWhile(array, predicate, isDrop, fromRight) {
+ var length = array.length,
+ index = fromRight ? length : -1;
+
+ while ((fromRight ? index-- : ++index < length) &&
+ predicate(array[index], index, array)) {}
+
+ return isDrop
+ ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
+ : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
+ }
+
+ /**
+ * The base implementation of `wrapperValue` which returns the result of
+ * performing a sequence of actions on the unwrapped `value`, where each
+ * successive action is supplied the return value of the previous.
+ *
+ * @private
+ * @param {*} value The unwrapped value.
+ * @param {Array} actions Actions to perform to resolve the unwrapped value.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseWrapperValue(value, actions) {
+ var result = value;
+ if (result instanceof LazyWrapper) {
+ result = result.value();
+ }
+ return arrayReduce(actions, function(result, action) {
+ return action.func.apply(action.thisArg, arrayPush([result], action.args));
+ }, result);
+ }
+
+ /**
+ * The base implementation of methods like `_.xor`, without support for
+ * iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ */
+ function baseXor(arrays, iteratee, comparator) {
+ var length = arrays.length;
+ if (length < 2) {
+ return length ? baseUniq(arrays[0]) : [];
+ }
+ var index = -1,
+ result = Array(length);
+
+ while (++index < length) {
+ var array = arrays[index],
+ othIndex = -1;
+
+ while (++othIndex < length) {
+ if (othIndex != index) {
+ result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
+ }
+ }
+ }
+ return baseUniq(baseFlatten(result, 1), iteratee, comparator);
+ }
+
+ /**
+ * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
+ *
+ * @private
+ * @param {Array} props The property identifiers.
+ * @param {Array} values The property values.
+ * @param {Function} assignFunc The function to assign values.
+ * @returns {Object} Returns the new object.
+ */
+ function baseZipObject(props, values, assignFunc) {
+ var index = -1,
+ length = props.length,
+ valsLength = values.length,
+ result = {};
+
+ while (++index < length) {
+ var value = index < valsLength ? values[index] : undefined;
+ assignFunc(result, props[index], value);
+ }
+ return result;
+ }
+
+ /**
+ * Casts `value` to an empty array if it's not an array like object.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array|Object} Returns the cast array-like object.
+ */
+ function castArrayLikeObject(value) {
+ return isArrayLikeObject(value) ? value : [];
+ }
+
+ /**
+ * Casts `value` to `identity` if it's not a function.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Function} Returns cast function.
+ */
+ function castFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ /**
+ * Casts `value` to a path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {Array} Returns the cast property path array.
+ */
+ function castPath(value, object) {
+ if (isArray(value)) {
+ return value;
+ }
+ return isKey(value, object) ? [value] : stringToPath(toString(value));
+ }
+
+ /**
+ * A `baseRest` alias which can be replaced with `identity` by module
+ * replacement plugins.
+ *
+ * @private
+ * @type {Function}
+ * @param {Function} func The function to apply a rest parameter to.
+ * @returns {Function} Returns the new function.
+ */
+ var castRest = baseRest;
+
+ /**
+ * Casts `array` to a slice if it's needed.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {number} start The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the cast slice.
+ */
+ function castSlice(array, start, end) {
+ var length = array.length;
+ end = end === undefined ? length : end;
+ return (!start && end >= length) ? array : baseSlice(array, start, end);
+ }
+
+ /**
+ * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
+ *
+ * @private
+ * @param {number|Object} id The timer id or timeout object of the timer to clear.
+ */
+ var clearTimeout = ctxClearTimeout || function(id) {
+ return root.clearTimeout(id);
+ };
+
+ /**
+ * Creates a clone of `buffer`.
+ *
+ * @private
+ * @param {Buffer} buffer The buffer to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Buffer} Returns the cloned buffer.
+ */
+ function cloneBuffer(buffer, isDeep) {
+ if (isDeep) {
+ return buffer.slice();
+ }
+ var length = buffer.length,
+ result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
+
+ buffer.copy(result);
+ return result;
+ }
+
+ /**
+ * Creates a clone of `arrayBuffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+ function cloneArrayBuffer(arrayBuffer) {
+ var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
+ new Uint8Array(result).set(new Uint8Array(arrayBuffer));
+ return result;
+ }
+
+ /**
+ * Creates a clone of `dataView`.
+ *
+ * @private
+ * @param {Object} dataView The data view to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned data view.
+ */
+ function cloneDataView(dataView, isDeep) {
+ var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
+ return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
+ }
+
+ /**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */
+ function cloneRegExp(regexp) {
+ var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
+ result.lastIndex = regexp.lastIndex;
+ return result;
+ }
+
+ /**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */
+ function cloneSymbol(symbol) {
+ return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
+ }
+
+ /**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+ function cloneTypedArray(typedArray, isDeep) {
+ var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
+ return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+ }
+
+ /**
+ * Compares values to sort them in ascending order.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
+ */
+ function compareAscending(value, other) {
+ if (value !== other) {
+ var valIsDefined = value !== undefined,
+ valIsNull = value === null,
+ valIsReflexive = value === value,
+ valIsSymbol = isSymbol(value);
+
+ var othIsDefined = other !== undefined,
+ othIsNull = other === null,
+ othIsReflexive = other === other,
+ othIsSymbol = isSymbol(other);
+
+ if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
+ (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
+ (valIsNull && othIsDefined && othIsReflexive) ||
+ (!valIsDefined && othIsReflexive) ||
+ !valIsReflexive) {
+ return 1;
+ }
+ if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
+ (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
+ (othIsNull && valIsDefined && valIsReflexive) ||
+ (!othIsDefined && valIsReflexive) ||
+ !othIsReflexive) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Used by `_.orderBy` to compare multiple properties of a value to another
+ * and stable sort them.
+ *
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
+ * @returns {number} Returns the sort order indicator for `object`.
+ */
+ function compareMultiple(object, other, orders) {
+ var index = -1,
+ objCriteria = object.criteria,
+ othCriteria = other.criteria,
+ length = objCriteria.length,
+ ordersLength = orders.length;
+
+ while (++index < length) {
+ var result = compareAscending(objCriteria[index], othCriteria[index]);
+ if (result) {
+ if (index >= ordersLength) {
+ return result;
+ }
+ var order = orders[index];
+ return result * (order == 'desc' ? -1 : 1);
+ }
+ }
+ // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+ // that causes it, under certain circumstances, to provide the same value for
+ // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
+ // for more details.
+ //
+ // This also ensures a stable sort in V8 and other engines.
+ // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
+ return object.index - other.index;
+ }
+
+ /**
+ * Creates an array that is the composition of partially applied arguments,
+ * placeholders, and provided arguments into a single array of arguments.
+ *
+ * @private
+ * @param {Array} args The provided arguments.
+ * @param {Array} partials The arguments to prepend to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @params {boolean} [isCurried] Specify composing for a curried function.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+ function composeArgs(args, partials, holders, isCurried) {
+ var argsIndex = -1,
+ argsLength = args.length,
+ holdersLength = holders.length,
+ leftIndex = -1,
+ leftLength = partials.length,
+ rangeLength = nativeMax(argsLength - holdersLength, 0),
+ result = Array(leftLength + rangeLength),
+ isUncurried = !isCurried;
+
+ while (++leftIndex < leftLength) {
+ result[leftIndex] = partials[leftIndex];
+ }
+ while (++argsIndex < holdersLength) {
+ if (isUncurried || argsIndex < argsLength) {
+ result[holders[argsIndex]] = args[argsIndex];
+ }
+ }
+ while (rangeLength--) {
+ result[leftIndex++] = args[argsIndex++];
+ }
+ return result;
+ }
+
+ /**
+ * This function is like `composeArgs` except that the arguments composition
+ * is tailored for `_.partialRight`.
+ *
+ * @private
+ * @param {Array} args The provided arguments.
+ * @param {Array} partials The arguments to append to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @params {boolean} [isCurried] Specify composing for a curried function.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+ function composeArgsRight(args, partials, holders, isCurried) {
+ var argsIndex = -1,
+ argsLength = args.length,
+ holdersIndex = -1,
+ holdersLength = holders.length,
+ rightIndex = -1,
+ rightLength = partials.length,
+ rangeLength = nativeMax(argsLength - holdersLength, 0),
+ result = Array(rangeLength + rightLength),
+ isUncurried = !isCurried;
+
+ while (++argsIndex < rangeLength) {
+ result[argsIndex] = args[argsIndex];
+ }
+ var offset = argsIndex;
+ while (++rightIndex < rightLength) {
+ result[offset + rightIndex] = partials[rightIndex];
+ }
+ while (++holdersIndex < holdersLength) {
+ if (isUncurried || argsIndex < argsLength) {
+ result[offset + holders[holdersIndex]] = args[argsIndex++];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+ function copyArray(source, array) {
+ var index = -1,
+ length = source.length;
+
+ array || (array = Array(length));
+ while (++index < length) {
+ array[index] = source[index];
+ }
+ return array;
+ }
+
+ /**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property identifiers to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObject(source, props, object, customizer) {
+ var isNew = !object;
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index];
+
+ var newValue = customizer
+ ? customizer(object[key], source[key], key, object, source)
+ : undefined;
+
+ if (newValue === undefined) {
+ newValue = source[key];
+ }
+ if (isNew) {
+ baseAssignValue(object, key, newValue);
+ } else {
+ assignValue(object, key, newValue);
+ }
+ }
+ return object;
+ }
+
+ /**
+ * Copies own symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+ function copySymbols(source, object) {
+ return copyObject(source, getSymbols(source), object);
+ }
+
+ /**
+ * Copies own and inherited symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+ function copySymbolsIn(source, object) {
+ return copyObject(source, getSymbolsIn(source), object);
+ }
+
+ /**
+ * Creates a function like `_.groupBy`.
+ *
+ * @private
+ * @param {Function} setter The function to set accumulator values.
+ * @param {Function} [initializer] The accumulator object initializer.
+ * @returns {Function} Returns the new aggregator function.
+ */
+ function createAggregator(setter, initializer) {
+ return function(collection, iteratee) {
+ var func = isArray(collection) ? arrayAggregator : baseAggregator,
+ accumulator = initializer ? initializer() : {};
+
+ return func(collection, setter, getIteratee(iteratee, 2), accumulator);
+ };
+ }
+
+ /**
+ * Creates a function like `_.assign`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */
+ function createAssigner(assigner) {
+ return baseRest(function(object, sources) {
+ var index = -1,
+ length = sources.length,
+ customizer = length > 1 ? sources[length - 1] : undefined,
+ guard = length > 2 ? sources[2] : undefined;
+
+ customizer = (assigner.length > 3 && typeof customizer == 'function')
+ ? (length--, customizer)
+ : undefined;
+
+ if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+ customizer = length < 3 ? undefined : customizer;
+ length = 1;
+ }
+ object = Object(object);
+ while (++index < length) {
+ var source = sources[index];
+ if (source) {
+ assigner(object, source, index, customizer);
+ }
+ }
+ return object;
+ });
+ }
+
+ /**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseEach(eachFunc, fromRight) {
+ return function(collection, iteratee) {
+ if (collection == null) {
+ return collection;
+ }
+ if (!isArrayLike(collection)) {
+ return eachFunc(collection, iteratee);
+ }
+ var length = collection.length,
+ index = fromRight ? length : -1,
+ iterable = Object(collection);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ if (iteratee(iterable[index], index, iterable) === false) {
+ break;
+ }
+ }
+ return collection;
+ };
+ }
+
+ /**
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ };
+ }
+
+ /**
+ * Creates a function that wraps `func` to invoke it with the optional `this`
+ * binding of `thisArg`.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createBind(func, bitmask, thisArg) {
+ var isBind = bitmask & WRAP_BIND_FLAG,
+ Ctor = createCtor(func);
+
+ function wrapper() {
+ var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+ return fn.apply(isBind ? thisArg : this, arguments);
+ }
+ return wrapper;
+ }
+
+ /**
+ * Creates a function like `_.lowerFirst`.
+ *
+ * @private
+ * @param {string} methodName The name of the `String` case method to use.
+ * @returns {Function} Returns the new case function.
+ */
+ function createCaseFirst(methodName) {
+ return function(string) {
+ string = toString(string);
+
+ var strSymbols = hasUnicode(string)
+ ? stringToArray(string)
+ : undefined;
+
+ var chr = strSymbols
+ ? strSymbols[0]
+ : string.charAt(0);
+
+ var trailing = strSymbols
+ ? castSlice(strSymbols, 1).join('')
+ : string.slice(1);
+
+ return chr[methodName]() + trailing;
+ };
+ }
+
+ /**
+ * Creates a function like `_.camelCase`.
+ *
+ * @private
+ * @param {Function} callback The function to combine each word.
+ * @returns {Function} Returns the new compounder function.
+ */
+ function createCompounder(callback) {
+ return function(string) {
+ return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
+ };
+ }
+
+ /**
+ * Creates a function that produces an instance of `Ctor` regardless of
+ * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+ *
+ * @private
+ * @param {Function} Ctor The constructor to wrap.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createCtor(Ctor) {
+ return function() {
+ // Use a `switch` statement to work with class constructors. See
+ // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+ // for more details.
+ var args = arguments;
+ switch (args.length) {
+ case 0: return new Ctor;
+ case 1: return new Ctor(args[0]);
+ case 2: return new Ctor(args[0], args[1]);
+ case 3: return new Ctor(args[0], args[1], args[2]);
+ case 4: return new Ctor(args[0], args[1], args[2], args[3]);
+ case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+ case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+ case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+ }
+ var thisBinding = baseCreate(Ctor.prototype),
+ result = Ctor.apply(thisBinding, args);
+
+ // Mimic the constructor's `return` behavior.
+ // See https://es5.github.io/#x13.2.2 for more details.
+ return isObject(result) ? result : thisBinding;
+ };
+ }
+
+ /**
+ * Creates a function that wraps `func` to enable currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {number} arity The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createCurry(func, bitmask, arity) {
+ var Ctor = createCtor(func);
+
+ function wrapper() {
+ var length = arguments.length,
+ args = Array(length),
+ index = length,
+ placeholder = getHolder(wrapper);
+
+ while (index--) {
+ args[index] = arguments[index];
+ }
+ var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
+ ? []
+ : replaceHolders(args, placeholder);
+
+ length -= holders.length;
+ if (length < arity) {
+ return createRecurry(
+ func, bitmask, createHybrid, wrapper.placeholder, undefined,
+ args, holders, undefined, undefined, arity - length);
+ }
+ var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+ return apply(fn, this, args);
+ }
+ return wrapper;
+ }
+
+ /**
+ * Creates a `_.find` or `_.findLast` function.
+ *
+ * @private
+ * @param {Function} findIndexFunc The function to find the collection index.
+ * @returns {Function} Returns the new find function.
+ */
+ function createFind(findIndexFunc) {
+ return function(collection, predicate, fromIndex) {
+ var iterable = Object(collection);
+ if (!isArrayLike(collection)) {
+ var iteratee = getIteratee(predicate, 3);
+ collection = keys(collection);
+ predicate = function(key) { return iteratee(iterable[key], key, iterable); };
+ }
+ var index = findIndexFunc(collection, predicate, fromIndex);
+ return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
+ };
+ }
+
+ /**
+ * Creates a `_.flow` or `_.flowRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new flow function.
+ */
+ function createFlow(fromRight) {
+ return flatRest(function(funcs) {
+ var length = funcs.length,
+ index = length,
+ prereq = LodashWrapper.prototype.thru;
+
+ if (fromRight) {
+ funcs.reverse();
+ }
+ while (index--) {
+ var func = funcs[index];
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
+ var wrapper = new LodashWrapper([], true);
+ }
+ }
+ index = wrapper ? index : length;
+ while (++index < length) {
+ func = funcs[index];
+
+ var funcName = getFuncName(func),
+ data = funcName == 'wrapper' ? getData(func) : undefined;
+
+ if (data && isLaziable(data[0]) &&
+ data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
+ !data[4].length && data[9] == 1
+ ) {
+ wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
+ } else {
+ wrapper = (func.length == 1 && isLaziable(func))
+ ? wrapper[funcName]()
+ : wrapper.thru(func);
+ }
+ }
+ return function() {
+ var args = arguments,
+ value = args[0];
+
+ if (wrapper && args.length == 1 && isArray(value)) {
+ return wrapper.plant(value).value();
+ }
+ var index = 0,
+ result = length ? funcs[index].apply(this, args) : value;
+
+ while (++index < length) {
+ result = funcs[index].call(this, result);
+ }
+ return result;
+ };
+ });
+ }
+
+ /**
+ * Creates a function that wraps `func` to invoke it with optional `this`
+ * binding of `thisArg`, partial application, and currying.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to
+ * the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [partialsRight] The arguments to append to those provided
+ * to the new function.
+ * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+ var isAry = bitmask & WRAP_ARY_FLAG,
+ isBind = bitmask & WRAP_BIND_FLAG,
+ isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
+ isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
+ isFlip = bitmask & WRAP_FLIP_FLAG,
+ Ctor = isBindKey ? undefined : createCtor(func);
+
+ function wrapper() {
+ var length = arguments.length,
+ args = Array(length),
+ index = length;
+
+ while (index--) {
+ args[index] = arguments[index];
+ }
+ if (isCurried) {
+ var placeholder = getHolder(wrapper),
+ holdersCount = countHolders(args, placeholder);
+ }
+ if (partials) {
+ args = composeArgs(args, partials, holders, isCurried);
+ }
+ if (partialsRight) {
+ args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
+ }
+ length -= holdersCount;
+ if (isCurried && length < arity) {
+ var newHolders = replaceHolders(args, placeholder);
+ return createRecurry(
+ func, bitmask, createHybrid, wrapper.placeholder, thisArg,
+ args, newHolders, argPos, ary, arity - length
+ );
+ }
+ var thisBinding = isBind ? thisArg : this,
+ fn = isBindKey ? thisBinding[func] : func;
+
+ length = args.length;
+ if (argPos) {
+ args = reorder(args, argPos);
+ } else if (isFlip && length > 1) {
+ args.reverse();
+ }
+ if (isAry && ary < length) {
+ args.length = ary;
+ }
+ if (this && this !== root && this instanceof wrapper) {
+ fn = Ctor || createCtor(fn);
+ }
+ return fn.apply(thisBinding, args);
+ }
+ return wrapper;
+ }
+
+ /**
+ * Creates a function like `_.invertBy`.
+ *
+ * @private
+ * @param {Function} setter The function to set accumulator values.
+ * @param {Function} toIteratee The function to resolve iteratees.
+ * @returns {Function} Returns the new inverter function.
+ */
+ function createInverter(setter, toIteratee) {
+ return function(object, iteratee) {
+ return baseInverter(object, setter, toIteratee(iteratee), {});
+ };
+ }
+
+ /**
+ * Creates a function that performs a mathematical operation on two values.
+ *
+ * @private
+ * @param {Function} operator The function to perform the operation.
+ * @param {number} [defaultValue] The value used for `undefined` arguments.
+ * @returns {Function} Returns the new mathematical operation function.
+ */
+ function createMathOperation(operator, defaultValue) {
+ return function(value, other) {
+ var result;
+ if (value === undefined && other === undefined) {
+ return defaultValue;
+ }
+ if (value !== undefined) {
+ result = value;
+ }
+ if (other !== undefined) {
+ if (result === undefined) {
+ return other;
+ }
+ if (typeof value == 'string' || typeof other == 'string') {
+ value = baseToString(value);
+ other = baseToString(other);
+ } else {
+ value = baseToNumber(value);
+ other = baseToNumber(other);
+ }
+ result = operator(value, other);
+ }
+ return result;
+ };
+ }
+
+ /**
+ * Creates a function like `_.over`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over iteratees.
+ * @returns {Function} Returns the new over function.
+ */
+ function createOver(arrayFunc) {
+ return flatRest(function(iteratees) {
+ iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
+ return baseRest(function(args) {
+ var thisArg = this;
+ return arrayFunc(iteratees, function(iteratee) {
+ return apply(iteratee, thisArg, args);
+ });
+ });
+ });
+ }
+
+ /**
+ * Creates the padding for `string` based on `length`. The `chars` string
+ * is truncated if the number of characters exceeds `length`.
+ *
+ * @private
+ * @param {number} length The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padding for `string`.
+ */
+ function createPadding(length, chars) {
+ chars = chars === undefined ? ' ' : baseToString(chars);
+
+ var charsLength = chars.length;
+ if (charsLength < 2) {
+ return charsLength ? baseRepeat(chars, length) : chars;
+ }
+ var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
+ return hasUnicode(chars)
+ ? castSlice(stringToArray(result), 0, length).join('')
+ : result.slice(0, length);
+ }
+
+ /**
+ * Creates a function that wraps `func` to invoke it with the `this` binding
+ * of `thisArg` and `partials` prepended to the arguments it receives.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} partials The arguments to prepend to those provided to
+ * the new function.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createPartial(func, bitmask, thisArg, partials) {
+ var isBind = bitmask & WRAP_BIND_FLAG,
+ Ctor = createCtor(func);
+
+ function wrapper() {
+ var argsIndex = -1,
+ argsLength = arguments.length,
+ leftIndex = -1,
+ leftLength = partials.length,
+ args = Array(leftLength + argsLength),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+
+ while (++leftIndex < leftLength) {
+ args[leftIndex] = partials[leftIndex];
+ }
+ while (argsLength--) {
+ args[leftIndex++] = arguments[++argsIndex];
+ }
+ return apply(fn, isBind ? thisArg : this, args);
+ }
+ return wrapper;
+ }
+
+ /**
+ * Creates a `_.range` or `_.rangeRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new range function.
+ */
+ function createRange(fromRight) {
+ return function(start, end, step) {
+ if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
+ end = step = undefined;
+ }
+ // Ensure the sign of `-0` is preserved.
+ start = toFinite(start);
+ if (end === undefined) {
+ end = start;
+ start = 0;
+ } else {
+ end = toFinite(end);
+ }
+ step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
+ return baseRange(start, end, step, fromRight);
+ };
+ }
+
+ /**
+ * Creates a function that performs a relational operation on two values.
+ *
+ * @private
+ * @param {Function} operator The function to perform the operation.
+ * @returns {Function} Returns the new relational operation function.
+ */
+ function createRelationalOperation(operator) {
+ return function(value, other) {
+ if (!(typeof value == 'string' && typeof other == 'string')) {
+ value = toNumber(value);
+ other = toNumber(other);
+ }
+ return operator(value, other);
+ };
+ }
+
+ /**
+ * Creates a function that wraps `func` to continue currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @param {Function} wrapFunc The function to create the `func` wrapper.
+ * @param {*} placeholder The placeholder value.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to
+ * the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+ var isCurry = bitmask & WRAP_CURRY_FLAG,
+ newHolders = isCurry ? holders : undefined,
+ newHoldersRight = isCurry ? undefined : holders,
+ newPartials = isCurry ? partials : undefined,
+ newPartialsRight = isCurry ? undefined : partials;
+
+ bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
+ bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
+
+ if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
+ bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
+ }
+ var newData = [
+ func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
+ newHoldersRight, argPos, ary, arity
+ ];
+
+ var result = wrapFunc.apply(undefined, newData);
+ if (isLaziable(func)) {
+ setData(result, newData);
+ }
+ result.placeholder = placeholder;
+ return setWrapToString(result, func, bitmask);
+ }
+
+ /**
+ * Creates a function like `_.round`.
+ *
+ * @private
+ * @param {string} methodName The name of the `Math` method to use when rounding.
+ * @returns {Function} Returns the new round function.
+ */
+ function createRound(methodName) {
+ var func = Math[methodName];
+ return function(number, precision) {
+ number = toNumber(number);
+ precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
+ if (precision && nativeIsFinite(number)) {
+ // Shift with exponential notation to avoid floating-point issues.
+ // See [MDN](https://mdn.io/round#Examples) for more details.
+ var pair = (toString(number) + 'e').split('e'),
+ value = func(pair[0] + 'e' + (+pair[1] + precision));
+
+ pair = (toString(value) + 'e').split('e');
+ return +(pair[0] + 'e' + (+pair[1] - precision));
+ }
+ return func(number);
+ };
+ }
+
+ /**
+ * Creates a set object of `values`.
+ *
+ * @private
+ * @param {Array} values The values to add to the set.
+ * @returns {Object} Returns the new set.
+ */
+ var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
+ return new Set(values);
+ };
+
+ /**
+ * Creates a `_.toPairs` or `_.toPairsIn` function.
+ *
+ * @private
+ * @param {Function} keysFunc The function to get the keys of a given object.
+ * @returns {Function} Returns the new pairs function.
+ */
+ function createToPairs(keysFunc) {
+ return function(object) {
+ var tag = getTag(object);
+ if (tag == mapTag) {
+ return mapToArray(object);
+ }
+ if (tag == setTag) {
+ return setToPairs(object);
+ }
+ return baseToPairs(object, keysFunc(object));
+ };
+ }
+
+ /**
+ * Creates a function that either curries or invokes `func` with optional
+ * `this` binding and partially applied arguments.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask flags.
+ * 1 - `_.bind`
+ * 2 - `_.bindKey`
+ * 4 - `_.curry` or `_.curryRight` of a bound function
+ * 8 - `_.curry`
+ * 16 - `_.curryRight`
+ * 32 - `_.partial`
+ * 64 - `_.partialRight`
+ * 128 - `_.rearg`
+ * 256 - `_.ary`
+ * 512 - `_.flip`
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to be partially applied.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+ var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
+ if (!isBindKey && typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ var length = partials ? partials.length : 0;
+ if (!length) {
+ bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
+ partials = holders = undefined;
+ }
+ ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
+ arity = arity === undefined ? arity : toInteger(arity);
+ length -= holders ? holders.length : 0;
+
+ if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
+ var partialsRight = partials,
+ holdersRight = holders;
+
+ partials = holders = undefined;
+ }
+ var data = isBindKey ? undefined : getData(func);
+
+ var newData = [
+ func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
+ argPos, ary, arity
+ ];
+
+ if (data) {
+ mergeData(newData, data);
+ }
+ func = newData[0];
+ bitmask = newData[1];
+ thisArg = newData[2];
+ partials = newData[3];
+ holders = newData[4];
+ arity = newData[9] = newData[9] === undefined
+ ? (isBindKey ? 0 : func.length)
+ : nativeMax(newData[9] - length, 0);
+
+ if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
+ bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
+ }
+ if (!bitmask || bitmask == WRAP_BIND_FLAG) {
+ var result = createBind(func, bitmask, thisArg);
+ } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
+ result = createCurry(func, bitmask, arity);
+ } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
+ result = createPartial(func, bitmask, thisArg, partials);
+ } else {
+ result = createHybrid.apply(undefined, newData);
+ }
+ var setter = data ? baseSetData : setData;
+ return setWrapToString(setter(result, newData), func, bitmask);
+ }
+
+ /**
+ * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
+ * of source objects to the destination object for all destination properties
+ * that resolve to `undefined`.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to assign.
+ * @param {Object} object The parent object of `objValue`.
+ * @returns {*} Returns the value to assign.
+ */
+ function customDefaultsAssignIn(objValue, srcValue, key, object) {
+ if (objValue === undefined ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+ return srcValue;
+ }
+ return objValue;
+ }
+
+ /**
+ * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
+ * objects into destination objects that are passed thru.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to merge.
+ * @param {Object} object The parent object of `objValue`.
+ * @param {Object} source The parent object of `srcValue`.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ * counterparts.
+ * @returns {*} Returns the value to assign.
+ */
+ function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
+ if (isObject(objValue) && isObject(srcValue)) {
+ // Recursively merge objects and arrays (susceptible to call stack limits).
+ stack.set(srcValue, objValue);
+ baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
+ stack['delete'](srcValue);
+ }
+ return objValue;
+ }
+
+ /**
+ * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
+ * objects.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @param {string} key The key of the property to inspect.
+ * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
+ */
+ function customOmitClone(value) {
+ return isPlainObject(value) ? undefined : value;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `array` and `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */
+ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+ arrLength = array.length,
+ othLength = other.length;
+
+ if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
+ return false;
+ }
+ // Check that cyclic values are equal.
+ var arrStacked = stack.get(array);
+ var othStacked = stack.get(other);
+ if (arrStacked && othStacked) {
+ return arrStacked == other && othStacked == array;
+ }
+ var index = -1,
+ result = true,
+ seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
+
+ stack.set(array, other);
+ stack.set(other, array);
+
+ // Ignore non-index properties.
+ while (++index < arrLength) {
+ var arrValue = array[index],
+ othValue = other[index];
+
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, arrValue, index, other, array, stack)
+ : customizer(arrValue, othValue, index, array, other, stack);
+ }
+ if (compared !== undefined) {
+ if (compared) {
+ continue;
+ }
+ result = false;
+ break;
+ }
+ // Recursively compare arrays (susceptible to call stack limits).
+ if (seen) {
+ if (!arraySome(other, function(othValue, othIndex) {
+ if (!cacheHas(seen, othIndex) &&
+ (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
+ return seen.push(othIndex);
+ }
+ })) {
+ result = false;
+ break;
+ }
+ } else if (!(
+ arrValue === othValue ||
+ equalFunc(arrValue, othValue, bitmask, customizer, stack)
+ )) {
+ result = false;
+ break;
+ }
+ }
+ stack['delete'](array);
+ stack['delete'](other);
+ return result;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
+ switch (tag) {
+ case dataViewTag:
+ if ((object.byteLength != other.byteLength) ||
+ (object.byteOffset != other.byteOffset)) {
+ return false;
+ }
+ object = object.buffer;
+ other = other.buffer;
+
+ case arrayBufferTag:
+ if ((object.byteLength != other.byteLength) ||
+ !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
+ return false;
+ }
+ return true;
+
+ case boolTag:
+ case dateTag:
+ case numberTag:
+ // Coerce booleans to `1` or `0` and dates to milliseconds.
+ // Invalid dates are coerced to `NaN`.
+ return eq(+object, +other);
+
+ case errorTag:
+ return object.name == other.name && object.message == other.message;
+
+ case regexpTag:
+ case stringTag:
+ // Coerce regexes to strings and treat strings, primitives and objects,
+ // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
+ // for more details.
+ return object == (other + '');
+
+ case mapTag:
+ var convert = mapToArray;
+
+ case setTag:
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
+ convert || (convert = setToArray);
+
+ if (object.size != other.size && !isPartial) {
+ return false;
+ }
+ // Assume cyclic values are equal.
+ var stacked = stack.get(object);
+ if (stacked) {
+ return stacked == other;
+ }
+ bitmask |= COMPARE_UNORDERED_FLAG;
+
+ // Recursively compare objects (susceptible to call stack limits).
+ stack.set(object, other);
+ var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
+ stack['delete'](object);
+ return result;
+
+ case symbolTag:
+ if (symbolValueOf) {
+ return symbolValueOf.call(object) == symbolValueOf.call(other);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+ objProps = getAllKeys(object),
+ objLength = objProps.length,
+ othProps = getAllKeys(other),
+ othLength = othProps.length;
+
+ if (objLength != othLength && !isPartial) {
+ return false;
+ }
+ var index = objLength;
+ while (index--) {
+ var key = objProps[index];
+ if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
+ return false;
+ }
+ }
+ // Check that cyclic values are equal.
+ var objStacked = stack.get(object);
+ var othStacked = stack.get(other);
+ if (objStacked && othStacked) {
+ return objStacked == other && othStacked == object;
+ }
+ var result = true;
+ stack.set(object, other);
+ stack.set(other, object);
+
+ var skipCtor = isPartial;
+ while (++index < objLength) {
+ key = objProps[index];
+ var objValue = object[key],
+ othValue = other[key];
+
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, objValue, key, other, object, stack)
+ : customizer(objValue, othValue, key, object, other, stack);
+ }
+ // Recursively compare objects (susceptible to call stack limits).
+ if (!(compared === undefined
+ ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
+ : compared
+ )) {
+ result = false;
+ break;
+ }
+ skipCtor || (skipCtor = key == 'constructor');
+ }
+ if (result && !skipCtor) {
+ var objCtor = object.constructor,
+ othCtor = other.constructor;
+
+ // Non `Object` object instances with different constructors are not equal.
+ if (objCtor != othCtor &&
+ ('constructor' in object && 'constructor' in other) &&
+ !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+ typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+ result = false;
+ }
+ }
+ stack['delete'](object);
+ stack['delete'](other);
+ return result;
+ }
+
+ /**
+ * A specialized version of `baseRest` which flattens the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @returns {Function} Returns the new function.
+ */
+ function flatRest(func) {
+ return setToString(overRest(func, undefined, flatten), func + '');
+ }
+
+ /**
+ * Creates an array of own enumerable property names and symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+ function getAllKeys(object) {
+ return baseGetAllKeys(object, keys, getSymbols);
+ }
+
+ /**
+ * Creates an array of own and inherited enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+ function getAllKeysIn(object) {
+ return baseGetAllKeys(object, keysIn, getSymbolsIn);
+ }
+
+ /**
+ * Gets metadata for `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {*} Returns the metadata for `func`.
+ */
+ var getData = !metaMap ? noop : function(func) {
+ return metaMap.get(func);
+ };
+
+ /**
+ * Gets the name of `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {string} Returns the function name.
+ */
+ function getFuncName(func) {
+ var result = (func.name + ''),
+ array = realNames[result],
+ length = hasOwnProperty.call(realNames, result) ? array.length : 0;
+
+ while (length--) {
+ var data = array[length],
+ otherFunc = data.func;
+ if (otherFunc == null || otherFunc == func) {
+ return data.name;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Gets the argument placeholder value for `func`.
+ *
+ * @private
+ * @param {Function} func The function to inspect.
+ * @returns {*} Returns the placeholder value.
+ */
+ function getHolder(func) {
+ var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
+ return object.placeholder;
+ }
+
+ /**
+ * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
+ * this function returns the custom method, otherwise it returns `baseIteratee`.
+ * If arguments are provided, the chosen function is invoked with them and
+ * its result is returned.
+ *
+ * @private
+ * @param {*} [value] The value to convert to an iteratee.
+ * @param {number} [arity] The arity of the created iteratee.
+ * @returns {Function} Returns the chosen function or its result.
+ */
+ function getIteratee() {
+ var result = lodash.iteratee || iteratee;
+ result = result === iteratee ? baseIteratee : result;
+ return arguments.length ? result(arguments[0], arguments[1]) : result;
+ }
+
+ /**
+ * Gets the data for `map`.
+ *
+ * @private
+ * @param {Object} map The map to query.
+ * @param {string} key The reference key.
+ * @returns {*} Returns the map data.
+ */
+ function getMapData(map, key) {
+ var data = map.__data__;
+ return isKeyable(key)
+ ? data[typeof key == 'string' ? 'string' : 'hash']
+ : data.map;
+ }
+
+ /**
+ * Gets the property names, values, and compare flags of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the match data of `object`.
+ */
+ function getMatchData(object) {
+ var result = keys(object),
+ length = result.length;
+
+ while (length--) {
+ var key = result[length],
+ value = object[key];
+
+ result[length] = [key, value, isStrictComparable(value)];
+ }
+ return result;
+ }
+
+ /**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+ function getNative(object, key) {
+ var value = getValue(object, key);
+ return baseIsNative(value) ? value : undefined;
+ }
+
+ /**
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the raw `toStringTag`.
+ */
+ function getRawTag(value) {
+ var isOwn = hasOwnProperty.call(value, symToStringTag),
+ tag = value[symToStringTag];
+
+ try {
+ value[symToStringTag] = undefined;
+ var unmasked = true;
+ } catch (e) {}
+
+ var result = nativeObjectToString.call(value);
+ if (unmasked) {
+ if (isOwn) {
+ value[symToStringTag] = tag;
+ } else {
+ delete value[symToStringTag];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates an array of the own enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+ var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
+ if (object == null) {
+ return [];
+ }
+ object = Object(object);
+ return arrayFilter(nativeGetSymbols(object), function(symbol) {
+ return propertyIsEnumerable.call(object, symbol);
+ });
+ };
+
+ /**
+ * Creates an array of the own and inherited enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+ var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
+ var result = [];
+ while (object) {
+ arrayPush(result, getSymbols(object));
+ object = getPrototype(object);
+ }
+ return result;
+ };
+
+ /**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+ var getTag = baseGetTag;
+
+ // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
+ if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
+ (Map && getTag(new Map) != mapTag) ||
+ (Promise && getTag(Promise.resolve()) != promiseTag) ||
+ (Set && getTag(new Set) != setTag) ||
+ (WeakMap && getTag(new WeakMap) != weakMapTag)) {
+ getTag = function(value) {
+ var result = baseGetTag(value),
+ Ctor = result == objectTag ? value.constructor : undefined,
+ ctorString = Ctor ? toSource(Ctor) : '';
+
+ if (ctorString) {
+ switch (ctorString) {
+ case dataViewCtorString: return dataViewTag;
+ case mapCtorString: return mapTag;
+ case promiseCtorString: return promiseTag;
+ case setCtorString: return setTag;
+ case weakMapCtorString: return weakMapTag;
+ }
+ }
+ return result;
+ };
+ }
+
+ /**
+ * Gets the view, applying any `transforms` to the `start` and `end` positions.
+ *
+ * @private
+ * @param {number} start The start of the view.
+ * @param {number} end The end of the view.
+ * @param {Array} transforms The transformations to apply to the view.
+ * @returns {Object} Returns an object containing the `start` and `end`
+ * positions of the view.
+ */
+ function getView(start, end, transforms) {
+ var index = -1,
+ length = transforms.length;
+
+ while (++index < length) {
+ var data = transforms[index],
+ size = data.size;
+
+ switch (data.type) {
+ case 'drop': start += size; break;
+ case 'dropRight': end -= size; break;
+ case 'take': end = nativeMin(end, start + size); break;
+ case 'takeRight': start = nativeMax(start, end - size); break;
+ }
+ }
+ return { 'start': start, 'end': end };
+ }
+
+ /**
+ * Extracts wrapper details from the `source` body comment.
+ *
+ * @private
+ * @param {string} source The source to inspect.
+ * @returns {Array} Returns the wrapper details.
+ */
+ function getWrapDetails(source) {
+ var match = source.match(reWrapDetails);
+ return match ? match[1].split(reSplitDetails) : [];
+ }
+
+ /**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+ function hasPath(object, path, hasFunc) {
+ path = castPath(path, object);
+
+ var index = -1,
+ length = path.length,
+ result = false;
+
+ while (++index < length) {
+ var key = toKey(path[index]);
+ if (!(result = object != null && hasFunc(object, key))) {
+ break;
+ }
+ object = object[key];
+ }
+ if (result || ++index != length) {
+ return result;
+ }
+ length = object == null ? 0 : object.length;
+ return !!length && isLength(length) && isIndex(key, length) &&
+ (isArray(object) || isArguments(object));
+ }
+
+ /**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+ function initCloneArray(array) {
+ var length = array.length,
+ result = new array.constructor(length);
+
+ // Add properties assigned by `RegExp#exec`.
+ if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+ result.index = array.index;
+ result.input = array.input;
+ }
+ return result;
+ }
+
+ /**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+ function initCloneObject(object) {
+ return (typeof object.constructor == 'function' && !isPrototype(object))
+ ? baseCreate(getPrototype(object))
+ : {};
+ }
+
+ /**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+ function initCloneByTag(object, tag, isDeep) {
+ var Ctor = object.constructor;
+ switch (tag) {
+ case arrayBufferTag:
+ return cloneArrayBuffer(object);
+
+ case boolTag:
+ case dateTag:
+ return new Ctor(+object);
+
+ case dataViewTag:
+ return cloneDataView(object, isDeep);
+
+ case float32Tag: case float64Tag:
+ case int8Tag: case int16Tag: case int32Tag:
+ case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+ return cloneTypedArray(object, isDeep);
+
+ case mapTag:
+ return new Ctor;
+
+ case numberTag:
+ case stringTag:
+ return new Ctor(object);
+
+ case regexpTag:
+ return cloneRegExp(object);
+
+ case setTag:
+ return new Ctor;
+
+ case symbolTag:
+ return cloneSymbol(object);
+ }
+ }
+
+ /**
+ * Inserts wrapper `details` in a comment at the top of the `source` body.
+ *
+ * @private
+ * @param {string} source The source to modify.
+ * @returns {Array} details The details to insert.
+ * @returns {string} Returns the modified source.
+ */
+ function insertWrapDetails(source, details) {
+ var length = details.length;
+ if (!length) {
+ return source;
+ }
+ var lastIndex = length - 1;
+ details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
+ details = details.join(length > 2 ? ', ' : ' ');
+ return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
+ }
+
+ /**
+ * Checks if `value` is a flattenable `arguments` object or array.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+ */
+ function isFlattenable(value) {
+ return isArray(value) || isArguments(value) ||
+ !!(spreadableSymbol && value && value[spreadableSymbol]);
+ }
+
+ /**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+ function isIndex(value, length) {
+ var type = typeof value;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+
+ return !!length &&
+ (type == 'number' ||
+ (type != 'symbol' && reIsUint.test(value))) &&
+ (value > -1 && value % 1 == 0 && value < length);
+ }
+
+ /**
+ * Checks if the given arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+ * else `false`.
+ */
+ function isIterateeCall(value, index, object) {
+ if (!isObject(object)) {
+ return false;
+ }
+ var type = typeof index;
+ if (type == 'number'
+ ? (isArrayLike(object) && isIndex(index, object.length))
+ : (type == 'string' && index in object)
+ ) {
+ return eq(object[index], value);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */
+ function isKey(value, object) {
+ if (isArray(value)) {
+ return false;
+ }
+ var type = typeof value;
+ if (type == 'number' || type == 'symbol' || type == 'boolean' ||
+ value == null || isSymbol(value)) {
+ return true;
+ }
+ return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object));
+ }
+
+ /**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+ function isKeyable(value) {
+ var type = typeof value;
+ return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
+ ? (value !== '__proto__')
+ : (value === null);
+ }
+
+ /**
+ * Checks if `func` has a lazy counterpart.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
+ * else `false`.
+ */
+ function isLaziable(func) {
+ var funcName = getFuncName(func),
+ other = lodash[funcName];
+
+ if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+ return false;
+ }
+ if (func === other) {
+ return true;
+ }
+ var data = getData(other);
+ return !!data && func === data[0];
+ }
+
+ /**
+ * Checks if `func` has its source masked.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+ */
+ function isMasked(func) {
+ return !!maskSrcKey && (maskSrcKey in func);
+ }
+
+ /**
+ * Checks if `func` is capable of being masked.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
+ */
+ var isMaskable = coreJsData ? isFunction : stubFalse;
+
+ /**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+ return value === proto;
+ }
+
+ /**
+ * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` if suitable for strict
+ * equality comparisons, else `false`.
+ */
+ function isStrictComparable(value) {
+ return value === value && !isObject(value);
+ }
+
+ /**
+ * A specialized version of `matchesProperty` for source values suitable
+ * for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */
+ function matchesStrictComparable(key, srcValue) {
+ return function(object) {
+ if (object == null) {
+ return false;
+ }
+ return object[key] === srcValue &&
+ (srcValue !== undefined || (key in Object(object)));
+ };
+ }
+
+ /**
+ * A specialized version of `_.memoize` which clears the memoized function's
+ * cache when it exceeds `MAX_MEMOIZE_SIZE`.
+ *
+ * @private
+ * @param {Function} func The function to have its output memoized.
+ * @returns {Function} Returns the new memoized function.
+ */
+ function memoizeCapped(func) {
+ var result = memoize(func, function(key) {
+ if (cache.size === MAX_MEMOIZE_SIZE) {
+ cache.clear();
+ }
+ return key;
+ });
+
+ var cache = result.cache;
+ return result;
+ }
+
+ /**
+ * Merges the function metadata of `source` into `data`.
+ *
+ * Merging metadata reduces the number of wrappers used to invoke a function.
+ * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
+ * may be applied regardless of execution order. Methods like `_.ary` and
+ * `_.rearg` modify function arguments, making the order in which they are
+ * executed important, preventing the merging of metadata. However, we make
+ * an exception for a safe combined case where curried functions have `_.ary`
+ * and or `_.rearg` applied.
+ *
+ * @private
+ * @param {Array} data The destination metadata.
+ * @param {Array} source The source metadata.
+ * @returns {Array} Returns `data`.
+ */
+ function mergeData(data, source) {
+ var bitmask = data[1],
+ srcBitmask = source[1],
+ newBitmask = bitmask | srcBitmask,
+ isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
+
+ var isCombo =
+ ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
+ ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
+ ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
+
+ // Exit early if metadata can't be merged.
+ if (!(isCommon || isCombo)) {
+ return data;
+ }
+ // Use source `thisArg` if available.
+ if (srcBitmask & WRAP_BIND_FLAG) {
+ data[2] = source[2];
+ // Set when currying a bound function.
+ newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
+ }
+ // Compose partial arguments.
+ var value = source[3];
+ if (value) {
+ var partials = data[3];
+ data[3] = partials ? composeArgs(partials, value, source[4]) : value;
+ data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
+ }
+ // Compose partial right arguments.
+ value = source[5];
+ if (value) {
+ partials = data[5];
+ data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
+ data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
+ }
+ // Use source `argPos` if available.
+ value = source[7];
+ if (value) {
+ data[7] = value;
+ }
+ // Use source `ary` if it's smaller.
+ if (srcBitmask & WRAP_ARY_FLAG) {
+ data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+ }
+ // Use source `arity` if one is not provided.
+ if (data[9] == null) {
+ data[9] = source[9];
+ }
+ // Use source `func` and merge bitmasks.
+ data[0] = source[0];
+ data[1] = newBitmask;
+
+ return data;
+ }
+
+ /**
+ * This function is like
+ * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * except that it includes inherited enumerable properties.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function nativeKeysIn(object) {
+ var result = [];
+ if (object != null) {
+ for (var key in Object(object)) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Converts `value` to a string using `Object.prototype.toString`.
+ *
+ * @private
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ */
+ function objectToString(value) {
+ return nativeObjectToString.call(value);
+ }
+
+ /**
+ * A specialized version of `baseRest` which transforms the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @param {Function} transform The rest array transform.
+ * @returns {Function} Returns the new function.
+ */
+ function overRest(func, start, transform) {
+ start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ array = Array(length);
+
+ while (++index < length) {
+ array[index] = args[start + index];
+ }
+ index = -1;
+ var otherArgs = Array(start + 1);
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = transform(array);
+ return apply(func, this, otherArgs);
+ };
+ }
+
+ /**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */
+ function parent(object, path) {
+ return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
+ }
+
+ /**
+ * Reorder `array` according to the specified indexes where the element at
+ * the first index is assigned as the first element, the element at
+ * the second index is assigned as the second element, and so on.
+ *
+ * @private
+ * @param {Array} array The array to reorder.
+ * @param {Array} indexes The arranged array indexes.
+ * @returns {Array} Returns `array`.
+ */
+ function reorder(array, indexes) {
+ var arrLength = array.length,
+ length = nativeMin(indexes.length, arrLength),
+ oldArray = copyArray(array);
+
+ while (length--) {
+ var index = indexes[length];
+ array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+ }
+ return array;
+ }
+
+ /**
+ * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */
+ function safeGet(object, key) {
+ if (key === 'constructor' && typeof object[key] === 'function') {
+ return;
+ }
+
+ if (key == '__proto__') {
+ return;
+ }
+
+ return object[key];
+ }
+
+ /**
+ * Sets metadata for `func`.
+ *
+ * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+ * period of time, it will trip its breaker and transition to an identity
+ * function to avoid garbage collection pauses in V8. See
+ * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
+ * for more details.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+ var setData = shortOut(baseSetData);
+
+ /**
+ * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
+ *
+ * @private
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @returns {number|Object} Returns the timer id or timeout object.
+ */
+ var setTimeout = ctxSetTimeout || function(func, wait) {
+ return root.setTimeout(func, wait);
+ };
+
+ /**
+ * Sets the `toString` method of `func` to return `string`.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+ var setToString = shortOut(baseSetToString);
+
+ /**
+ * Sets the `toString` method of `wrapper` to mimic the source of `reference`
+ * with wrapper details in a comment at the top of the source body.
+ *
+ * @private
+ * @param {Function} wrapper The function to modify.
+ * @param {Function} reference The reference function.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @returns {Function} Returns `wrapper`.
+ */
+ function setWrapToString(wrapper, reference, bitmask) {
+ var source = (reference + '');
+ return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
+ }
+
+ /**
+ * Creates a function that'll short out and invoke `identity` instead
+ * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
+ * milliseconds.
+ *
+ * @private
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new shortable function.
+ */
+ function shortOut(func) {
+ var count = 0,
+ lastCalled = 0;
+
+ return function() {
+ var stamp = nativeNow(),
+ remaining = HOT_SPAN - (stamp - lastCalled);
+
+ lastCalled = stamp;
+ if (remaining > 0) {
+ if (++count >= HOT_COUNT) {
+ return arguments[0];
+ }
+ } else {
+ count = 0;
+ }
+ return func.apply(undefined, arguments);
+ };
+ }
+
+ /**
+ * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
+ *
+ * @private
+ * @param {Array} array The array to shuffle.
+ * @param {number} [size=array.length] The size of `array`.
+ * @returns {Array} Returns `array`.
+ */
+ function shuffleSelf(array, size) {
+ var index = -1,
+ length = array.length,
+ lastIndex = length - 1;
+
+ size = size === undefined ? length : size;
+ while (++index < size) {
+ var rand = baseRandom(index, lastIndex),
+ value = array[rand];
+
+ array[rand] = array[index];
+ array[index] = value;
+ }
+ array.length = size;
+ return array;
+ }
+
+ /**
+ * Converts `string` to a property path array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
+ */
+ var stringToPath = memoizeCapped(function(string) {
+ var result = [];
+ if (string.charCodeAt(0) === 46 /* . */) {
+ result.push('');
+ }
+ string.replace(rePropName, function(match, number, quote, subString) {
+ result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
+ });
+ return result;
+ });
+
+ /**
+ * Converts `value` to a string key if it's not a string or symbol.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {string|symbol} Returns the key.
+ */
+ function toKey(value) {
+ if (typeof value == 'string' || isSymbol(value)) {
+ return value;
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+ }
+
+ /**
+ * Converts `func` to its source code.
+ *
+ * @private
+ * @param {Function} func The function to convert.
+ * @returns {string} Returns the source code.
+ */
+ function toSource(func) {
+ if (func != null) {
+ try {
+ return funcToString.call(func);
+ } catch (e) {}
+ try {
+ return (func + '');
+ } catch (e) {}
+ }
+ return '';
+ }
+
+ /**
+ * Updates wrapper `details` based on `bitmask` flags.
+ *
+ * @private
+ * @returns {Array} details The details to modify.
+ * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+ * @returns {Array} Returns `details`.
+ */
+ function updateWrapDetails(details, bitmask) {
+ arrayEach(wrapFlags, function(pair) {
+ var value = '_.' + pair[0];
+ if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
+ details.push(value);
+ }
+ });
+ return details.sort();
+ }
+
+ /**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */
+ function wrapperClone(wrapper) {
+ if (wrapper instanceof LazyWrapper) {
+ return wrapper.clone();
+ }
+ var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+ result.__actions__ = copyArray(wrapper.__actions__);
+ result.__index__ = wrapper.__index__;
+ result.__values__ = wrapper.__values__;
+ return result;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates an array of elements split into groups the length of `size`.
+ * If `array` can't be split evenly, the final chunk will be the remaining
+ * elements.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to process.
+ * @param {number} [size=1] The length of each chunk
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the new array of chunks.
+ * @example
+ *
+ * _.chunk(['a', 'b', 'c', 'd'], 2);
+ * // => [['a', 'b'], ['c', 'd']]
+ *
+ * _.chunk(['a', 'b', 'c', 'd'], 3);
+ * // => [['a', 'b', 'c'], ['d']]
+ */
+ function chunk(array, size, guard) {
+ if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
+ size = 1;
+ } else {
+ size = nativeMax(toInteger(size), 0);
+ }
+ var length = array == null ? 0 : array.length;
+ if (!length || size < 1) {
+ return [];
+ }
+ var index = 0,
+ resIndex = 0,
+ result = Array(nativeCeil(length / size));
+
+ while (index < length) {
+ result[resIndex++] = baseSlice(array, index, (index += size));
+ }
+ return result;
+ }
+
+ /**
+ * Creates an array with all falsey values removed. The values `false`, `null`,
+ * `0`, `""`, `undefined`, and `NaN` are falsey.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to compact.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.compact([0, 1, false, 2, '', 3]);
+ * // => [1, 2, 3]
+ */
+ function compact(array) {
+ var index = -1,
+ length = array == null ? 0 : array.length,
+ resIndex = 0,
+ result = [];
+
+ while (++index < length) {
+ var value = array[index];
+ if (value) {
+ result[resIndex++] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ function concat() {
+ var length = arguments.length;
+ if (!length) {
+ return [];
+ }
+ var args = Array(length - 1),
+ array = arguments[0],
+ index = length;
+
+ while (index--) {
+ args[index - 1] = arguments[index];
+ }
+ return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
+ }
+
+ /**
+ * Creates an array of `array` values not included in the other given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * **Note:** Unlike `_.pullAll`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.without, _.xor
+ * @example
+ *
+ * _.difference([2, 1], [2, 3]);
+ * // => [1]
+ */
+ var difference = baseRest(function(array, values) {
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
+ : [];
+ });
+
+ /**
+ * This method is like `_.difference` except that it accepts `iteratee` which
+ * is invoked for each element of `array` and `values` to generate the criterion
+ * by which they're compared. The order and references of result values are
+ * determined by the first array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var differenceBy = baseRest(function(array, values) {
+ var iteratee = last(values);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
+ : [];
+ });
+
+ /**
+ * This method is like `_.difference` except that it accepts `comparator`
+ * which is invoked to compare elements of `array` to `values`. The order and
+ * references of result values are determined by the first array. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
+ *
+ * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ *
+ * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }]
+ */
+ var differenceWith = baseRest(function(array, values) {
+ var comparator = last(values);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
+ : [];
+ });
+
+ /**
+ * Creates a slice of `array` with `n` elements dropped from the beginning.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to drop.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.drop([1, 2, 3]);
+ * // => [2, 3]
+ *
+ * _.drop([1, 2, 3], 2);
+ * // => [3]
+ *
+ * _.drop([1, 2, 3], 5);
+ * // => []
+ *
+ * _.drop([1, 2, 3], 0);
+ * // => [1, 2, 3]
+ */
+ function drop(array, n, guard) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ return baseSlice(array, n < 0 ? 0 : n, length);
+ }
+
+ /**
+ * Creates a slice of `array` with `n` elements dropped from the end.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to drop.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.dropRight([1, 2, 3]);
+ * // => [1, 2]
+ *
+ * _.dropRight([1, 2, 3], 2);
+ * // => [1]
+ *
+ * _.dropRight([1, 2, 3], 5);
+ * // => []
+ *
+ * _.dropRight([1, 2, 3], 0);
+ * // => [1, 2, 3]
+ */
+ function dropRight(array, n, guard) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
+ return baseSlice(array, 0, n < 0 ? 0 : n);
+ }
+
+ /**
+ * Creates a slice of `array` excluding elements dropped from the end.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.dropRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.dropRightWhile(users, ['active', false]);
+ * // => objects for ['barney']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.dropRightWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */
+ function dropRightWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, getIteratee(predicate, 3), true, true)
+ : [];
+ }
+
+ /**
+ * Creates a slice of `array` excluding elements dropped from the beginning.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.dropWhile(users, function(o) { return !o.active; });
+ * // => objects for ['pebbles']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.dropWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.dropWhile(users, ['active', false]);
+ * // => objects for ['pebbles']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.dropWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */
+ function dropWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, getIteratee(predicate, 3), true)
+ : [];
+ }
+
+ /**
+ * Fills elements of `array` with `value` from `start` up to, but not
+ * including, `end`.
+ *
+ * **Note:** This method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.2.0
+ * @category Array
+ * @param {Array} array The array to fill.
+ * @param {*} value The value to fill `array` with.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _.fill(array, 'a');
+ * console.log(array);
+ * // => ['a', 'a', 'a']
+ *
+ * _.fill(Array(3), 2);
+ * // => [2, 2, 2]
+ *
+ * _.fill([4, 6, 8, 10], '*', 1, 3);
+ * // => [4, '*', '*', 10]
+ */
+ function fill(array, value, start, end) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
+ start = 0;
+ end = length;
+ }
+ return baseFill(array, value, start, end);
+ }
+
+ /**
+ * This method is like `_.find` except that it returns the index of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.findIndex(users, function(o) { return o.user == 'barney'; });
+ * // => 0
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findIndex(users, { 'user': 'fred', 'active': false });
+ * // => 1
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findIndex(users, ['active', false]);
+ * // => 0
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findIndex(users, 'active');
+ * // => 2
+ */
+ function findIndex(array, predicate, fromIndex) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return -1;
+ }
+ var index = fromIndex == null ? 0 : toInteger(fromIndex);
+ if (index < 0) {
+ index = nativeMax(length + index, 0);
+ }
+ return baseFindIndex(array, getIteratee(predicate, 3), index);
+ }
+
+ /**
+ * This method is like `_.findIndex` except that it iterates over elements
+ * of `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
+ * // => 2
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findLastIndex(users, { 'user': 'barney', 'active': true });
+ * // => 0
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findLastIndex(users, ['active', false]);
+ * // => 2
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findLastIndex(users, 'active');
+ * // => 0
+ */
+ function findLastIndex(array, predicate, fromIndex) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return -1;
+ }
+ var index = length - 1;
+ if (fromIndex !== undefined) {
+ index = toInteger(fromIndex);
+ index = fromIndex < 0
+ ? nativeMax(length + index, 0)
+ : nativeMin(index, length - 1);
+ }
+ return baseFindIndex(array, getIteratee(predicate, 3), index, true);
+ }
+
+ /**
+ * Flattens `array` a single level deep.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flatten([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, [3, [4]], 5]
+ */
+ function flatten(array) {
+ var length = array == null ? 0 : array.length;
+ return length ? baseFlatten(array, 1) : [];
+ }
+
+ /**
+ * Recursively flattens `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flattenDeep([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, 3, 4, 5]
+ */
+ function flattenDeep(array) {
+ var length = array == null ? 0 : array.length;
+ return length ? baseFlatten(array, INFINITY) : [];
+ }
+
+ /**
+ * Recursively flatten `array` up to `depth` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.4.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @param {number} [depth=1] The maximum recursion depth.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * var array = [1, [2, [3, [4]], 5]];
+ *
+ * _.flattenDepth(array, 1);
+ * // => [1, 2, [3, [4]], 5]
+ *
+ * _.flattenDepth(array, 2);
+ * // => [1, 2, 3, [4], 5]
+ */
+ function flattenDepth(array, depth) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ depth = depth === undefined ? 1 : toInteger(depth);
+ return baseFlatten(array, depth);
+ }
+
+ /**
+ * The inverse of `_.toPairs`; this method returns an object composed
+ * from key-value `pairs`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} pairs The key-value pairs.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.fromPairs([['a', 1], ['b', 2]]);
+ * // => { 'a': 1, 'b': 2 }
+ */
+ function fromPairs(pairs) {
+ var index = -1,
+ length = pairs == null ? 0 : pairs.length,
+ result = {};
+
+ while (++index < length) {
+ var pair = pairs[index];
+ result[pair[0]] = pair[1];
+ }
+ return result;
+ }
+
+ /**
+ * Gets the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias first
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the first element of `array`.
+ * @example
+ *
+ * _.head([1, 2, 3]);
+ * // => 1
+ *
+ * _.head([]);
+ * // => undefined
+ */
+ function head(array) {
+ return (array && array.length) ? array[0] : undefined;
+ }
+
+ /**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the
+ * offset from the end of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // Search from the `fromIndex`.
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */
+ function indexOf(array, value, fromIndex) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return -1;
+ }
+ var index = fromIndex == null ? 0 : toInteger(fromIndex);
+ if (index < 0) {
+ index = nativeMax(length + index, 0);
+ }
+ return baseIndexOf(array, value, index);
+ }
+
+ /**
+ * Gets all but the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.initial([1, 2, 3]);
+ * // => [1, 2]
+ */
+ function initial(array) {
+ var length = array == null ? 0 : array.length;
+ return length ? baseSlice(array, 0, -1) : [];
+ }
+
+ /**
+ * Creates an array of unique values that are included in all given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersection([2, 1], [2, 3]);
+ * // => [2]
+ */
+ var intersection = baseRest(function(arrays) {
+ var mapped = arrayMap(arrays, castArrayLikeObject);
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped)
+ : [];
+ });
+
+ /**
+ * This method is like `_.intersection` except that it accepts `iteratee`
+ * which is invoked for each element of each `arrays` to generate the criterion
+ * by which they're compared. The order and references of result values are
+ * determined by the first array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [2.1]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }]
+ */
+ var intersectionBy = baseRest(function(arrays) {
+ var iteratee = last(arrays),
+ mapped = arrayMap(arrays, castArrayLikeObject);
+
+ if (iteratee === last(mapped)) {
+ iteratee = undefined;
+ } else {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, getIteratee(iteratee, 2))
+ : [];
+ });
+
+ /**
+ * This method is like `_.intersection` except that it accepts `comparator`
+ * which is invoked to compare elements of `arrays`. The order and references
+ * of result values are determined by the first array. The comparator is
+ * invoked with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.intersectionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }]
+ */
+ var intersectionWith = baseRest(function(arrays) {
+ var comparator = last(arrays),
+ mapped = arrayMap(arrays, castArrayLikeObject);
+
+ comparator = typeof comparator == 'function' ? comparator : undefined;
+ if (comparator) {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, undefined, comparator)
+ : [];
+ });
+
+ /**
+ * Converts all elements in `array` into a string separated by `separator`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to convert.
+ * @param {string} [separator=','] The element separator.
+ * @returns {string} Returns the joined string.
+ * @example
+ *
+ * _.join(['a', 'b', 'c'], '~');
+ * // => 'a~b~c'
+ */
+ function join(array, separator) {
+ return array == null ? '' : nativeJoin.call(array, separator);
+ }
+
+ /**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+ function last(array) {
+ var length = array == null ? 0 : array.length;
+ return length ? array[length - 1] : undefined;
+ }
+
+ /**
+ * This method is like `_.indexOf` except that it iterates over elements of
+ * `array` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.lastIndexOf([1, 2, 1, 2], 2);
+ * // => 3
+ *
+ * // Search from the `fromIndex`.
+ * _.lastIndexOf([1, 2, 1, 2], 2, 2);
+ * // => 1
+ */
+ function lastIndexOf(array, value, fromIndex) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return -1;
+ }
+ var index = length;
+ if (fromIndex !== undefined) {
+ index = toInteger(fromIndex);
+ index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
+ }
+ return value === value
+ ? strictLastIndexOf(array, value, index)
+ : baseFindIndex(array, baseIsNaN, index, true);
+ }
+
+ /**
+ * Gets the element at index `n` of `array`. If `n` is negative, the nth
+ * element from the end is returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.11.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=0] The index of the element to return.
+ * @returns {*} Returns the nth element of `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'd'];
+ *
+ * _.nth(array, 1);
+ * // => 'b'
+ *
+ * _.nth(array, -2);
+ * // => 'c';
+ */
+ function nth(array, n) {
+ return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
+ }
+
+ /**
+ * Removes all given values from `array` using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
+ * to remove elements from an array by predicate.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...*} [values] The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+ *
+ * _.pull(array, 'a', 'c');
+ * console.log(array);
+ * // => ['b', 'b']
+ */
+ var pull = baseRest(pullAll);
+
+ /**
+ * This method is like `_.pull` except that it accepts an array of values to remove.
+ *
+ * **Note:** Unlike `_.difference`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+ *
+ * _.pullAll(array, ['a', 'c']);
+ * console.log(array);
+ * // => ['b', 'b']
+ */
+ function pullAll(array, values) {
+ return (array && array.length && values && values.length)
+ ? basePullAll(array, values)
+ : array;
+ }
+
+ /**
+ * This method is like `_.pullAll` except that it accepts `iteratee` which is
+ * invoked for each element of `array` and `values` to generate the criterion
+ * by which they're compared. The iteratee is invoked with one argument: (value).
+ *
+ * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+ *
+ * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+ * console.log(array);
+ * // => [{ 'x': 2 }]
+ */
+ function pullAllBy(array, values, iteratee) {
+ return (array && array.length && values && values.length)
+ ? basePullAll(array, values, getIteratee(iteratee, 2))
+ : array;
+ }
+
+ /**
+ * This method is like `_.pullAll` except that it accepts `comparator` which
+ * is invoked to compare elements of `array` to `values`. The comparator is
+ * invoked with two arguments: (arrVal, othVal).
+ *
+ * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
+ *
+ * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
+ * console.log(array);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
+ */
+ function pullAllWith(array, values, comparator) {
+ return (array && array.length && values && values.length)
+ ? basePullAll(array, values, undefined, comparator)
+ : array;
+ }
+
+ /**
+ * Removes elements from `array` corresponding to `indexes` and returns an
+ * array of removed elements.
+ *
+ * **Note:** Unlike `_.at`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...(number|number[])} [indexes] The indexes of elements to remove.
+ * @returns {Array} Returns the new array of removed elements.
+ * @example
+ *
+ * var array = ['a', 'b', 'c', 'd'];
+ * var pulled = _.pullAt(array, [1, 3]);
+ *
+ * console.log(array);
+ * // => ['a', 'c']
+ *
+ * console.log(pulled);
+ * // => ['b', 'd']
+ */
+ var pullAt = flatRest(function(array, indexes) {
+ var length = array == null ? 0 : array.length,
+ result = baseAt(array, indexes);
+
+ basePullAt(array, arrayMap(indexes, function(index) {
+ return isIndex(index, length) ? +index : index;
+ }).sort(compareAscending));
+
+ return result;
+ });
+
+ /**
+ * Removes all elements from `array` that `predicate` returns truthy for
+ * and returns an array of the removed elements. The predicate is invoked
+ * with three arguments: (value, index, array).
+ *
+ * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
+ * to pull elements from an array by value.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new array of removed elements.
+ * @example
+ *
+ * var array = [1, 2, 3, 4];
+ * var evens = _.remove(array, function(n) {
+ * return n % 2 == 0;
+ * });
+ *
+ * console.log(array);
+ * // => [1, 3]
+ *
+ * console.log(evens);
+ * // => [2, 4]
+ */
+ function remove(array, predicate) {
+ var result = [];
+ if (!(array && array.length)) {
+ return result;
+ }
+ var index = -1,
+ indexes = [],
+ length = array.length;
+
+ predicate = getIteratee(predicate, 3);
+ while (++index < length) {
+ var value = array[index];
+ if (predicate(value, index, array)) {
+ result.push(value);
+ indexes.push(index);
+ }
+ }
+ basePullAt(array, indexes);
+ return result;
+ }
+
+ /**
+ * Reverses `array` so that the first element becomes the last, the second
+ * element becomes the second to last, and so on.
+ *
+ * **Note:** This method mutates `array` and is based on
+ * [`Array#reverse`](https://mdn.io/Array/reverse).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _.reverse(array);
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
+ */
+ function reverse(array) {
+ return array == null ? array : nativeReverse.call(array);
+ }
+
+ /**
+ * Creates a slice of `array` from `start` up to, but not including, `end`.
+ *
+ * **Note:** This method is used instead of
+ * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
+ * returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function slice(array, start, end) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
+ start = 0;
+ end = length;
+ }
+ else {
+ start = start == null ? 0 : toInteger(start);
+ end = end === undefined ? length : toInteger(end);
+ }
+ return baseSlice(array, start, end);
+ }
+
+ /**
+ * Uses a binary search to determine the lowest index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * _.sortedIndex([30, 50], 40);
+ * // => 1
+ */
+ function sortedIndex(array, value) {
+ return baseSortedIndex(array, value);
+ }
+
+ /**
+ * This method is like `_.sortedIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * var objects = [{ 'x': 4 }, { 'x': 5 }];
+ *
+ * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+ * // => 0
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
+ * // => 0
+ */
+ function sortedIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
+ }
+
+ /**
+ * This method is like `_.indexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
+ * // => 1
+ */
+ function sortedIndexOf(array, value) {
+ var length = array == null ? 0 : array.length;
+ if (length) {
+ var index = baseSortedIndex(array, value);
+ if (index < length && eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * This method is like `_.sortedIndex` except that it returns the highest
+ * index at which `value` should be inserted into `array` in order to
+ * maintain its sort order.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
+ * // => 4
+ */
+ function sortedLastIndex(array, value) {
+ return baseSortedIndex(array, value, true);
+ }
+
+ /**
+ * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted
+ * into `array`.
+ * @example
+ *
+ * var objects = [{ 'x': 4 }, { 'x': 5 }];
+ *
+ * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+ * // => 1
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
+ * // => 1
+ */
+ function sortedLastIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
+ }
+
+ /**
+ * This method is like `_.lastIndexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
+ * // => 3
+ */
+ function sortedLastIndexOf(array, value) {
+ var length = array == null ? 0 : array.length;
+ if (length) {
+ var index = baseSortedIndex(array, value, true) - 1;
+ if (eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * This method is like `_.uniq` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniq([1, 1, 2]);
+ * // => [1, 2]
+ */
+ function sortedUniq(array) {
+ return (array && array.length)
+ ? baseSortedUniq(array)
+ : [];
+ }
+
+ /**
+ * This method is like `_.uniqBy` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+ * // => [1.1, 2.3]
+ */
+ function sortedUniqBy(array, iteratee) {
+ return (array && array.length)
+ ? baseSortedUniq(array, getIteratee(iteratee, 2))
+ : [];
+ }
+
+ /**
+ * Gets all but the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.tail([1, 2, 3]);
+ * // => [2, 3]
+ */
+ function tail(array) {
+ var length = array == null ? 0 : array.length;
+ return length ? baseSlice(array, 1, length) : [];
+ }
+
+ /**
+ * Creates a slice of `array` with `n` elements taken from the beginning.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to take.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.take([1, 2, 3]);
+ * // => [1]
+ *
+ * _.take([1, 2, 3], 2);
+ * // => [1, 2]
+ *
+ * _.take([1, 2, 3], 5);
+ * // => [1, 2, 3]
+ *
+ * _.take([1, 2, 3], 0);
+ * // => []
+ */
+ function take(array, n, guard) {
+ if (!(array && array.length)) {
+ return [];
+ }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ return baseSlice(array, 0, n < 0 ? 0 : n);
+ }
+
+ /**
+ * Creates a slice of `array` with `n` elements taken from the end.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {number} [n=1] The number of elements to take.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.takeRight([1, 2, 3]);
+ * // => [3]
+ *
+ * _.takeRight([1, 2, 3], 2);
+ * // => [2, 3]
+ *
+ * _.takeRight([1, 2, 3], 5);
+ * // => [1, 2, 3]
+ *
+ * _.takeRight([1, 2, 3], 0);
+ * // => []
+ */
+ function takeRight(array, n, guard) {
+ var length = array == null ? 0 : array.length;
+ if (!length) {
+ return [];
+ }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
+ return baseSlice(array, n < 0 ? 0 : n, length);
+ }
+
+ /**
+ * Creates a slice of `array` with elements taken from the end. Elements are
+ * taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.takeRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['pebbles']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.takeRightWhile(users, ['active', false]);
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.takeRightWhile(users, 'active');
+ * // => []
+ */
+ function takeRightWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, getIteratee(predicate, 3), false, true)
+ : [];
+ }
+
+ /**
+ * Creates a slice of `array` with elements taken from the beginning. Elements
+ * are taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.takeWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.takeWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.takeWhile(users, ['active', false]);
+ * // => objects for ['barney', 'fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.takeWhile(users, 'active');
+ * // => []
+ */
+ function takeWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, getIteratee(predicate, 3))
+ : [];
+ }
+
+ /**
+ * Creates an array of unique values, in order, from all given arrays using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.union([2], [1, 2]);
+ * // => [2, 1]
+ */
+ var union = baseRest(function(arrays) {
+ return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
+ });
+
+ /**
+ * This method is like `_.union` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by
+ * which uniqueness is computed. Result values are chosen from the first
+ * array in which the value occurs. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.unionBy([2.1], [1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+ var unionBy = baseRest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
+ });
+
+ /**
+ * This method is like `_.union` except that it accepts `comparator` which
+ * is invoked to compare elements of `arrays`. Result values are chosen from
+ * the first array in which the value occurs. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.unionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var unionWith = baseRest(function(arrays) {
+ var comparator = last(arrays);
+ comparator = typeof comparator == 'function' ? comparator : undefined;
+ return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
+ });
+
+ /**
+ * Creates a duplicate-free version of an array, using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept. The order of result values is determined by the order they occur
+ * in the array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniq([2, 1, 2]);
+ * // => [2, 1]
+ */
+ function uniq(array) {
+ return (array && array.length) ? baseUniq(array) : [];
+ }
+
+ /**
+ * This method is like `_.uniq` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * uniqueness is computed. The order of result values is determined by the
+ * order they occur in the array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+ function uniqBy(array, iteratee) {
+ return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
+ }
+
+ /**
+ * This method is like `_.uniq` except that it accepts `comparator` which
+ * is invoked to compare elements of `array`. The order of result values is
+ * determined by the order they occur in the array.The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.uniqWith(objects, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+ */
+ function uniqWith(array, comparator) {
+ comparator = typeof comparator == 'function' ? comparator : undefined;
+ return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
+ }
+
+ /**
+ * This method is like `_.zip` except that it accepts an array of grouped
+ * elements and creates an array regrouping the elements to their pre-zip
+ * configuration.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.2.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ *
+ * _.unzip(zipped);
+ * // => [['a', 'b'], [1, 2], [true, false]]
+ */
+ function unzip(array) {
+ if (!(array && array.length)) {
+ return [];
+ }
+ var length = 0;
+ array = arrayFilter(array, function(group) {
+ if (isArrayLikeObject(group)) {
+ length = nativeMax(group.length, length);
+ return true;
+ }
+ });
+ return baseTimes(length, function(index) {
+ return arrayMap(array, baseProperty(index));
+ });
+ }
+
+ /**
+ * This method is like `_.unzip` except that it accepts `iteratee` to specify
+ * how regrouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ * regrouped values.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+ * // => [[1, 10, 100], [2, 20, 200]]
+ *
+ * _.unzipWith(zipped, _.add);
+ * // => [3, 30, 300]
+ */
+ function unzipWith(array, iteratee) {
+ if (!(array && array.length)) {
+ return [];
+ }
+ var result = unzip(array);
+ if (iteratee == null) {
+ return result;
+ }
+ return arrayMap(result, function(group) {
+ return apply(iteratee, undefined, group);
+ });
+ }
+
+ /**
+ * Creates an array excluding all given values using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * **Note:** Unlike `_.pull`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...*} [values] The values to exclude.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.difference, _.xor
+ * @example
+ *
+ * _.without([2, 1, 2, 3], 1, 2);
+ * // => [3]
+ */
+ var without = baseRest(function(array, values) {
+ return isArrayLikeObject(array)
+ ? baseDifference(array, values)
+ : [];
+ });
+
+ /**
+ * Creates an array of unique values that is the
+ * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
+ * of the given arrays. The order of result values is determined by the order
+ * they occur in the arrays.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.difference, _.without
+ * @example
+ *
+ * _.xor([2, 1], [2, 3]);
+ * // => [1, 3]
+ */
+ var xor = baseRest(function(arrays) {
+ return baseXor(arrayFilter(arrays, isArrayLikeObject));
+ });
+
+ /**
+ * This method is like `_.xor` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by
+ * which by which they're compared. The order of result values is determined
+ * by the order they occur in the arrays. The iteratee is invoked with one
+ * argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [1.2, 3.4]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var xorBy = baseRest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
+ });
+
+ /**
+ * This method is like `_.xor` except that it accepts `comparator` which is
+ * invoked to compare elements of `arrays`. The order of result values is
+ * determined by the order they occur in the arrays. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.xorWith(objects, others, _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var xorWith = baseRest(function(arrays) {
+ var comparator = last(arrays);
+ comparator = typeof comparator == 'function' ? comparator : undefined;
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
+ });
+
+ /**
+ * Creates an array of grouped elements, the first of which contains the
+ * first elements of the given arrays, the second of which contains the
+ * second elements of the given arrays, and so on.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ */
+ var zip = baseRest(unzip);
+
+ /**
+ * This method is like `_.fromPairs` except that it accepts two arrays,
+ * one of property identifiers and one of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.4.0
+ * @category Array
+ * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [values=[]] The property values.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.zipObject(['a', 'b'], [1, 2]);
+ * // => { 'a': 1, 'b': 2 }
+ */
+ function zipObject(props, values) {
+ return baseZipObject(props || [], values || [], assignValue);
+ }
+
+ /**
+ * This method is like `_.zipObject` except that it supports property paths.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.1.0
+ * @category Array
+ * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [values=[]] The property values.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
+ * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
+ */
+ function zipObjectDeep(props, values) {
+ return baseZipObject(props || [], values || [], baseSet);
+ }
+
+ /**
+ * This method is like `_.zip` except that it accepts `iteratee` to specify
+ * how grouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ * grouped values.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+ * return a + b + c;
+ * });
+ * // => [111, 222]
+ */
+ var zipWith = baseRest(function(arrays) {
+ var length = arrays.length,
+ iteratee = length > 1 ? arrays[length - 1] : undefined;
+
+ iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
+ return unzipWith(arrays, iteratee);
+ });
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a `lodash` wrapper instance that wraps `value` with explicit method
+ * chain sequences enabled. The result of such sequences must be unwrapped
+ * with `_#value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.3.0
+ * @category Seq
+ * @param {*} value The value to wrap.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'pebbles', 'age': 1 }
+ * ];
+ *
+ * var youngest = _
+ * .chain(users)
+ * .sortBy('age')
+ * .map(function(o) {
+ * return o.user + ' is ' + o.age;
+ * })
+ * .head()
+ * .value();
+ * // => 'pebbles is 1'
+ */
+ function chain(value) {
+ var result = lodash(value);
+ result.__chain__ = true;
+ return result;
+ }
+
+ /**
+ * This method invokes `interceptor` and returns `value`. The interceptor
+ * is invoked with one argument; (value). The purpose of this method is to
+ * "tap into" a method chain sequence in order to modify intermediate results.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * _([1, 2, 3])
+ * .tap(function(array) {
+ * // Mutate input array.
+ * array.pop();
+ * })
+ * .reverse()
+ * .value();
+ * // => [2, 1]
+ */
+ function tap(value, interceptor) {
+ interceptor(value);
+ return value;
+ }
+
+ /**
+ * This method is like `_.tap` except that it returns the result of `interceptor`.
+ * The purpose of this method is to "pass thru" values replacing intermediate
+ * results in a method chain sequence.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns the result of `interceptor`.
+ * @example
+ *
+ * _(' abc ')
+ * .chain()
+ * .trim()
+ * .thru(function(value) {
+ * return [value];
+ * })
+ * .value();
+ * // => ['abc']
+ */
+ function thru(value, interceptor) {
+ return interceptor(value);
+ }
+
+ /**
+ * This method is the wrapper version of `_.at`.
+ *
+ * @name at
+ * @memberOf _
+ * @since 1.0.0
+ * @category Seq
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _(object).at(['a[0].b.c', 'a[1]']).value();
+ * // => [3, 4]
+ */
+ var wrapperAt = flatRest(function(paths) {
+ var length = paths.length,
+ start = length ? paths[0] : 0,
+ value = this.__wrapped__,
+ interceptor = function(object) { return baseAt(object, paths); };
+
+ if (length > 1 || this.__actions__.length ||
+ !(value instanceof LazyWrapper) || !isIndex(start)) {
+ return this.thru(interceptor);
+ }
+ value = value.slice(start, +start + (length ? 1 : 0));
+ value.__actions__.push({
+ 'func': thru,
+ 'args': [interceptor],
+ 'thisArg': undefined
+ });
+ return new LodashWrapper(value, this.__chain__).thru(function(array) {
+ if (length && !array.length) {
+ array.push(undefined);
+ }
+ return array;
+ });
+ });
+
+ /**
+ * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
+ *
+ * @name chain
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // A sequence without explicit chaining.
+ * _(users).head();
+ * // => { 'user': 'barney', 'age': 36 }
+ *
+ * // A sequence with explicit chaining.
+ * _(users)
+ * .chain()
+ * .head()
+ * .pick('user')
+ * .value();
+ * // => { 'user': 'barney' }
+ */
+ function wrapperChain() {
+ return chain(this);
+ }
+
+ /**
+ * Executes the chain sequence and returns the wrapped result.
+ *
+ * @name commit
+ * @memberOf _
+ * @since 3.2.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var array = [1, 2];
+ * var wrapped = _(array).push(3);
+ *
+ * console.log(array);
+ * // => [1, 2]
+ *
+ * wrapped = wrapped.commit();
+ * console.log(array);
+ * // => [1, 2, 3]
+ *
+ * wrapped.last();
+ * // => 3
+ *
+ * console.log(array);
+ * // => [1, 2, 3]
+ */
+ function wrapperCommit() {
+ return new LodashWrapper(this.value(), this.__chain__);
+ }
+
+ /**
+ * Gets the next value on a wrapped object following the
+ * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
+ *
+ * @name next
+ * @memberOf _
+ * @since 4.0.0
+ * @category Seq
+ * @returns {Object} Returns the next iterator value.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 1 }
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 2 }
+ *
+ * wrapped.next();
+ * // => { 'done': true, 'value': undefined }
+ */
+ function wrapperNext() {
+ if (this.__values__ === undefined) {
+ this.__values__ = toArray(this.value());
+ }
+ var done = this.__index__ >= this.__values__.length,
+ value = done ? undefined : this.__values__[this.__index__++];
+
+ return { 'done': done, 'value': value };
+ }
+
+ /**
+ * Enables the wrapper to be iterable.
+ *
+ * @name Symbol.iterator
+ * @memberOf _
+ * @since 4.0.0
+ * @category Seq
+ * @returns {Object} Returns the wrapper object.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped[Symbol.iterator]() === wrapped;
+ * // => true
+ *
+ * Array.from(wrapped);
+ * // => [1, 2]
+ */
+ function wrapperToIterator() {
+ return this;
+ }
+
+ /**
+ * Creates a clone of the chain sequence planting `value` as the wrapped value.
+ *
+ * @name plant
+ * @memberOf _
+ * @since 3.2.0
+ * @category Seq
+ * @param {*} value The value to plant.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2]).map(square);
+ * var other = wrapped.plant([3, 4]);
+ *
+ * other.value();
+ * // => [9, 16]
+ *
+ * wrapped.value();
+ * // => [1, 4]
+ */
+ function wrapperPlant(value) {
+ var result,
+ parent = this;
+
+ while (parent instanceof baseLodash) {
+ var clone = wrapperClone(parent);
+ clone.__index__ = 0;
+ clone.__values__ = undefined;
+ if (result) {
+ previous.__wrapped__ = clone;
+ } else {
+ result = clone;
+ }
+ var previous = clone;
+ parent = parent.__wrapped__;
+ }
+ previous.__wrapped__ = value;
+ return result;
+ }
+
+ /**
+ * This method is the wrapper version of `_.reverse`.
+ *
+ * **Note:** This method mutates the wrapped array.
+ *
+ * @name reverse
+ * @memberOf _
+ * @since 0.1.0
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _(array).reverse().value()
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
+ */
+ function wrapperReverse() {
+ var value = this.__wrapped__;
+ if (value instanceof LazyWrapper) {
+ var wrapped = value;
+ if (this.__actions__.length) {
+ wrapped = new LazyWrapper(this);
+ }
+ wrapped = wrapped.reverse();
+ wrapped.__actions__.push({
+ 'func': thru,
+ 'args': [reverse],
+ 'thisArg': undefined
+ });
+ return new LodashWrapper(wrapped, this.__chain__);
+ }
+ return this.thru(reverse);
+ }
+
+ /**
+ * Executes the chain sequence to resolve the unwrapped value.
+ *
+ * @name value
+ * @memberOf _
+ * @since 0.1.0
+ * @alias toJSON, valueOf
+ * @category Seq
+ * @returns {*} Returns the resolved unwrapped value.
+ * @example
+ *
+ * _([1, 2, 3]).value();
+ * // => [1, 2, 3]
+ */
+ function wrapperValue() {
+ return baseWrapperValue(this.__wrapped__, this.__actions__);
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The corresponding value of
+ * each key is the number of times the key was returned by `iteratee`. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.countBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': 1, '6': 2 }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.countBy(['one', 'two', 'three'], 'length');
+ * // => { '3': 2, '5': 1 }
+ */
+ var countBy = createAggregator(function(result, value, key) {
+ if (hasOwnProperty.call(result, key)) {
+ ++result[key];
+ } else {
+ baseAssignValue(result, key, 1);
+ }
+ });
+
+ /**
+ * Checks if `predicate` returns truthy for **all** elements of `collection`.
+ * Iteration is stopped once `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * **Note:** This method returns `true` for
+ * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
+ * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
+ * elements of empty collections.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check,
+ * else `false`.
+ * @example
+ *
+ * _.every([true, 1, null, 'yes'], Boolean);
+ * // => false
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.every(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.every(users, ['active', false]);
+ * // => true
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.every(users, 'active');
+ * // => false
+ */
+ function every(collection, predicate, guard) {
+ var func = isArray(collection) ? arrayEvery : baseEvery;
+ if (guard && isIterateeCall(collection, predicate, guard)) {
+ predicate = undefined;
+ }
+ return func(collection, getIteratee(predicate, 3));
+ }
+
+ /**
+ * Iterates over elements of `collection`, returning an array of all elements
+ * `predicate` returns truthy for. The predicate is invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * **Note:** Unlike `_.remove`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @see _.reject
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.filter(users, { 'age': 36, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.filter(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.filter(users, 'active');
+ * // => objects for ['barney']
+ *
+ * // Combining several predicates using `_.overEvery` or `_.overSome`.
+ * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
+ * // => objects for ['fred', 'barney']
+ */
+ function filter(collection, predicate) {
+ var func = isArray(collection) ? arrayFilter : baseFilter;
+ return func(collection, getIteratee(predicate, 3));
+ }
+
+ /**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false },
+ * { 'user': 'pebbles', 'age': 1, 'active': true }
+ * ];
+ *
+ * _.find(users, function(o) { return o.age < 40; });
+ * // => object for 'barney'
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.find(users, { 'age': 1, 'active': true });
+ * // => object for 'pebbles'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.find(users, ['active', false]);
+ * // => object for 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.find(users, 'active');
+ * // => object for 'barney'
+ */
+ var find = createFind(findIndex);
+
+ /**
+ * This method is like `_.find` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=collection.length-1] The index to search from.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * _.findLast([1, 2, 3, 4], function(n) {
+ * return n % 2 == 1;
+ * });
+ * // => 3
+ */
+ var findLast = createFind(findLastIndex);
+
+ /**
+ * Creates a flattened array of values by running each element in `collection`
+ * thru `iteratee` and flattening the mapped results. The iteratee is invoked
+ * with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _.flatMap([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */
+ function flatMap(collection, iteratee) {
+ return baseFlatten(map(collection, iteratee), 1);
+ }
+
+ /**
+ * This method is like `_.flatMap` except that it recursively flattens the
+ * mapped results.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [[[n, n]]];
+ * }
+ *
+ * _.flatMapDeep([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */
+ function flatMapDeep(collection, iteratee) {
+ return baseFlatten(map(collection, iteratee), INFINITY);
+ }
+
+ /**
+ * This method is like `_.flatMap` except that it recursively flattens the
+ * mapped results up to `depth` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.7.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {number} [depth=1] The maximum recursion depth.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [[[n, n]]];
+ * }
+ *
+ * _.flatMapDepth([1, 2], duplicate, 2);
+ * // => [[1, 1], [2, 2]]
+ */
+ function flatMapDepth(collection, iteratee, depth) {
+ depth = depth === undefined ? 1 : toInteger(depth);
+ return baseFlatten(map(collection, iteratee), depth);
+ }
+
+ /**
+ * Iterates over elements of `collection` and invokes `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length"
+ * property are iterated like arrays. To avoid this behavior use `_.forIn`
+ * or `_.forOwn` for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @see _.forEachRight
+ * @example
+ *
+ * _.forEach([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => Logs `1` then `2`.
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ */
+ function forEach(collection, iteratee) {
+ var func = isArray(collection) ? arrayEach : baseEach;
+ return func(collection, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * This method is like `_.forEach` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @alias eachRight
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @see _.forEach
+ * @example
+ *
+ * _.forEachRight([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => Logs `2` then `1`.
+ */
+ function forEachRight(collection, iteratee) {
+ var func = isArray(collection) ? arrayEachRight : baseEachRight;
+ return func(collection, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The order of grouped values
+ * is determined by the order they occur in `collection`. The corresponding
+ * value of each key is an array of elements responsible for generating the
+ * key. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': [4.2], '6': [6.1, 6.3] }
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.groupBy(['one', 'two', 'three'], 'length');
+ * // => { '3': ['one', 'two'], '5': ['three'] }
+ */
+ var groupBy = createAggregator(function(result, value, key) {
+ if (hasOwnProperty.call(result, key)) {
+ result[key].push(value);
+ } else {
+ baseAssignValue(result, key, [value]);
+ }
+ });
+
+ /**
+ * Checks if `value` is in `collection`. If `collection` is a string, it's
+ * checked for a substring of `value`, otherwise
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * is used for equality comparisons. If `fromIndex` is negative, it's used as
+ * the offset from the end of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
+ * @example
+ *
+ * _.includes([1, 2, 3], 1);
+ * // => true
+ *
+ * _.includes([1, 2, 3], 1, 2);
+ * // => false
+ *
+ * _.includes({ 'a': 1, 'b': 2 }, 1);
+ * // => true
+ *
+ * _.includes('abcd', 'bc');
+ * // => true
+ */
+ function includes(collection, value, fromIndex, guard) {
+ collection = isArrayLike(collection) ? collection : values(collection);
+ fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
+
+ var length = collection.length;
+ if (fromIndex < 0) {
+ fromIndex = nativeMax(length + fromIndex, 0);
+ }
+ return isString(collection)
+ ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
+ : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
+ }
+
+ /**
+ * Invokes the method at `path` of each element in `collection`, returning
+ * an array of the results of each invoked method. Any additional arguments
+ * are provided to each invoked method. If `path` is a function, it's invoked
+ * for, and `this` bound to, each element in `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array|Function|string} path The path of the method to invoke or
+ * the function invoked per iteration.
+ * @param {...*} [args] The arguments to invoke each method with.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
+ * // => [[1, 5, 7], [1, 2, 3]]
+ *
+ * _.invokeMap([123, 456], String.prototype.split, '');
+ * // => [['1', '2', '3'], ['4', '5', '6']]
+ */
+ var invokeMap = baseRest(function(collection, path, args) {
+ var index = -1,
+ isFunc = typeof path == 'function',
+ result = isArrayLike(collection) ? Array(collection.length) : [];
+
+ baseEach(collection, function(value) {
+ result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
+ });
+ return result;
+ });
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The corresponding value of
+ * each key is the last element responsible for generating the key. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * var array = [
+ * { 'dir': 'left', 'code': 97 },
+ * { 'dir': 'right', 'code': 100 }
+ * ];
+ *
+ * _.keyBy(array, function(o) {
+ * return String.fromCharCode(o.code);
+ * });
+ * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(array, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+ */
+ var keyBy = createAggregator(function(result, value, key) {
+ baseAssignValue(result, key, value);
+ });
+
+ /**
+ * Creates an array of values by running each element in `collection` thru
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
+ * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
+ * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
+ * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * _.map([4, 8], square);
+ * // => [16, 64]
+ *
+ * _.map({ 'a': 4, 'b': 8 }, square);
+ * // => [16, 64] (iteration order is not guaranteed)
+ *
+ * var users = [
+ * { 'user': 'barney' },
+ * { 'user': 'fred' }
+ * ];
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */
+ function map(collection, iteratee) {
+ var func = isArray(collection) ? arrayMap : baseMap;
+ return func(collection, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * This method is like `_.sortBy` except that it allows specifying the sort
+ * orders of the iteratees to sort by. If `orders` is unspecified, all values
+ * are sorted in ascending order. Otherwise, specify an order of "desc" for
+ * descending or "asc" for ascending sort order of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
+ * The iteratees to sort by.
+ * @param {string[]} [orders] The sort orders of `iteratees`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 34 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'barney', 'age': 36 }
+ * ];
+ *
+ * // Sort by `user` in ascending order and by `age` in descending order.
+ * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ */
+ function orderBy(collection, iteratees, orders, guard) {
+ if (collection == null) {
+ return [];
+ }
+ if (!isArray(iteratees)) {
+ iteratees = iteratees == null ? [] : [iteratees];
+ }
+ orders = guard ? undefined : orders;
+ if (!isArray(orders)) {
+ orders = orders == null ? [] : [orders];
+ }
+ return baseOrderBy(collection, iteratees, orders);
+ }
+
+ /**
+ * Creates an array of elements split into two groups, the first of which
+ * contains elements `predicate` returns truthy for, the second of which
+ * contains elements `predicate` returns falsey for. The predicate is
+ * invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of grouped elements.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true },
+ * { 'user': 'pebbles', 'age': 1, 'active': false }
+ * ];
+ *
+ * _.partition(users, function(o) { return o.active; });
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.partition(users, { 'age': 1, 'active': false });
+ * // => objects for [['pebbles'], ['barney', 'fred']]
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.partition(users, ['active', false]);
+ * // => objects for [['barney', 'pebbles'], ['fred']]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.partition(users, 'active');
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ */
+ var partition = createAggregator(function(result, value, key) {
+ result[key ? 0 : 1].push(value);
+ }, function() { return [[], []]; });
+
+ /**
+ * Reduces `collection` to a value which is the accumulated result of running
+ * each element in `collection` thru `iteratee`, where each successive
+ * invocation is supplied the return value of the previous. If `accumulator`
+ * is not given, the first element of `collection` is used as the initial
+ * value. The iteratee is invoked with four arguments:
+ * (accumulator, value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.reduce`, `_.reduceRight`, and `_.transform`.
+ *
+ * The guarded methods are:
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+ * and `sortBy`
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @see _.reduceRight
+ * @example
+ *
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
+ * }, 0);
+ * // => 3
+ *
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * return result;
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
+ */
+ function reduce(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduce : baseReduce,
+ initAccum = arguments.length < 3;
+
+ return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
+ }
+
+ /**
+ * This method is like `_.reduce` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @see _.reduce
+ * @example
+ *
+ * var array = [[0, 1], [2, 3], [4, 5]];
+ *
+ * _.reduceRight(array, function(flattened, other) {
+ * return flattened.concat(other);
+ * }, []);
+ * // => [4, 5, 2, 3, 0, 1]
+ */
+ function reduceRight(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduceRight : baseReduce,
+ initAccum = arguments.length < 3;
+
+ return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
+ }
+
+ /**
+ * The opposite of `_.filter`; this method returns the elements of `collection`
+ * that `predicate` does **not** return truthy for.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @see _.filter
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true }
+ * ];
+ *
+ * _.reject(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.reject(users, { 'age': 40, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.reject(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.reject(users, 'active');
+ * // => objects for ['barney']
+ */
+ function reject(collection, predicate) {
+ var func = isArray(collection) ? arrayFilter : baseFilter;
+ return func(collection, negate(getIteratee(predicate, 3)));
+ }
+
+ /**
+ * Gets a random element from `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
+ * @example
+ *
+ * _.sample([1, 2, 3, 4]);
+ * // => 2
+ */
+ function sample(collection) {
+ var func = isArray(collection) ? arraySample : baseSample;
+ return func(collection);
+ }
+
+ /**
+ * Gets `n` random elements at unique keys from `collection` up to the
+ * size of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} [n=1] The number of elements to sample.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Array} Returns the random elements.
+ * @example
+ *
+ * _.sampleSize([1, 2, 3], 2);
+ * // => [3, 1]
+ *
+ * _.sampleSize([1, 2, 3], 4);
+ * // => [2, 3, 1]
+ */
+ function sampleSize(collection, n, guard) {
+ if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
+ n = 1;
+ } else {
+ n = toInteger(n);
+ }
+ var func = isArray(collection) ? arraySampleSize : baseSampleSize;
+ return func(collection, n);
+ }
+
+ /**
+ * Creates an array of shuffled values, using a version of the
+ * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to shuffle.
+ * @returns {Array} Returns the new shuffled array.
+ * @example
+ *
+ * _.shuffle([1, 2, 3, 4]);
+ * // => [4, 1, 3, 2]
+ */
+ function shuffle(collection) {
+ var func = isArray(collection) ? arrayShuffle : baseShuffle;
+ return func(collection);
+ }
+
+ /**
+ * Gets the size of `collection` by returning its length for array-like
+ * values or the number of own enumerable string keyed properties for objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
+ * @example
+ *
+ * _.size([1, 2, 3]);
+ * // => 3
+ *
+ * _.size({ 'a': 1, 'b': 2 });
+ * // => 2
+ *
+ * _.size('pebbles');
+ * // => 7
+ */
+ function size(collection) {
+ if (collection == null) {
+ return 0;
+ }
+ if (isArrayLike(collection)) {
+ return isString(collection) ? stringSize(collection) : collection.length;
+ }
+ var tag = getTag(collection);
+ if (tag == mapTag || tag == setTag) {
+ return collection.size;
+ }
+ return baseKeys(collection).length;
+ }
+
+ /**
+ * Checks if `predicate` returns truthy for **any** element of `collection`.
+ * Iteration is stopped once `predicate` returns truthy. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ * else `false`.
+ * @example
+ *
+ * _.some([null, 0, 'yes', false], Boolean);
+ * // => true
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.some(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.some(users, ['active', false]);
+ * // => true
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.some(users, 'active');
+ * // => true
+ */
+ function some(collection, predicate, guard) {
+ var func = isArray(collection) ? arraySome : baseSome;
+ if (guard && isIterateeCall(collection, predicate, guard)) {
+ predicate = undefined;
+ }
+ return func(collection, getIteratee(predicate, 3));
+ }
+
+ /**
+ * Creates an array of elements, sorted in ascending order by the results of
+ * running each element in a collection thru each iteratee. This method
+ * performs a stable sort, that is, it preserves the original sort order of
+ * equal elements. The iteratees are invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {...(Function|Function[])} [iteratees=[_.identity]]
+ * The iteratees to sort by.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 30 },
+ * { 'user': 'barney', 'age': 34 }
+ * ];
+ *
+ * _.sortBy(users, [function(o) { return o.user; }]);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
+ *
+ * _.sortBy(users, ['user', 'age']);
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
+ */
+ var sortBy = baseRest(function(collection, iteratees) {
+ if (collection == null) {
+ return [];
+ }
+ var length = iteratees.length;
+ if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
+ iteratees = [];
+ } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
+ iteratees = [iteratees[0]];
+ }
+ return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
+ });
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Gets the timestamp of the number of milliseconds that have elapsed since
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Date
+ * @returns {number} Returns the timestamp.
+ * @example
+ *
+ * _.defer(function(stamp) {
+ * console.log(_.now() - stamp);
+ * }, _.now());
+ * // => Logs the number of milliseconds it took for the deferred invocation.
+ */
+ var now = ctxNow || function() {
+ return root.Date.now();
+ };
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * The opposite of `_.before`; this method creates a function that invokes
+ * `func` once it's called `n` or more times.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {number} n The number of calls before `func` is invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var saves = ['profile', 'settings'];
+ *
+ * var done = _.after(saves.length, function() {
+ * console.log('done saving!');
+ * });
+ *
+ * _.forEach(saves, function(type) {
+ * asyncSave({ 'type': type, 'complete': done });
+ * });
+ * // => Logs 'done saving!' after the two async saves have completed.
+ */
+ function after(n, func) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ n = toInteger(n);
+ return function() {
+ if (--n < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ }
+
+ /**
+ * Creates a function that invokes `func`, with up to `n` arguments,
+ * ignoring any additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @param {number} [n=func.length] The arity cap.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new capped function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.ary(parseInt, 1));
+ * // => [6, 8, 10]
+ */
+ function ary(func, n, guard) {
+ n = guard ? undefined : n;
+ n = (func && n == null) ? func.length : n;
+ return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
+ }
+
+ /**
+ * Creates a function that invokes `func`, with the `this` binding and arguments
+ * of the created function, while it's called less than `n` times. Subsequent
+ * calls to the created function return the result of the last `func` invocation.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {number} n The number of calls at which `func` is no longer invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * jQuery(element).on('click', _.before(5, addContactToList));
+ * // => Allows adding up to 4 contacts to the list.
+ */
+ function before(n, func) {
+ var result;
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ n = toInteger(n);
+ return function() {
+ if (--n > 0) {
+ result = func.apply(this, arguments);
+ }
+ if (n <= 1) {
+ func = undefined;
+ }
+ return result;
+ };
+ }
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of `thisArg`
+ * and `partials` prepended to the arguments it receives.
+ *
+ * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
+ * property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * function greet(greeting, punctuation) {
+ * return greeting + ' ' + this.user + punctuation;
+ * }
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * var bound = _.bind(greet, object, 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * // Bound with placeholders.
+ * var bound = _.bind(greet, object, _, '!');
+ * bound('hi');
+ * // => 'hi fred!'
+ */
+ var bind = baseRest(function(func, thisArg, partials) {
+ var bitmask = WRAP_BIND_FLAG;
+ if (partials.length) {
+ var holders = replaceHolders(partials, getHolder(bind));
+ bitmask |= WRAP_PARTIAL_FLAG;
+ }
+ return createWrap(func, bitmask, thisArg, partials, holders);
+ });
+
+ /**
+ * Creates a function that invokes the method at `object[key]` with `partials`
+ * prepended to the arguments it receives.
+ *
+ * This method differs from `_.bind` by allowing bound functions to reference
+ * methods that may be redefined or don't yet exist. See
+ * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
+ * for more details.
+ *
+ * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.10.0
+ * @category Function
+ * @param {Object} object The object to invoke the method on.
+ * @param {string} key The key of the method.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * var object = {
+ * 'user': 'fred',
+ * 'greet': function(greeting, punctuation) {
+ * return greeting + ' ' + this.user + punctuation;
+ * }
+ * };
+ *
+ * var bound = _.bindKey(object, 'greet', 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * object.greet = function(greeting, punctuation) {
+ * return greeting + 'ya ' + this.user + punctuation;
+ * };
+ *
+ * bound('!');
+ * // => 'hiya fred!'
+ *
+ * // Bound with placeholders.
+ * var bound = _.bindKey(object, 'greet', _, '!');
+ * bound('hi');
+ * // => 'hiya fred!'
+ */
+ var bindKey = baseRest(function(object, key, partials) {
+ var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
+ if (partials.length) {
+ var holders = replaceHolders(partials, getHolder(bindKey));
+ bitmask |= WRAP_PARTIAL_FLAG;
+ }
+ return createWrap(key, bitmask, object, partials, holders);
+ });
+
+ /**
+ * Creates a function that accepts arguments of `func` and either invokes
+ * `func` returning its result, if at least `arity` number of arguments have
+ * been provided, or returns a function that accepts the remaining `func`
+ * arguments, and so on. The arity of `func` may be specified if `func.length`
+ * is not sufficient.
+ *
+ * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for provided arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of curried functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Function
+ * @param {Function} func The function to curry.
+ * @param {number} [arity=func.length] The arity of `func`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new curried function.
+ * @example
+ *
+ * var abc = function(a, b, c) {
+ * return [a, b, c];
+ * };
+ *
+ * var curried = _.curry(abc);
+ *
+ * curried(1)(2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2, 3);
+ * // => [1, 2, 3]
+ *
+ * // Curried with placeholders.
+ * curried(1)(_, 3)(2);
+ * // => [1, 2, 3]
+ */
+ function curry(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curry.placeholder;
+ return result;
+ }
+
+ /**
+ * This method is like `_.curry` except that arguments are applied to `func`
+ * in the manner of `_.partialRight` instead of `_.partial`.
+ *
+ * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for provided arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of curried functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to curry.
+ * @param {number} [arity=func.length] The arity of `func`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the new curried function.
+ * @example
+ *
+ * var abc = function(a, b, c) {
+ * return [a, b, c];
+ * };
+ *
+ * var curried = _.curryRight(abc);
+ *
+ * curried(3)(2)(1);
+ * // => [1, 2, 3]
+ *
+ * curried(2, 3)(1);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2, 3);
+ * // => [1, 2, 3]
+ *
+ * // Curried with placeholders.
+ * curried(3)(1, _)(2);
+ * // => [1, 2, 3]
+ */
+ function curryRight(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curryRight.placeholder;
+ return result;
+ }
+
+ /**
+ * Creates a debounced function that delays invoking `func` until after `wait`
+ * milliseconds have elapsed since the last time the debounced function was
+ * invoked. The debounced function comes with a `cancel` method to cancel
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
+ * Provide `options` to indicate whether `func` should be invoked on the
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+ * with the last arguments provided to the debounced function. Subsequent
+ * calls to the debounced function return the result of the last `func`
+ * invocation.
+ *
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the debounced function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * for details over the differences between `_.debounce` and `_.throttle`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to debounce.
+ * @param {number} [wait=0] The number of milliseconds to delay.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=false]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {number} [options.maxWait]
+ * The maximum time `func` is allowed to be delayed before it's invoked.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @returns {Function} Returns the new debounced function.
+ * @example
+ *
+ * // Avoid costly calculations while the window size is in flux.
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+ *
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
+ * 'leading': true,
+ * 'trailing': false
+ * }));
+ *
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
+ * var source = new EventSource('/stream');
+ * jQuery(source).on('message', debounced);
+ *
+ * // Cancel the trailing debounced invocation.
+ * jQuery(window).on('popstate', debounced.cancel);
+ */
+ function debounce(func, wait, options) {
+ var lastArgs,
+ lastThis,
+ maxWait,
+ result,
+ timerId,
+ lastCallTime,
+ lastInvokeTime = 0,
+ leading = false,
+ maxing = false,
+ trailing = true;
+
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ wait = toNumber(wait) || 0;
+ if (isObject(options)) {
+ leading = !!options.leading;
+ maxing = 'maxWait' in options;
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
+ }
+
+ function invokeFunc(time) {
+ var args = lastArgs,
+ thisArg = lastThis;
+
+ lastArgs = lastThis = undefined;
+ lastInvokeTime = time;
+ result = func.apply(thisArg, args);
+ return result;
+ }
+
+ function leadingEdge(time) {
+ // Reset any `maxWait` timer.
+ lastInvokeTime = time;
+ // Start the timer for the trailing edge.
+ timerId = setTimeout(timerExpired, wait);
+ // Invoke the leading edge.
+ return leading ? invokeFunc(time) : result;
+ }
+
+ function remainingWait(time) {
+ var timeSinceLastCall = time - lastCallTime,
+ timeSinceLastInvoke = time - lastInvokeTime,
+ timeWaiting = wait - timeSinceLastCall;
+
+ return maxing
+ ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
+ : timeWaiting;
+ }
+
+ function shouldInvoke(time) {
+ var timeSinceLastCall = time - lastCallTime,
+ timeSinceLastInvoke = time - lastInvokeTime;
+
+ // Either this is the first call, activity has stopped and we're at the
+ // trailing edge, the system time has gone backwards and we're treating
+ // it as the trailing edge, or we've hit the `maxWait` limit.
+ return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
+ (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
+ }
+
+ function timerExpired() {
+ var time = now();
+ if (shouldInvoke(time)) {
+ return trailingEdge(time);
+ }
+ // Restart the timer.
+ timerId = setTimeout(timerExpired, remainingWait(time));
+ }
+
+ function trailingEdge(time) {
+ timerId = undefined;
+
+ // Only invoke if we have `lastArgs` which means `func` has been
+ // debounced at least once.
+ if (trailing && lastArgs) {
+ return invokeFunc(time);
+ }
+ lastArgs = lastThis = undefined;
+ return result;
+ }
+
+ function cancel() {
+ if (timerId !== undefined) {
+ clearTimeout(timerId);
+ }
+ lastInvokeTime = 0;
+ lastArgs = lastCallTime = lastThis = timerId = undefined;
+ }
+
+ function flush() {
+ return timerId === undefined ? result : trailingEdge(now());
+ }
+
+ function debounced() {
+ var time = now(),
+ isInvoking = shouldInvoke(time);
+
+ lastArgs = arguments;
+ lastThis = this;
+ lastCallTime = time;
+
+ if (isInvoking) {
+ if (timerId === undefined) {
+ return leadingEdge(lastCallTime);
+ }
+ if (maxing) {
+ // Handle invocations in a tight loop.
+ clearTimeout(timerId);
+ timerId = setTimeout(timerExpired, wait);
+ return invokeFunc(lastCallTime);
+ }
+ }
+ if (timerId === undefined) {
+ timerId = setTimeout(timerExpired, wait);
+ }
+ return result;
+ }
+ debounced.cancel = cancel;
+ debounced.flush = flush;
+ return debounced;
+ }
+
+ /**
+ * Defers invoking the `func` until the current call stack has cleared. Any
+ * additional arguments are provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to defer.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.defer(function(text) {
+ * console.log(text);
+ * }, 'deferred');
+ * // => Logs 'deferred' after one millisecond.
+ */
+ var defer = baseRest(function(func, args) {
+ return baseDelay(func, 1, args);
+ });
+
+ /**
+ * Invokes `func` after `wait` milliseconds. Any additional arguments are
+ * provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.delay(function(text) {
+ * console.log(text);
+ * }, 1000, 'later');
+ * // => Logs 'later' after one second.
+ */
+ var delay = baseRest(function(func, wait, args) {
+ return baseDelay(func, toNumber(wait) || 0, args);
+ });
+
+ /**
+ * Creates a function that invokes `func` with arguments reversed.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to flip arguments for.
+ * @returns {Function} Returns the new flipped function.
+ * @example
+ *
+ * var flipped = _.flip(function() {
+ * return _.toArray(arguments);
+ * });
+ *
+ * flipped('a', 'b', 'c', 'd');
+ * // => ['d', 'c', 'b', 'a']
+ */
+ function flip(func) {
+ return createWrap(func, WRAP_FLIP_FLAG);
+ }
+
+ /**
+ * Creates a function that memoizes the result of `func`. If `resolver` is
+ * provided, it determines the cache key for storing the result based on the
+ * arguments provided to the memoized function. By default, the first argument
+ * provided to the memoized function is used as the map cache key. The `func`
+ * is invoked with the `this` binding of the memoized function.
+ *
+ * **Note:** The cache is exposed as the `cache` property on the memoized
+ * function. Its creation may be customized by replacing the `_.memoize.Cache`
+ * constructor with one whose instances implement the
+ * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
+ * method interface of `clear`, `delete`, `get`, `has`, and `set`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to have its output memoized.
+ * @param {Function} [resolver] The function to resolve the cache key.
+ * @returns {Function} Returns the new memoized function.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ * var other = { 'c': 3, 'd': 4 };
+ *
+ * var values = _.memoize(_.values);
+ * values(object);
+ * // => [1, 2]
+ *
+ * values(other);
+ * // => [3, 4]
+ *
+ * object.a = 2;
+ * values(object);
+ * // => [1, 2]
+ *
+ * // Modify the result cache.
+ * values.cache.set(object, ['a', 'b']);
+ * values(object);
+ * // => ['a', 'b']
+ *
+ * // Replace `_.memoize.Cache`.
+ * _.memoize.Cache = WeakMap;
+ */
+ function memoize(func, resolver) {
+ if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ var memoized = function() {
+ var args = arguments,
+ key = resolver ? resolver.apply(this, args) : args[0],
+ cache = memoized.cache;
+
+ if (cache.has(key)) {
+ return cache.get(key);
+ }
+ var result = func.apply(this, args);
+ memoized.cache = cache.set(key, result) || cache;
+ return result;
+ };
+ memoized.cache = new (memoize.Cache || MapCache);
+ return memoized;
+ }
+
+ // Expose `MapCache`.
+ memoize.Cache = MapCache;
+
+ /**
+ * Creates a function that negates the result of the predicate `func`. The
+ * `func` predicate is invoked with the `this` binding and arguments of the
+ * created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} predicate The predicate to negate.
+ * @returns {Function} Returns the new negated function.
+ * @example
+ *
+ * function isEven(n) {
+ * return n % 2 == 0;
+ * }
+ *
+ * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
+ * // => [1, 3, 5]
+ */
+ function negate(predicate) {
+ if (typeof predicate != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return function() {
+ var args = arguments;
+ switch (args.length) {
+ case 0: return !predicate.call(this);
+ case 1: return !predicate.call(this, args[0]);
+ case 2: return !predicate.call(this, args[0], args[1]);
+ case 3: return !predicate.call(this, args[0], args[1], args[2]);
+ }
+ return !predicate.apply(this, args);
+ };
+ }
+
+ /**
+ * Creates a function that is restricted to invoking `func` once. Repeat calls
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var initialize = _.once(createApplication);
+ * initialize();
+ * initialize();
+ * // => `createApplication` is invoked once
+ */
+ function once(func) {
+ return before(2, func);
+ }
+
+ /**
+ * Creates a function that invokes `func` with its arguments transformed.
+ *
+ * @static
+ * @since 4.0.0
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms=[_.identity]]
+ * The argument transforms.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var func = _.overArgs(function(x, y) {
+ * return [x, y];
+ * }, [square, doubled]);
+ *
+ * func(9, 3);
+ * // => [81, 6]
+ *
+ * func(10, 5);
+ * // => [100, 10]
+ */
+ var overArgs = castRest(function(func, transforms) {
+ transforms = (transforms.length == 1 && isArray(transforms[0]))
+ ? arrayMap(transforms[0], baseUnary(getIteratee()))
+ : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
+
+ var funcsLength = transforms.length;
+ return baseRest(function(args) {
+ var index = -1,
+ length = nativeMin(args.length, funcsLength);
+
+ while (++index < length) {
+ args[index] = transforms[index].call(this, args[index]);
+ }
+ return apply(func, this, args);
+ });
+ });
+
+ /**
+ * Creates a function that invokes `func` with `partials` prepended to the
+ * arguments it receives. This method is like `_.bind` except it does **not**
+ * alter the `this` binding.
+ *
+ * The `_.partial.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of partially
+ * applied functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.2.0
+ * @category Function
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new partially applied function.
+ * @example
+ *
+ * function greet(greeting, name) {
+ * return greeting + ' ' + name;
+ * }
+ *
+ * var sayHelloTo = _.partial(greet, 'hello');
+ * sayHelloTo('fred');
+ * // => 'hello fred'
+ *
+ * // Partially applied with placeholders.
+ * var greetFred = _.partial(greet, _, 'fred');
+ * greetFred('hi');
+ * // => 'hi fred'
+ */
+ var partial = baseRest(function(func, partials) {
+ var holders = replaceHolders(partials, getHolder(partial));
+ return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
+ });
+
+ /**
+ * This method is like `_.partial` except that partially applied arguments
+ * are appended to the arguments it receives.
+ *
+ * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
+ * builds, may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of partially
+ * applied functions.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Function
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new partially applied function.
+ * @example
+ *
+ * function greet(greeting, name) {
+ * return greeting + ' ' + name;
+ * }
+ *
+ * var greetFred = _.partialRight(greet, 'fred');
+ * greetFred('hi');
+ * // => 'hi fred'
+ *
+ * // Partially applied with placeholders.
+ * var sayHelloTo = _.partialRight(greet, 'hello', _);
+ * sayHelloTo('fred');
+ * // => 'hello fred'
+ */
+ var partialRight = baseRest(function(func, partials) {
+ var holders = replaceHolders(partials, getHolder(partialRight));
+ return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
+ });
+
+ /**
+ * Creates a function that invokes `func` with arguments arranged according
+ * to the specified `indexes` where the argument value at the first index is
+ * provided as the first argument, the argument value at the second index is
+ * provided as the second argument, and so on.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Function
+ * @param {Function} func The function to rearrange arguments for.
+ * @param {...(number|number[])} indexes The arranged argument indexes.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var rearged = _.rearg(function(a, b, c) {
+ * return [a, b, c];
+ * }, [2, 0, 1]);
+ *
+ * rearged('b', 'c', 'a')
+ * // => ['a', 'b', 'c']
+ */
+ var rearg = flatRest(function(func, indexes) {
+ return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
+ });
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as
+ * an array.
+ *
+ * **Note:** This method is based on the
+ * [rest parameter](https://mdn.io/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.rest(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+ function rest(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ start = start === undefined ? start : toInteger(start);
+ return baseRest(func, start);
+ }
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * create function and an array of arguments much like
+ * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
+ *
+ * **Note:** This method is based on the
+ * [spread operator](https://mdn.io/spread_operator).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.2.0
+ * @category Function
+ * @param {Function} func The function to spread arguments over.
+ * @param {number} [start=0] The start position of the spread.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.spread(function(who, what) {
+ * return who + ' says ' + what;
+ * });
+ *
+ * say(['fred', 'hello']);
+ * // => 'fred says hello'
+ *
+ * var numbers = Promise.all([
+ * Promise.resolve(40),
+ * Promise.resolve(36)
+ * ]);
+ *
+ * numbers.then(_.spread(function(x, y) {
+ * return x + y;
+ * }));
+ * // => a Promise of 76
+ */
+ function spread(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ start = start == null ? 0 : nativeMax(toInteger(start), 0);
+ return baseRest(function(args) {
+ var array = args[start],
+ otherArgs = castSlice(args, 0, start);
+
+ if (array) {
+ arrayPush(otherArgs, array);
+ }
+ return apply(func, this, otherArgs);
+ });
+ }
+
+ /**
+ * Creates a throttled function that only invokes `func` at most once per
+ * every `wait` milliseconds. The throttled function comes with a `cancel`
+ * method to cancel delayed `func` invocations and a `flush` method to
+ * immediately invoke them. Provide `options` to indicate whether `func`
+ * should be invoked on the leading and/or trailing edge of the `wait`
+ * timeout. The `func` is invoked with the last arguments provided to the
+ * throttled function. Subsequent calls to the throttled function return the
+ * result of the last `func` invocation.
+ *
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the throttled function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * for details over the differences between `_.throttle` and `_.debounce`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to throttle.
+ * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=true]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @returns {Function} Returns the new throttled function.
+ * @example
+ *
+ * // Avoid excessively updating the position while scrolling.
+ * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
+ *
+ * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+ * jQuery(element).on('click', throttled);
+ *
+ * // Cancel the trailing throttled invocation.
+ * jQuery(window).on('popstate', throttled.cancel);
+ */
+ function throttle(func, wait, options) {
+ var leading = true,
+ trailing = true;
+
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ if (isObject(options)) {
+ leading = 'leading' in options ? !!options.leading : leading;
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
+ }
+ return debounce(func, wait, {
+ 'leading': leading,
+ 'maxWait': wait,
+ 'trailing': trailing
+ });
+ }
+
+ /**
+ * Creates a function that accepts up to one argument, ignoring any
+ * additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.unary(parseInt));
+ * // => [6, 8, 10]
+ */
+ function unary(func) {
+ return ary(func, 1);
+ }
+
+ /**
+ * Creates a function that provides `value` to `wrapper` as its first
+ * argument. Any additional arguments provided to the function are appended
+ * to those provided to the `wrapper`. The wrapper is invoked with the `this`
+ * binding of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {*} value The value to wrap.
+ * @param {Function} [wrapper=identity] The wrapper function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var p = _.wrap(_.escape, function(func, text) {
+ * return '' + func(text) + '
';
+ * });
+ *
+ * p('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles
'
+ */
+ function wrap(value, wrapper) {
+ return partial(castFunction(wrapper), value);
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Casts `value` as an array if it's not one.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.4.0
+ * @category Lang
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the cast array.
+ * @example
+ *
+ * _.castArray(1);
+ * // => [1]
+ *
+ * _.castArray({ 'a': 1 });
+ * // => [{ 'a': 1 }]
+ *
+ * _.castArray('abc');
+ * // => ['abc']
+ *
+ * _.castArray(null);
+ * // => [null]
+ *
+ * _.castArray(undefined);
+ * // => [undefined]
+ *
+ * _.castArray();
+ * // => []
+ *
+ * var array = [1, 2, 3];
+ * console.log(_.castArray(array) === array);
+ * // => true
+ */
+ function castArray() {
+ if (!arguments.length) {
+ return [];
+ }
+ var value = arguments[0];
+ return isArray(value) ? value : [value];
+ }
+
+ /**
+ * Creates a shallow clone of `value`.
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+ * and supports cloning arrays, array buffers, booleans, date objects, maps,
+ * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+ * arrays. The own enumerable properties of `arguments` objects are cloned
+ * as plain objects. An empty object is returned for uncloneable values such
+ * as error objects, functions, DOM nodes, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @returns {*} Returns the cloned value.
+ * @see _.cloneDeep
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var shallow = _.clone(objects);
+ * console.log(shallow[0] === objects[0]);
+ * // => true
+ */
+ function clone(value) {
+ return baseClone(value, CLONE_SYMBOLS_FLAG);
+ }
+
+ /**
+ * This method is like `_.clone` except that it accepts `customizer` which
+ * is invoked to produce the cloned value. If `customizer` returns `undefined`,
+ * cloning is handled by the method instead. The `customizer` is invoked with
+ * up to four arguments; (value [, index|key, object, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the cloned value.
+ * @see _.cloneDeepWith
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(false);
+ * }
+ * }
+ *
+ * var el = _.cloneWith(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 0
+ */
+ function cloneWith(value, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
+ }
+
+ /**
+ * This method is like `_.clone` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @returns {*} Returns the deep cloned value.
+ * @see _.clone
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var deep = _.cloneDeep(objects);
+ * console.log(deep[0] === objects[0]);
+ * // => false
+ */
+ function cloneDeep(value) {
+ return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
+ }
+
+ /**
+ * This method is like `_.cloneWith` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the deep cloned value.
+ * @see _.cloneWith
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(true);
+ * }
+ * }
+ *
+ * var el = _.cloneDeepWith(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 20
+ */
+ function cloneDeepWith(value, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
+ }
+
+ /**
+ * Checks if `object` conforms to `source` by invoking the predicate
+ * properties of `source` with the corresponding property values of `object`.
+ *
+ * **Note:** This method is equivalent to `_.conforms` when `source` is
+ * partially applied.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.14.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ *
+ * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
+ * // => true
+ *
+ * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
+ * // => false
+ */
+ function conformsTo(object, source) {
+ return source == null || baseConformsTo(object, source, keys(source));
+ }
+
+ /**
+ * Performs a
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+ function eq(value, other) {
+ return value === other || (value !== value && other !== other);
+ }
+
+ /**
+ * Checks if `value` is greater than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than `other`,
+ * else `false`.
+ * @see _.lt
+ * @example
+ *
+ * _.gt(3, 1);
+ * // => true
+ *
+ * _.gt(3, 3);
+ * // => false
+ *
+ * _.gt(1, 3);
+ * // => false
+ */
+ var gt = createRelationalOperation(baseGt);
+
+ /**
+ * Checks if `value` is greater than or equal to `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than or equal to
+ * `other`, else `false`.
+ * @see _.lte
+ * @example
+ *
+ * _.gte(3, 1);
+ * // => true
+ *
+ * _.gte(3, 3);
+ * // => true
+ *
+ * _.gte(1, 3);
+ * // => false
+ */
+ var gte = createRelationalOperation(function(value, other) {
+ return value >= other;
+ });
+
+ /**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ * else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+ var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
+ return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
+ !propertyIsEnumerable.call(value, 'callee');
+ };
+
+ /**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+ var isArray = Array.isArray;
+
+ /**
+ * Checks if `value` is classified as an `ArrayBuffer` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+ * @example
+ *
+ * _.isArrayBuffer(new ArrayBuffer(2));
+ * // => true
+ *
+ * _.isArrayBuffer(new Array(2));
+ * // => false
+ */
+ var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
+
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null && isLength(value.length) && !isFunction(value);
+ }
+
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
+ * else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
+
+ /**
+ * Checks if `value` is classified as a boolean primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
+ * @example
+ *
+ * _.isBoolean(false);
+ * // => true
+ *
+ * _.isBoolean(null);
+ * // => false
+ */
+ function isBoolean(value) {
+ return value === true || value === false ||
+ (isObjectLike(value) && baseGetTag(value) == boolTag);
+ }
+
+ /**
+ * Checks if `value` is a buffer.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */
+ var isBuffer = nativeIsBuffer || stubFalse;
+
+ /**
+ * Checks if `value` is classified as a `Date` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+ * @example
+ *
+ * _.isDate(new Date);
+ * // => true
+ *
+ * _.isDate('Mon April 23 2012');
+ * // => false
+ */
+ var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
+
+ /**
+ * Checks if `value` is likely a DOM element.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
+ * @example
+ *
+ * _.isElement(document.body);
+ * // => true
+ *
+ * _.isElement('');
+ * // => false
+ */
+ function isElement(value) {
+ return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
+ }
+
+ /**
+ * Checks if `value` is an empty object, collection, map, or set.
+ *
+ * Objects are considered empty if they have no own enumerable string keyed
+ * properties.
+ *
+ * Array-like values such as `arguments` objects, arrays, buffers, strings, or
+ * jQuery-like collections are considered empty if they have a `length` of `0`.
+ * Similarly, maps and sets are considered empty if they have a `size` of `0`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+ * @example
+ *
+ * _.isEmpty(null);
+ * // => true
+ *
+ * _.isEmpty(true);
+ * // => true
+ *
+ * _.isEmpty(1);
+ * // => true
+ *
+ * _.isEmpty([1, 2, 3]);
+ * // => false
+ *
+ * _.isEmpty({ 'a': 1 });
+ * // => false
+ */
+ function isEmpty(value) {
+ if (value == null) {
+ return true;
+ }
+ if (isArrayLike(value) &&
+ (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
+ isBuffer(value) || isTypedArray(value) || isArguments(value))) {
+ return !value.length;
+ }
+ var tag = getTag(value);
+ if (tag == mapTag || tag == setTag) {
+ return !value.size;
+ }
+ if (isPrototype(value)) {
+ return !baseKeys(value).length;
+ }
+ for (var key in value) {
+ if (hasOwnProperty.call(value, key)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Performs a deep comparison between two values to determine if they are
+ * equivalent.
+ *
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are compared by strict equality, i.e. `===`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.isEqual(object, other);
+ * // => true
+ *
+ * object === other;
+ * // => false
+ */
+ function isEqual(value, other) {
+ return baseIsEqual(value, other);
+ }
+
+ /**
+ * This method is like `_.isEqual` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * are handled by the method instead. The `customizer` is invoked with up to
+ * six arguments: (objValue, othValue [, index|key, object, other, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, othValue) {
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var array = ['hello', 'goodbye'];
+ * var other = ['hi', 'goodbye'];
+ *
+ * _.isEqualWith(array, other, customizer);
+ * // => true
+ */
+ function isEqualWith(value, other, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ var result = customizer ? customizer(value, other) : undefined;
+ return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
+ }
+
+ /**
+ * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
+ * `SyntaxError`, `TypeError`, or `URIError` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
+ * @example
+ *
+ * _.isError(new Error);
+ * // => true
+ *
+ * _.isError(Error);
+ * // => false
+ */
+ function isError(value) {
+ if (!isObjectLike(value)) {
+ return false;
+ }
+ var tag = baseGetTag(value);
+ return tag == errorTag || tag == domExcTag ||
+ (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
+ }
+
+ /**
+ * Checks if `value` is a finite primitive number.
+ *
+ * **Note:** This method is based on
+ * [`Number.isFinite`](https://mdn.io/Number/isFinite).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
+ * @example
+ *
+ * _.isFinite(3);
+ * // => true
+ *
+ * _.isFinite(Number.MIN_VALUE);
+ * // => true
+ *
+ * _.isFinite(Infinity);
+ * // => false
+ *
+ * _.isFinite('3');
+ * // => false
+ */
+ function isFinite(value) {
+ return typeof value == 'number' && nativeIsFinite(value);
+ }
+
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+ function isFunction(value) {
+ if (!isObject(value)) {
+ return false;
+ }
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 9 which returns 'object' for typed arrays and other constructors.
+ var tag = baseGetTag(value);
+ return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
+ }
+
+ /**
+ * Checks if `value` is an integer.
+ *
+ * **Note:** This method is based on
+ * [`Number.isInteger`](https://mdn.io/Number/isInteger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
+ * @example
+ *
+ * _.isInteger(3);
+ * // => true
+ *
+ * _.isInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isInteger(Infinity);
+ * // => false
+ *
+ * _.isInteger('3');
+ * // => false
+ */
+ function isInteger(value) {
+ return typeof value == 'number' && value == toInteger(value);
+ }
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' &&
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+ }
+
+ /**
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return value != null && (type == 'object' || type == 'function');
+ }
+
+ /**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return value != null && typeof value == 'object';
+ }
+
+ /**
+ * Checks if `value` is classified as a `Map` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ * @example
+ *
+ * _.isMap(new Map);
+ * // => true
+ *
+ * _.isMap(new WeakMap);
+ * // => false
+ */
+ var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
+
+ /**
+ * Performs a partial deep comparison between `object` and `source` to
+ * determine if `object` contains equivalent property values.
+ *
+ * **Note:** This method is equivalent to `_.matches` when `source` is
+ * partially applied.
+ *
+ * Partial comparisons will match empty array and empty object `source`
+ * values against any array or object value, respectively. See `_.isEqual`
+ * for a list of supported value comparisons.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ *
+ * _.isMatch(object, { 'b': 2 });
+ * // => true
+ *
+ * _.isMatch(object, { 'b': 1 });
+ * // => false
+ */
+ function isMatch(object, source) {
+ return object === source || baseIsMatch(object, source, getMatchData(source));
+ }
+
+ /**
+ * This method is like `_.isMatch` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * are handled by the method instead. The `customizer` is invoked with five
+ * arguments: (objValue, srcValue, index|key, object, source).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, srcValue) {
+ * if (isGreeting(objValue) && isGreeting(srcValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var object = { 'greeting': 'hello' };
+ * var source = { 'greeting': 'hi' };
+ *
+ * _.isMatchWith(object, source, customizer);
+ * // => true
+ */
+ function isMatchWith(object, source, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return baseIsMatch(object, source, getMatchData(source), customizer);
+ }
+
+ /**
+ * Checks if `value` is `NaN`.
+ *
+ * **Note:** This method is based on
+ * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
+ * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
+ * `undefined` and other non-number values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ * @example
+ *
+ * _.isNaN(NaN);
+ * // => true
+ *
+ * _.isNaN(new Number(NaN));
+ * // => true
+ *
+ * isNaN(undefined);
+ * // => true
+ *
+ * _.isNaN(undefined);
+ * // => false
+ */
+ function isNaN(value) {
+ // An `NaN` primitive is the only value that is not equal to itself.
+ // Perform the `toStringTag` check first to avoid errors with some
+ // ActiveX objects in IE.
+ return isNumber(value) && value != +value;
+ }
+
+ /**
+ * Checks if `value` is a pristine native function.
+ *
+ * **Note:** This method can't reliably detect native functions in the presence
+ * of the core-js package because core-js circumvents this kind of detection.
+ * Despite multiple requests, the core-js maintainer has made it clear: any
+ * attempt to fix the detection will be obstructed. As a result, we're left
+ * with little choice but to throw an error. Unfortunately, this also affects
+ * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
+ * which rely on core-js.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ * else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+ function isNative(value) {
+ if (isMaskable(value)) {
+ throw new Error(CORE_ERROR_TEXT);
+ }
+ return baseIsNative(value);
+ }
+
+ /**
+ * Checks if `value` is `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
+ * @example
+ *
+ * _.isNull(null);
+ * // => true
+ *
+ * _.isNull(void 0);
+ * // => false
+ */
+ function isNull(value) {
+ return value === null;
+ }
+
+ /**
+ * Checks if `value` is `null` or `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
+ * @example
+ *
+ * _.isNil(null);
+ * // => true
+ *
+ * _.isNil(void 0);
+ * // => true
+ *
+ * _.isNil(NaN);
+ * // => false
+ */
+ function isNil(value) {
+ return value == null;
+ }
+
+ /**
+ * Checks if `value` is classified as a `Number` primitive or object.
+ *
+ * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
+ * classified as numbers, use the `_.isFinite` method.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a number, else `false`.
+ * @example
+ *
+ * _.isNumber(3);
+ * // => true
+ *
+ * _.isNumber(Number.MIN_VALUE);
+ * // => true
+ *
+ * _.isNumber(Infinity);
+ * // => true
+ *
+ * _.isNumber('3');
+ * // => false
+ */
+ function isNumber(value) {
+ return typeof value == 'number' ||
+ (isObjectLike(value) && baseGetTag(value) == numberTag);
+ }
+
+ /**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.8.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+ function isPlainObject(value) {
+ if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
+ return false;
+ }
+ var proto = getPrototype(value);
+ if (proto === null) {
+ return true;
+ }
+ var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+ return typeof Ctor == 'function' && Ctor instanceof Ctor &&
+ funcToString.call(Ctor) == objectCtorString;
+ }
+
+ /**
+ * Checks if `value` is classified as a `RegExp` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+ * @example
+ *
+ * _.isRegExp(/abc/);
+ * // => true
+ *
+ * _.isRegExp('/abc/');
+ * // => false
+ */
+ var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
+
+ /**
+ * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
+ * double precision number which isn't the result of a rounded unsafe integer.
+ *
+ * **Note:** This method is based on
+ * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
+ * @example
+ *
+ * _.isSafeInteger(3);
+ * // => true
+ *
+ * _.isSafeInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isSafeInteger(Infinity);
+ * // => false
+ *
+ * _.isSafeInteger('3');
+ * // => false
+ */
+ function isSafeInteger(value) {
+ return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
+ }
+
+ /**
+ * Checks if `value` is classified as a `Set` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ * @example
+ *
+ * _.isSet(new Set);
+ * // => true
+ *
+ * _.isSet(new WeakSet);
+ * // => false
+ */
+ var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+ function isString(value) {
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
+ }
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+ function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && baseGetTag(value) == symbolTag);
+ }
+
+ /**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */
+ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+
+ /**
+ * Checks if `value` is `undefined`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+ * @example
+ *
+ * _.isUndefined(void 0);
+ * // => true
+ *
+ * _.isUndefined(null);
+ * // => false
+ */
+ function isUndefined(value) {
+ return value === undefined;
+ }
+
+ /**
+ * Checks if `value` is classified as a `WeakMap` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
+ * @example
+ *
+ * _.isWeakMap(new WeakMap);
+ * // => true
+ *
+ * _.isWeakMap(new Map);
+ * // => false
+ */
+ function isWeakMap(value) {
+ return isObjectLike(value) && getTag(value) == weakMapTag;
+ }
+
+ /**
+ * Checks if `value` is classified as a `WeakSet` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
+ * @example
+ *
+ * _.isWeakSet(new WeakSet);
+ * // => true
+ *
+ * _.isWeakSet(new Set);
+ * // => false
+ */
+ function isWeakSet(value) {
+ return isObjectLike(value) && baseGetTag(value) == weakSetTag;
+ }
+
+ /**
+ * Checks if `value` is less than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than `other`,
+ * else `false`.
+ * @see _.gt
+ * @example
+ *
+ * _.lt(1, 3);
+ * // => true
+ *
+ * _.lt(3, 3);
+ * // => false
+ *
+ * _.lt(3, 1);
+ * // => false
+ */
+ var lt = createRelationalOperation(baseLt);
+
+ /**
+ * Checks if `value` is less than or equal to `other`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.9.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than or equal to
+ * `other`, else `false`.
+ * @see _.gte
+ * @example
+ *
+ * _.lte(1, 3);
+ * // => true
+ *
+ * _.lte(3, 3);
+ * // => true
+ *
+ * _.lte(3, 1);
+ * // => false
+ */
+ var lte = createRelationalOperation(function(value, other) {
+ return value <= other;
+ });
+
+ /**
+ * Converts `value` to an array.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the converted array.
+ * @example
+ *
+ * _.toArray({ 'a': 1, 'b': 2 });
+ * // => [1, 2]
+ *
+ * _.toArray('abc');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toArray(1);
+ * // => []
+ *
+ * _.toArray(null);
+ * // => []
+ */
+ function toArray(value) {
+ if (!value) {
+ return [];
+ }
+ if (isArrayLike(value)) {
+ return isString(value) ? stringToArray(value) : copyArray(value);
+ }
+ if (symIterator && value[symIterator]) {
+ return iteratorToArray(value[symIterator]());
+ }
+ var tag = getTag(value),
+ func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+ return func(value);
+ }
+
+ /**
+ * Converts `value` to a finite number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.12.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted number.
+ * @example
+ *
+ * _.toFinite(3.2);
+ * // => 3.2
+ *
+ * _.toFinite(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toFinite(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toFinite('3.2');
+ * // => 3.2
+ */
+ function toFinite(value) {
+ if (!value) {
+ return value === 0 ? value : 0;
+ }
+ value = toNumber(value);
+ if (value === INFINITY || value === -INFINITY) {
+ var sign = (value < 0 ? -1 : 1);
+ return sign * MAX_INTEGER;
+ }
+ return value === value ? value : 0;
+ }
+
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3.2);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3.2');
+ * // => 3
+ */
+ function toInteger(value) {
+ var result = toFinite(value),
+ remainder = result % 1;
+
+ return result === result ? (remainder ? result - remainder : result) : 0;
+ }
+
+ /**
+ * Converts `value` to an integer suitable for use as the length of an
+ * array-like object.
+ *
+ * **Note:** This method is based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toLength(3.2);
+ * // => 3
+ *
+ * _.toLength(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toLength(Infinity);
+ * // => 4294967295
+ *
+ * _.toLength('3.2');
+ * // => 3
+ */
+ function toLength(value) {
+ return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
+ }
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3.2);
+ * // => 3.2
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3.2');
+ * // => 3.2
+ */
+ function toNumber(value) {
+ if (typeof value == 'number') {
+ return value;
+ }
+ if (isSymbol(value)) {
+ return NAN;
+ }
+ if (isObject(value)) {
+ var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
+ value = isObject(other) ? (other + '') : other;
+ }
+ if (typeof value != 'string') {
+ return value === 0 ? value : +value;
+ }
+ value = baseTrim(value);
+ var isBinary = reIsBinary.test(value);
+ return (isBinary || reIsOctal.test(value))
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+ : (reIsBadHex.test(value) ? NAN : +value);
+ }
+
+ /**
+ * Converts `value` to a plain object flattening inherited enumerable string
+ * keyed properties of `value` to own properties of the plain object.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Object} Returns the converted plain object.
+ * @example
+ *
+ * function Foo() {
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.assign({ 'a': 1 }, new Foo);
+ * // => { 'a': 1, 'b': 2 }
+ *
+ * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+ * // => { 'a': 1, 'b': 2, 'c': 3 }
+ */
+ function toPlainObject(value) {
+ return copyObject(value, keysIn(value));
+ }
+
+ /**
+ * Converts `value` to a safe integer. A safe integer can be compared and
+ * represented correctly.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toSafeInteger(3.2);
+ * // => 3
+ *
+ * _.toSafeInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toSafeInteger(Infinity);
+ * // => 9007199254740991
+ *
+ * _.toSafeInteger('3.2');
+ * // => 3
+ */
+ function toSafeInteger(value) {
+ return value
+ ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
+ : (value === 0 ? value : 0);
+ }
+
+ /**
+ * Converts `value` to a string. An empty string is returned for `null`
+ * and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ return value == null ? '' : baseToString(value);
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Assigns own enumerable string keyed properties of source objects to the
+ * destination object. Source objects are applied from left to right.
+ * Subsequent sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object` and is loosely based on
+ * [`Object.assign`](https://mdn.io/Object/assign).
+ *
+ * @static
+ * @memberOf _
+ * @since 0.10.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.assignIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * function Bar() {
+ * this.c = 3;
+ * }
+ *
+ * Foo.prototype.b = 2;
+ * Bar.prototype.d = 4;
+ *
+ * _.assign({ 'a': 0 }, new Foo, new Bar);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ var assign = createAssigner(function(object, source) {
+ if (isPrototype(source) || isArrayLike(source)) {
+ copyObject(source, keys(source), object);
+ return;
+ }
+ for (var key in source) {
+ if (hasOwnProperty.call(source, key)) {
+ assignValue(object, key, source[key]);
+ }
+ }
+ });
+
+ /**
+ * This method is like `_.assign` except that it iterates over own and
+ * inherited source properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias extend
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.assign
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * function Bar() {
+ * this.c = 3;
+ * }
+ *
+ * Foo.prototype.b = 2;
+ * Bar.prototype.d = 4;
+ *
+ * _.assignIn({ 'a': 0 }, new Foo, new Bar);
+ * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
+ */
+ var assignIn = createAssigner(function(object, source) {
+ copyObject(source, keysIn(source), object);
+ });
+
+ /**
+ * This method is like `_.assignIn` except that it accepts `customizer`
+ * which is invoked to produce the assigned values. If `customizer` returns
+ * `undefined`, assignment is handled by the method instead. The `customizer`
+ * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias extendWith
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @see _.assignWith
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignInWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
+ copyObject(source, keysIn(source), object, customizer);
+ });
+
+ /**
+ * This method is like `_.assign` except that it accepts `customizer`
+ * which is invoked to produce the assigned values. If `customizer` returns
+ * `undefined`, assignment is handled by the method instead. The `customizer`
+ * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @see _.assignInWith
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
+ copyObject(source, keys(source), object, customizer);
+ });
+
+ /**
+ * Creates an array of values corresponding to `paths` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Array} Returns the picked values.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _.at(object, ['a[0].b.c', 'a[1]']);
+ * // => [3, 4]
+ */
+ var at = flatRest(baseAt);
+
+ /**
+ * Creates an object that inherits from the `prototype` object. If a
+ * `properties` object is given, its own enumerable string keyed properties
+ * are assigned to the created object.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.3.0
+ * @category Object
+ * @param {Object} prototype The object to inherit from.
+ * @param {Object} [properties] The properties to assign to the object.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * function Shape() {
+ * this.x = 0;
+ * this.y = 0;
+ * }
+ *
+ * function Circle() {
+ * Shape.call(this);
+ * }
+ *
+ * Circle.prototype = _.create(Shape.prototype, {
+ * 'constructor': Circle
+ * });
+ *
+ * var circle = new Circle;
+ * circle instanceof Circle;
+ * // => true
+ *
+ * circle instanceof Shape;
+ * // => true
+ */
+ function create(prototype, properties) {
+ var result = baseCreate(prototype);
+ return properties == null ? result : baseAssign(result, properties);
+ }
+
+ /**
+ * Assigns own and inherited enumerable string keyed properties of source
+ * objects to the destination object for all destination properties that
+ * resolve to `undefined`. Source objects are applied from left to right.
+ * Once a property is set, additional values of the same property are ignored.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.defaultsDeep
+ * @example
+ *
+ * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var defaults = baseRest(function(object, sources) {
+ object = Object(object);
+
+ var index = -1;
+ var length = sources.length;
+ var guard = length > 2 ? sources[2] : undefined;
+
+ if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+ length = 1;
+ }
+
+ while (++index < length) {
+ var source = sources[index];
+ var props = keysIn(source);
+ var propsIndex = -1;
+ var propsLength = props.length;
+
+ while (++propsIndex < propsLength) {
+ var key = props[propsIndex];
+ var value = object[key];
+
+ if (value === undefined ||
+ (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+ object[key] = source[key];
+ }
+ }
+ }
+
+ return object;
+ });
+
+ /**
+ * This method is like `_.defaults` except that it recursively assigns
+ * default properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.10.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @see _.defaults
+ * @example
+ *
+ * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
+ * // => { 'a': { 'b': 2, 'c': 3 } }
+ */
+ var defaultsDeep = baseRest(function(args) {
+ args.push(undefined, customDefaultsMerge);
+ return apply(mergeWith, undefined, args);
+ });
+
+ /**
+ * This method is like `_.find` except that it returns the key of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element,
+ * else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findKey(users, function(o) { return o.age < 40; });
+ * // => 'barney' (iteration order is not guaranteed)
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findKey(users, { 'age': 1, 'active': true });
+ * // => 'pebbles'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findKey(users, 'active');
+ * // => 'barney'
+ */
+ function findKey(object, predicate) {
+ return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
+ }
+
+ /**
+ * This method is like `_.findKey` except that it iterates over elements of
+ * a collection in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element,
+ * else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findLastKey(users, function(o) { return o.age < 40; });
+ * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findLastKey(users, { 'age': 36, 'active': true });
+ * // => 'barney'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findLastKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findLastKey(users, 'active');
+ * // => 'pebbles'
+ */
+ function findLastKey(object, predicate) {
+ return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
+ }
+
+ /**
+ * Iterates over own and inherited enumerable string keyed properties of an
+ * object and invokes `iteratee` for each property. The iteratee is invoked
+ * with three arguments: (value, key, object). Iteratee functions may exit
+ * iteration early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forInRight
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forIn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
+ */
+ function forIn(object, iteratee) {
+ return object == null
+ ? object
+ : baseFor(object, getIteratee(iteratee, 3), keysIn);
+ }
+
+ /**
+ * This method is like `_.forIn` except that it iterates over properties of
+ * `object` in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forInRight(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
+ */
+ function forInRight(object, iteratee) {
+ return object == null
+ ? object
+ : baseForRight(object, getIteratee(iteratee, 3), keysIn);
+ }
+
+ /**
+ * Iterates over own enumerable string keyed properties of an object and
+ * invokes `iteratee` for each property. The iteratee is invoked with three
+ * arguments: (value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forOwnRight
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ */
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * This method is like `_.forOwn` except that it iterates over properties of
+ * `object` in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.0.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @see _.forOwn
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwnRight(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
+ */
+ function forOwnRight(object, iteratee) {
+ return object && baseForOwnRight(object, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * Creates an array of function property names from own enumerable properties
+ * of `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the function names.
+ * @see _.functionsIn
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functions(new Foo);
+ * // => ['a', 'b']
+ */
+ function functions(object) {
+ return object == null ? [] : baseFunctions(object, keys(object));
+ }
+
+ /**
+ * Creates an array of function property names from own and inherited
+ * enumerable properties of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the function names.
+ * @see _.functions
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functionsIn(new Foo);
+ * // => ['a', 'b', 'c']
+ */
+ function functionsIn(object) {
+ return object == null ? [] : baseFunctions(object, keysIn(object));
+ }
+
+ /**
+ * Gets the value at `path` of `object`. If the resolved value is
+ * `undefined`, the `defaultValue` is returned in its place.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.get(object, 'a[0].b.c');
+ * // => 3
+ *
+ * _.get(object, ['a', '0', 'b', 'c']);
+ * // => 3
+ *
+ * _.get(object, 'a.b.c', 'default');
+ * // => 'default'
+ */
+ function get(object, path, defaultValue) {
+ var result = object == null ? undefined : baseGet(object, path);
+ return result === undefined ? defaultValue : result;
+ }
+
+ /**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': 2 } };
+ * var other = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b');
+ * // => true
+ *
+ * _.has(object, ['a', 'b']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+ function has(object, path) {
+ return object != null && hasPath(object, path, baseHas);
+ }
+
+ /**
+ * Checks if `path` is a direct or inherited property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.hasIn(object, 'a');
+ * // => true
+ *
+ * _.hasIn(object, 'a.b');
+ * // => true
+ *
+ * _.hasIn(object, ['a', 'b']);
+ * // => true
+ *
+ * _.hasIn(object, 'b');
+ * // => false
+ */
+ function hasIn(object, path) {
+ return object != null && hasPath(object, path, baseHasIn);
+ }
+
+ /**
+ * Creates an object composed of the inverted keys and values of `object`.
+ * If `object` contains duplicate values, subsequent values overwrite
+ * property assignments of previous values.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.7.0
+ * @category Object
+ * @param {Object} object The object to invert.
+ * @returns {Object} Returns the new inverted object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2, 'c': 1 };
+ *
+ * _.invert(object);
+ * // => { '1': 'c', '2': 'b' }
+ */
+ var invert = createInverter(function(result, value, key) {
+ if (value != null &&
+ typeof value.toString != 'function') {
+ value = nativeObjectToString.call(value);
+ }
+
+ result[value] = key;
+ }, constant(identity));
+
+ /**
+ * This method is like `_.invert` except that the inverted object is generated
+ * from the results of running each element of `object` thru `iteratee`. The
+ * corresponding inverted value of each inverted key is an array of keys
+ * responsible for generating the inverted value. The iteratee is invoked
+ * with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.1.0
+ * @category Object
+ * @param {Object} object The object to invert.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the new inverted object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2, 'c': 1 };
+ *
+ * _.invertBy(object);
+ * // => { '1': ['a', 'c'], '2': ['b'] }
+ *
+ * _.invertBy(object, function(value) {
+ * return 'group' + value;
+ * });
+ * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
+ */
+ var invertBy = createInverter(function(result, value, key) {
+ if (value != null &&
+ typeof value.toString != 'function') {
+ value = nativeObjectToString.call(value);
+ }
+
+ if (hasOwnProperty.call(result, value)) {
+ result[value].push(key);
+ } else {
+ result[value] = [key];
+ }
+ }, getIteratee);
+
+ /**
+ * Invokes the method at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+ *
+ * _.invoke(object, 'a[0].b.c.slice', 1, 3);
+ * // => [2, 3]
+ */
+ var invoke = baseRest(baseInvoke);
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+ function keys(object) {
+ return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
+ }
+
+ /**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+ function keysIn(object) {
+ return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
+ }
+
+ /**
+ * The opposite of `_.mapValues`; this method creates an object with the
+ * same values as `object` and keys generated by running each own enumerable
+ * string keyed property of `object` thru `iteratee`. The iteratee is invoked
+ * with three arguments: (value, key, object).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @see _.mapValues
+ * @example
+ *
+ * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
+ * return key + value;
+ * });
+ * // => { 'a1': 1, 'b2': 2 }
+ */
+ function mapKeys(object, iteratee) {
+ var result = {};
+ iteratee = getIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ baseAssignValue(result, iteratee(value, key, object), value);
+ });
+ return result;
+ }
+
+ /**
+ * Creates an object with the same keys as `object` and values generated
+ * by running each own enumerable string keyed property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, key, object).
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @see _.mapKeys
+ * @example
+ *
+ * var users = {
+ * 'fred': { 'user': 'fred', 'age': 40 },
+ * 'pebbles': { 'user': 'pebbles', 'age': 1 }
+ * };
+ *
+ * _.mapValues(users, function(o) { return o.age; });
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.mapValues(users, 'age');
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ */
+ function mapValues(object, iteratee) {
+ var result = {};
+ iteratee = getIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ baseAssignValue(result, key, iteratee(value, key, object));
+ });
+ return result;
+ }
+
+ /**
+ * This method is like `_.assign` except that it recursively merges own and
+ * inherited enumerable string keyed properties of source objects into the
+ * destination object. Source properties that resolve to `undefined` are
+ * skipped if a destination value exists. Array and plain object properties
+ * are merged recursively. Other objects and value types are overridden by
+ * assignment. Source objects are applied from left to right. Subsequent
+ * sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.5.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {
+ * 'a': [{ 'b': 2 }, { 'd': 4 }]
+ * };
+ *
+ * var other = {
+ * 'a': [{ 'c': 3 }, { 'e': 5 }]
+ * };
+ *
+ * _.merge(object, other);
+ * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
+ */
+ var merge = createAssigner(function(object, source, srcIndex) {
+ baseMerge(object, source, srcIndex);
+ });
+
+ /**
+ * This method is like `_.merge` except that it accepts `customizer` which
+ * is invoked to produce the merged values of the destination and source
+ * properties. If `customizer` returns `undefined`, merging is handled by the
+ * method instead. The `customizer` is invoked with six arguments:
+ * (objValue, srcValue, key, object, source, stack).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} customizer The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * if (_.isArray(objValue)) {
+ * return objValue.concat(srcValue);
+ * }
+ * }
+ *
+ * var object = { 'a': [1], 'b': [2] };
+ * var other = { 'a': [3], 'b': [4] };
+ *
+ * _.mergeWith(object, other, customizer);
+ * // => { 'a': [1, 3], 'b': [2, 4] }
+ */
+ var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
+ baseMerge(object, source, srcIndex, customizer);
+ });
+
+ /**
+ * The opposite of `_.pick`; this method creates an object composed of the
+ * own and inherited enumerable property paths of `object` that are not omitted.
+ *
+ * **Note:** This method is considerably slower than `_.pick`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [paths] The property paths to omit.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omit(object, ['a', 'c']);
+ * // => { 'b': '2' }
+ */
+ var omit = flatRest(function(object, paths) {
+ var result = {};
+ if (object == null) {
+ return result;
+ }
+ var isDeep = false;
+ paths = arrayMap(paths, function(path) {
+ path = castPath(path, object);
+ isDeep || (isDeep = path.length > 1);
+ return path;
+ });
+ copyObject(object, getAllKeysIn(object), result);
+ if (isDeep) {
+ result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
+ }
+ var length = paths.length;
+ while (length--) {
+ baseUnset(result, paths[length]);
+ }
+ return result;
+ });
+
+ /**
+ * The opposite of `_.pickBy`; this method creates an object composed of
+ * the own and inherited enumerable string keyed properties of `object` that
+ * `predicate` doesn't return truthy for. The predicate is invoked with two
+ * arguments: (value, key).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omitBy(object, _.isNumber);
+ * // => { 'b': '2' }
+ */
+ function omitBy(object, predicate) {
+ return pickBy(object, negate(getIteratee(predicate)));
+ }
+
+ /**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ var pick = flatRest(function(object, paths) {
+ return object == null ? {} : basePick(object, paths);
+ });
+
+ /**
+ * Creates an object composed of the `object` properties `predicate` returns
+ * truthy for. The predicate is invoked with two arguments: (value, key).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pickBy(object, _.isNumber);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ function pickBy(object, predicate) {
+ if (object == null) {
+ return {};
+ }
+ var props = arrayMap(getAllKeysIn(object), function(prop) {
+ return [prop];
+ });
+ predicate = getIteratee(predicate);
+ return basePickBy(object, props, function(value, path) {
+ return predicate(value, path[0]);
+ });
+ }
+
+ /**
+ * This method is like `_.get` except that if the resolved value is a
+ * function it's invoked with the `this` binding of its parent object and
+ * its result is returned.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to resolve.
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
+ *
+ * _.result(object, 'a[0].b.c1');
+ * // => 3
+ *
+ * _.result(object, 'a[0].b.c2');
+ * // => 4
+ *
+ * _.result(object, 'a[0].b.c3', 'default');
+ * // => 'default'
+ *
+ * _.result(object, 'a[0].b.c3', _.constant('default'));
+ * // => 'default'
+ */
+ function result(object, path, defaultValue) {
+ path = castPath(path, object);
+
+ var index = -1,
+ length = path.length;
+
+ // Ensure the loop is entered when path is empty.
+ if (!length) {
+ length = 1;
+ object = undefined;
+ }
+ while (++index < length) {
+ var value = object == null ? undefined : object[toKey(path[index])];
+ if (value === undefined) {
+ index = length;
+ value = defaultValue;
+ }
+ object = isFunction(value) ? value.call(object) : value;
+ }
+ return object;
+ }
+
+ /**
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
+ * it's created. Arrays are created for missing index properties while objects
+ * are created for all other missing properties. Use `_.setWith` to customize
+ * `path` creation.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.set(object, 'a[0].b.c', 4);
+ * console.log(object.a[0].b.c);
+ * // => 4
+ *
+ * _.set(object, ['x', '0', 'y', 'z'], 5);
+ * console.log(object.x[0].y.z);
+ * // => 5
+ */
+ function set(object, path, value) {
+ return object == null ? object : baseSet(object, path, value);
+ }
+
+ /**
+ * This method is like `_.set` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {};
+ *
+ * _.setWith(object, '[0][1]', 'a', Object);
+ * // => { '0': { '1': 'a' } }
+ */
+ function setWith(object, path, value, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return object == null ? object : baseSet(object, path, value, customizer);
+ }
+
+ /**
+ * Creates an array of own enumerable string keyed-value pairs for `object`
+ * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
+ * entries are returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias entries
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairs(new Foo);
+ * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+ */
+ var toPairs = createToPairs(keys);
+
+ /**
+ * Creates an array of own and inherited enumerable string keyed-value pairs
+ * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
+ * or set, its entries are returned.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @alias entriesIn
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairsIn(new Foo);
+ * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
+ */
+ var toPairsIn = createToPairs(keysIn);
+
+ /**
+ * An alternative to `_.reduce`; this method transforms `object` to a new
+ * `accumulator` object which is the result of running each of its own
+ * enumerable string keyed properties thru `iteratee`, with each invocation
+ * potentially mutating the `accumulator` object. If `accumulator` is not
+ * provided, a new object with the same `[[Prototype]]` will be used. The
+ * iteratee is invoked with four arguments: (accumulator, value, key, object).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.3.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The custom accumulator value.
+ * @returns {*} Returns the accumulated value.
+ * @example
+ *
+ * _.transform([2, 3, 4], function(result, n) {
+ * result.push(n *= n);
+ * return n % 2 == 0;
+ * }, []);
+ * // => [4, 9]
+ *
+ * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] }
+ */
+ function transform(object, iteratee, accumulator) {
+ var isArr = isArray(object),
+ isArrLike = isArr || isBuffer(object) || isTypedArray(object);
+
+ iteratee = getIteratee(iteratee, 4);
+ if (accumulator == null) {
+ var Ctor = object && object.constructor;
+ if (isArrLike) {
+ accumulator = isArr ? new Ctor : [];
+ }
+ else if (isObject(object)) {
+ accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
+ }
+ else {
+ accumulator = {};
+ }
+ }
+ (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
+ return iteratee(accumulator, value, index, object);
+ });
+ return accumulator;
+ }
+
+ /**
+ * Removes the property at `path` of `object`.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 7 } }] };
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ *
+ * _.unset(object, ['a', '0', 'b', 'c']);
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ */
+ function unset(object, path) {
+ return object == null ? true : baseUnset(object, path);
+ }
+
+ /**
+ * This method is like `_.set` except that accepts `updater` to produce the
+ * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
+ * is invoked with one argument: (value).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {Function} updater The function to produce the updated value.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.update(object, 'a[0].b.c', function(n) { return n * n; });
+ * console.log(object.a[0].b.c);
+ * // => 9
+ *
+ * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
+ * console.log(object.x[0].y.z);
+ * // => 0
+ */
+ function update(object, path, updater) {
+ return object == null ? object : baseUpdate(object, path, castFunction(updater));
+ }
+
+ /**
+ * This method is like `_.update` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.6.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {Function} updater The function to produce the updated value.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = {};
+ *
+ * _.updateWith(object, '[0][1]', _.constant('a'), Object);
+ * // => { '0': { '1': 'a' } }
+ */
+ function updateWith(object, path, updater, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
+ }
+
+ /**
+ * Creates an array of the own enumerable string keyed property values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.values(new Foo);
+ * // => [1, 2] (iteration order is not guaranteed)
+ *
+ * _.values('hi');
+ * // => ['h', 'i']
+ */
+ function values(object) {
+ return object == null ? [] : baseValues(object, keys(object));
+ }
+
+ /**
+ * Creates an array of the own and inherited enumerable string keyed property
+ * values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.valuesIn(new Foo);
+ * // => [1, 2, 3] (iteration order is not guaranteed)
+ */
+ function valuesIn(object) {
+ return object == null ? [] : baseValues(object, keysIn(object));
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Clamps `number` within the inclusive `lower` and `upper` bounds.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Number
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ * @example
+ *
+ * _.clamp(-10, -5, 5);
+ * // => -5
+ *
+ * _.clamp(10, -5, 5);
+ * // => 5
+ */
+ function clamp(number, lower, upper) {
+ if (upper === undefined) {
+ upper = lower;
+ lower = undefined;
+ }
+ if (upper !== undefined) {
+ upper = toNumber(upper);
+ upper = upper === upper ? upper : 0;
+ }
+ if (lower !== undefined) {
+ lower = toNumber(lower);
+ lower = lower === lower ? lower : 0;
+ }
+ return baseClamp(toNumber(number), lower, upper);
+ }
+
+ /**
+ * Checks if `n` is between `start` and up to, but not including, `end`. If
+ * `end` is not specified, it's set to `start` with `start` then set to `0`.
+ * If `start` is greater than `end` the params are swapped to support
+ * negative ranges.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.3.0
+ * @category Number
+ * @param {number} number The number to check.
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ * @see _.range, _.rangeRight
+ * @example
+ *
+ * _.inRange(3, 2, 4);
+ * // => true
+ *
+ * _.inRange(4, 8);
+ * // => true
+ *
+ * _.inRange(4, 2);
+ * // => false
+ *
+ * _.inRange(2, 2);
+ * // => false
+ *
+ * _.inRange(1.2, 2);
+ * // => true
+ *
+ * _.inRange(5.2, 4);
+ * // => false
+ *
+ * _.inRange(-3, -2, -6);
+ * // => true
+ */
+ function inRange(number, start, end) {
+ start = toFinite(start);
+ if (end === undefined) {
+ end = start;
+ start = 0;
+ } else {
+ end = toFinite(end);
+ }
+ number = toNumber(number);
+ return baseInRange(number, start, end);
+ }
+
+ /**
+ * Produces a random number between the inclusive `lower` and `upper` bounds.
+ * If only one argument is provided a number between `0` and the given number
+ * is returned. If `floating` is `true`, or either `lower` or `upper` are
+ * floats, a floating-point number is returned instead of an integer.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.7.0
+ * @category Number
+ * @param {number} [lower=0] The lower bound.
+ * @param {number} [upper=1] The upper bound.
+ * @param {boolean} [floating] Specify returning a floating-point number.
+ * @returns {number} Returns the random number.
+ * @example
+ *
+ * _.random(0, 5);
+ * // => an integer between 0 and 5
+ *
+ * _.random(5);
+ * // => also an integer between 0 and 5
+ *
+ * _.random(5, true);
+ * // => a floating-point number between 0 and 5
+ *
+ * _.random(1.2, 5.2);
+ * // => a floating-point number between 1.2 and 5.2
+ */
+ function random(lower, upper, floating) {
+ if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
+ upper = floating = undefined;
+ }
+ if (floating === undefined) {
+ if (typeof upper == 'boolean') {
+ floating = upper;
+ upper = undefined;
+ }
+ else if (typeof lower == 'boolean') {
+ floating = lower;
+ lower = undefined;
+ }
+ }
+ if (lower === undefined && upper === undefined) {
+ lower = 0;
+ upper = 1;
+ }
+ else {
+ lower = toFinite(lower);
+ if (upper === undefined) {
+ upper = lower;
+ lower = 0;
+ } else {
+ upper = toFinite(upper);
+ }
+ }
+ if (lower > upper) {
+ var temp = lower;
+ lower = upper;
+ upper = temp;
+ }
+ if (floating || lower % 1 || upper % 1) {
+ var rand = nativeRandom();
+ return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
+ }
+ return baseRandom(lower, upper);
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the camel cased string.
+ * @example
+ *
+ * _.camelCase('Foo Bar');
+ * // => 'fooBar'
+ *
+ * _.camelCase('--foo-bar--');
+ * // => 'fooBar'
+ *
+ * _.camelCase('__FOO_BAR__');
+ * // => 'fooBar'
+ */
+ var camelCase = createCompounder(function(result, word, index) {
+ word = word.toLowerCase();
+ return result + (index ? capitalize(word) : word);
+ });
+
+ /**
+ * Converts the first character of `string` to upper case and the remaining
+ * to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to capitalize.
+ * @returns {string} Returns the capitalized string.
+ * @example
+ *
+ * _.capitalize('FRED');
+ * // => 'Fred'
+ */
+ function capitalize(string) {
+ return upperFirst(toString(string).toLowerCase());
+ }
+
+ /**
+ * Deburrs `string` by converting
+ * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+ * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
+ * letters to basic Latin letters and removing
+ * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to deburr.
+ * @returns {string} Returns the deburred string.
+ * @example
+ *
+ * _.deburr('déjà vu');
+ * // => 'deja vu'
+ */
+ function deburr(string) {
+ string = toString(string);
+ return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
+ }
+
+ /**
+ * Checks if `string` ends with the given target string.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {string} [target] The string to search for.
+ * @param {number} [position=string.length] The position to search up to.
+ * @returns {boolean} Returns `true` if `string` ends with `target`,
+ * else `false`.
+ * @example
+ *
+ * _.endsWith('abc', 'c');
+ * // => true
+ *
+ * _.endsWith('abc', 'b');
+ * // => false
+ *
+ * _.endsWith('abc', 'b', 2);
+ * // => true
+ */
+ function endsWith(string, target, position) {
+ string = toString(string);
+ target = baseToString(target);
+
+ var length = string.length;
+ position = position === undefined
+ ? length
+ : baseClamp(toInteger(position), 0, length);
+
+ var end = position;
+ position -= target.length;
+ return position >= 0 && string.slice(position, end) == target;
+ }
+
+ /**
+ * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
+ * corresponding HTML entities.
+ *
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
+ *
+ * Though the ">" character is escaped for symmetry, characters like
+ * ">" and "/" don't need escaping in HTML and have no special meaning
+ * unless they're part of a tag or unquoted attribute value. See
+ * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+ * (under "semi-related fun fact") for more details.
+ *
+ * When working with HTML you should always
+ * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
+ * XSS vectors.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escape('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles'
+ */
+ function escape(string) {
+ string = toString(string);
+ return (string && reHasUnescapedHtml.test(string))
+ ? string.replace(reUnescapedHtml, escapeHtmlChar)
+ : string;
+ }
+
+ /**
+ * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+ * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escapeRegExp('[lodash](https://lodash.com/)');
+ * // => '\[lodash\]\(https://lodash\.com/\)'
+ */
+ function escapeRegExp(string) {
+ string = toString(string);
+ return (string && reHasRegExpChar.test(string))
+ ? string.replace(reRegExpChar, '\\$&')
+ : string;
+ }
+
+ /**
+ * Converts `string` to
+ * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the kebab cased string.
+ * @example
+ *
+ * _.kebabCase('Foo Bar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('fooBar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('__FOO_BAR__');
+ * // => 'foo-bar'
+ */
+ var kebabCase = createCompounder(function(result, word, index) {
+ return result + (index ? '-' : '') + word.toLowerCase();
+ });
+
+ /**
+ * Converts `string`, as space separated words, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.lowerCase('--Foo-Bar--');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('fooBar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('__FOO_BAR__');
+ * // => 'foo bar'
+ */
+ var lowerCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + word.toLowerCase();
+ });
+
+ /**
+ * Converts the first character of `string` to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.lowerFirst('Fred');
+ * // => 'fred'
+ *
+ * _.lowerFirst('FRED');
+ * // => 'fRED'
+ */
+ var lowerFirst = createCaseFirst('toLowerCase');
+
+ /**
+ * Pads `string` on the left and right sides if it's shorter than `length`.
+ * Padding characters are truncated if they can't be evenly divided by `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.pad('abc', 8);
+ * // => ' abc '
+ *
+ * _.pad('abc', 8, '_-');
+ * // => '_-abc_-_'
+ *
+ * _.pad('abc', 3);
+ * // => 'abc'
+ */
+ function pad(string, length, chars) {
+ string = toString(string);
+ length = toInteger(length);
+
+ var strLength = length ? stringSize(string) : 0;
+ if (!length || strLength >= length) {
+ return string;
+ }
+ var mid = (length - strLength) / 2;
+ return (
+ createPadding(nativeFloor(mid), chars) +
+ string +
+ createPadding(nativeCeil(mid), chars)
+ );
+ }
+
+ /**
+ * Pads `string` on the right side if it's shorter than `length`. Padding
+ * characters are truncated if they exceed `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.padEnd('abc', 6);
+ * // => 'abc '
+ *
+ * _.padEnd('abc', 6, '_-');
+ * // => 'abc_-_'
+ *
+ * _.padEnd('abc', 3);
+ * // => 'abc'
+ */
+ function padEnd(string, length, chars) {
+ string = toString(string);
+ length = toInteger(length);
+
+ var strLength = length ? stringSize(string) : 0;
+ return (length && strLength < length)
+ ? (string + createPadding(length - strLength, chars))
+ : string;
+ }
+
+ /**
+ * Pads `string` on the left side if it's shorter than `length`. Padding
+ * characters are truncated if they exceed `length`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.padStart('abc', 6);
+ * // => ' abc'
+ *
+ * _.padStart('abc', 6, '_-');
+ * // => '_-_abc'
+ *
+ * _.padStart('abc', 3);
+ * // => 'abc'
+ */
+ function padStart(string, length, chars) {
+ string = toString(string);
+ length = toInteger(length);
+
+ var strLength = length ? stringSize(string) : 0;
+ return (length && strLength < length)
+ ? (createPadding(length - strLength, chars) + string)
+ : string;
+ }
+
+ /**
+ * Converts `string` to an integer of the specified radix. If `radix` is
+ * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
+ * hexadecimal, in which case a `radix` of `16` is used.
+ *
+ * **Note:** This method aligns with the
+ * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category String
+ * @param {string} string The string to convert.
+ * @param {number} [radix=10] The radix to interpret `value` by.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.parseInt('08');
+ * // => 8
+ *
+ * _.map(['6', '08', '10'], _.parseInt);
+ * // => [6, 8, 10]
+ */
+ function parseInt(string, radix, guard) {
+ if (guard || radix == null) {
+ radix = 0;
+ } else if (radix) {
+ radix = +radix;
+ }
+ return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
+ }
+
+ /**
+ * Repeats the given string `n` times.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to repeat.
+ * @param {number} [n=1] The number of times to repeat the string.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {string} Returns the repeated string.
+ * @example
+ *
+ * _.repeat('*', 3);
+ * // => '***'
+ *
+ * _.repeat('abc', 2);
+ * // => 'abcabc'
+ *
+ * _.repeat('abc', 0);
+ * // => ''
+ */
+ function repeat(string, n, guard) {
+ if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
+ n = 1;
+ } else {
+ n = toInteger(n);
+ }
+ return baseRepeat(toString(string), n);
+ }
+
+ /**
+ * Replaces matches for `pattern` in `string` with `replacement`.
+ *
+ * **Note:** This method is based on
+ * [`String#replace`](https://mdn.io/String/replace).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to modify.
+ * @param {RegExp|string} pattern The pattern to replace.
+ * @param {Function|string} replacement The match replacement.
+ * @returns {string} Returns the modified string.
+ * @example
+ *
+ * _.replace('Hi Fred', 'Fred', 'Barney');
+ * // => 'Hi Barney'
+ */
+ function replace() {
+ var args = arguments,
+ string = toString(args[0]);
+
+ return args.length < 3 ? string : string.replace(args[1], args[2]);
+ }
+
+ /**
+ * Converts `string` to
+ * [snake case](https://en.wikipedia.org/wiki/Snake_case).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the snake cased string.
+ * @example
+ *
+ * _.snakeCase('Foo Bar');
+ * // => 'foo_bar'
+ *
+ * _.snakeCase('fooBar');
+ * // => 'foo_bar'
+ *
+ * _.snakeCase('--FOO-BAR--');
+ * // => 'foo_bar'
+ */
+ var snakeCase = createCompounder(function(result, word, index) {
+ return result + (index ? '_' : '') + word.toLowerCase();
+ });
+
+ /**
+ * Splits `string` by `separator`.
+ *
+ * **Note:** This method is based on
+ * [`String#split`](https://mdn.io/String/split).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to split.
+ * @param {RegExp|string} separator The separator pattern to split by.
+ * @param {number} [limit] The length to truncate results to.
+ * @returns {Array} Returns the string segments.
+ * @example
+ *
+ * _.split('a-b-c', '-', 2);
+ * // => ['a', 'b']
+ */
+ function split(string, separator, limit) {
+ if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
+ separator = limit = undefined;
+ }
+ limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
+ if (!limit) {
+ return [];
+ }
+ string = toString(string);
+ if (string && (
+ typeof separator == 'string' ||
+ (separator != null && !isRegExp(separator))
+ )) {
+ separator = baseToString(separator);
+ if (!separator && hasUnicode(string)) {
+ return castSlice(stringToArray(string), 0, limit);
+ }
+ }
+ return string.split(separator, limit);
+ }
+
+ /**
+ * Converts `string` to
+ * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.1.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the start cased string.
+ * @example
+ *
+ * _.startCase('--foo-bar--');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('fooBar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('__FOO_BAR__');
+ * // => 'FOO BAR'
+ */
+ var startCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + upperFirst(word);
+ });
+
+ /**
+ * Checks if `string` starts with the given target string.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {string} [target] The string to search for.
+ * @param {number} [position=0] The position to search from.
+ * @returns {boolean} Returns `true` if `string` starts with `target`,
+ * else `false`.
+ * @example
+ *
+ * _.startsWith('abc', 'a');
+ * // => true
+ *
+ * _.startsWith('abc', 'b');
+ * // => false
+ *
+ * _.startsWith('abc', 'b', 1);
+ * // => true
+ */
+ function startsWith(string, target, position) {
+ string = toString(string);
+ position = position == null
+ ? 0
+ : baseClamp(toInteger(position), 0, string.length);
+
+ target = baseToString(target);
+ return string.slice(position, position + target.length) == target;
+ }
+
+ /**
+ * Creates a compiled template function that can interpolate data properties
+ * in "interpolate" delimiters, HTML-escape interpolated data properties in
+ * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
+ * properties may be accessed as free variables in the template. If a setting
+ * object is given, it takes precedence over `_.templateSettings` values.
+ *
+ * **Note:** In the development build `_.template` utilizes
+ * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+ * for easier debugging.
+ *
+ * For more information on precompiling templates see
+ * [lodash's custom builds documentation](https://lodash.com/custom-builds).
+ *
+ * For more information on Chrome extension sandboxes see
+ * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The template string.
+ * @param {Object} [options={}] The options object.
+ * @param {RegExp} [options.escape=_.templateSettings.escape]
+ * The HTML "escape" delimiter.
+ * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
+ * The "evaluate" delimiter.
+ * @param {Object} [options.imports=_.templateSettings.imports]
+ * An object to import into the template as free variables.
+ * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
+ * The "interpolate" delimiter.
+ * @param {string} [options.sourceURL='lodash.templateSources[n]']
+ * The sourceURL of the compiled template.
+ * @param {string} [options.variable='obj']
+ * The data object variable name.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @returns {Function} Returns the compiled template function.
+ * @example
+ *
+ * // Use the "interpolate" delimiter to create a compiled template.
+ * var compiled = _.template('hello <%= user %>!');
+ * compiled({ 'user': 'fred' });
+ * // => 'hello fred!'
+ *
+ * // Use the HTML "escape" delimiter to escape data property values.
+ * var compiled = _.template('<%- value %>');
+ * compiled({ 'value': '