From 03f23cf5c96c0d30d616777ac1fa88bcf41eaef7 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 27 Aug 2019 11:35:48 -0700 Subject: [PATCH 01/72] Implement Atom XML support in core-http --- .../lib/atomResourceSerializerBase.ts | 174 ++++++++++ .../core-http/lib/atomXmlOperationSpec.ts | 14 + sdk/core/core-http/lib/coreHttp.ts | 85 ++++- .../sasServiceClientCredentials.ts | 102 ++++++ .../core-http/lib/httpOperationResponse.ts | 7 +- .../lib/policies/atomSerializationPolicy.ts | 183 ++++++++++ sdk/core/core-http/lib/resourceSerializer.ts | 21 ++ sdk/core/core-http/lib/util/atomHandler.ts | 199 +++++++++++ sdk/core/core-http/lib/util/constants.ts | 54 +++ sdk/core/core-http/lib/util/utils.ts | 318 ++++++++++++++++-- sdk/core/core-http/lib/util/xml.browser.ts | 32 +- sdk/core/core-http/lib/util/xml.ts | 42 +++ sdk/core/core-http/lib/webResource.ts | 130 +++++-- sdk/core/core-http/package.json | 4 +- sdk/core/core-http/rollup.config.ts | 9 +- .../policies/atomSerializationPolicyTests.ts | 128 +++++++ 16 files changed, 1414 insertions(+), 88 deletions(-) create mode 100644 sdk/core/core-http/lib/atomResourceSerializerBase.ts create mode 100644 sdk/core/core-http/lib/atomXmlOperationSpec.ts create mode 100644 sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts create mode 100644 sdk/core/core-http/lib/policies/atomSerializationPolicy.ts create mode 100644 sdk/core/core-http/lib/resourceSerializer.ts create mode 100644 sdk/core/core-http/lib/util/atomHandler.ts create mode 100644 sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts new file mode 100644 index 000000000000..33b8abaac5dd --- /dev/null +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -0,0 +1,174 @@ +// +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { stringIsEmpty, stringStartsWith } from "./util/utils"; +import { Constants } from "./util/constants"; +import { AtomHandler } from "./util/atomHandler"; +import { each, isUndefined, isArray, isObject, isDate } from "./util/utils"; +const url = require("url"); +const xmlbuilder = require("xmlbuilder"); + +const atomHandler = new AtomHandler(); + +export class AtomResourceSerializerBase { + static setName(entry: any, nameProperty: any): any { + var parsedUrl: any = url.parse(entry[Constants.ATOM_METADATA_MARKER].id); + var parts = parsedUrl.pathname!.split("/"); + + for (var i = 0; i * 2 < parts.length - 1; i++) { + entry[nameProperty[i]] = parts[i * 2 + 1]; + } + } + + static _serialize(resourceName: any, resource: any, properties: any): any { + var content: any = {}; + content[resourceName] = { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" + } + }; + + if (resource) { + // Sort properties according to what is allowed by the service + each(properties, function(property: any): any { + if (!isUndefined(resource[property])) { + content[resourceName][property] = resource[property]; + } + }); + } + + return atomHandler.serializeEntry(content); + } + + static _parse(nameProperty: any, xml: any): any { + var result = atomHandler.parse(xml); + + if (!result) { + return undefined; + } + if (isArray(result)) { + each(result, function(entry: any): any { + AtomResourceSerializerBase.setName(entry, nameProperty); + }); + } else { + AtomResourceSerializerBase.setName(result, nameProperty); + } + return result; + } + + static serializeEntry(content: any, namespaces?: any, properties?: any): any { + var doc = xmlbuilder.create("entry").att("xmlns", "http://www.w3.org/2005/Atom"); + + each(namespaces, function(namespace: any): any { + doc = doc.att("xmlns:" + namespace.key, namespace.url); + }); + + if (properties) { + Object.keys(properties).forEach(function(property) { + doc = doc.ele(property, properties[property]).up(); + }); + } + + doc = doc.ele("updated", new Date().toISOString()).up(); + + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + + doc = AtomResourceSerializerBase._writeElementValue(doc, "content", content); + + return doc.doc().toString(); + } + + static _writeElementValue(parentElement: any, name: any, value: any): any { + var ignored = false; + var propertyTagName = name; + + if (!stringIsEmpty(value) && isObject(value) && !isDate(value)) { + if (Array.isArray(value) && value.length > 0) { + // Example: + // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] + // XML: hi therehello there + + Object.keys(value).forEach(function(i: any) { + parentElement = AtomResourceSerializerBase._writeElementValue( + parentElement, + name, + value[i] + ); + }); + + // For an array no element was actually added at this level, so skip uping level. + ignored = true; + } else if ( + value[Constants.XML_METADATA_MARKER] !== undefined && + value[Constants.XML_VALUE_MARKER] !== undefined + ) { + // Example: + // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } + // XML: hi there + + parentElement = parentElement.ele(propertyTagName); + if (!stringIsEmpty(value[Constants.XML_VALUE_MARKER])) { + if (stringStartsWith(value[Constants.XML_VALUE_MARKER], "hi therehello there + + parentElement = parentElement.ele(propertyTagName); + for (var propertyName in value) { + if ( + propertyName !== Constants.XML_METADATA_MARKER && + value.hasOwnProperty(propertyName) + ) { + parentElement = AtomResourceSerializerBase._writeElementValue( + parentElement, + propertyName, + value[propertyName] + ); + } + } + } + } else { + parentElement = parentElement.ele(propertyTagName); + if (!stringIsEmpty(value)) { + if (stringStartsWith(value.toString().trim(), "} The signed request object. + */ + signRequest(webResource: WebResource): any { + if (!webResource.headers) webResource.headers = new HttpHeaders(); + + var targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); + + let date = new Date(); + date.setMinutes(date.getMinutes() + 5); + var expirationDate = Math.round(date.valueOf() / 1000); + var signature = this._generateSignature(targetUri, expirationDate); + webResource.headers.set( + HeaderConstants.AUTHORIZATION, + util.format( + "SharedAccessSignature sig=%s&se=%s&skn=%s&sr=%s", + signature, + expirationDate, + this.keyName, + targetUri + ) + ); + + return Promise.resolve(webResource); + } +} diff --git a/sdk/core/core-http/lib/httpOperationResponse.ts b/sdk/core/core-http/lib/httpOperationResponse.ts index 9b30056b32df..26d325f712f5 100644 --- a/sdk/core/core-http/lib/httpOperationResponse.ts +++ b/sdk/core/core-http/lib/httpOperationResponse.ts @@ -29,7 +29,7 @@ declare global { * Stub declaration of the browser-only Blob type. * Full type information can be obtained by including "lib": ["dom"] in tsconfig.json. */ - interface Blob { } + interface Blob {} } /** @@ -52,6 +52,11 @@ export interface HttpOperationResponse extends HttpResponse { */ parsedBody?: any; + /** + * The error information in JSON or XML + */ + errorBody?: any; + /** * BROWSER ONLY * diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts new file mode 100644 index 000000000000..d15fe7e6f53c --- /dev/null +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { HttpOperationResponse } from "../httpOperationResponse"; +import { WebResource } from "../webResource"; +import { + BaseRequestPolicy, + RequestPolicy, + RequestPolicyFactory, + RequestPolicyOptions +} from "./requestPolicy"; +import { Constants } from "../util/constants"; +import { parseAtomXML } from "../util/xml"; +import { isString, extend, byteLength } from "../util/utils"; +import { ResourceSerializer } from "../resourceSerializer"; + +/** + * Create a new serialization RequestPolicyCreator that will serialize/deserialize + * HTTP request bodies as they pass through the HTTP pipeline. + */ +export function atomSerializationPolicy(): RequestPolicyFactory { + return { + create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => { + return new AtomSerializationPolicy(nextPolicy, options); + } + }; +} + +/** + * A RequestPolicy that will + * - serialize HTTP requests with input in JSON to ATOM based XML requests, and + * - deserialize the ATOM based XML responses as they pass through the HTTP pipeline. + */ +export class AtomSerializationPolicy extends BaseRequestPolicy { + constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptions) { + super(nextPolicy, options); + } + + public async sendRequest(request: WebResource): Promise { + let shouldParseResponse = false; + let serializer: ResourceSerializer; + if (request.atomXmlOperationSpec) { + serializer = request.atomXmlOperationSpec.serializer; + shouldParseResponse = request.atomXmlOperationSpec.shouldParseResponse; + if (request.body) { + request.body = serializer.serialize(JSON.parse(request.body)); + } + } + + return this._nextPolicy.sendRequest(request).then((response: HttpOperationResponse) => { + const parsedResponse: HttpOperationResponse = this.parseResponse(response); + + // Construct response with 'result' to be backward compatibile + const responseInCustomJson: any = { + error: parsedResponse.errorBody, + response: parsedResponse.parsedBody, + result: undefined + }; + responseInCustomJson.result = + shouldParseResponse && serializer + ? serializer.parse(responseInCustomJson.response) + : undefined; + + response.parsedBody = responseInCustomJson; + return response; + }); + } + + /** + * Process the response. + * @ignore + * + * @param {WebResource} webResource The web resource that made the request. + * @param {Response} response The response object. + * @return The normalized responseObject. + */ + private parseResponse(response: HttpOperationResponse): HttpOperationResponse { + const parsedResponse: HttpOperationResponse = this._parseXmlResponse(response); + + if (response.status >= 200 && response.status < 300 && response.errorBody == undefined) { + return response; + } + + const HttpResponseCodes: any = Constants.HttpResponseCodes; + + if (parsedResponse.errorBody == undefined) { + var code = Object.keys(HttpResponseCodes).filter(function(name: any): any { + if (HttpResponseCodes[name] === response.status) { + return name; + } + }); + + parsedResponse.errorBody = { error: { code: code[0] } }; + } + + var normalizedError = this._normalizeError(parsedResponse.errorBody, response); + parsedResponse.errorBody = normalizedError; + return parsedResponse; + } + + private _parseXmlResponse(response: HttpOperationResponse): HttpOperationResponse { + const parsedResponse = response; + try { + if (response.bodyAsText && byteLength(response.bodyAsText.toString()) > 0) { + parsedResponse.parsedBody = parseAtomXML(response.bodyAsText); + } + } catch (e) { + parsedResponse.errorBody = { + error: { code: "Given object is not an Atom XML response" } + }; + } + return parsedResponse; + } + + _normalizeError(error: any, response: HttpOperationResponse): any { + if (isString(error)) { + return new Error(error); + } else if (error) { + var normalizedError: any = {}; + + var odataErrorFormat = !!error["odata.error"]; + var errorProperties = error.Error || error.error || error["odata.error"] || error; + if (odataErrorFormat) { + for (var property in errorProperties) { + if (errorProperties.hasOwnProperty(property)) { + var value = null; + if ( + property === Constants.ODATA_ERROR_MESSAGE && + !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + ) { + if ( + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE] + ) { + value = + errorProperties[Constants.ODATA_ERROR_MESSAGE][ + Constants.ODATA_ERROR_MESSAGE_VALUE + ]; + } else { + value = "missing value in the message property of the odata error format"; + } + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + } + } + } else { + for (var property in errorProperties) { + if (errorProperties.hasOwnProperty(property)) { + var value = null; + if (property !== "$") { + if (errorProperties[property] && errorProperties[property]["_"]) { + value = errorProperties[property]["_"]; + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + } + } + } + } + var errorMessage = normalizedError.code; + if (normalizedError.detail) { + errorMessage += " - " + normalizedError.detail; + } + + if (response) { + if (response.status) { + normalizedError.statusCode = response.status; + } + + if (response.headers && response.headers.get("x-ms-request-id")) { + normalizedError.requestId = response.headers.get("x-ms-request-id"); + } + } + + var errorObject = new Error(errorMessage); + return extend(errorObject, normalizedError); + } + + return undefined; + } +} diff --git a/sdk/core/core-http/lib/resourceSerializer.ts b/sdk/core/core-http/lib/resourceSerializer.ts new file mode 100644 index 000000000000..cccdd1e68922 --- /dev/null +++ b/sdk/core/core-http/lib/resourceSerializer.ts @@ -0,0 +1,21 @@ +// +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +export abstract class ResourceSerializer { + abstract serialize(resource: any): any; + + abstract parse(xml: any): any; +} diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts new file mode 100644 index 000000000000..6575932d0448 --- /dev/null +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -0,0 +1,199 @@ +// +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { Constants } from "./constants"; +import util from "util"; +import { isArray, each, stringIsEmpty, stringStartsWith, isDate, isObject } from "./utils"; +const xmlbuilder = require("xmlbuilder"); + +export class AtomHandler { + parseEntryResult(entry: any): any { + var contentElementName = Object.keys(entry.content).filter(function(key) { + return key !== Constants.XML_METADATA_MARKER; + })[0]; + + delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; + var result = entry.content[contentElementName]; + + if (result) { + if (entry[Constants.XML_METADATA_MARKER]) { + result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; + } else { + result[Constants.ATOM_METADATA_MARKER] = {}; + } + + result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; + + for (var property in entry) { + if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { + result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; + } + } + } + + return result; + } + + parseFeedResult(feed: any): any { + var result = []; + var self = this; + if (feed.entry) { + if (isArray(feed.entry)) { + each(feed.entry, function(entry: any) { + result.push(self.parseEntryResult(entry)); + }); + } else { + result.push(self.parseEntryResult(feed.entry)); + } + } + return result; + } + + parse(xml: any): any { + var self = this; + if (!xml) { + return; + } + + if (xml.feed) { + return self.parseFeedResult(xml.feed); + } + + if (xml.entry) { + return self.parseEntryResult(xml.entry); + } + + throw new Error("Unrecognized result " + util.inspect(xml)); + } + + /** + * @param {object} content The content payload as it is to be serialized. It should include any root node(s). + * @param {array} namespaces An array of top level namespaces to be defined. + */ + serializeEntry(content: any, namespaces?: any, properties?: any): any { + var doc = xmlbuilder.create(); + + doc = doc + .begin("entry", { version: "1.0", encoding: "utf-8", standalone: "yes" }) + .att("xmlns", "http://www.w3.org/2005/Atom"); + + each(namespaces, function(namespace: any): any { + doc = doc.att("xmlns:" + namespace.key, namespace.url); + }); + + if (properties) { + Object.keys(properties).forEach(function(property) { + doc = doc.ele(property, properties[property]).up(); + }); + } + + doc = doc.ele("updated", new Date().toISOString()).up(); + + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + + doc = this._writeElementValue(doc, "content", content); + + return doc.doc().toString(); + } + + /* + * Writes a single property for an entry or complex type. + * + * @param {object} parentElement Parent DOM element under which the property should be added. + * @param {string} name Property name. + * @param {object} value Property value. + * @return {object} The current DOM element. + * + * {Deprecated} + */ + _writeElementValue(parentElement: any, name: any, value: any): any { + var self = this; + var ignored = false; + var propertyTagName = name; + + if (!stringIsEmpty(value) && isObject(value) && !isDate(value)) { + if (Array.isArray(value) && value.length > 0) { + // Example: + // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] + // XML: hi therehello there + + Object.keys(value).forEach(function(i: any) { + parentElement = self._writeElementValue(parentElement, name, value[i]); + }); + + // For an array no element was actually added at this level, so skip uping level. + ignored = true; + } else if ( + value[Constants.XML_METADATA_MARKER] !== undefined && + value[Constants.XML_VALUE_MARKER] !== undefined + ) { + // Example: + // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } + // XML: hi there + + parentElement = parentElement.ele(propertyTagName); + if (!stringIsEmpty(value[Constants.XML_VALUE_MARKER])) { + if (stringStartsWith(value[Constants.XML_VALUE_MARKER], "hi therehello there + + parentElement = parentElement.ele(propertyTagName); + for (var propertyName in value) { + if ( + propertyName !== Constants.XML_METADATA_MARKER && + value.hasOwnProperty(propertyName) + ) { + parentElement = self._writeElementValue( + parentElement, + propertyName, + value[propertyName] + ); + } + } + } + } else { + parentElement = parentElement.ele(propertyTagName); + if (!stringIsEmpty(value)) { + if (stringStartsWith(value.toString().trim(), ", kickst * * @returns {object} Returns the merged target object. */ -export function mergeObjects(source: { [key: string]: any; }, target: { [key: string]: any; }) { +export function mergeObjects(source: { [key: string]: any }, target: { [key: string]: any }) { Object.keys(source).forEach((key) => { target[key] = source[key]; }); @@ -168,7 +180,12 @@ export interface ServiceCallback { * @param {WebResource} [request] The raw/actual request sent to the server if an error did not occur. * @param {HttpOperationResponse} [response] The raw/actual response from the server if an error did not occur. */ - (err: Error | RestError | null, result?: TResult, request?: WebResource, response?: HttpOperationResponse): void; + ( + err: Error | RestError | null, + result?: TResult, + request?: WebResource, + response?: HttpOperationResponse + ): void; } /** @@ -182,11 +199,14 @@ export function promiseToCallback(promise: Promise): Function { throw new Error("The provided input is not a Promise."); } return (cb: Function): void => { - promise.then((data: any) => { - cb(undefined, data); - }, (err: Error) => { - cb(err); - }); + promise.then( + (data: any) => { + cb(undefined, data); + }, + (err: Error) => { + cb(err); + } + ); }; } @@ -200,11 +220,14 @@ export function promiseToServiceCallback(promise: Promise): void => { - promise.then((data: HttpOperationResponse) => { - process.nextTick(cb, undefined, data.parsedBody as T, data.request, data); - }, (err: Error) => { - process.nextTick(cb, err); - }); + promise.then( + (data: HttpOperationResponse) => { + process.nextTick(cb, undefined, data.parsedBody as T, data.request, data); + }, + (err: Error) => { + process.nextTick(cb, err); + } + ); }; } @@ -221,8 +244,8 @@ export function prepareXMLRootList(obj: any, elementName: string) { * @param {Array} sourceCtors An array of source objects from which the properties need to be taken. */ export function applyMixins(targetCtor: any, sourceCtors: any[]): void { - sourceCtors.forEach(sourceCtors => { - Object.getOwnPropertyNames(sourceCtors.prototype).forEach(name => { + sourceCtors.forEach((sourceCtors) => { + Object.getOwnPropertyNames(sourceCtors.prototype).forEach((name) => { targetCtor.prototype[name] = sourceCtors.prototype[name]; }); }); @@ -246,16 +269,265 @@ export function isDuration(value: string): boolean { * @param {string} replaceValue The value to replace searchValue with in the value argument. * @returns {string | undefined} The value where each instance of searchValue was replaced with replacedValue. */ -export function replaceAll(value: string | undefined, searchValue: string, replaceValue: string): string | undefined { +export function replaceAll( + value: string | undefined, + searchValue: string, + replaceValue: string +): string | undefined { return !value || !searchValue ? value : value.split(searchValue).join(replaceValue || ""); } /** - * Determines whether the given enity is a basic/primitive type + * Determines whether the given entity is a basic/primitive type * (string, number, boolean, null, undefined). - * @param value Any entity - * @return boolean - true is it is primitive type, false otherwise. + * @param {any} value Any entity + * @return {boolean} - true is it is primitive type, false otherwise. */ export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } + +/** + * Determines whether the given `value` is an empty string or not. + * @param {any} value Any entity + * @return {boolean} - true if it is equivalent to an empty string, false otherwise. + */ +export function stringIsEmpty(value: any) { + return isNull(value) || isUndefined(value) || value === ""; +} + +/** + * Checks if given `text` starts with the specified `prefix` + * @param text Input string + * @return {boolean} - true if yes, false otherwise. + */ +export function stringStartsWith(text: string, prefix: string) { + if (isNull(prefix)) { + return true; + } + + return text.substr(0, prefix.length) === prefix; +} + +/** + * Returns the number of keys (properties) in an object. + * + * @param {object} value The object which keys are to be counted. + * @return {number} The number of keys in the object. + */ +export function objectKeysLength(value: any) { + if (!value) { + return 0; + } + + return keys(value).length; +} + +/** + * Returns the name of the first property in an object. + * + * @param {object} value The object which key is to be returned. + * @return {number} The name of the first key in the object. + */ +export function objectFirstKey(value: any) { + if (value && Object.keys(value).length > 0) { + return Object.keys(value)[0]; + } + + // Object has no properties + return null; +} + +/** + * Determines whether the given `value` is a null object or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export function objectIsNull(value: any) { + return isNull(value) || isUndefined(value); +} + +/** + * Determines whether the given `value` is a `Date` object or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export function isDate(value: any) { + return Object.prototype.toString.call(value) == "[object Date]"; +} + +/** + * Determines whether the given `value` is a `string` object or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export function isString(value: any) { + return Object.prototype.toString.call(value) == "[object String]"; +} + +/** + * Determines whether the given `value` is a `Array` object or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export const isArray = + Array.isArray || + function(value: any) { + return Object.prototype.toString.call(value) == "[object Array]"; + }; + +/** + * Determines whether the given `value` is a `Object` or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export const isObject = function(value: any) { + return value === Object(value); +}; + +/** + * Determines whether the given `value` is an undefined entity or not. + * @param {any} value Any entity + * @return {boolean} - true if yes, false otherwise. + */ +export const isUndefined = function(value: any) { + return value === void 0; +}; + +/** + * Utility to iterate over given entity's values. + * @param {any} obj - The object to execute operation(s) on. + * @param {any} iterator - The iterator callback to use + * @param {any} context - Optional context for use with iterator + * @return {any} - the final extended object + */ +export const each = function(obj: any, iterator: any, context?: any) { + if (obj == null) return; + if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === {}) return; + } + } else { + for (var key in obj) { + if (has(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === {}) return; + } + } + } +}; + +/** + * Extends given object `obj` with the passed in `source` object. + * @param {any} obj + * @param {any} source + * @return {any} - the final extended object + */ +export const extend = function(obj: any, source: any) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + return obj; +}; + +// Private helper utilities +const has = function(obj: any, key: any) { + return Object.prototype.hasOwnProperty.call(obj, key); +}; + +const isNull = function(value: any) { + return value === null; +}; + +const keys = + Object.keys || + function(obj: any) { + if (obj !== Object(obj)) throw new TypeError("Invalid object"); + var keys = []; + for (var key in obj) if (has(obj, key)) keys[keys.length] = key; + return keys; + }; + +export function byteLength(string: any) { + return utf8ToBytes(string).length; // assume utf8 +} + +function utf8ToBytes(string: any, units?: any) { + units = units || Infinity; + var codePoint; + var length = string.length; + var leadSurrogate = null; + var bytes = []; + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + + // is surrogate component + if (codePoint > 0xd7ff && codePoint < 0xe000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xdbff) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); + continue; + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); + continue; + } + + // valid lead + leadSurrogate = codePoint; + + continue; + } + + // 2 leads in a row + if (codePoint < 0xdc00) { + if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); + leadSurrogate = codePoint; + continue; + } + + // valid surrogate pair + codePoint = (((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000; + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); + } + + leadSurrogate = null; + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break; + bytes.push(codePoint); + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break; + bytes.push((codePoint >> 0x6) | 0xc0, (codePoint & 0x3f) | 0x80); + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break; + bytes.push( + (codePoint >> 0xc) | 0xe0, + ((codePoint >> 0x6) & 0x3f) | 0x80, + (codePoint & 0x3f) | 0x80 + ); + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break; + bytes.push( + (codePoint >> 0x12) | 0xf0, + ((codePoint >> 0xc) & 0x3f) | 0x80, + ((codePoint >> 0x6) & 0x3f) | 0x80, + (codePoint & 0x3f) | 0x80 + ); + } else { + throw new Error("Invalid code point"); + } + } + + return bytes; +} diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 059b329d141a..09d26b7e70fa 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -16,7 +16,8 @@ export function parseXML(str: string): Promise { let errorNS = ""; try { - errorNS = parser.parseFromString("INVALID", "text/xml").getElementsByTagName("parsererror")[0].namespaceURI!; + errorNS = parser.parseFromString("INVALID", "text/xml").getElementsByTagName("parsererror")[0] + .namespaceURI!; } catch (ignored) { // Most browsers will return a document containing , but IE will throw. } @@ -48,7 +49,12 @@ function domToObject(node: Node): any { const childNodeCount: number = node.childNodes.length; const firstChildNode: Node = node.childNodes[0]; - const onlyChildTextValue: string | undefined = (firstChildNode && childNodeCount === 1 && firstChildNode.nodeType === Node.TEXT_NODE && firstChildNode.nodeValue) || undefined; + const onlyChildTextValue: string | undefined = + (firstChildNode && + childNodeCount === 1 && + firstChildNode.nodeType === Node.TEXT_NODE && + firstChildNode.nodeValue) || + undefined; const elementWithAttributes: Element | undefined = asElementWithAttributes(node); if (elementWithAttributes) { @@ -93,12 +99,14 @@ const doc = document.implementation.createDocument(null, null, null); const serializer = new XMLSerializer(); export function stringifyXML(obj: any, opts?: { rootName?: string }) { - const rootName = opts && opts.rootName || "root"; + const rootName = (opts && opts.rootName) || "root"; const dom = buildNode(obj, rootName)[0]; - return '' + serializer.serializeToString(dom); + return ( + '' + serializer.serializeToString(dom) + ); } -function buildAttributes(attrs: { [key: string]: { toString(): string; } }): Attr[] { +function buildAttributes(attrs: { [key: string]: { toString(): string } }): Attr[] { const result = []; for (const key of Object.keys(attrs)) { const attr = doc.createAttribute(key); @@ -113,8 +121,7 @@ function buildNode(obj: any, elementName: string): Node[] { const elem = doc.createElement(elementName); elem.textContent = obj.toString(); return [elem]; - } - else if (Array.isArray(obj)) { + } else if (Array.isArray(obj)) { const result = []; for (const arrayElem of obj) { for (const child of buildNode(arrayElem, elementName)) { @@ -136,8 +143,15 @@ function buildNode(obj: any, elementName: string): Node[] { } } return [elem]; - } - else { + } else { throw new Error(`Illegal value passed to buildObject: ${obj}`); } } + +export function parseAtomXML(body: any): any { + throw new Error(`parseAtomXML(${body}) is not supported in browser yet.`); +} + +export function parseStringError(body: any): any { + throw new Error(`parseStringError(${body}) is not supported in browser yet.`); +} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 575d9ab00da3..0a15b008e2ad 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -35,3 +35,45 @@ export function parseXML(str: string): Promise { } }); } + +export function parseAtomXML(body: any): any { + var parsed; + var parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); + parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { + if (err) { + throw err; + } else { + parsed = parsedBody; + } + }); + return parsed; +} + +/** + * Gets the default xml2js settings applicable for Atom based XML operations. + * @ignore + * @return {object} The default settings + */ +function _getDefaultSettingsForAtomXmlOperations(): any { + var xml2jsSettings = xml2js.defaults["0.2"]; + xml2jsSettings.normalize = false; + xml2jsSettings.trim = false; + xml2jsSettings.attrkey = "$"; + xml2jsSettings.charkey = "_"; + xml2jsSettings.explicitArray = false; + xml2jsSettings.ignoreAttrs = true; + + return xml2jsSettings; +} + +/** + * + * @param str Helper utility to clean up unintended characters that get appended by OS. + */ +function _removeBOM(str: any) { + if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { + str = str.substring(1); + } + + return str; +} diff --git a/sdk/core/core-http/lib/webResource.ts b/sdk/core/core-http/lib/webResource.ts index cac837cae01c..c01ff5efba28 100644 --- a/sdk/core/core-http/lib/webResource.ts +++ b/sdk/core/core-http/lib/webResource.ts @@ -9,9 +9,23 @@ import { HttpOperationResponse } from "./httpOperationResponse"; import { OperationResponse } from "./operationResponse"; import { ProxySettings } from "./serviceClient"; import { AbortSignalLike } from "@azure/abort-controller"; - -export type HttpMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "TRACE"; -export type HttpRequestBody = Blob | string | ArrayBuffer | ArrayBufferView | (() => NodeJS.ReadableStream); +import { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; + +export type HttpMethods = + | "GET" + | "PUT" + | "POST" + | "DELETE" + | "PATCH" + | "HEAD" + | "OPTIONS" + | "TRACE"; +export type HttpRequestBody = + | Blob + | string + | ArrayBuffer + | ArrayBufferView + | (() => NodeJS.ReadableStream); /** * Fired in response to upload or download progress. @@ -20,7 +34,7 @@ export type TransferProgressEvent = { /** * The number of bytes loaded so far. */ - loadedBytes: number + loadedBytes: number; }; /** @@ -50,10 +64,14 @@ export class WebResource { * HttpOperationResponse combination. If this is undefined, then a simple status code lookup will * be used. */ - operationResponseGetter?: (operationSpec: OperationSpec, response: HttpOperationResponse) => (undefined | OperationResponse); + operationResponseGetter?: ( + operationSpec: OperationSpec, + response: HttpOperationResponse + ) => undefined | OperationResponse; formData?: any; - query?: { [key: string]: any; }; + query?: { [key: string]: any }; operationSpec?: OperationSpec; + atomXmlOperationSpec?: AtomXmlOperationSpec; withCredentials: boolean; timeout: number; proxySettings?: ProxySettings; @@ -71,8 +89,8 @@ export class WebResource { url?: string, method?: HttpMethods, body?: any, - query?: { [key: string]: any; }, - headers?: { [key: string]: any; } | HttpHeaders, + query?: { [key: string]: any }, + headers?: { [key: string]: any } | HttpHeaders, streamResponseBody?: boolean, withCredentials?: boolean, abortSignal?: AbortSignalLike, @@ -80,12 +98,12 @@ export class WebResource { onUploadProgress?: (progress: TransferProgressEvent) => void, onDownloadProgress?: (progress: TransferProgressEvent) => void, proxySettings?: ProxySettings, - keepAlive?: boolean) { - + keepAlive?: boolean + ) { this.streamResponseBody = streamResponseBody; this.url = url || ""; this.method = method || "GET"; - this.headers = (headers instanceof HttpHeaders ? headers : new HttpHeaders(headers)); + this.headers = headers instanceof HttpHeaders ? headers : new HttpHeaders(headers); this.body = body; this.query = query; this.formData = undefined; @@ -127,18 +145,22 @@ export class WebResource { } if (options.url && options.pathTemplate) { - throw new Error("options.url and options.pathTemplate are mutually exclusive. Please provide exactly one of them."); + throw new Error( + "options.url and options.pathTemplate are mutually exclusive. Please provide exactly one of them." + ); } - - if ((options.pathTemplate == undefined || typeof options.pathTemplate.valueOf() !== "string") && (options.url == undefined || typeof options.url.valueOf() !== "string")) { + if ( + (options.pathTemplate == undefined || typeof options.pathTemplate.valueOf() !== "string") && + (options.url == undefined || typeof options.url.valueOf() !== "string") + ) { throw new Error("Please provide exactly one of options.pathTemplate or options.url."); } // set the url if it is provided. if (options.url) { if (typeof options.url !== "string") { - throw new Error("options.url must be of type \"string\"."); + throw new Error('options.url must be of type "string".'); } this.url = options.url; } @@ -147,35 +169,55 @@ export class WebResource { if (options.method) { const validMethods = ["GET", "PUT", "HEAD", "DELETE", "OPTIONS", "POST", "PATCH", "TRACE"]; if (validMethods.indexOf(options.method.toUpperCase()) === -1) { - throw new Error("The provided method \"" + options.method + "\" is invalid. Supported HTTP methods are: " + JSON.stringify(validMethods)); + throw new Error( + 'The provided method "' + + options.method + + '" is invalid. Supported HTTP methods are: ' + + JSON.stringify(validMethods) + ); } } - this.method = (options.method.toUpperCase() as HttpMethods); + this.method = options.method.toUpperCase() as HttpMethods; // construct the url if path template is provided if (options.pathTemplate) { const { pathTemplate, pathParameters } = options; if (typeof pathTemplate !== "string") { - throw new Error("options.pathTemplate must be of type \"string\"."); + throw new Error('options.pathTemplate must be of type "string".'); } if (!options.baseUrl) { options.baseUrl = "https://management.azure.com"; } const baseUrl = options.baseUrl; - let url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + (pathTemplate.startsWith("/") ? pathTemplate.slice(1) : pathTemplate); - const segments = url.match(/({\w*\s*\w*})/ig); + let url = + baseUrl + + (baseUrl.endsWith("/") ? "" : "/") + + (pathTemplate.startsWith("/") ? pathTemplate.slice(1) : pathTemplate); + const segments = url.match(/({\w*\s*\w*})/gi); if (segments && segments.length) { if (!pathParameters) { - throw new Error(`pathTemplate: ${pathTemplate} has been provided. Hence, options.pathParameters must also be provided.`); + throw new Error( + `pathTemplate: ${pathTemplate} has been provided. Hence, options.pathParameters must also be provided.` + ); } - segments.forEach(function (item) { + segments.forEach(function(item) { const pathParamName = item.slice(1, -1); const pathParam = (pathParameters as { [key: string]: any })[pathParamName]; - if (pathParam === null || pathParam === undefined || !(typeof pathParam === "string" || typeof pathParam === "object")) { - throw new Error(`pathTemplate: ${pathTemplate} contains the path parameter ${pathParamName}` + - ` however, it is not present in ${pathParameters} - ${JSON.stringify(pathParameters, undefined, 2)}.` + - `The value of the path parameter can either be a "string" of the form { ${pathParamName}: "some sample value" } or ` + - `it can be an "object" of the form { "${pathParamName}": { value: "some sample value", skipUrlEncoding: true } }.`); + if ( + pathParam === null || + pathParam === undefined || + !(typeof pathParam === "string" || typeof pathParam === "object") + ) { + throw new Error( + `pathTemplate: ${pathTemplate} contains the path parameter ${pathParamName}` + + ` however, it is not present in ${pathParameters} - ${JSON.stringify( + pathParameters, + undefined, + 2 + )}.` + + `The value of the path parameter can either be a "string" of the form { ${pathParamName}: "some sample value" } or ` + + `it can be an "object" of the form { "${pathParamName}": { value: "some sample value", skipUrlEncoding: true } }.` + ); } if (typeof pathParam.valueOf() === "string") { @@ -184,7 +226,9 @@ export class WebResource { if (typeof pathParam.valueOf() === "object") { if (!pathParam.value) { - throw new Error(`options.pathParameters[${pathParamName}] is of type "object" but it does not contain a "value" property.`); + throw new Error( + `options.pathParameters[${pathParamName}] is of type "object" but it does not contain a "value" property.` + ); } if (pathParam.skipUrlEncoding) { url = url.replace(item, pathParam.value); @@ -201,9 +245,11 @@ export class WebResource { if (options.queryParameters) { const queryParameters = options.queryParameters; if (typeof queryParameters !== "object") { - throw new Error(`options.queryParameters must be of type object. It should be a JSON object ` + - `of "query-parameter-name" as the key and the "query-parameter-value" as the value. ` + - `The "query-parameter-value" may be fo type "string" or an "object" of the form { value: "query-parameter-value", skipUrlEncoding: true }.`); + throw new Error( + `options.queryParameters must be of type object. It should be a JSON object ` + + `of "query-parameter-name" as the key and the "query-parameter-value" as the value. ` + + `The "query-parameter-value" may be fo type "string" or an "object" of the form { value: "query-parameter-value", skipUrlEncoding: true }.` + ); } // append question mark if it is not present in the url if (this.url && this.url.indexOf("?") === -1) { @@ -219,10 +265,11 @@ export class WebResource { if (typeof queryParam === "string") { queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam)); this.query[queryParamName] = encodeURIComponent(queryParam); - } - else if (typeof queryParam === "object") { + } else if (typeof queryParam === "object") { if (!queryParam.value) { - throw new Error(`options.queryParameters[${queryParamName}] is of type "object" but it does not contain a "value" property.`); + throw new Error( + `options.queryParameters[${queryParamName}] is of type "object" but it does not contain a "value" property.` + ); } if (queryParam.skipUrlEncoding) { queryParams.push(queryParamName + "=" + queryParam.value); @@ -233,7 +280,7 @@ export class WebResource { } } } - }// end-of-for + } // end-of-for // append the queryString this.url += queryParams.join("&"); } @@ -272,7 +319,11 @@ export class WebResource { } } else { if (options.serializationMapper) { - this.body = new Serializer(options.mappers).serialize(options.serializationMapper, options.body, "requestBody"); + this.body = new Serializer(options.mappers).serialize( + options.serializationMapper, + options.body, + "requestBody" + ); } if (!options.disableJsonStringifyOnBody) { this.body = JSON.stringify(options.body); @@ -303,7 +354,8 @@ export class WebResource { this.abortSignal, this.timeout, this.onUploadProgress, - this.onDownloadProgress); + this.onDownloadProgress + ); if (this.formData) { result.formData = this.formData; @@ -313,6 +365,10 @@ export class WebResource { result.operationSpec = this.operationSpec; } + if (this.atomXmlOperationSpec) { + result.atomXmlOperationSpec = this.atomXmlOperationSpec; + } + if (this.shouldDeserialize) { result.shouldDeserialize = this.shouldDeserialize; } diff --git a/sdk/core/core-http/package.json b/sdk/core/core-http/package.json index 790f7301dc31..5955a1d9b520 100644 --- a/sdk/core/core-http/package.json +++ b/sdk/core/core-http/package.json @@ -114,6 +114,7 @@ "@azure/core-auth": "1.0.0-preview.3", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.1", + "buffer": "^5.2.1", "form-data": "^2.5.0", "node-fetch": "^2.6.0", "process": "^0.11.10", @@ -121,7 +122,8 @@ "tslib": "^1.9.3", "tunnel": "^0.0.6", "uuid": "^3.3.2", - "xml2js": "^0.4.19" + "xml2js": "^0.4.19", + "xmlbuilder": "^0.4.3" }, "devDependencies": { "@azure/logger-js": "^1.0.2", diff --git a/sdk/core/core-http/rollup.config.ts b/sdk/core/core-http/rollup.config.ts index 0e73c2362b9d..f4316ce5f1ae 100644 --- a/sdk/core/core-http/rollup.config.ts +++ b/sdk/core/core-http/rollup.config.ts @@ -33,7 +33,7 @@ const nodeConfig = { "tslib", "tunnel", "uuid/v4", - "xml2js", + "xml2js" ], output: { file: "./dist/coreHttp.node.js", @@ -43,7 +43,7 @@ const nodeConfig = { }, plugins: [ nodeResolve({ - mainFields: ["module", "main"], + mainFields: ["module", "main"] }), commonjs(), sourcemaps(), @@ -74,10 +74,11 @@ const browserConfig = { "./policies/msRestUserAgentPolicy": "./policies/msRestUserAgentPolicy.browser", "./policies/proxyPolicy": "./policies/proxyPolicy.browser", "./util/xml": "./util/xml.browser", - "./util/base64": "./util/base64.browser", + "./util/base64": "./util/base64.browser" }), nodeResolve({ - mainFields: ["module", "main", "browser"] + mainFields: ["module", "browser"], + preferBuiltins: true }), commonjs(), sourcemaps(), diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts new file mode 100644 index 000000000000..aafb2be4fe09 --- /dev/null +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { assert } from "chai"; +import { HttpHeaders } from "../../lib/httpHeaders"; +import { HttpOperationResponse } from "../../lib/httpOperationResponse"; +import { + HttpClient, + AtomXmlOperationSpec, + AtomResourceSerializerBase, + ResourceSerializer +} from "../../lib/coreHttp"; +import { + AtomSerializationPolicy, + atomSerializationPolicy +} from "../../lib/policies/atomSerializationPolicy"; +import { RequestPolicy, RequestPolicyOptions } from "../../lib/policies/requestPolicy"; +import { WebResource } from "../../lib/webResource"; + +describe("atomSerializationPolicy", function() { + const mockPolicy: RequestPolicy = { + sendRequest(request: WebResource): Promise { + return Promise.resolve({ + request: request, + status: 200, + headers: new HttpHeaders() + }); + } + }; + + it(`should not modify a request that has no request body serializer`, async function() { + const atomSerializationPolicy = new AtomSerializationPolicy( + mockPolicy, + new RequestPolicyOptions() + ); + + const request = createRequest(); + request.body = "hello there!"; + + await atomSerializationPolicy.sendRequest(request); + assert.strictEqual(request.body, "hello there!"); + }); + + it("should return an error if receiving a non-XML response body", async function() { + const request: WebResource = createRequest(); + const mockClient: HttpClient = { + sendRequest: (req) => + Promise.resolve({ + request: req, + status: 200, + headers: new HttpHeaders({ "Content-Type": "application/json" }), + bodyAsText: `{ "simple": "JSONobject" }` + }) + }; + + const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); + const response = await policy.sendRequest(request); + assert.deepEqual(response.bodyAsText, `{ "simple": "JSONobject" }`); + assert.deepEqual(response.parsedBody.error.code, "Given object is not an Atom XML response"); + }); + + it("with xml response body, application/xml content-type and AtomXMLOperationSpec", async function() { + const request: WebResource = createRequest({ + serializer: new MockSerializer(), + shouldParseResponse: false + }); + + const expectedResult = { + entry: { + author: { + name: "servicebuslocalperftestspremium1" + }, + content: { + QueueDescription: { + LockDuration: "PT2M", + MaxSizeInMegabytes: "1024" + } + }, + id: + "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", + title: "testQueuePath4" + } + }; + + const mockClient: HttpClient = { + sendRequest: (req) => + Promise.resolve({ + request: req, + status: 200, + headers: new HttpHeaders({ + "content-type": "application/xml" + }), + bodyAsText: `https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024`, + parsedBody: `https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024` + }) + }; + + const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); + const response = await policy.sendRequest(request); + assert.deepEqual(response.parsedBody, getCustomResult(undefined, undefined, expectedResult)); + }); +}); + +function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource { + const request = new WebResource(); + request.atomXmlOperationSpec = atomXmlOperationSpec; + return request; +} + +function getCustomResult(error: any, result: any, response: any): any { + return { + error: error, + result: result, + response: response + }; +} + +class MockSerializer extends ResourceSerializer { + serialize(resource: any): any { + var properties = ["LockDuration", "MaxSizeInMegabytes"]; + + return AtomResourceSerializerBase._serialize("QueueDescription", resource, properties); + } + + parse(xml: any): any { + return AtomResourceSerializerBase._parse(["QueueName"], xml); + } +} From dfa9f569ab03c433903b27e5b4ffb90b91ab8529 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 27 Aug 2019 16:06:35 -0700 Subject: [PATCH 02/72] Minor refactor / simplification of XML serialization code --- sdk/core/core-http/lib/util/atomHandler.ts | 105 +++++++++++---------- sdk/core/core-http/lib/util/xml.browser.ts | 8 +- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index 6575932d0448..0a27dfce3b8e 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -20,63 +20,26 @@ import { isArray, each, stringIsEmpty, stringStartsWith, isDate, isObject } from const xmlbuilder = require("xmlbuilder"); export class AtomHandler { - parseEntryResult(entry: any): any { - var contentElementName = Object.keys(entry.content).filter(function(key) { - return key !== Constants.XML_METADATA_MARKER; - })[0]; - - delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; - var result = entry.content[contentElementName]; - - if (result) { - if (entry[Constants.XML_METADATA_MARKER]) { - result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; - } else { - result[Constants.ATOM_METADATA_MARKER] = {}; - } - - result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; - - for (var property in entry) { - if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { - result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; - } - } - } - - return result; - } - - parseFeedResult(feed: any): any { - var result = []; - var self = this; - if (feed.entry) { - if (isArray(feed.entry)) { - each(feed.entry, function(entry: any) { - result.push(self.parseEntryResult(entry)); - }); - } else { - result.push(self.parseEntryResult(feed.entry)); - } - } - return result; - } - - parse(xml: any): any { + /** + * Utility to deserialize the given content even further based on + * if it's a single `entry` or `feed` + * @param {object} xmlInJson + * */ + parse(xmlInJson: any): any { var self = this; - if (!xml) { + if (!xmlInJson) { return; } - if (xml.feed) { - return self.parseFeedResult(xml.feed); + if (xmlInJson.feed) { + return self.parseFeedResult(xmlInJson.feed); } - if (xml.entry) { - return self.parseEntryResult(xml.entry); + if (xmlInJson.entry) { + return self.parseEntryResult(xmlInJson.entry); } - throw new Error("Unrecognized result " + util.inspect(xml)); + throw new Error("Unrecognized result " + util.inspect(xmlInJson)); } /** @@ -119,7 +82,7 @@ export class AtomHandler { * * {Deprecated} */ - _writeElementValue(parentElement: any, name: any, value: any): any { + private _writeElementValue(parentElement: any, name: any, value: any): any { var self = this; var ignored = false; var propertyTagName = name; @@ -196,4 +159,46 @@ export class AtomHandler { return parentElement; } + + private parseEntryResult(entry: any): any { + var contentElementName = Object.keys(entry.content).filter(function(key) { + return key !== Constants.XML_METADATA_MARKER; + })[0]; + + delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; + var result = entry.content[contentElementName]; + + if (result) { + if (entry[Constants.XML_METADATA_MARKER]) { + result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; + } else { + result[Constants.ATOM_METADATA_MARKER] = {}; + } + + result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; + + for (var property in entry) { + if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { + result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; + } + } + } + + return result; + } + + private parseFeedResult(feed: any): any { + var result = []; + var self = this; + if (feed.entry) { + if (isArray(feed.entry)) { + each(feed.entry, function(entry: any) { + result.push(self.parseEntryResult(entry)); + }); + } else { + result.push(self.parseEntryResult(feed.entry)); + } + } + return result; + } } diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 09d26b7e70fa..0f26d20eb8f6 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -149,9 +149,7 @@ function buildNode(obj: any, elementName: string): Node[] { } export function parseAtomXML(body: any): any { - throw new Error(`parseAtomXML(${body}) is not supported in browser yet.`); -} - -export function parseStringError(body: any): any { - throw new Error(`parseStringError(${body}) is not supported in browser yet.`); + const dom = parser.parseFromString(body, "text/xml"); + throwIfError(dom); + return domToObject(dom.childNodes[0]); } From e9dbea0622d585e50ab16d9c09f3cbf2ae57bdf8 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 27 Aug 2019 16:08:21 -0700 Subject: [PATCH 03/72] Add in pnpm-lock.yaml file --- common/config/rush/pnpm-lock.yaml | 57 ++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 75da21dd8639..fe5101ce630b 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -165,6 +165,7 @@ dependencies: tunnel: 0.0.6 typescript: 3.5.3 uglify-js: 3.6.0 + underscore: 1.4.4 url: 0.11.0 util: 0.12.1 uuid: 3.3.3 @@ -174,6 +175,7 @@ dependencies: ws: 7.1.2 xhr-mock: 2.5.0 xml2js: 0.4.19 + xmlbuilder: 0.4.3 yargs: 13.3.0 yarn: 1.17.3 lockfileVersion: 5.1 @@ -9024,6 +9026,10 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + /underscore/1.4.4: + dev: false + resolution: + integrity: sha1-YaajIBBiKvoHljvzJSA88SI51gQ= /underscore/1.8.3: dev: false resolution: @@ -9525,6 +9531,12 @@ packages: dev: false resolution: integrity: sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + /xmlbuilder/0.4.3: + dev: false + engines: + node: '>=0.2.0' + resolution: + integrity: sha1-xGFLp04K0ZbmCcknLNnh3bKKilg= /xmlbuilder/8.2.2: dev: false engines: @@ -9793,7 +9805,7 @@ packages: dev: false name: '@rush-temp/abort-controller' resolution: - integrity: sha512-bOazCplSYAusToKu3B9vUnNASGvMSR9Yyj4i1PFTGdOfMyd5t+VZcS6RgEdtcAr+6MoUwJ230UkC/7JZ+HkdVQ== + integrity: sha512-W9CsoX+0a+9AAHje89SaMJSq4zFtlcVwA8KRQR6nf+e0aSBjmIiU4NAZUfRwvXE11vWhjo+YUcV2+ISBt/UvWQ== tarball: 'file:projects/abort-controller.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': @@ -9861,7 +9873,7 @@ packages: dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-zOQxTAzv2RDm8YmYZ8Tr+y82OmJANT0b3iJuBg+e02gcCSAS7N57zjeaZYSjq6dNEND7Jseo+xVZ/QdDNVGIsA== + integrity: sha512-jJ88adCOOKofY9LnfVCihOXMnB467Q3PLZuj4GmJpM51DyFx0KdCic1n3TqTj7SQ9sj1rKtVWyVAVAaOJRwTTA== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -9896,7 +9908,7 @@ packages: dev: false name: '@rush-temp/core-arm' resolution: - integrity: sha512-9uqsxSLJiO0MSCXGkCe42Kf/kJO0w7GuYc4efzzjMJOsbsjBfu4wpt5IJOyzMUznyaPBFKOiR8wKboyhNfbzmg== + integrity: sha512-GVZI9FYYYQ4Jt0BkIi0OJ5vhcKGeoUhaUA8mw3XXNBvERXJqBZSpiWiJ03lXbnEgWvcz4Yn2EvgiWT0JSj2gkw== tarball: 'file:projects/core-arm.tgz' version: 0.0.0 'file:projects/core-asynciterator-polyfill.tgz': @@ -9914,7 +9926,7 @@ packages: dev: false name: '@rush-temp/core-asynciterator-polyfill' resolution: - integrity: sha512-X2qR67x/Wgwcs8VjH/m3EA7HFB22mL2sf9YJCvpdIUXvz5ENGH54U4TC8IAc2AxcqlKjOi1pwFUAf9yBf4nAJQ== + integrity: sha512-hp2FjyoaLo9iJIGV0Aq7UI8oGzIr29OewVSFfuckKI+2aDUrh6Kamlg/hw/HrZ/a3ybccP3oqGjwA2uze4DoAg== tarball: 'file:projects/core-asynciterator-polyfill.tgz' version: 0.0.0 'file:projects/core-auth.tgz': @@ -9952,7 +9964,7 @@ packages: dev: false name: '@rush-temp/core-auth' resolution: - integrity: sha512-WcJPwF+dNlpEQW1GRzGQIY6YEI+uz6ChF3PISTFVyFbZjK1k+5r0ly2DRCplHUd6tVJ2GoqbqmSHR8Doz/E4Mw== + integrity: sha512-oVJYTPPuUZ3iD4kJtFBd0lRmS1aca8qhLXqlV3TtVIIw/MHZ+kQiFiy/bJTwjSpxOWzL4b4l8yeg2dAXjyuROg== tarball: 'file:projects/core-auth.tgz' version: 0.0.0 'file:projects/core-http.tgz': @@ -10025,17 +10037,19 @@ packages: tunnel: 0.0.6 typescript: 3.5.3 uglify-js: 3.6.0 + underscore: 1.4.4 uuid: 3.3.3 webpack: 4.39.2_webpack@4.39.2 webpack-cli: 3.3.7_webpack@4.39.2 webpack-dev-middleware: 3.7.0_webpack@4.39.2 xhr-mock: 2.5.0 xml2js: 0.4.19 + xmlbuilder: 0.4.3 yarn: 1.17.3 dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-tnBnNKZPZvmwesatSPql50OdGqX9w/Hi2qEbvu2ATsp93+M6E5Ofg37iul2dlUdzwkfwa3tX97eTikU96MyvXw== + integrity: sha512-jZg32+noo1+LHfWEkWzu/cwN4vaxXenspeoozEwNiA3hgD7PI2DKZfrbVBOp1zj6Wp3VSkG3Kv2NydKXm971rw== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': @@ -10054,7 +10068,7 @@ packages: dev: false name: '@rush-temp/core-paging' resolution: - integrity: sha512-/l5SA2u/jUrYjvQBf24YFdaoYW4GAdU3iDoGDekLbjH2fSP8wOt/3oDlBM8pxGD54TB7s06Oi4OjBsQN6F5tgw== + integrity: sha512-rorSx6Oeq/VsKWv3L8qwnHYihYjPZS/PiCZZrIlGt7WfSH8iS60XFPxRrAiP+zIhosvd1hDlSmQ8k30iIB10QA== tarball: 'file:projects/core-paging.tgz' version: 0.0.0 'file:projects/core-tracing.tgz': @@ -10092,7 +10106,7 @@ packages: dev: false name: '@rush-temp/core-tracing' resolution: - integrity: sha512-yAQfqHw4bMOPRFf2Q0SGJtgtdw+RPhMQtkNBh1s8TO5kk1HV7cE6S4Fh3kH3msRmRFM3M9yLmdcVt5asCcRjtg== + integrity: sha512-CRGjX9TjXCkXJMbYqwOpJxxMCDPq3ZUqJML0wdJD/1dUX84mu9aD0iMi6QjPxMPiuYmlvbqJ+aLaNXcZPoNY3A== tarball: 'file:projects/core-tracing.tgz' version: 0.0.0 'file:projects/event-hubs.tgz': @@ -10168,7 +10182,7 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-ij9RrsZTCY20A1azLf+CQ2/sC3oz8FwzxNv+of934zmASFqNxTqwylat1zRPj/zQ+5WHpfq5BoNmXpTgshzzRg== + integrity: sha512-TMdz6KTaNgEH8tAeEntd48I6dIV5yZbYrDxgW0cLV4eR+agvLKFa3XPx6H8iiwF/Jyn/eMKu56iLP/nwnxUVFw== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -10225,7 +10239,7 @@ packages: dev: false name: '@rush-temp/event-processor-host' resolution: - integrity: sha512-7/7AixJ0rDkzWSL4l0i3DbufYn8MgykQREWpVm5pTMaNi6HqQZGwCMSyCiVqRBSheWcn+shtaCNlRTAOA7nw2g== + integrity: sha512-c/puCLm/oWyCMxHOUHQ3ZszUEyoBpeoPBnpMiLYhdqGIl1cXBYxOzXJaN3MN4EgzztvbG/kUtOZt2h+tAoP7NA== tarball: 'file:projects/event-processor-host.tgz' version: 0.0.0 'file:projects/identity.tgz': @@ -10277,7 +10291,7 @@ packages: dev: false name: '@rush-temp/identity' resolution: - integrity: sha512-zBuzYgT0J+3USAuHuU/4bUU5W++5Fsp3U747YIjXOR2tSbiX9QVv9DKUgtJD8lQm1jdvZduzwIhMBTJd68lk8Q== + integrity: sha512-aVvXmz3WeYJqmGGqVVfQOL30VQi09y/31viVZ6CfXy0MzUtrSmCwX9sfKDR3RnbvjtULGivZvJp7OY5Pwv2EPw== tarball: 'file:projects/identity.tgz' version: 0.0.0 'file:projects/keyvault-certificates.tgz': @@ -10345,7 +10359,7 @@ packages: dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-RGwQyIALGePUl3hTCS4uu9E8RIKUpOvv/MYZDgwfQOo5ZvGrWN1HkDd0OaafAnfDFFM7aalGt1JnZBh9RCGFFQ== + integrity: sha512-8YOlO6QG3YkvNcFPbJL8nbroNLJpDcxGdBXukPxgNcw74wWIEGACMb77FRZbsviTl4Fm882+yJTVl6q4xNZHww== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -10414,7 +10428,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-jxZzHCbuJfaD39hHIzP3fyE2eidbNN7iXcHNptZk8qt+rp9E0d5MgpGrgdFbqVPFhUl5AqAbrRfUlOdYvvHR2Q== + integrity: sha512-DjVpS2TWUSIbp4acVsnz9mklUM/foZjjrVIs1Vo86HzF28igiFanj74BoWmiVzfubanC9+KwdEjQQ8U9CsWIXA== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -10481,7 +10495,7 @@ packages: dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-KKRhMhKadWkVD6YNbv0oc5hUwWXePFshonrEk8sPqWCJy2wmxDQcByw5kXfvu4ff1pBu5YU2/WGJea+78lvg4Q== + integrity: sha512-Sml9gYtRdzXKZ/tiXOrFJebP7VayBC8dZmiCGWeypwyeME7KfNUu7RS1/SoVL3FICnoG9DGBOhuW4Hitmzx8yA== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/service-bus.tgz': @@ -10558,7 +10572,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-afJ8wnIxTmCpYPotxye4XswCWAlNTlXQIU8MJh7Tf0YRxLZXtUZSndz8Z9LjXcKyOJst5u1Cub0GTONIs0ZS9Q== + integrity: sha512-FwSxg/1Ynbnbyna5nzRpMryYhlKwPQagswhSvdmTEBT14skEz2wxcO1ZCalQL3yUHxtLqNTbwSEWs/m1iwVRbQ== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -10628,7 +10642,7 @@ packages: dev: false name: '@rush-temp/storage-blob' resolution: - integrity: sha512-hxiIH/jGLBocF8uWR2vDOwx7w+bFJvNGW/k+Ds1FDZxQatiZLLgQvutwzTLc2oKNBxUrXKssQGIG7e7oHl08+A== + integrity: sha512-kn2byrHTxQIDWXEwQS14S523e/NgrUkWWdtk/EyQb11NWHZJGzqWOR7soCXQgZfmWIGgjKfPFM/Xwrqf3vECMA== tarball: 'file:projects/storage-blob.tgz' version: 0.0.0 'file:projects/storage-file.tgz': @@ -10698,7 +10712,7 @@ packages: dev: false name: '@rush-temp/storage-file' resolution: - integrity: sha512-Om0AwUAkaQ2MXCiO3Tbr9o7dAHIAORNMEGG/vHmjsQT1TcMnQtxkj6W3Vi12arC7Befc2eRBK6qCx4dmAWUc0g== + integrity: sha512-oj8bSAecZKtBXtPot5VqiCMqKQx5sQIjbNgGg1IyGwsdfgeTJKgMYOJpPK8MSMqvYK9EZudw3jkeFOIA378j1w== tarball: 'file:projects/storage-file.tgz' version: 0.0.0 'file:projects/storage-queue.tgz': @@ -10767,7 +10781,7 @@ packages: dev: false name: '@rush-temp/storage-queue' resolution: - integrity: sha512-emEeCElwVRQ9uXdWyORLRGge2NTOWtKaZ1UNKrzC8EOToJuJapl7SG6SxCpvXuLOxVyhMXLQCOx+IRAWLi9XlA== + integrity: sha512-73zOl+s2xrm/5cQo1kRzdupjV451qFHM1SMEHnZMNG5uX8NlLPFy3A5qPcj5dGcrBwdA33JdZKYhMkLCLk48fQ== tarball: 'file:projects/storage-queue.tgz' version: 0.0.0 'file:projects/template.tgz': @@ -10817,7 +10831,7 @@ packages: dev: false name: '@rush-temp/template' resolution: - integrity: sha512-CT4vFqfIOTwrzlk0gsSp71MNMAgA6cbt4Sa3BkCVhr81N6oXnvIoGIMCtzSerpvI8j1auYc0yM4rKldxNSFTqA== + integrity: sha512-gMekh0FZCuSys6TamLN8h1nt7hJ/ah6Ryu7nR26ETWqXzxQnsnZrq27JRWgA2x5QFv5XBXXZJayhpUId9K+8bA== tarball: 'file:projects/template.tgz' version: 0.0.0 'file:projects/testhub.tgz': @@ -10838,9 +10852,10 @@ packages: dev: false name: '@rush-temp/testhub' resolution: - integrity: sha512-VxrbDXfuJ6Nz4rm0DHlJ+0sMk4RMKRflIyu7WxXLZGBpri9KLivFyNA0TWfZBifpdy3T1kVXyLOccskpzczDvA== + integrity: sha512-5P+X3IwgFa9rlq+jbtHxWVZWF1kDmRZwV8jQfHMYV5CLsJjXKw1yISIRSFmCmuXDdHYEnxO1bnRGi34QeZ+63g== tarball: 'file:projects/testhub.tgz' version: 0.0.0 +registry: '' specifiers: '@azure/amqp-common': 1.0.0-preview.6 '@azure/arm-servicebus': ^3.2.0 @@ -11008,6 +11023,7 @@ specifiers: tunnel: ^0.0.6 typescript: ^3.2.2 uglify-js: ^3.4.9 + underscore: 1.4.x url: ^0.11.0 util: ^0.12.1 uuid: ^3.3.2 @@ -11017,5 +11033,6 @@ specifiers: ws: ^7.1.1 xhr-mock: ^2.4.1 xml2js: ^0.4.19 + xmlbuilder: 0.4.3 yargs: ^13.0.0 yarn: ^1.6.0 From fbf047eb142bbed6fa79c0ee9102fefb1d593805 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 27 Aug 2019 16:12:14 -0700 Subject: [PATCH 04/72] Fix export --- sdk/core/core-http/lib/coreHttp.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index b9da422ea9c8..65b4d3ea9e1a 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -104,9 +104,7 @@ export { atomSerializationPolicy, AtomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { - SasServiceClientCredentials as ServiceBusSASServiceClientCredentials -} from "./credentials/sasServiceClientCredentials"; +export { SasServiceClientCredentials } from "./credentials/sasServiceClientCredentials"; export { ResourceSerializer } from "./resourceSerializer"; export { AtomResourceSerializerBase } from "./atomResourceSerializerBase"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; From 1082642e1a3110f0b54cd008994d6a7f71906e4c Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 27 Aug 2019 21:02:11 -0700 Subject: [PATCH 05/72] Browserified changes --- common/config/rush/pnpm-lock.yaml | 41 ++++++- .../lib/atomResourceSerializerBase.ts | 116 ++---------------- sdk/core/core-http/lib/coreHttp.ts | 3 +- .../sasServiceClientCredentials.ts | 37 +++--- sdk/core/core-http/lib/util/atomHandler.ts | 95 +++++++++++--- sdk/core/core-http/rollup.config.ts | 4 +- 6 files changed, 144 insertions(+), 152 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index fe5101ce630b..34a1e8a49e42 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -85,6 +85,7 @@ dependencies: eslint-plugin-promise: 4.2.1 events: 3.0.0 express: 4.17.1 + fast-xml-parser: 3.12.20 fetch-mock: 7.3.9 form-data: 2.5.0 fs-extra: 8.1.0 @@ -165,7 +166,6 @@ dependencies: tunnel: 0.0.6 typescript: 3.5.3 uglify-js: 3.6.0 - underscore: 1.4.4 url: 0.11.0 util: 0.12.1 uuid: 3.3.3 @@ -175,7 +175,6 @@ dependencies: ws: 7.1.2 xhr-mock: 2.5.0 xml2js: 0.4.19 - xmlbuilder: 0.4.3 yargs: 13.3.0 yarn: 1.17.3 lockfileVersion: 5.1 @@ -758,6 +757,13 @@ packages: dev: false resolution: integrity: sha512-O6Xgai01b9PB3IGA0lRIp1Ex3JBcxGDhdO0n3NIIpCyDOAjxcIGQFmkvgJpP8anTrthxOUQjBfLdRRi0Zn/TXA== + /@types/xmlbuilder/11.0.1: + dependencies: + xmlbuilder: 0.4.3 + deprecated: 'This is a stub types definition. xmlbuilder provides its own type definitions, so you do not need this installed.' + dev: false + resolution: + integrity: sha512-ScJDpWPSAyO7s2BO5eUQTqyhO7i8c4r7Waj5eEwQYGApaNXW6E0pb9l1llDZ1VKGiBdGLMtLmqAi4eaKbzJ0dQ== /@types/yargs-parser/13.0.0: dev: false resolution: @@ -3801,6 +3807,14 @@ packages: dev: false resolution: integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + /fast-xml-parser/3.12.20: + dependencies: + nimnjs: 1.3.2 + dev: false + hasBin: true + requiresBuild: true + resolution: + integrity: sha512-viadHdefuuqkyJWUhF2r2Ymb5LJ0T7uQhzSRv4OZzYxpoPQnY05KtaX0pLkolabD7tLzIE8q/OytIAEhqPyYbw== /fd-slicer/1.0.1: dependencies: pend: 1.2.0 @@ -6370,6 +6384,21 @@ packages: dev: false resolution: integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + /nimn-date-parser/1.0.0: + dev: false + resolution: + integrity: sha512-1Nf+x3EeMvHUiHsVuEhiZnwA8RMeOBVTQWfB1S2n9+i6PYCofHd2HRMD+WOHIHYshy4T4Gk8wQoCol7Hq3av8Q== + /nimn_schema_builder/1.1.0: + dev: false + resolution: + integrity: sha512-DK5/B8CM4qwzG2URy130avcwPev4uO0ev836FbQyKo1ms6I9z/i6EJyiZ+d9xtgloxUri0W+5gfR8YbPq7SheA== + /nimnjs/1.3.2: + dependencies: + nimn-date-parser: 1.0.0 + nimn_schema_builder: 1.1.0 + dev: false + resolution: + integrity: sha512-TIOtI4iqkQrUM1tiM76AtTQem0c7e56SkDZ7sj1d1MfUsqRcq2ZWQvej/O+HBTZV7u/VKnwlKTDugK/75IRPPw== /nise/1.5.1: dependencies: '@sinonjs/formatio': 3.2.1 @@ -9986,9 +10015,11 @@ packages: '@types/webpack': 4.39.0 '@types/webpack-dev-middleware': 2.0.3 '@types/xml2js': 0.4.4 + '@types/xmlbuilder': 11.0.1 '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 babel-runtime: 6.26.0 + buffer: 5.4.0 chai: 4.2.0 eslint: 6.2.1 eslint-config-prettier: 6.1.0_eslint@6.2.1 @@ -9996,6 +10027,7 @@ packages: eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 express: 4.17.1 + fast-xml-parser: 3.12.20 fetch-mock: 7.3.9 form-data: 2.5.0 glob: 7.1.4 @@ -10049,7 +10081,7 @@ packages: dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-jZg32+noo1+LHfWEkWzu/cwN4vaxXenspeoozEwNiA3hgD7PI2DKZfrbVBOp1zj6Wp3VSkG3Kv2NydKXm971rw== + integrity: sha512-9XQ12/wFXJSTZV162Y/HEK9GoOtwggro+S2/G55qMwgL6zVjGfPI0/AkU/jzP+qsXjybV9LkUg9ixmchWvr5Xg== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': @@ -10943,6 +10975,7 @@ specifiers: eslint-plugin-promise: ^4.1.1 events: ^3.0.0 express: ^4.16.3 + fast-xml-parser: ^3.12.20 fetch-mock: ^7.3.9 form-data: ^2.5.0 fs-extra: ^8.1.0 @@ -11023,7 +11056,6 @@ specifiers: tunnel: ^0.0.6 typescript: ^3.2.2 uglify-js: ^3.4.9 - underscore: 1.4.x url: ^0.11.0 util: ^0.12.1 uuid: ^3.3.2 @@ -11033,6 +11065,5 @@ specifiers: ws: ^7.1.1 xhr-mock: ^2.4.1 xml2js: ^0.4.19 - xmlbuilder: 0.4.3 yargs: ^13.0.0 yarn: ^1.6.0 diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 33b8abaac5dd..79dd3a5d4f04 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -14,18 +14,21 @@ // limitations under the License. // -import { stringIsEmpty, stringStartsWith } from "./util/utils"; +import { isNode } from "./util/utils"; import { Constants } from "./util/constants"; import { AtomHandler } from "./util/atomHandler"; -import { each, isUndefined, isArray, isObject, isDate } from "./util/utils"; -const url = require("url"); -const xmlbuilder = require("xmlbuilder"); +import { each, isUndefined, isArray } from "./util/utils"; const atomHandler = new AtomHandler(); export class AtomResourceSerializerBase { static setName(entry: any, nameProperty: any): any { - var parsedUrl: any = url.parse(entry[Constants.ATOM_METADATA_MARKER].id); + let parsedUrl: any; + if (isNode) { + parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); + } else { + parsedUrl = new window.URL(entry[Constants.ATOM_METADATA_MARKER].id); + } var parts = parsedUrl.pathname!.split("/"); for (var i = 0; i * 2 < parts.length - 1; i++) { @@ -68,107 +71,4 @@ export class AtomResourceSerializerBase { } return result; } - - static serializeEntry(content: any, namespaces?: any, properties?: any): any { - var doc = xmlbuilder.create("entry").att("xmlns", "http://www.w3.org/2005/Atom"); - - each(namespaces, function(namespace: any): any { - doc = doc.att("xmlns:" + namespace.key, namespace.url); - }); - - if (properties) { - Object.keys(properties).forEach(function(property) { - doc = doc.ele(property, properties[property]).up(); - }); - } - - doc = doc.ele("updated", new Date().toISOString()).up(); - - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - - doc = AtomResourceSerializerBase._writeElementValue(doc, "content", content); - - return doc.doc().toString(); - } - - static _writeElementValue(parentElement: any, name: any, value: any): any { - var ignored = false; - var propertyTagName = name; - - if (!stringIsEmpty(value) && isObject(value) && !isDate(value)) { - if (Array.isArray(value) && value.length > 0) { - // Example: - // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] - // XML: hi therehello there - - Object.keys(value).forEach(function(i: any) { - parentElement = AtomResourceSerializerBase._writeElementValue( - parentElement, - name, - value[i] - ); - }); - - // For an array no element was actually added at this level, so skip uping level. - ignored = true; - } else if ( - value[Constants.XML_METADATA_MARKER] !== undefined && - value[Constants.XML_VALUE_MARKER] !== undefined - ) { - // Example: - // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } - // XML: hi there - - parentElement = parentElement.ele(propertyTagName); - if (!stringIsEmpty(value[Constants.XML_VALUE_MARKER])) { - if (stringStartsWith(value[Constants.XML_VALUE_MARKER], "hi therehello there - - parentElement = parentElement.ele(propertyTagName); - for (var propertyName in value) { - if ( - propertyName !== Constants.XML_METADATA_MARKER && - value.hasOwnProperty(propertyName) - ) { - parentElement = AtomResourceSerializerBase._writeElementValue( - parentElement, - propertyName, - value[propertyName] - ); - } - } - } - } else { - parentElement = parentElement.ele(propertyTagName); - if (!stringIsEmpty(value)) { - if (stringStartsWith(value.toString().trim(), "' + serializer.serializeToString(dom) + ); + } - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + buildNode(obj: any, elementName: string): Node[] { + // tslint:disable-next-line:no-null-keyword - doc = this._writeElementValue(doc, "content", content); + const doc = document.implementation.createDocument(null, "entry", null); + if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { + const elem = doc.createElement(elementName); + elem.textContent = obj.toString(); + return [elem]; + } else if (Array.isArray(obj)) { + const result = []; + for (const arrayElem of obj) { + for (const child of this.buildNode(arrayElem, elementName)) { + result.push(child); + } + } + return result; + } else if (typeof obj === "object") { + const elem = doc.createElement(elementName); + for (const key of Object.keys(obj)) { + if (key === "$") { + for (const attr of this.buildAttributes(doc, obj[key])) { + elem.attributes.setNamedItem(attr); + } + } else { + for (const child of this.buildNode(obj[key], key)) { + elem.appendChild(child); + } + } + } + return [elem]; + } else { + throw new Error(`Illegal value passed to buildObject: ${obj}`); + } + } - return doc.doc().toString(); + buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { + const result = []; + for (const key of Object.keys(attrs)) { + const attr = doc.createAttribute(key); + attr.value = attrs[key].toString(); + result.push(attr); + } + return result; } /* diff --git a/sdk/core/core-http/rollup.config.ts b/sdk/core/core-http/rollup.config.ts index f4316ce5f1ae..41c1c7f2c995 100644 --- a/sdk/core/core-http/rollup.config.ts +++ b/sdk/core/core-http/rollup.config.ts @@ -60,7 +60,7 @@ const nodeConfig = { */ const browserConfig = { input: "./es/lib/coreHttp.js", - external: [], + external: ["crypto"], output: { file: "./dist/coreHttp.browser.js", format: "umd", @@ -78,7 +78,7 @@ const browserConfig = { }), nodeResolve({ mainFields: ["module", "browser"], - preferBuiltins: true + preferBuiltins: false }), commonjs(), sourcemaps(), From b0db0347c9ea6268357d96ee5841105b8b81fd1d Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 28 Aug 2019 14:08:26 -0700 Subject: [PATCH 06/72] New pnpm-lock.yaml file --- common/config/rush/pnpm-lock.yaml | 1030 ++++++++++++++--------------- 1 file changed, 499 insertions(+), 531 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 34a1e8a49e42..68572302b679 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -57,18 +57,18 @@ dependencies: '@types/tough-cookie': 2.3.5 '@types/tunnel': 0.0.1 '@types/uuid': 3.4.5 - '@types/webpack': 4.39.0 + '@types/webpack': 4.39.1 '@types/webpack-dev-middleware': 2.0.3 - '@types/ws': 6.0.2 + '@types/ws': 6.0.3 '@types/xml2js': 0.4.4 '@types/yargs': 13.0.2 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 async-lock: 1.2.2 azure-storage: 2.10.3 babel-runtime: 6.26.0 - buffer: 5.4.0 + buffer: 5.4.2 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 @@ -78,14 +78,13 @@ dependencies: delay: 4.3.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 express: 4.17.1 - fast-xml-parser: 3.12.20 fetch-mock: 7.3.9 form-data: 2.5.0 fs-extra: 8.1.0 @@ -97,24 +96,24 @@ dependencies: is-buffer: 2.0.3 jssha: 2.3.1 jws: 3.2.2 - karma: 4.2.0 - karma-chai: 0.1.0_chai@4.2.0+karma@4.2.0 + karma: 4.3.0 + karma-chai: 0.1.0_chai@4.2.0+karma@4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 - karma-rollup-preprocessor: 7.0.2_rollup@1.19.4 + karma-rollup-preprocessor: 7.0.2_rollup@1.20.3 karma-sourcemap-loader: 0.3.7 karma-typescript-es6-transform: 4.1.1 - karma-webpack: 4.0.2_webpack@4.39.2 + karma-webpack: 4.0.2_webpack@4.39.3 long: 4.0.0 mocha: 6.2.0 mocha-chrome: 2.0.0 @@ -122,7 +121,7 @@ dependencies: mocha-multi: 1.1.3_mocha@6.2.0 moment: 2.24.0 msal: 1.1.3 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 node-fetch: 2.6.0 npm-run-all: 4.1.5 @@ -138,43 +137,44 @@ dependencies: rhea: 1.0.8 rhea-promise: 0.1.15 rimraf: 2.7.1 - rollup: 1.19.4 + rollup: 1.20.3 rollup-plugin-alias: 1.5.2 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 rollup-plugin-node-globals: 1.4.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-uglify: 6.0.2_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-uglify: 6.0.2_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 semver: 5.7.1 shx: 0.3.2 sinon: 7.4.1 source-map-support: 0.5.13 stream-browserify: 2.0.2 - terser: 4.2.0 + terser: 4.2.1 tough-cookie: 3.0.1 - ts-loader: 6.0.4_typescript@3.5.3 + ts-loader: 6.0.4_typescript@3.6.2 ts-mocha: 6.0.0_mocha@6.2.0 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 tunnel: 0.0.6 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 url: 0.11.0 util: 0.12.1 uuid: 3.3.3 - webpack: 4.39.2_webpack@4.39.2 - webpack-cli: 3.3.7_webpack@4.39.2 - webpack-dev-middleware: 3.7.0_webpack@4.39.2 + webpack: 4.39.3_webpack@4.39.3 + webpack-cli: 3.3.7_webpack@4.39.3 + webpack-dev-middleware: 3.7.0_webpack@4.39.3 ws: 7.1.2 xhr-mock: 2.5.0 xml2js: 0.4.19 + xmlbuilder: 0.4.3 yargs: 13.3.0 yarn: 1.17.3 lockfileVersion: 5.1 @@ -185,7 +185,7 @@ packages: '@types/async-lock': 1.1.1 '@types/is-buffer': 2.0.0 async-lock: 1.2.2 - buffer: 5.4.0 + buffer: 5.4.2 debug: 3.2.6 events: 3.0.0 is-buffer: 2.0.3 @@ -721,7 +721,7 @@ packages: dependencies: '@types/connect': 3.4.32 '@types/memory-fs': 0.3.2 - '@types/webpack': 4.39.0 + '@types/webpack': 4.39.1 loglevel: 1.6.3 dev: false resolution: @@ -734,7 +734,7 @@ packages: dev: false resolution: integrity: sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w== - /@types/webpack/4.39.0: + /@types/webpack/4.39.1: dependencies: '@types/anymatch': 1.3.1 '@types/node': 8.10.52 @@ -744,26 +744,19 @@ packages: source-map: 0.6.1 dev: false resolution: - integrity: sha512-8gUiAl6RBI4IoCJVQ9AChp4k2Tcd4ocNei2S83goHKCj8WesBtlqp9/wPd29dArHIGMdHxICwBi8YMm8PD6PEg== - /@types/ws/6.0.2: + integrity: sha512-rgO9ihNu/l72Sjx3shqwc9r6gi+tOMsqxhMEZhOEVIZt82GFOeUyEdpTk1BO2HqEHLS/XJW8ldUTIIfIMMyYFQ== + /@types/ws/6.0.3: dependencies: '@types/node': 8.10.52 dev: false resolution: - integrity: sha512-22XiR1ox9LftTaAtn/c5JCninwc7moaqbkJfaDUb7PkaUitcf5vbTZHdq9dxSMviCm9C3W85rzB8e6yNR70apQ== + integrity: sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w== /@types/xml2js/0.4.4: dependencies: '@types/node': 8.10.52 dev: false resolution: integrity: sha512-O6Xgai01b9PB3IGA0lRIp1Ex3JBcxGDhdO0n3NIIpCyDOAjxcIGQFmkvgJpP8anTrthxOUQjBfLdRRi0Zn/TXA== - /@types/xmlbuilder/11.0.1: - dependencies: - xmlbuilder: 0.4.3 - deprecated: 'This is a stub types definition. xmlbuilder provides its own type definitions, so you do not need this installed.' - dev: false - resolution: - integrity: sha512-ScJDpWPSAyO7s2BO5eUQTqyhO7i8c4r7Waj5eEwQYGApaNXW6E0pb9l1llDZ1VKGiBdGLMtLmqAi4eaKbzJ0dQ== /@types/yargs-parser/13.0.0: dev: false resolution: @@ -778,15 +771,15 @@ packages: dev: false resolution: integrity: sha1-LrHQCl5Ow/pYx2r94S4YK2bcXBw= - /@typescript-eslint/eslint-plugin/2.0.0_3cafee28902d96627d4743e014bc28ff: + /@typescript-eslint/eslint-plugin/2.0.0_725fda8723c9f372c79013d5541f9bc5: dependencies: - '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.1 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 - eslint: 6.2.1 + '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.2 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + eslint: 6.2.2 eslint-utils: 1.4.2 functional-red-black-tree: 1.0.1 regexpp: 2.0.1 - tsutils: 3.17.1_typescript@3.5.3 + tsutils: 3.17.1_typescript@3.6.2 dev: false engines: node: ^8.10.0 || ^10.13.0 || >=11.10.1 @@ -796,11 +789,11 @@ packages: typescript: '*' resolution: integrity: sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA== - /@typescript-eslint/experimental-utils/2.0.0_eslint@6.2.1: + /@typescript-eslint/experimental-utils/2.0.0_eslint@6.2.2: dependencies: '@types/json-schema': 7.0.3 '@typescript-eslint/typescript-estree': 2.0.0 - eslint: 6.2.1 + eslint: 6.2.2 eslint-scope: 4.0.3 dev: false engines: @@ -809,12 +802,12 @@ packages: eslint: '*' resolution: integrity: sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg== - /@typescript-eslint/parser/2.0.0_eslint@6.2.1: + /@typescript-eslint/parser/2.0.0_eslint@6.2.2: dependencies: '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.1 + '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.2 '@typescript-eslint/typescript-estree': 2.0.0 - eslint: 6.2.1 + eslint: 6.2.2 eslint-visitor-keys: 1.1.0 dev: false engines: @@ -1115,14 +1108,12 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - /ansi-escapes/4.2.1: - dependencies: - type-fest: 0.5.2 + /ansi-escapes/3.2.0: dev: false engines: - node: '>=8' + node: '>=4' resolution: - integrity: sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== + integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== /ansi-gray/0.1.1: dependencies: ansi-wrap: 0.1.0 @@ -2183,7 +2174,7 @@ packages: /browserslist/3.2.8: dependencies: caniuse-lite: 1.0.30000989 - electron-to-chromium: 1.3.236 + electron-to-chromium: 1.3.243 dev: false hasBin: true resolution: @@ -2237,13 +2228,13 @@ packages: dev: false resolution: integrity: sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= - /buffer/5.4.0: + /buffer/5.4.2: dependencies: base64-js: 1.3.1 ieee754: 1.1.13 dev: false resolution: - integrity: sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g== + integrity: sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== /builtin-modules/3.1.0: dev: false engines: @@ -2432,7 +2423,7 @@ packages: dev: false resolution: integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - /chokidar/2.1.6: + /chokidar/2.1.8: dependencies: anymatch: 2.0.0 async-each: 1.0.3 @@ -2449,7 +2440,7 @@ packages: optionalDependencies: fsevents: 1.2.9 resolution: - integrity: sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== /chokidar/3.0.2: dependencies: anymatch: 3.0.3 @@ -2526,14 +2517,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - /cli-cursor/3.1.0: + /cli-cursor/2.1.0: dependencies: - restore-cursor: 3.1.0 + restore-cursor: 2.0.0 dev: false engines: - node: '>=8' + node: '>=4' resolution: - integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + integrity: sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= /cli-width/2.2.0: dev: false resolution: @@ -3014,10 +3005,17 @@ packages: node: '>=0.12' resolution: integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - /deep-equal/1.0.1: + /deep-equal/1.1.0: + dependencies: + is-arguments: 1.0.4 + is-date-object: 1.0.1 + is-regex: 1.0.4 + object-is: 1.0.1 + object-keys: 1.1.1 + regexp.prototype.flags: 1.2.0 dev: false resolution: - integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + integrity: sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== /deep-is/0.1.3: dev: false resolution: @@ -3222,10 +3220,10 @@ packages: dev: false resolution: integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - /electron-to-chromium/1.3.236: + /electron-to-chromium/1.3.243: dev: false resolution: - integrity: sha512-LWOvuJ80pLO3FtFqTcGuXB0dxdMtzSCkRmbXdY5mHUvXRQGor3sTVmyfU70aD2yF5i+fbHz52ncWr5T3xUYHlA== + integrity: sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== /elliptic/6.5.0: dependencies: bn.js: 4.11.8 @@ -3242,10 +3240,6 @@ packages: dev: false resolution: integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - /emoji-regex/8.0.0: - dev: false - resolution: - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== /emojis-list/2.1.0: dev: false engines: @@ -3431,9 +3425,9 @@ packages: source-map: 0.2.0 resolution: integrity: sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= - /eslint-config-prettier/6.1.0_eslint@6.2.1: + /eslint-config-prettier/6.1.0_eslint@6.2.2: dependencies: - eslint: 6.2.1 + eslint: 6.2.2 get-stdin: 6.0.0 dev: false hasBin: true @@ -3441,9 +3435,9 @@ packages: eslint: '>=3.14.1' resolution: integrity: sha512-k9fny9sPjIBQ2ftFTesJV21Rg4R/7a7t7LCtZVrYQiHEp8Nnuk3EGaDmsKSAnsPj0BYcgB2zxzHa2NTkIxcOLg== - /eslint-plugin-no-null/1.0.2_eslint@6.2.1: + /eslint-plugin-no-null/1.0.2_eslint@6.2.2: dependencies: - eslint: 6.2.1 + eslint: 6.2.2 dev: false engines: node: '>=5.0.0' @@ -3495,7 +3489,7 @@ packages: node: '>=4' resolution: integrity: sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - /eslint/6.2.1: + /eslint/6.2.2: dependencies: '@babel/code-frame': 7.5.5 ajv: 6.10.2 @@ -3506,7 +3500,7 @@ packages: eslint-scope: 5.0.0 eslint-utils: 1.4.2 eslint-visitor-keys: 1.1.0 - espree: 6.1.0 + espree: 6.1.1 esquery: 1.0.1 esutils: 2.0.3 file-entry-cache: 5.0.1 @@ -3516,7 +3510,7 @@ packages: ignore: 4.0.6 import-fresh: 3.1.0 imurmurhash: 0.1.4 - inquirer: 6.5.1 + inquirer: 6.5.2 is-glob: 4.0.1 js-yaml: 3.13.1 json-stable-stringify-without-jsonify: 1.0.1 @@ -3539,8 +3533,8 @@ packages: node: ^8.10.0 || ^10.13.0 || >=11.10.1 hasBin: true resolution: - integrity: sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg== - /espree/6.1.0: + integrity: sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== + /espree/6.1.1: dependencies: acorn: 7.0.0 acorn-jsx: 5.0.2_acorn@7.0.0 @@ -3549,7 +3543,7 @@ packages: engines: node: '>=6.0.0' resolution: - integrity: sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ== + integrity: sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== /esprima/2.7.3: dev: false engines: @@ -3807,14 +3801,6 @@ packages: dev: false resolution: integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - /fast-xml-parser/3.12.20: - dependencies: - nimnjs: 1.3.2 - dev: false - hasBin: true - requiresBuild: true - resolution: - integrity: sha512-viadHdefuuqkyJWUhF2r2Ymb5LJ0T7uQhzSRv4OZzYxpoPQnY05KtaX0pLkolabD7tLzIE8q/OytIAEhqPyYbw== /fd-slicer/1.0.1: dependencies: pend: 1.2.0 @@ -3838,14 +3824,14 @@ packages: dev: false resolution: integrity: sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - /figures/3.0.0: + /figures/2.0.0: dependencies: escape-string-regexp: 1.0.5 dev: false engines: - node: '>=8' + node: '>=4' resolution: - integrity: sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== + integrity: sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= /file-entry-cache/5.0.1: dependencies: flat-cache: 2.0.1 @@ -3998,14 +3984,14 @@ packages: node: '>=4.0' resolution: integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - /follow-redirects/1.7.0: + /follow-redirects/1.8.1: dependencies: debug: 3.2.6 dev: false engines: node: '>=4.0' resolution: - integrity: sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + integrity: sha512-micCIbldHioIegeKs41DoH0KS3AXfFzgS30qVkM6z/XOE/GJgvmsoc839NUqa1B9udYe9dQxgv7KFwng6+p/dw== /for-in/1.0.2: dev: false engines: @@ -4241,7 +4227,7 @@ packages: dependencies: anymatch: 2.0.0 async-done: 1.3.2 - chokidar: 2.1.6 + chokidar: 2.1.8 is-negated-glob: 1.0.0 just-debounce: 1.0.0 object.defaults: 1.1.0 @@ -4620,7 +4606,7 @@ packages: /http-proxy/1.17.0: dependencies: eventemitter3: 3.1.2 - follow-redirects: 1.7.0 + follow-redirects: 1.8.1 requires-port: 1.0.0 dev: false engines: @@ -4743,26 +4729,26 @@ packages: dev: false resolution: integrity: sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - /inquirer/6.5.1: + /inquirer/6.5.2: dependencies: - ansi-escapes: 4.2.1 + ansi-escapes: 3.2.0 chalk: 2.4.2 - cli-cursor: 3.1.0 + cli-cursor: 2.1.0 cli-width: 2.2.0 external-editor: 3.1.0 - figures: 3.0.0 + figures: 2.0.0 lodash: 4.17.15 - mute-stream: 0.0.8 + mute-stream: 0.0.7 run-async: 2.3.0 rxjs: 6.5.2 - string-width: 4.1.0 + string-width: 2.1.1 strip-ansi: 5.2.0 through: 2.3.8 dev: false engines: node: '>=6.0.0' resolution: - integrity: sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw== + integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== /interpret/1.2.0: dev: false engines: @@ -4950,12 +4936,6 @@ packages: node: '>=4' resolution: integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - /is-fullwidth-code-point/3.0.0: - dev: false - engines: - node: '>=8' - resolution: - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== /is-generator-function/1.0.7: dev: false engines: @@ -5385,10 +5365,10 @@ packages: dev: false resolution: integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - /karma-chai/0.1.0_chai@4.2.0+karma@4.2.0: + /karma-chai/0.1.0_chai@4.2.0+karma@4.3.0: dependencies: chai: 4.2.0 - karma: 4.2.0 + karma: 4.3.0 dev: false peerDependencies: chai: '*' @@ -5411,10 +5391,10 @@ packages: dev: false resolution: integrity: sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw== - /karma-edge-launcher/0.4.2_karma@4.2.0: + /karma-edge-launcher/0.4.2_karma@4.3.0: dependencies: edge-launcher: 1.2.2 - karma: 4.2.0 + karma: 4.3.0 dev: false engines: node: '>=4' @@ -5432,18 +5412,18 @@ packages: dev: false resolution: integrity: sha512-j9Zp8M8+VLq1nI/5xZGfzeaEPtGQ/vk3G+Y8vpmFWLvKLNZ2TDjD6cu2dUu7lDbu1HXNgatsAX4jgCZTkR9qhQ== - /karma-ie-launcher/1.0.0_karma@4.2.0: + /karma-ie-launcher/1.0.0_karma@4.3.0: dependencies: - karma: 4.2.0 + karma: 4.3.0 lodash: 4.17.15 dev: false peerDependencies: karma: '>=0.9' resolution: integrity: sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw= - /karma-json-preprocessor/0.3.3_karma@4.2.0: + /karma-json-preprocessor/0.3.3_karma@4.3.0: dependencies: - karma: 4.2.0 + karma: 4.3.0 dev: false peerDependencies: karma: '>=0.9' @@ -5455,9 +5435,9 @@ packages: dev: false resolution: integrity: sha512-kNCi+0UrXAeTJMpMsHkHNbfmlErsYT+/haNakJIhsE/gtj3Jx7zWRg7BTc1HHSbH5KeVXVRJr3/KLB/NHWY7Hg== - /karma-junit-reporter/1.2.0_karma@4.2.0: + /karma-junit-reporter/1.2.0_karma@4.3.0: dependencies: - karma: 4.2.0 + karma: 4.3.0 path-is-absolute: 1.0.1 xmlbuilder: 8.2.2 dev: false @@ -5465,10 +5445,10 @@ packages: karma: '>=0.9' resolution: integrity: sha1-T5xAzt+xo5X4rvh2q/lhiZF8Y5Y= - /karma-mocha-reporter/2.2.5_karma@4.2.0: + /karma-mocha-reporter/2.2.5_karma@4.3.0: dependencies: chalk: 2.4.2 - karma: 4.2.0 + karma: 4.3.0 log-symbols: 2.2.0 strip-ansi: 4.0.0 dev: false @@ -5493,11 +5473,11 @@ packages: karma-coverage: '>=0.5.4' resolution: integrity: sha512-FM5h8eHcHbMMR+2INBUxD+4+wUbkCnobfn5uWprkLyj6Xcm2MRFQOuAJn9h2H13nNso6rk+QoNpHd5xCevlPOw== - /karma-rollup-preprocessor/7.0.2_rollup@1.19.4: + /karma-rollup-preprocessor/7.0.2_rollup@1.20.3: dependencies: chokidar: 3.0.2 debounce: 1.2.0 - rollup: 1.19.4 + rollup: 1.20.3 dev: false engines: node: '>= 8.0.0' @@ -5522,15 +5502,15 @@ packages: dev: false resolution: integrity: sha512-WTGGThwufBT73c20q30iTcXq8Jb3Wat/h+JW1lwKgMtymT5rVxLknoaUVNfenaV3+cRMiTEsBT773kz9jWk6IQ== - /karma-webpack/4.0.2_webpack@4.39.2: + /karma-webpack/4.0.2_webpack@4.39.3: dependencies: clone-deep: 4.0.1 loader-utils: 1.2.3 neo-async: 2.6.1 schema-utils: 1.0.0 source-map: 0.7.3 - webpack: 4.39.2_webpack@4.39.2 - webpack-dev-middleware: 3.7.0_webpack@4.39.2 + webpack: 4.39.3_webpack@4.39.3 + webpack-dev-middleware: 3.7.0_webpack@4.39.3 dev: false engines: node: '>= 8.9.0' @@ -5538,7 +5518,7 @@ packages: webpack: ^4.0.0 resolution: integrity: sha512-970/okAsdUOmiMOCY8sb17A2I8neS25Ad9uhyK3GHgmRSIFJbDcNEFE8dqqUhNe9OHiCC9k3DMrSmtd/0ymP1A== - /karma/4.2.0: + /karma/4.3.0: dependencies: bluebird: 3.5.5 body-parser: 1.19.0 @@ -5572,7 +5552,7 @@ packages: node: '>= 8' hasBin: true resolution: - integrity: sha512-fmCuxN1rwJxTdZfOXK5LjlmS4Ana/OvzNMpkyLL/TLE8hmgSkpVpMYQ7RTVa8TNKRVQDZNl5W1oF5cfKfgIMlA== + integrity: sha512-NSPViHOt+RW38oJklvYxQC4BSQsv737oQlr/r06pCM+slDOr4myuI1ivkRmp+3dVpJDfZt2DmaPJ2wkx+ZZuMQ== /kind-of/1.1.0: dev: false engines: @@ -6108,6 +6088,12 @@ packages: hasBin: true resolution: integrity: sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + /mimic-fn/1.2.0: + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== /mimic-fn/2.1.0: dev: false engines: @@ -6306,10 +6292,10 @@ packages: node: '>= 0.10' resolution: integrity: sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== - /mute-stream/0.0.8: + /mute-stream/0.0.7: dev: false resolution: - integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + integrity: sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= /nan/2.14.0: dev: false optional: true @@ -6384,22 +6370,7 @@ packages: dev: false resolution: integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - /nimn-date-parser/1.0.0: - dev: false - resolution: - integrity: sha512-1Nf+x3EeMvHUiHsVuEhiZnwA8RMeOBVTQWfB1S2n9+i6PYCofHd2HRMD+WOHIHYshy4T4Gk8wQoCol7Hq3av8Q== - /nimn_schema_builder/1.1.0: - dev: false - resolution: - integrity: sha512-DK5/B8CM4qwzG2URy130avcwPev4uO0ev836FbQyKo1ms6I9z/i6EJyiZ+d9xtgloxUri0W+5gfR8YbPq7SheA== - /nimnjs/1.3.2: - dependencies: - nimn-date-parser: 1.0.0 - nimn_schema_builder: 1.1.0 - dev: false - resolution: - integrity: sha512-TIOtI4iqkQrUM1tiM76AtTQem0c7e56SkDZ7sj1d1MfUsqRcq2ZWQvej/O+HBTZV7u/VKnwlKTDugK/75IRPPw== - /nise/1.5.1: + /nise/1.5.2: dependencies: '@sinonjs/formatio': 3.2.1 '@sinonjs/text-encoding': 0.7.1 @@ -6408,12 +6379,12 @@ packages: path-to-regexp: 1.7.0 dev: false resolution: - integrity: sha512-edFWm0fsFG2n318rfEnKlTZTkjlbVOFF9XIA+fj+Ed+Qz1laYW2lobwavWoMzGrYDHH1EpiNJgDfvGnkZztR/g== + integrity: sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA== /nock/10.0.6: dependencies: chai: 4.2.0 debug: 4.1.1 - deep-equal: 1.0.1 + deep-equal: 1.1.0 json-stringify-safe: 5.0.1 lodash: 4.17.15 mkdirp: 0.5.1 @@ -6557,7 +6528,7 @@ packages: resolve-from: 4.0.0 rimraf: 2.7.1 signal-exit: 3.0.2 - spawn-wrap: 1.4.2 + spawn-wrap: 1.4.3 test-exclude: 5.2.3 uuid: 3.3.3 yargs: 13.3.0 @@ -6592,6 +6563,12 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + /object-is/1.0.1: + dev: false + engines: + node: '>= 0.4' + resolution: + integrity: sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= /object-keys/1.1.1: dev: false engines: @@ -6688,14 +6665,14 @@ packages: dev: false resolution: integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - /onetime/5.1.0: + /onetime/2.0.1: dependencies: - mimic-fn: 2.1.0 + mimic-fn: 1.2.0 dev: false engines: - node: '>=6' + node: '>=4' resolution: - integrity: sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + integrity: sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= /open/6.4.0: dependencies: is-wsl: 1.1.0 @@ -7525,6 +7502,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + /regexp.prototype.flags/1.2.0: + dependencies: + define-properties: 1.1.3 + dev: false + engines: + node: '>= 0.4' + resolution: + integrity: sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== /regexpp/2.0.1: dev: false engines: @@ -7735,15 +7720,15 @@ packages: dev: false resolution: integrity: sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== - /restore-cursor/3.1.0: + /restore-cursor/2.0.0: dependencies: - onetime: 5.1.0 + onetime: 2.0.1 signal-exit: 3.0.2 dev: false engines: - node: '>=8' + node: '>=4' resolution: - integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + integrity: sha1-n37ih/gv0ybU/RYpI9YhKe7g368= /ret/0.1.15: dev: false engines: @@ -7803,19 +7788,19 @@ packages: dev: false resolution: integrity: sha512-ODeZXhTxpD48sfcYLAFc1BGrsXKDj7o1CSNH3uYbdK3o0NxyMmaQPTNgW+ko+am92DLC8QSTe4kyxTuEkI5S5w== - /rollup-plugin-commonjs/10.0.2_rollup@1.19.4: + /rollup-plugin-commonjs/10.1.0_rollup@1.20.3: dependencies: estree-walker: 0.6.1 is-reference: 1.1.3 magic-string: 0.25.3 resolve: 1.12.0 - rollup: 1.19.4 + rollup: 1.20.3 rollup-pluginutils: 2.8.1 dev: false peerDependencies: rollup: '>=1.12.0' resolution: - integrity: sha512-DxeR4QXTgTOFseYls1V7vgKbrSJmPYNdEMOs0OvH+7+89C3GiIonU9gFrE0u39Vv1KWm3wepq8KAvKugtoM2Zw== + integrity: sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q== /rollup-plugin-inject/3.0.1: dependencies: estree-walker: 0.6.1 @@ -7847,13 +7832,13 @@ packages: dev: false resolution: integrity: sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g== - /rollup-plugin-node-resolve/5.2.0_rollup@1.19.4: + /rollup-plugin-node-resolve/5.2.0_rollup@1.20.3: dependencies: '@types/resolve': 0.0.8 builtin-modules: 3.1.0 is-module: 1.0.0 resolve: 1.12.0 - rollup: 1.19.4 + rollup: 1.20.3 rollup-pluginutils: 2.8.1 dev: false peerDependencies: @@ -7871,9 +7856,9 @@ packages: dev: false resolution: integrity: sha512-rZqFD43y4U9nSqVq3iyWBiDwmBQJY8Txi04yI9jTKD3xcl7CbFjh1qRpQshUB3sONLubDzm7vJiwB+1MEGv67w== - /rollup-plugin-sourcemaps/0.4.2_rollup@1.19.4: + /rollup-plugin-sourcemaps/0.4.2_rollup@1.20.3: dependencies: - rollup: 1.19.4 + rollup: 1.20.3 rollup-pluginutils: 2.8.1 source-map-resolve: 0.5.2 dev: false @@ -7884,24 +7869,24 @@ packages: rollup: '>=0.31.2' resolution: integrity: sha1-YhJaqUCHqt97g+9N+vYptHMTXoc= - /rollup-plugin-terser/5.1.1_rollup@1.19.4: + /rollup-plugin-terser/5.1.1_rollup@1.20.3: dependencies: '@babel/code-frame': 7.5.5 jest-worker: 24.9.0 - rollup: 1.19.4 + rollup: 1.20.3 rollup-pluginutils: 2.8.1 serialize-javascript: 1.8.0 - terser: 4.2.0 + terser: 4.2.1 dev: false peerDependencies: rollup: '>=0.66.0 <2' resolution: integrity: sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ== - /rollup-plugin-uglify/6.0.2_rollup@1.19.4: + /rollup-plugin-uglify/6.0.2_rollup@1.20.3: dependencies: '@babel/code-frame': 7.5.5 jest-worker: 24.9.0 - rollup: 1.19.4 + rollup: 1.20.3 serialize-javascript: 1.8.0 uglify-js: 3.6.0 dev: false @@ -7909,12 +7894,12 @@ packages: rollup: '>=0.66.0 <2' resolution: integrity: sha512-qwz2Tryspn5QGtPUowq5oumKSxANKdrnfz7C0jm4lKxvRDsNe/hSGsB9FntUul7UeC4TsZEWKErVgE1qWSO0gw== - /rollup-plugin-visualizer/2.5.4_rollup@1.19.4: + /rollup-plugin-visualizer/2.5.4_rollup@1.20.3: dependencies: mkdirp: 0.5.1 open: 6.4.0 pupa: 2.0.1 - rollup: 1.19.4 + rollup: 1.20.3 source-map: 0.7.3 dev: false engines: @@ -7929,15 +7914,15 @@ packages: dev: false resolution: integrity: sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg== - /rollup/1.19.4: + /rollup/1.20.3: dependencies: '@types/estree': 0.0.39 '@types/node': 12.7.2 - acorn: 6.3.0 + acorn: 7.0.0 dev: false hasBin: true resolution: - integrity: sha512-G24w409GNj7i/Yam2cQla6qV2k6Nug8bD2DZg9v63QX/cH/dEdbNJg8H4lUm5M1bRpPKRUC465Rm9H51JTKOfQ== + integrity: sha512-/OMCkY0c6E8tleeVm4vQVDz24CkVgvueK3r8zTYu2AQNpjrcaPwO9hE+pWj5LTFrvvkaxt4MYIp2zha4y0lRvg== /run-async/2.3.0: dependencies: is-promise: 2.1.0 @@ -8139,7 +8124,7 @@ packages: '@sinonjs/samsam': 3.3.3 diff: 3.5.0 lolex: 4.2.0 - nise: 1.5.1 + nise: 1.5.2 supports-color: 5.5.0 dev: false resolution: @@ -8309,7 +8294,7 @@ packages: node: '>= 0.10' resolution: integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== - /spawn-wrap/1.4.2: + /spawn-wrap/1.4.3: dependencies: foreground-child: 1.5.6 mkdirp: 0.5.1 @@ -8319,7 +8304,7 @@ packages: which: 1.3.1 dev: false resolution: - integrity: sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + integrity: sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw== /spdx-correct/3.1.0: dependencies: spdx-expression-parse: 3.0.0 @@ -8486,16 +8471,6 @@ packages: node: '>=6' resolution: integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - /string-width/4.1.0: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 5.2.0 - dev: false - engines: - node: '>=8' - resolution: - integrity: sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ== /string.prototype.padend/3.0.0: dependencies: define-properties: 1.1.3 @@ -8655,7 +8630,7 @@ packages: node: '>=6' resolution: integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - /terser-webpack-plugin/1.4.1_webpack@4.39.2: + /terser-webpack-plugin/1.4.1_webpack@4.39.3: dependencies: cacache: 12.0.3 find-cache-dir: 2.1.0 @@ -8663,8 +8638,8 @@ packages: schema-utils: 1.0.0 serialize-javascript: 1.8.0 source-map: 0.6.1 - terser: 4.2.0 - webpack: 4.39.2_webpack@4.39.2 + terser: 4.2.1 + webpack: 4.39.3_webpack@4.39.3 webpack-sources: 1.4.3 worker-farm: 1.7.0 dev: false @@ -8674,7 +8649,7 @@ packages: webpack: ^4.0.0 resolution: integrity: sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg== - /terser/4.2.0: + /terser/4.2.1: dependencies: commander: 2.20.0 source-map: 0.6.1 @@ -8684,7 +8659,7 @@ packages: node: '>=6.0.0' hasBin: true resolution: - integrity: sha512-6lPt7lZdZ/13icQJp8XasFOwZjFJkxFFIb/N1fhYEQNoNI3Ilo3KABZ9OocZvZoB39r6SiIk/0+v/bt8nZoSeA== + integrity: sha512-cGbc5utAcX4a9+2GGVX4DsenG6v0x3glnDi5hx8816X1McEAwPlPgRtXPJzSBsbpILxZ8MQMT0KvArLuE0HP5A== /test-exclude/5.2.3: dependencies: glob: 7.1.4 @@ -8884,14 +8859,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - /ts-loader/6.0.4_typescript@3.5.3: + /ts-loader/6.0.4_typescript@3.6.2: dependencies: chalk: 2.4.2 enhanced-resolve: 4.1.0 loader-utils: 1.2.3 micromatch: 4.0.2 semver: 6.3.0 - typescript: 3.5.3 + typescript: 3.6.2 dev: false engines: node: '>=8.6' @@ -8929,13 +8904,13 @@ packages: hasBin: true resolution: integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== - /ts-node/8.3.0_typescript@3.5.3: + /ts-node/8.3.0_typescript@3.6.2: dependencies: arg: 4.1.1 diff: 4.0.1 make-error: 1.3.5 source-map-support: 0.5.13 - typescript: 3.5.3 + typescript: 3.6.2 yn: 3.1.1 dev: false engines: @@ -8960,10 +8935,10 @@ packages: dev: false resolution: integrity: sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - /tsutils/3.17.1_typescript@3.5.3: + /tsutils/3.17.1_typescript@3.6.2: dependencies: tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 dev: false engines: node: '>= 6' @@ -9005,12 +8980,6 @@ packages: node: '>=4' resolution: integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - /type-fest/0.5.2: - dev: false - engines: - node: '>=6' - resolution: - integrity: sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== /type-is/1.6.18: dependencies: media-typer: 0.3.0 @@ -9035,6 +9004,13 @@ packages: hasBin: true resolution: integrity: sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== + /typescript/3.6.2: + dev: false + engines: + node: '>=4.2.0' + hasBin: true + resolution: + integrity: sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw== /uglify-js/3.6.0: dependencies: commander: 2.20.0 @@ -9055,10 +9031,6 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-5z3T17DXxe2G+6xrCufYxqadUPo= - /underscore/1.4.4: - dev: false - resolution: - integrity: sha1-YaajIBBiKvoHljvzJSA88SI51gQ= /underscore/1.8.3: dev: false resolution: @@ -9337,7 +9309,7 @@ packages: integrity: sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= /watchpack/1.6.0: dependencies: - chokidar: 2.1.6 + chokidar: 2.1.8 graceful-fs: 4.2.2 neo-async: 2.6.1 dev: false @@ -9347,7 +9319,7 @@ packages: dev: false resolution: integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - /webpack-cli/3.3.7_webpack@4.39.2: + /webpack-cli/3.3.7_webpack@4.39.3: dependencies: chalk: 2.4.2 cross-spawn: 6.0.5 @@ -9359,7 +9331,7 @@ packages: loader-utils: 1.2.3 supports-color: 6.1.0 v8-compile-cache: 2.0.3 - webpack: 4.39.2_webpack@4.39.2 + webpack: 4.39.3_webpack@4.39.3 yargs: 13.2.4 dev: false engines: @@ -9369,12 +9341,12 @@ packages: webpack: 4.x.x resolution: integrity: sha512-OhTUCttAsr+IZSMVwGROGRHvT+QAs8H6/mHIl4SvhAwYywjiylYjpwybGx7WQ9Hkb45FhjtsymkwiRRbGJ1SZQ== - /webpack-dev-middleware/3.7.0_webpack@4.39.2: + /webpack-dev-middleware/3.7.0_webpack@4.39.3: dependencies: memory-fs: 0.4.1 mime: 2.4.4 range-parser: 1.2.1 - webpack: 4.39.2_webpack@4.39.2 + webpack: 4.39.3_webpack@4.39.3 webpack-log: 2.0.0 dev: false engines: @@ -9399,7 +9371,7 @@ packages: dev: false resolution: integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - /webpack/4.39.2_webpack@4.39.2: + /webpack/4.39.3_webpack@4.39.3: dependencies: '@webassemblyjs/ast': 1.8.5 '@webassemblyjs/helper-module-context': 1.8.5 @@ -9421,7 +9393,7 @@ packages: node-libs-browser: 2.2.1 schema-utils: 1.0.0 tapable: 1.1.3 - terser-webpack-plugin: 1.4.1_webpack@4.39.2 + terser-webpack-plugin: 1.4.1_webpack@4.39.3 watchpack: 1.6.0 webpack-sources: 1.4.3 dev: false @@ -9431,7 +9403,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA== + integrity: sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ== /whatwg-url/6.5.0: dependencies: lodash.sortby: 4.7.0 @@ -9794,26 +9766,26 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 delay: 4.3.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -9821,16 +9793,16 @@ packages: nyc: 14.1.1 prettier: 1.18.2 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - ts-node: 8.3.0_typescript@3.5.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 dev: false name: '@rush-temp/abort-controller' resolution: @@ -9849,25 +9821,25 @@ packages: '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/sinon': 7.0.13 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 async-lock: 1.2.2 - buffer: 5.4.0 + buffer: 5.4.2 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 cross-env: 5.2.0 debug: 3.2.6 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 is-buffer: 2.0.3 jssha: 2.3.1 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-mocha: 1.3.0 mocha: 6.2.0 @@ -9880,22 +9852,22 @@ packages: rhea: 1.0.8 rhea-promise: 1.0.0 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 rollup-plugin-node-globals: 1.4.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 sinon: 7.4.1 stream-browserify: 2.0.2 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 url: 0.11.0 util: 0.12.1 ws: 7.1.2 @@ -9910,12 +9882,12 @@ packages: '@types/chai': 4.2.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 chai: 4.2.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 mocha: 6.2.0 @@ -9924,14 +9896,14 @@ packages: npm-run-all: 4.1.5 nyc: 14.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 shx: 0.3.2 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 yarn: 1.17.3 dev: false @@ -9943,15 +9915,15 @@ packages: 'file:projects/core-asynciterator-polyfill.tgz': dependencies: '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 prettier: 1.18.2 - typescript: 3.5.3 + typescript: 3.6.2 dev: false name: '@rush-temp/core-asynciterator-polyfill' resolution: @@ -9963,13 +9935,13 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 inherits: 2.0.4 @@ -9978,17 +9950,17 @@ packages: mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/core-auth' @@ -10012,33 +9984,31 @@ packages: '@types/tough-cookie': 2.3.5 '@types/tunnel': 0.0.1 '@types/uuid': 3.4.5 - '@types/webpack': 4.39.0 + '@types/webpack': 4.39.1 '@types/webpack-dev-middleware': 2.0.3 '@types/xml2js': 0.4.4 - '@types/xmlbuilder': 11.0.1 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 babel-runtime: 6.26.0 - buffer: 5.4.0 + buffer: 5.4.2 chai: 4.2.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 express: 4.17.1 - fast-xml-parser: 3.12.20 fetch-mock: 7.3.9 form-data: 2.5.0 glob: 7.1.4 - karma: 4.2.0 - karma-chai: 0.1.0_chai@4.2.0+karma@4.2.0 + karma: 4.3.0 + karma-chai: 0.1.0_chai@4.2.0+karma@4.3.0 karma-chrome-launcher: 3.1.0 karma-mocha: 1.3.0 - karma-rollup-preprocessor: 7.0.2_rollup@1.19.4 + karma-rollup-preprocessor: 7.0.2_rollup@1.20.3 karma-sourcemap-loader: 0.3.7 karma-typescript-es6-transform: 4.1.1 - karma-webpack: 4.0.2_webpack@4.39.2 + karma-webpack: 4.0.2_webpack@4.39.3 mocha: 6.2.0 mocha-chrome: 2.0.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -10050,30 +10020,29 @@ packages: puppeteer: 1.19.0 regenerator-runtime: 0.13.3 rimraf: 2.7.1 - rollup: 1.19.4 + rollup: 1.20.3 rollup-plugin-alias: 1.5.2 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 semver: 5.7.1 shx: 0.3.2 sinon: 7.4.1 - terser: 4.2.0 + terser: 4.2.1 tough-cookie: 3.0.1 - ts-loader: 6.0.4_typescript@3.5.3 - ts-node: 8.3.0_typescript@3.5.3 + ts-loader: 6.0.4_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 tunnel: 0.0.6 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 - underscore: 1.4.4 uuid: 3.3.3 - webpack: 4.39.2_webpack@4.39.2 - webpack-cli: 3.3.7_webpack@4.39.2 - webpack-dev-middleware: 3.7.0_webpack@4.39.2 + webpack: 4.39.3_webpack@4.39.3 + webpack-cli: 3.3.7_webpack@4.39.3 + webpack-dev-middleware: 3.7.0_webpack@4.39.3 xhr-mock: 2.5.0 xml2js: 0.4.19 xmlbuilder: 0.4.3 @@ -10081,22 +10050,22 @@ packages: dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-9XQ12/wFXJSTZV162Y/HEK9GoOtwggro+S2/G55qMwgL6zVjGfPI0/AkU/jzP+qsXjybV9LkUg9ixmchWvr5Xg== + integrity: sha512-Dfkft2Q6+Vr7JtMQLUj/2cQXdbBiH8v7SExaEdbe+lz58f+lVgtThUV4lYpRXK162aTy7JlwT077zS1C0tJ1SA== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': dependencies: '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 prettier: 1.18.2 - typescript: 3.5.3 + typescript: 3.6.2 dev: false name: '@rush-temp/core-paging' resolution: @@ -10108,13 +10077,13 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 inherits: 2.0.4 @@ -10123,17 +10092,17 @@ packages: mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/core-tracing' @@ -10155,36 +10124,36 @@ packages: '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/uuid': 3.4.5 - '@types/ws': 6.0.2 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@types/ws': 6.0.3 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 async-lock: 1.2.2 - buffer: 5.4.0 + buffer: 5.4.2 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 cross-env: 5.2.0 debug: 3.2.6 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 is-buffer: 2.0.3 jssha: 2.3.1 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -10195,20 +10164,20 @@ packages: puppeteer: 1.19.0 rhea-promise: 1.0.0 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 ts-mocha: 6.0.0_mocha@6.2.0 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uuid: 3.3.3 ws: 7.1.2 dev: false @@ -10231,9 +10200,9 @@ packages: '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/uuid': 3.4.5 - '@types/ws': 6.0.2 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@types/ws': 6.0.3 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 async-lock: 1.2.2 azure-storage: 2.10.3 chai: 4.2.0 @@ -10242,9 +10211,9 @@ packages: cross-env: 5.2.0 debug: 3.2.6 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 @@ -10255,17 +10224,17 @@ packages: path-browserify: 1.0.0 prettier: 1.18.2 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-uglify: 6.0.2_rollup@1.19.4 - ts-node: 8.3.0_typescript@3.5.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-uglify: 6.0.2_rollup@1.20.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uuid: 3.3.3 ws: 7.1.2 dev: false @@ -10281,23 +10250,23 @@ packages: '@types/node': 8.10.52 '@types/qs': 6.5.3 '@types/uuid': 3.4.5 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.1 + eslint: 6.2.2 events: 3.0.0 inherits: 2.0.4 jws: 3.2.2 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 karma-env-preprocessor: 0.1.1 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -10307,17 +10276,17 @@ packages: puppeteer: 1.19.0 qs: 6.8.0 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 uuid: 3.3.3 dev: false @@ -10339,53 +10308,53 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 url: 0.11.0 dev: false @@ -10408,53 +10377,53 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 url: 0.11.0 dev: false @@ -10475,53 +10444,53 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uglify-js: 3.6.0 url: 0.11.0 dev: false @@ -10545,34 +10514,34 @@ packages: '@types/long': 4.0.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@types/ws': 6.0.2 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@types/ws': 6.0.3 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 - buffer: 5.4.0 + buffer: 5.4.2 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 cross-env: 5.2.0 debug: 3.2.6 delay: 4.3.0 dotenv: 8.1.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 is-buffer: 2.0.3 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 long: 4.0.0 mocha: 6.2.0 @@ -10587,24 +10556,24 @@ packages: rhea: 1.0.8 rhea-promise: 0.1.15 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - ts-node: 8.3.0_typescript@3.5.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 ws: 7.1.2 dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-FwSxg/1Ynbnbyna5nzRpMryYhlKwPQagswhSvdmTEBT14skEz2wxcO1ZCalQL3yUHxtLqNTbwSEWs/m1iwVRbQ== + integrity: sha512-T1C1Z51gQB4jheztKHYtaVy343I9ljyH70RintWH0IQN6pseu93pIU4jiBMaAYQH1HFZK7SLIEInKFN8YkVdEg== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -10618,15 +10587,15 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 @@ -10634,42 +10603,42 @@ packages: gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/storage-blob' @@ -10688,15 +10657,15 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 @@ -10704,42 +10673,42 @@ packages: gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/storage-file' @@ -10758,57 +10727,57 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-json-preprocessor: 0.3.3_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.3.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.1 + nise: 1.5.2 nock: 10.0.6 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/storage-queue' @@ -10821,44 +10790,44 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff - '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.1 - eslint-config-prettier: 6.1.0_eslint@6.2.1 - eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint: 6.2.2 + eslint-config-prettier: 6.1.0_eslint@6.2.2 + eslint-plugin-no-null: 1.0.2_eslint@6.2.2 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 inherits: 2.0.4 - karma: 4.2.0 + karma: 4.3.0 karma-chrome-launcher: 3.1.0 karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.2.0 + karma-edge-launcher: 0.4.2_karma@4.3.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.2.0 - karma-junit-reporter: 1.2.0_karma@4.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 rimraf: 2.7.1 - rollup: 1.19.4 - rollup-plugin-commonjs: 10.0.2_rollup@1.19.4 + rollup: 1.20.3 + rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.19.4 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.19.4 - rollup-plugin-terser: 5.1.1_rollup@1.19.4 - rollup-plugin-visualizer: 2.5.4_rollup@1.19.4 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 util: 0.12.1 dev: false name: '@rush-temp/template' @@ -10878,7 +10847,7 @@ packages: rhea: 1.0.8 rimraf: 2.7.1 tslib: 1.10.0 - typescript: 3.5.3 + typescript: 3.6.2 uuid: 3.3.3 yargs: 13.3.0 dev: false @@ -10887,7 +10856,6 @@ packages: integrity: sha512-5P+X3IwgFa9rlq+jbtHxWVZWF1kDmRZwV8jQfHMYV5CLsJjXKw1yISIRSFmCmuXDdHYEnxO1bnRGi34QeZ+63g== tarball: 'file:projects/testhub.tgz' version: 0.0.0 -registry: '' specifiers: '@azure/amqp-common': 1.0.0-preview.6 '@azure/arm-servicebus': ^3.2.0 @@ -10975,7 +10943,6 @@ specifiers: eslint-plugin-promise: ^4.1.1 events: ^3.0.0 express: ^4.16.3 - fast-xml-parser: ^3.12.20 fetch-mock: ^7.3.9 form-data: ^2.5.0 fs-extra: ^8.1.0 @@ -11065,5 +11032,6 @@ specifiers: ws: ^7.1.1 xhr-mock: ^2.4.1 xml2js: ^0.4.19 + xmlbuilder: ^0.4.3 yargs: ^13.0.0 yarn: ^1.6.0 From d64198cb01b49112380149504b39e9cc2cfb67a6 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 28 Aug 2019 17:23:18 -0700 Subject: [PATCH 07/72] Minor refactoring and verify all tests pass in browser --- .../lib/policies/atomSerializationPolicy.ts | 12 ++++++------ sdk/core/core-http/lib/util/atomHandler.ts | 16 ++++++++-------- sdk/core/core-http/lib/util/xml.browser.ts | 5 +++-- sdk/core/core-http/lib/util/xml.ts | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index d15fe7e6f53c..6d4006cc3653 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -10,7 +10,7 @@ import { RequestPolicyOptions } from "./requestPolicy"; import { Constants } from "../util/constants"; -import { parseAtomXML } from "../util/xml"; +import { parseAtomXmlDataToJson } from "../util/xml"; import { isString, extend, byteLength } from "../util/utils"; import { ResourceSerializer } from "../resourceSerializer"; @@ -75,7 +75,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { * @return The normalized responseObject. */ private parseResponse(response: HttpOperationResponse): HttpOperationResponse { - const parsedResponse: HttpOperationResponse = this._parseXmlResponse(response); + const parsedResponse: HttpOperationResponse = this._parseXmlResponseToJson(response); if (response.status >= 200 && response.status < 300 && response.errorBody == undefined) { return response; @@ -98,11 +98,11 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { return parsedResponse; } - private _parseXmlResponse(response: HttpOperationResponse): HttpOperationResponse { - const parsedResponse = response; + private _parseXmlResponseToJson(responseInXml: HttpOperationResponse): HttpOperationResponse { + const parsedResponse = responseInXml; try { - if (response.bodyAsText && byteLength(response.bodyAsText.toString()) > 0) { - parsedResponse.parsedBody = parseAtomXML(response.bodyAsText); + if (responseInXml.bodyAsText && byteLength(responseInXml.bodyAsText.toString()) > 0) { + parsedResponse.parsedBody = parseAtomXmlDataToJson(responseInXml.bodyAsText); } } catch (e) { parsedResponse.errorBody = { diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index 3546de07de87..9b9860a7d956 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -19,8 +19,6 @@ import { isArray, each, stringIsEmpty, stringStartsWith, isDate, isObject, isNod let xmlbuilder: any; if (isNode) { xmlbuilder = require("xmlbuilder"); -} else { - xmlbuilder = {}; } export class AtomHandler { @@ -51,6 +49,8 @@ export class AtomHandler { * @param {array} namespaces An array of top level namespaces to be defined. */ serializeEntry(content: any, namespaces?: any, properties?: any): any { + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + if (isNode) { var doc = xmlbuilder.create(); @@ -70,18 +70,18 @@ export class AtomHandler { doc = doc.ele("updated", new Date().toISOString()).up(); - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - doc = this._writeElementValue(doc, "content", content); - return doc.doc().toString(); } const serializer = new XMLSerializer(); const dom = this.buildNode(content, "content")[0]; - return ( - '' + serializer.serializeToString(dom) - ); + const result = + `${new Date().toISOString()}` + + serializer.serializeToString(dom) + + ``; + console.log(result); + return result; } buildNode(obj: any, elementName: string): Node[] { diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 0f26d20eb8f6..d27e2845e2e5 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -148,8 +148,9 @@ function buildNode(obj: any, elementName: string): Node[] { } } -export function parseAtomXML(body: any): any { +export function parseAtomXmlDataToJson(body: any): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); - return domToObject(dom.childNodes[0]); + const result = domToObject(dom); + return result; } diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 0a15b008e2ad..f9979037772e 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -36,7 +36,7 @@ export function parseXML(str: string): Promise { }); } -export function parseAtomXML(body: any): any { +export function parseAtomXmlDataToJson(body: any): any { var parsed; var parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { From 03156b38b3c5846cf6e65b18722ecf50799c4958 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 29 Aug 2019 15:00:03 -0700 Subject: [PATCH 08/72] Streamline browserification, address comments on modernization --- .../lib/atomResourceSerializerBase.ts | 50 ++-- .../sasServiceClientCredentials.ts | 47 +-- .../lib/policies/atomSerializationPolicy.ts | 59 ++-- sdk/core/core-http/lib/resourceSerializer.ts | 6 +- sdk/core/core-http/lib/util/atomHandler.ts | 282 +++--------------- sdk/core/core-http/lib/util/crypto.browser.ts | 30 ++ sdk/core/core-http/lib/util/crypto.ts | 14 + sdk/core/core-http/lib/util/utils.ts | 137 +-------- sdk/core/core-http/lib/util/xml.browser.ts | 58 ++-- sdk/core/core-http/lib/util/xml.ts | 112 ++++++- sdk/core/core-http/package.json | 1 + sdk/core/core-http/rollup.config.ts | 1 + .../policies/atomSerializationPolicyTests.ts | 10 +- sdk/core/core-http/webpack.testconfig.ts | 33 +- 14 files changed, 346 insertions(+), 494 deletions(-) create mode 100644 sdk/core/core-http/lib/util/crypto.browser.ts create mode 100644 sdk/core/core-http/lib/util/crypto.ts diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 79dd3a5d4f04..192ef16d997d 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -16,27 +16,11 @@ import { isNode } from "./util/utils"; import { Constants } from "./util/constants"; -import { AtomHandler } from "./util/atomHandler"; -import { each, isUndefined, isArray } from "./util/utils"; - -const atomHandler = new AtomHandler(); +import { serializeJsonToAtomXml } from "./util/xml"; +import { parseResultFromAtomResponse } from "./util/atomHandler"; export class AtomResourceSerializerBase { - static setName(entry: any, nameProperty: any): any { - let parsedUrl: any; - if (isNode) { - parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); - } else { - parsedUrl = new window.URL(entry[Constants.ATOM_METADATA_MARKER].id); - } - var parts = parsedUrl.pathname!.split("/"); - - for (var i = 0; i * 2 < parts.length - 1; i++) { - entry[nameProperty[i]] = parts[i * 2 + 1]; - } - } - - static _serialize(resourceName: any, resource: any, properties: any): any { + static serializeToAtomXmlRequest(resourceName: any, resource: any, properties: any): any { var content: any = {}; content[resourceName] = { $: { @@ -46,24 +30,24 @@ export class AtomResourceSerializerBase { if (resource) { // Sort properties according to what is allowed by the service - each(properties, function(property: any): any { - if (!isUndefined(resource[property])) { + properties.forEach((property: any) => { + if (resource[property] !== undefined) { content[resourceName][property] = resource[property]; } }); } - return atomHandler.serializeEntry(content); + return serializeJsonToAtomXml(content); } - static _parse(nameProperty: any, xml: any): any { - var result = atomHandler.parse(xml); + static deserializeAtomResponse(nameProperty: any, atomResponseInJson: any): any { + var result = parseResultFromAtomResponse(atomResponseInJson); if (!result) { return undefined; } - if (isArray(result)) { - each(result, function(entry: any): any { + if (Array.isArray(result)) { + result.forEach((entry: any) => { AtomResourceSerializerBase.setName(entry, nameProperty); }); } else { @@ -71,4 +55,18 @@ export class AtomResourceSerializerBase { } return result; } + + private static setName(entry: any, nameProperty: any): any { + let parsedUrl: any; + if (isNode) { + parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); + } else { + parsedUrl = new window.URL(entry[Constants.ATOM_METADATA_MARKER].id); + } + var parts = parsedUrl.pathname!.split("/"); + + for (var i = 0; i * 2 < parts.length - 1; i++) { + entry[nameProperty[i]] = parts[i * 2 + 1]; + } + } } diff --git a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts index 090cf0ce0d7d..07beb1369ca4 100644 --- a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts +++ b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts @@ -5,8 +5,7 @@ import { HttpHeaders } from "../httpHeaders"; import { WebResource } from "../webResource"; import { ServiceClientCredentials } from "./serviceClientCredentials"; import { Constants } from "../util/constants"; -import { objectIsNull, isNode } from "../util/utils"; -import crypto from "crypto"; +import { generateKey } from "../util/crypto"; const HeaderConstants = Constants.HeaderConstants; @@ -21,21 +20,13 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { * @param {string} connectionString Connection string. */ constructor(sharedAccessKeyName: string, sharedAccessKey: string) { - if ( - sharedAccessKeyName === null || - sharedAccessKeyName === undefined || - typeof sharedAccessKeyName.valueOf() !== "string" - ) { + if (sharedAccessKeyName == null) { throw new Error( "sharedAccessKeyName cannot be null or undefined and must be of type string." ); } - if ( - sharedAccessKey === null || - sharedAccessKey === undefined || - typeof sharedAccessKey.valueOf() !== "string" - ) { + if (sharedAccessKey == null) { throw new Error("sharedAccessKey cannot be null or undefined and must be of type string."); } @@ -45,10 +36,10 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { this.keyValue = keyValue; } - private _generateSignature(targetUri: any, expirationDate: any): any { - const getvalueToAppend = function(value: any, noNewLine?: any): any { + private async _generateSignature(targetUri: any, expirationDate: any): Promise { + const getValueToAppend = function(value: any, noNewLine?: any): any { var returnValue = ""; - if (!objectIsNull(value)) { + if (value != null) { returnValue = value; } @@ -59,24 +50,10 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { return returnValue; }; - var stringToSign = getvalueToAppend(targetUri) + getvalueToAppend(expirationDate, true); + var stringToSign = getValueToAppend(targetUri) + getValueToAppend(expirationDate, true); - if (isNode) { - // HmacSha256Sign - const result = encodeURIComponent( - crypto - .createHmac("sha256", this.keyValue) - .update(stringToSign) - .digest("base64") - ); - return result; - } else { - // @ts-ignore - var hash = CryptoJS.HmacSHA256(stringToSign, this.keyValue); - // @ts-ignore - const result = encodeURIComponent(CryptoJS.enc.Base64.stringify(hash)); - return result; - } + const result = await generateKey(this.keyValue, stringToSign); + return result; } /** @@ -85,7 +62,7 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { * @param {WebResource} webResource The WebResource to be signed. * @returns {Promise} The signed request object. */ - signRequest(webResource: WebResource): any { + async signRequest(webResource: WebResource): Promise { if (!webResource.headers) webResource.headers = new HttpHeaders(); var targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); @@ -93,13 +70,11 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { let date = new Date(); date.setMinutes(date.getMinutes() + 5); var expirationDate = Math.round(date.valueOf() / 1000); - var signature = this._generateSignature(targetUri, expirationDate); + var signature = await this._generateSignature(targetUri, expirationDate); webResource.headers.set( HeaderConstants.AUTHORIZATION, `SharedAccessSignature sig=${signature}&se=${expirationDate}&skn=${this.keyName}&sr=${targetUri}` ); - // TODO: Fix server side configuration on response headers - webResource.headers.set("access-control-allow-origin", "*"); return Promise.resolve(webResource); } } diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 6d4006cc3653..4353e905a77a 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -10,8 +10,8 @@ import { RequestPolicyOptions } from "./requestPolicy"; import { Constants } from "../util/constants"; -import { parseAtomXmlDataToJson } from "../util/xml"; -import { isString, extend, byteLength } from "../util/utils"; +import { deserializeAtomXmlToJson } from "../util/xml"; +import { isString, byteLength } from "../util/utils"; import { ResourceSerializer } from "../resourceSerializer"; /** @@ -102,7 +102,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const parsedResponse = responseInXml; try { if (responseInXml.bodyAsText && byteLength(responseInXml.bodyAsText.toString()) > 0) { - parsedResponse.parsedBody = parseAtomXmlDataToJson(responseInXml.bodyAsText); + parsedResponse.parsedBody = deserializeAtomXmlToJson(responseInXml.bodyAsText); } } catch (e) { parsedResponse.errorBody = { @@ -112,41 +112,37 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { return parsedResponse; } - _normalizeError(error: any, response: HttpOperationResponse): any { + private _normalizeError(error: any, response: HttpOperationResponse): any { if (isString(error)) { return new Error(error); } else if (error) { - var normalizedError: any = {}; + const normalizedError: any = {}; + const odataErrorFormat = !!error["odata.error"]; + const errorProperties = error.Error || error.error || error["odata.error"] || error; - var odataErrorFormat = !!error["odata.error"]; - var errorProperties = error.Error || error.error || error["odata.error"] || error; if (odataErrorFormat) { - for (var property in errorProperties) { - if (errorProperties.hasOwnProperty(property)) { - var value = null; + Object.keys(errorProperties).forEach((property: any) => { + let value = null; + if ( + property === Constants.ODATA_ERROR_MESSAGE && + !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + ) { if ( - property === Constants.ODATA_ERROR_MESSAGE && - !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE] ) { - if ( - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE] - ) { - value = - errorProperties[Constants.ODATA_ERROR_MESSAGE][ - Constants.ODATA_ERROR_MESSAGE_VALUE - ]; - } else { - value = "missing value in the message property of the odata error format"; - } + value = + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; } else { - value = errorProperties[property]; + value = "missing value in the message property of the odata error format"; } - normalizedError[property.toLowerCase()] = value; + } else { + value = errorProperties[property]; } - } + normalizedError[property.toLowerCase()] = value; + }); } else { - for (var property in errorProperties) { - if (errorProperties.hasOwnProperty(property)) { + Object.keys(errorProperties).forEach((property: any) => { + { var value = null; if (property !== "$") { if (errorProperties[property] && errorProperties[property]["_"]) { @@ -157,7 +153,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { normalizedError[property.toLowerCase()] = value; } } - } + }); } var errorMessage = normalizedError.code; if (normalizedError.detail) { @@ -174,8 +170,11 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } } - var errorObject = new Error(errorMessage); - return extend(errorObject, normalizedError); + var errorObject: any = { error: { code: errorMessage } }; + Object.keys(normalizedError).forEach((property: any) => { + errorObject[property] = normalizedError[property]; + }); + return errorObject; } return undefined; diff --git a/sdk/core/core-http/lib/resourceSerializer.ts b/sdk/core/core-http/lib/resourceSerializer.ts index cccdd1e68922..3e4daa78e63e 100644 --- a/sdk/core/core-http/lib/resourceSerializer.ts +++ b/sdk/core/core-http/lib/resourceSerializer.ts @@ -14,8 +14,8 @@ // limitations under the License. // -export abstract class ResourceSerializer { - abstract serialize(resource: any): any; +export interface ResourceSerializer { + serialize(resource: any): any; - abstract parse(xml: any): any; + parse(xml: any): any; } diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index 9b9860a7d956..cdbab5bc81f1 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -1,261 +1,63 @@ -// -// Copyright (c) Microsoft and contributors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - import { Constants } from "./constants"; -import { isArray, each, stringIsEmpty, stringStartsWith, isDate, isObject, isNode } from "./utils"; -let xmlbuilder: any; -if (isNode) { - xmlbuilder = require("xmlbuilder"); -} - -export class AtomHandler { - /** - * Utility to deserialize the given content even further based on - * if it's a single `entry` or `feed` - * @param {object} xmlInJson - * */ - parse(xmlInJson: any): any { - var self = this; - if (!xmlInJson) { - return; - } - if (xmlInJson.feed) { - return self.parseFeedResult(xmlInJson.feed); - } - - if (xmlInJson.entry) { - return self.parseEntryResult(xmlInJson.entry); - } - - throw new Error("Unrecognized result: " + xmlInJson); +/** + * Utility to deserialize the given JSON content even further based on + * if it's a single `entry` or `feed` + * @param {object} xmlInJson + * */ +export function parseResultFromAtomResponse(atomResponseInJson: any): any { + if (!atomResponseInJson) { + return; } - /** - * @param {object} content The content payload as it is to be serialized. It should include any root node(s). - * @param {array} namespaces An array of top level namespaces to be defined. - */ - serializeEntry(content: any, namespaces?: any, properties?: any): any { - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - - if (isNode) { - var doc = xmlbuilder.create(); - - doc = doc - .begin("entry", { version: "1.0", encoding: "utf-8", standalone: "yes" }) - .att("xmlns", "http://www.w3.org/2005/Atom"); - - each(namespaces, function(namespace: any): any { - doc = doc.att("xmlns:" + namespace.key, namespace.url); - }); - - if (properties) { - Object.keys(properties).forEach(function(property) { - doc = doc.ele(property, properties[property]).up(); - }); - } - - doc = doc.ele("updated", new Date().toISOString()).up(); - - doc = this._writeElementValue(doc, "content", content); - return doc.doc().toString(); - } - - const serializer = new XMLSerializer(); - const dom = this.buildNode(content, "content")[0]; - const result = - `${new Date().toISOString()}` + - serializer.serializeToString(dom) + - ``; - console.log(result); - return result; + if (atomResponseInJson.feed) { + return parseFeedResult(atomResponseInJson.feed); } - buildNode(obj: any, elementName: string): Node[] { - // tslint:disable-next-line:no-null-keyword - - const doc = document.implementation.createDocument(null, "entry", null); - if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { - const elem = doc.createElement(elementName); - elem.textContent = obj.toString(); - return [elem]; - } else if (Array.isArray(obj)) { - const result = []; - for (const arrayElem of obj) { - for (const child of this.buildNode(arrayElem, elementName)) { - result.push(child); - } - } - return result; - } else if (typeof obj === "object") { - const elem = doc.createElement(elementName); - for (const key of Object.keys(obj)) { - if (key === "$") { - for (const attr of this.buildAttributes(doc, obj[key])) { - elem.attributes.setNamedItem(attr); - } - } else { - for (const child of this.buildNode(obj[key], key)) { - elem.appendChild(child); - } - } - } - return [elem]; - } else { - throw new Error(`Illegal value passed to buildObject: ${obj}`); - } + if (atomResponseInJson.entry) { + return parseEntryResult(atomResponseInJson.entry); } - buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { - const result = []; - for (const key of Object.keys(attrs)) { - const attr = doc.createAttribute(key); - attr.value = attrs[key].toString(); - result.push(attr); - } - return result; - } - - /* - * Writes a single property for an entry or complex type. - * - * @param {object} parentElement Parent DOM element under which the property should be added. - * @param {string} name Property name. - * @param {object} value Property value. - * @return {object} The current DOM element. - * - * {Deprecated} - */ - private _writeElementValue(parentElement: any, name: any, value: any): any { - var self = this; - var ignored = false; - var propertyTagName = name; - - if (!stringIsEmpty(value) && isObject(value) && !isDate(value)) { - if (Array.isArray(value) && value.length > 0) { - // Example: - // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] - // XML: hi therehello there - - Object.keys(value).forEach(function(i: any) { - parentElement = self._writeElementValue(parentElement, name, value[i]); - }); + throw new Error("Unrecognized result: " + atomResponseInJson); +} - // For an array no element was actually added at this level, so skip uping level. - ignored = true; - } else if ( - value[Constants.XML_METADATA_MARKER] !== undefined && - value[Constants.XML_VALUE_MARKER] !== undefined - ) { - // Example: - // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } - // XML: hi there +function parseEntryResult(entry: any): any { + var contentElementName = Object.keys(entry.content).filter(function(key) { + return key !== Constants.XML_METADATA_MARKER; + })[0]; - parentElement = parentElement.ele(propertyTagName); - if (!stringIsEmpty(value[Constants.XML_VALUE_MARKER])) { - if (stringStartsWith(value[Constants.XML_VALUE_MARKER], "hi therehello there + delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; + var result = entry.content[contentElementName]; - parentElement = parentElement.ele(propertyTagName); - for (var propertyName in value) { - if ( - propertyName !== Constants.XML_METADATA_MARKER && - value.hasOwnProperty(propertyName) - ) { - parentElement = self._writeElementValue( - parentElement, - propertyName, - value[propertyName] - ); - } - } - } + if (result) { + if (entry[Constants.XML_METADATA_MARKER]) { + result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; } else { - parentElement = parentElement.ele(propertyTagName); - if (!stringIsEmpty(value)) { - if (stringStartsWith(value.toString().trim(), " { + if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { + result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; } - } - - return result; + }); } - private parseFeedResult(feed: any): any { - var result = []; - var self = this; - if (feed.entry) { - if (isArray(feed.entry)) { - each(feed.entry, function(entry: any) { - result.push(self.parseEntryResult(entry)); - }); - } else { - result.push(self.parseEntryResult(feed.entry)); - } + return result; +} + +function parseFeedResult(feed: any): any { + var result = []; + if (feed.entry) { + if (Array.isArray(feed.entry)) { + feed.entry.forEach((entry: any) => { + result.push(parseEntryResult(entry)); + }); + } else { + result.push(parseEntryResult(feed.entry)); } - return result; } + return result; } diff --git a/sdk/core/core-http/lib/util/crypto.browser.ts b/sdk/core/core-http/lib/util/crypto.browser.ts new file mode 100644 index 000000000000..38f8ad3cc3c8 --- /dev/null +++ b/sdk/core/core-http/lib/util/crypto.browser.ts @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { encodeByteArray } from "./base64"; + +export async function generateKey(secret: string, stringToSign: string): Promise { + const key = await window.crypto.subtle.importKey( + "raw", + convertToUint8Array(secret), + { + name: "HMAC", + hash: { name: "SHA-256" } + }, + false, + ["sign"] + ); + + let signature = await window.crypto.subtle.sign("HMAC", key, convertToUint8Array(stringToSign)); + const base64encodedString = encodeByteArray(new Uint8Array(signature)); + const result = encodeURIComponent(base64encodedString); + return result; +} + +function convertToUint8Array(value: string) { + const arr = new Uint8Array(value.length); + for (let i = 0; i < value.length; i++) { + arr[i] = value.charCodeAt(i); + } + return arr; +} diff --git a/sdk/core/core-http/lib/util/crypto.ts b/sdk/core/core-http/lib/util/crypto.ts new file mode 100644 index 000000000000..e19abf7691b4 --- /dev/null +++ b/sdk/core/core-http/lib/util/crypto.ts @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import crypto from "crypto"; + +export async function generateKey(secret: string, stringToSign: string) { + const result = encodeURIComponent( + crypto + .createHmac("sha256", secret) + .update(stringToSign) + .digest("base64") + ); + return result; +} diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 4f190d97dff2..16a1fca309f0 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -7,8 +7,13 @@ import { RestError } from "../restError"; import { WebResource } from "../webResource"; import { Constants } from "./constants"; +const validUuidRegex = new RegExp( + "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "ig" +); /** - * A constant that indicates whether the environment is node.js or browser based. + +* A constant that indicates whether the environment is node.js or browser based. */ export const isNode = typeof process !== "undefined" && @@ -81,10 +86,6 @@ export function stripRequest(request: WebResource): WebResource { * @return {boolean} True if the uuid is valid; false otherwise. */ export function isValidUuid(uuid: string): boolean { - const validUuidRegex = new RegExp( - "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", - "ig" - ); return validUuidRegex.test(uuid); } @@ -287,66 +288,19 @@ export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } -/** - * Determines whether the given `value` is an empty string or not. - * @param {any} value Any entity - * @return {boolean} - true if it is equivalent to an empty string, false otherwise. - */ -export function stringIsEmpty(value: any) { - return isNull(value) || isUndefined(value) || value === ""; -} - /** * Checks if given `text` starts with the specified `prefix` * @param text Input string * @return {boolean} - true if yes, false otherwise. */ export function stringStartsWith(text: string, prefix: string) { - if (isNull(prefix)) { + if (prefix == null) { return true; } return text.substr(0, prefix.length) === prefix; } -/** - * Returns the number of keys (properties) in an object. - * - * @param {object} value The object which keys are to be counted. - * @return {number} The number of keys in the object. - */ -export function objectKeysLength(value: any) { - if (!value) { - return 0; - } - - return keys(value).length; -} - -/** - * Returns the name of the first property in an object. - * - * @param {object} value The object which key is to be returned. - * @return {number} The name of the first key in the object. - */ -export function objectFirstKey(value: any) { - if (value && Object.keys(value).length > 0) { - return Object.keys(value)[0]; - } - - // Object has no properties - return null; -} - -/** - * Determines whether the given `value` is a null object or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export function objectIsNull(value: any) { - return isNull(value) || isUndefined(value); -} - /** * Determines whether the given `value` is a `Date` object or not. * @param {any} value Any entity @@ -365,17 +319,6 @@ export function isString(value: any) { return Object.prototype.toString.call(value) == "[object String]"; } -/** - * Determines whether the given `value` is a `Array` object or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export const isArray = - Array.isArray || - function(value: any) { - return Object.prototype.toString.call(value) == "[object Array]"; - }; - /** * Determines whether the given `value` is a `Object` or not. * @param {any} value Any entity @@ -385,72 +328,6 @@ export const isObject = function(value: any) { return value === Object(value); }; -/** - * Determines whether the given `value` is an undefined entity or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export const isUndefined = function(value: any) { - return value === void 0; -}; - -/** - * Utility to iterate over given entity's values. - * @param {any} obj - The object to execute operation(s) on. - * @param {any} iterator - The iterator callback to use - * @param {any} context - Optional context for use with iterator - * @return {any} - the final extended object - */ -export const each = function(obj: any, iterator: any, context?: any) { - if (obj == null) return; - if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === {}) return; - } - } else { - for (var key in obj) { - if (has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === {}) return; - } - } - } -}; - -/** - * Extends given object `obj` with the passed in `source` object. - * @param {any} obj - * @param {any} source - * @return {any} - the final extended object - */ -export const extend = function(obj: any, source: any) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - return obj; -}; - -// Private helper utilities -const has = function(obj: any, key: any) { - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -const isNull = function(value: any) { - return value === null; -}; - -const keys = - Object.keys || - function(obj: any) { - if (obj !== Object(obj)) throw new TypeError("Invalid object"); - var keys = []; - for (var key in obj) if (has(obj, key)) keys[keys.length] = key; - return keys; - }; - export function byteLength(string: any) { return utf8ToBytes(string).length; // assume utf8 } diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index d27e2845e2e5..461eca73b2c4 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { Constants } from "./constants"; + const parser = new DOMParser(); export function parseXML(str: string): Promise { try { @@ -94,29 +96,19 @@ function domToObject(node: Node): any { return result; } -// tslint:disable-next-line:no-null-keyword -const doc = document.implementation.createDocument(null, null, null); const serializer = new XMLSerializer(); export function stringifyXML(obj: any, opts?: { rootName?: string }) { const rootName = (opts && opts.rootName) || "root"; - const dom = buildNode(obj, rootName)[0]; + // tslint:disable-next-line:no-null-keyword + const doc = document.implementation.createDocument(null, null, null); + const dom = buildNode(doc, obj, rootName)[0]; return ( '' + serializer.serializeToString(dom) ); } -function buildAttributes(attrs: { [key: string]: { toString(): string } }): Attr[] { - const result = []; - for (const key of Object.keys(attrs)) { - const attr = doc.createAttribute(key); - attr.value = attrs[key].toString(); - result.push(attr); - } - return result; -} - -function buildNode(obj: any, elementName: string): Node[] { +function buildNode(doc: any, obj: any, elementName: string): Node[] { if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { const elem = doc.createElement(elementName); elem.textContent = obj.toString(); @@ -124,7 +116,7 @@ function buildNode(obj: any, elementName: string): Node[] { } else if (Array.isArray(obj)) { const result = []; for (const arrayElem of obj) { - for (const child of buildNode(arrayElem, elementName)) { + for (const child of buildNode(doc, arrayElem, elementName)) { result.push(child); } } @@ -133,11 +125,11 @@ function buildNode(obj: any, elementName: string): Node[] { const elem = doc.createElement(elementName); for (const key of Object.keys(obj)) { if (key === "$") { - for (const attr of buildAttributes(obj[key])) { + for (const attr of buildAttributes(doc, obj[key])) { elem.attributes.setNamedItem(attr); } } else { - for (const child of buildNode(obj[key], key)) { + for (const child of buildNode(doc, obj[key], key)) { elem.appendChild(child); } } @@ -148,9 +140,39 @@ function buildNode(obj: any, elementName: string): Node[] { } } -export function parseAtomXmlDataToJson(body: any): any { +function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { + const result = []; + for (const key of Object.keys(attrs)) { + const attr = doc.createAttribute(key); + attr.value = attrs[key].toString(); + result.push(attr); + } + return result; +} + +export function deserializeAtomXmlToJson(body: any): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); const result = domToObject(dom); return result; } + +/** + * @param {object} content The content payload as it is to be serialized. It should include any root node(s). + */ +export function serializeJsonToAtomXml(content: any): string { + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + + const serializer = new XMLSerializer(); + + // tslint:disable-next-line:no-null-keyword + const doc = document.implementation.createDocument(null, null, null); + const res = buildNode(doc, content, "content"); + const dom = res[0]; + + const result = + `${new Date().toISOString()}` + + serializer.serializeToString(dom) + + ``; + return result; +} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index f9979037772e..c5c177cf6e0c 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -2,6 +2,9 @@ // Licensed under the MIT License. import * as xml2js from "xml2js"; +import { Constants } from "./constants"; +import { stringStartsWith, isDate, isObject } from "./utils"; +const xmlbuilder: any = require("xmlbuilder"); export function stringifyXML(obj: any, opts?: { rootName?: string }) { const builder = new xml2js.Builder({ @@ -36,7 +39,7 @@ export function parseXML(str: string): Promise { }); } -export function parseAtomXmlDataToJson(body: any): any { +export function deserializeAtomXmlToJson(body: any): any { var parsed; var parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { @@ -49,6 +52,24 @@ export function parseAtomXmlDataToJson(body: any): any { return parsed; } +/** + * @param {object} content The content payload as it is to be serialized. It should include any root node(s). + */ +export function serializeJsonToAtomXml(content: any): any { + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + + var doc = xmlbuilder.create(); + + doc = doc + .begin("entry", { version: "1.0", encoding: "utf-8", standalone: "yes" }) + .att("xmlns", "http://www.w3.org/2005/Atom"); + + doc = doc.ele("updated", new Date().toISOString()).up(); + + doc = _writeElementValue(doc, "content", content); + return doc.doc().toString(); +} + /** * Gets the default xml2js settings applicable for Atom based XML operations. * @ignore @@ -77,3 +98,92 @@ function _removeBOM(str: any) { return str; } + +/* + * Writes a single property for an entry or complex type. + * + * @param {object} parentElement Parent DOM element under which the property should be added. + * @param {string} name Property name. + * @param {object} value Property value. + * @return {object} The current DOM element. + * + * {Deprecated} + */ +function _writeElementValue(parentElement: any, name: any, value: any): any { + var ignored = false; + var propertyTagName = name; + + if (!contentIsUndefinedOrEmpty(value) && isObject(value) && !isDate(value)) { + if (Array.isArray(value) && value.length > 0) { + // Example: + // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] + // XML: hi therehello there + + Object.keys(value).forEach(function(i: any) { + parentElement = _writeElementValue(parentElement, name, value[i]); + }); + + // For an array no element was actually added at this level, so skip uping level. + ignored = true; + } else if ( + value[Constants.XML_METADATA_MARKER] !== undefined && + value[Constants.XML_VALUE_MARKER] !== undefined + ) { + // Example: + // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } + // XML: hi there + + parentElement = parentElement.ele(propertyTagName); + if (!contentIsUndefinedOrEmpty(value[Constants.XML_VALUE_MARKER])) { + if (stringStartsWith(value[Constants.XML_VALUE_MARKER], "hi therehello there + + parentElement = parentElement.ele(propertyTagName); + for (var propertyName in value) { + if (propertyName !== Constants.XML_METADATA_MARKER && value.hasOwnProperty(propertyName)) { + parentElement = _writeElementValue(parentElement, propertyName, value[propertyName]); + } + } + } + } else { + parentElement = parentElement.ele(propertyTagName); + if (!contentIsUndefinedOrEmpty(value)) { + if (stringStartsWith(value.toString().trim(), " Date: Thu, 29 Aug 2019 16:37:51 -0700 Subject: [PATCH 09/72] Some more modernization fixes --- .../lib/atomResourceSerializerBase.ts | 35 +++++++------------ .../sasServiceClientCredentials.ts | 26 ++++---------- .../lib/policies/atomSerializationPolicy.ts | 23 ++++++------ sdk/core/core-http/lib/resourceSerializer.ts | 21 +++-------- sdk/core/core-http/lib/util/utils.ts | 20 ++++++----- sdk/core/core-http/lib/util/xml.browser.ts | 2 +- sdk/core/core-http/lib/util/xml.ts | 22 ++++++------ 7 files changed, 61 insertions(+), 88 deletions(-) diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 192ef16d997d..59ea1fe850b9 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -1,18 +1,5 @@ -// -// Copyright (c) Microsoft and contributors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. import { isNode } from "./util/utils"; import { Constants } from "./util/constants"; @@ -20,8 +7,12 @@ import { serializeJsonToAtomXml } from "./util/xml"; import { parseResultFromAtomResponse } from "./util/atomHandler"; export class AtomResourceSerializerBase { - static serializeToAtomXmlRequest(resourceName: any, resource: any, properties: any): any { - var content: any = {}; + static serializeToAtomXmlRequest( + resourceName: string, + resource: any, + properties: string[] + ): string { + const content: any = {}; content[resourceName] = { $: { xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" @@ -30,7 +21,7 @@ export class AtomResourceSerializerBase { if (resource) { // Sort properties according to what is allowed by the service - properties.forEach((property: any) => { + properties.forEach((property: string) => { if (resource[property] !== undefined) { content[resourceName][property] = resource[property]; } @@ -40,8 +31,8 @@ export class AtomResourceSerializerBase { return serializeJsonToAtomXml(content); } - static deserializeAtomResponse(nameProperty: any, atomResponseInJson: any): any { - var result = parseResultFromAtomResponse(atomResponseInJson); + static deserializeAtomResponse(nameProperty: string[], atomResponseInJson: any): any { + const result = parseResultFromAtomResponse(atomResponseInJson); if (!result) { return undefined; @@ -63,9 +54,9 @@ export class AtomResourceSerializerBase { } else { parsedUrl = new window.URL(entry[Constants.ATOM_METADATA_MARKER].id); } - var parts = parsedUrl.pathname!.split("/"); + const parts = parsedUrl.pathname!.split("/"); - for (var i = 0; i * 2 < parts.length - 1; i++) { + for (let i = 0; i * 2 < parts.length - 1; i++) { entry[nameProperty[i]] = parts[i * 2 + 1]; } } diff --git a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts index 07beb1369ca4..8719865a21cc 100644 --- a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts +++ b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts @@ -36,22 +36,8 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { this.keyValue = keyValue; } - private async _generateSignature(targetUri: any, expirationDate: any): Promise { - const getValueToAppend = function(value: any, noNewLine?: any): any { - var returnValue = ""; - if (value != null) { - returnValue = value; - } - - if (noNewLine !== true) { - returnValue += "\n"; - } - - return returnValue; - }; - - var stringToSign = getValueToAppend(targetUri) + getValueToAppend(expirationDate, true); - + private async _generateSignature(targetUri: string, expirationDate: number): Promise { + const stringToSign = `${targetUri}\n${expirationDate}`; const result = await generateKey(this.keyValue, stringToSign); return result; } @@ -65,16 +51,18 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { async signRequest(webResource: WebResource): Promise { if (!webResource.headers) webResource.headers = new HttpHeaders(); - var targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); + const targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); let date = new Date(); date.setMinutes(date.getMinutes() + 5); - var expirationDate = Math.round(date.valueOf() / 1000); - var signature = await this._generateSignature(targetUri, expirationDate); + const expirationDate = Math.round(date.valueOf() / 1000); + const signature = await this._generateSignature(targetUri, expirationDate); webResource.headers.set( HeaderConstants.AUTHORIZATION, `SharedAccessSignature sig=${signature}&se=${expirationDate}&skn=${this.keyName}&sr=${targetUri}` ); + // TODO: Fix server side configuration on response headers + webResource.headers.set("origin", "http://localhost"); return Promise.resolve(webResource); } } diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 4353e905a77a..212ee7a1e1ed 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -84,7 +84,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const HttpResponseCodes: any = Constants.HttpResponseCodes; if (parsedResponse.errorBody == undefined) { - var code = Object.keys(HttpResponseCodes).filter(function(name: any): any { + const code = Object.keys(HttpResponseCodes).filter(function(name: any): any { if (HttpResponseCodes[name] === response.status) { return name; } @@ -93,7 +93,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { parsedResponse.errorBody = { error: { code: code[0] } }; } - var normalizedError = this._normalizeError(parsedResponse.errorBody, response); + const normalizedError = this._normalizeError(parsedResponse.errorBody, response); parsedResponse.errorBody = normalizedError; return parsedResponse; } @@ -121,7 +121,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const errorProperties = error.Error || error.error || error["odata.error"] || error; if (odataErrorFormat) { - Object.keys(errorProperties).forEach((property: any) => { + Object.keys(errorProperties).forEach((property: string) => { let value = null; if ( property === Constants.ODATA_ERROR_MESSAGE && @@ -143,10 +143,13 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } else { Object.keys(errorProperties).forEach((property: any) => { { - var value = null; - if (property !== "$") { - if (errorProperties[property] && errorProperties[property]["_"]) { - value = errorProperties[property]["_"]; + let value = null; + if (property !== Constants.XML_METADATA_MARKER) { + if ( + errorProperties[property] && + errorProperties[property][Constants.XML_VALUE_MARKER] + ) { + value = errorProperties[property][Constants.XML_VALUE_MARKER]; } else { value = errorProperties[property]; } @@ -155,7 +158,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } }); } - var errorMessage = normalizedError.code; + let errorMessage = normalizedError.code; if (normalizedError.detail) { errorMessage += " - " + normalizedError.detail; } @@ -170,8 +173,8 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } } - var errorObject: any = { error: { code: errorMessage } }; - Object.keys(normalizedError).forEach((property: any) => { + const errorObject: any = { error: { code: errorMessage } }; + Object.keys(normalizedError).forEach((property: string) => { errorObject[property] = normalizedError[property]; }); return errorObject; diff --git a/sdk/core/core-http/lib/resourceSerializer.ts b/sdk/core/core-http/lib/resourceSerializer.ts index 3e4daa78e63e..f3c2140bcbc5 100644 --- a/sdk/core/core-http/lib/resourceSerializer.ts +++ b/sdk/core/core-http/lib/resourceSerializer.ts @@ -1,21 +1,8 @@ -// -// Copyright (c) Microsoft and contributors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. export interface ResourceSerializer { - serialize(resource: any): any; + serialize(resourceDataInJson: any): string; - parse(xml: any): any; + parse(atomResponseInJson: any): any; } diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 16a1fca309f0..8dd5336e9304 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -328,18 +328,22 @@ export const isObject = function(value: any) { return value === Object(value); }; -export function byteLength(string: any) { - return utf8ToBytes(string).length; // assume utf8 +/** + * Computes byte length of given string assuming the encoding to use is "utf-8" + * @param str + */ +export function byteLength(str: string) { + return utf8ToBytes(str).length; } -function utf8ToBytes(string: any, units?: any) { +function utf8ToBytes(string: string, units?: any) { units = units || Infinity; - var codePoint; - var length = string.length; - var leadSurrogate = null; - var bytes = []; + let codePoint; + const length = string.length; + let leadSurrogate = null; + const bytes = []; - for (var i = 0; i < length; ++i) { + for (let i = 0; i < length; ++i) { codePoint = string.charCodeAt(i); // is surrogate component diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 461eca73b2c4..f0b6995abd2a 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -150,7 +150,7 @@ function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string return result; } -export function deserializeAtomXmlToJson(body: any): any { +export function deserializeAtomXmlToJson(body: string): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); const result = domToObject(dom); diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index c5c177cf6e0c..90b022d77dbd 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -39,9 +39,9 @@ export function parseXML(str: string): Promise { }); } -export function deserializeAtomXmlToJson(body: any): any { - var parsed; - var parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); +export function deserializeAtomXmlToJson(body: string): any { + let parsed; + const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { throw err; @@ -55,10 +55,10 @@ export function deserializeAtomXmlToJson(body: any): any { /** * @param {object} content The content payload as it is to be serialized. It should include any root node(s). */ -export function serializeJsonToAtomXml(content: any): any { +export function serializeJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - var doc = xmlbuilder.create(); + let doc = xmlbuilder.create(); doc = doc .begin("entry", { version: "1.0", encoding: "utf-8", standalone: "yes" }) @@ -76,7 +76,7 @@ export function serializeJsonToAtomXml(content: any): any { * @return {object} The default settings */ function _getDefaultSettingsForAtomXmlOperations(): any { - var xml2jsSettings = xml2js.defaults["0.2"]; + const xml2jsSettings = xml2js.defaults["0.2"]; xml2jsSettings.normalize = false; xml2jsSettings.trim = false; xml2jsSettings.attrkey = "$"; @@ -110,8 +110,8 @@ function _removeBOM(str: any) { * {Deprecated} */ function _writeElementValue(parentElement: any, name: any, value: any): any { - var ignored = false; - var propertyTagName = name; + let ignored = false; + const propertyTagName = name; if (!contentIsUndefinedOrEmpty(value) && isObject(value) && !isDate(value)) { if (Array.isArray(value) && value.length > 0) { @@ -147,11 +147,11 @@ function _writeElementValue(parentElement: any, name: any, value: any): any { // XML: hi therehello there parentElement = parentElement.ele(propertyTagName); - for (var propertyName in value) { + Object.keys(value).forEach((propertyName: string) => { if (propertyName !== Constants.XML_METADATA_MARKER && value.hasOwnProperty(propertyName)) { parentElement = _writeElementValue(parentElement, propertyName, value[propertyName]); } - } + }); } } else { parentElement = parentElement.ele(propertyTagName); @@ -166,7 +166,7 @@ function _writeElementValue(parentElement: any, name: any, value: any): any { if (value && value[Constants.XML_METADATA_MARKER]) { // include the metadata - var attributeList = value[Constants.XML_METADATA_MARKER]; + const attributeList = value[Constants.XML_METADATA_MARKER]; Object.keys(attributeList).forEach(function(attribute) { parentElement = parentElement.att(attribute, attributeList[attribute]); }); From da009a613a07d4cc26bc090a08c6ed46dbd52a6d Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 4 Sep 2019 14:09:35 -0700 Subject: [PATCH 10/72] Address comments --- .../lib/atomResourceSerializerBase.ts | 5 +- sdk/core/core-http/lib/coreHttp.ts | 3 +- .../sasServiceClientCredentials.ts | 21 ++-- .../lib/policies/atomSerializationPolicy.ts | 20 ++-- .../policies/msRestUserAgentPolicy.browser.ts | 2 +- sdk/core/core-http/lib/util/atomHandler.ts | 8 +- sdk/core/core-http/lib/util/constants.ts | 24 ++--- sdk/core/core-http/lib/util/crypto.browser.ts | 2 +- sdk/core/core-http/lib/util/utils.ts | 95 +------------------ sdk/core/core-http/lib/util/xml.ts | 2 +- sdk/core/core-http/test/cryptoTests.ts | 17 ++++ .../policies/atomSerializationPolicyTests.ts | 5 +- 12 files changed, 67 insertions(+), 137 deletions(-) create mode 100644 sdk/core/core-http/test/cryptoTests.ts diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 59ea1fe850b9..38506264dc65 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -10,12 +10,13 @@ export class AtomResourceSerializerBase { static serializeToAtomXmlRequest( resourceName: string, resource: any, - properties: string[] + properties: string[], + xmlNamespace: string ): string { const content: any = {}; content[resourceName] = { $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" + xmlns: xmlNamespace } }; diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 1ca56d4f6a48..65b4d3ea9e1a 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -80,8 +80,7 @@ export { isValidUuid, applyMixins, isNode, - isDuration, - byteLength + isDuration } from "./util/utils"; export { URLBuilder, URLQuery } from "./url"; export { AbortSignalLike } from "@azure/abort-controller"; diff --git a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts index 8719865a21cc..46f550ef4d01 100644 --- a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts +++ b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts @@ -17,23 +17,22 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { * Creates a new sasServiceClientCredentials object. * * @constructor - * @param {string} connectionString Connection string. + * @param {string} sharedAccessKeyName The SAS key name to use. + * @param {string} sharedAccessKey The SAS key value to use */ constructor(sharedAccessKeyName: string, sharedAccessKey: string) { - if (sharedAccessKeyName == null) { + if (typeof sharedAccessKeyName !== "string") { throw new Error( "sharedAccessKeyName cannot be null or undefined and must be of type string." ); } - if (sharedAccessKey == null) { + if (typeof sharedAccessKey !== "string") { throw new Error("sharedAccessKey cannot be null or undefined and must be of type string."); } - const keyName = sharedAccessKeyName; - const keyValue = sharedAccessKey; - this.keyName = keyName; - this.keyValue = keyValue; + this.keyName = sharedAccessKeyName; + this.keyValue = sharedAccessKey; } private async _generateSignature(targetUri: string, expirationDate: number): Promise { @@ -53,16 +52,14 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { const targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); - let date = new Date(); + const date = new Date(); date.setMinutes(date.getMinutes() + 5); - const expirationDate = Math.round(date.valueOf() / 1000); + const expirationDate = Math.round(date.getTime() / 1000); const signature = await this._generateSignature(targetUri, expirationDate); webResource.headers.set( HeaderConstants.AUTHORIZATION, `SharedAccessSignature sig=${signature}&se=${expirationDate}&skn=${this.keyName}&sr=${targetUri}` ); - // TODO: Fix server side configuration on response headers - webResource.headers.set("origin", "http://localhost"); - return Promise.resolve(webResource); + return webResource; } } diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 212ee7a1e1ed..7b018ae30527 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -11,7 +11,7 @@ import { } from "./requestPolicy"; import { Constants } from "../util/constants"; import { deserializeAtomXmlToJson } from "../util/xml"; -import { isString, byteLength } from "../util/utils"; +import { isString } from "../util/utils"; import { ResourceSerializer } from "../resourceSerializer"; /** @@ -84,13 +84,13 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const HttpResponseCodes: any = Constants.HttpResponseCodes; if (parsedResponse.errorBody == undefined) { - const code = Object.keys(HttpResponseCodes).filter(function(name: any): any { - if (HttpResponseCodes[name] === response.status) { - return name; - } - }); - - parsedResponse.errorBody = { error: { code: code[0] } }; + if (Object.keys(HttpResponseCodes).indexOf(response.status.toString()) < 0) { + parsedResponse.errorBody = { + error: { code: `UnrecognizedHttpResponseStatus: ${response.status}` } + }; + } else { + parsedResponse.errorBody = { error: { code: HttpResponseCodes[response.status] } }; + } } const normalizedError = this._normalizeError(parsedResponse.errorBody, response); @@ -101,12 +101,12 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { private _parseXmlResponseToJson(responseInXml: HttpOperationResponse): HttpOperationResponse { const parsedResponse = responseInXml; try { - if (responseInXml.bodyAsText && byteLength(responseInXml.bodyAsText.toString()) > 0) { + if (responseInXml.bodyAsText && responseInXml.bodyAsText.toString().length > 0) { parsedResponse.parsedBody = deserializeAtomXmlToJson(responseInXml.bodyAsText); } } catch (e) { parsedResponse.errorBody = { - error: { code: "Given object is not an Atom XML response" } + error: { code: "ResponseNotInAtomXMLFormat" } }; } return parsedResponse; diff --git a/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts b/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts index 491cf5d13c19..5d5464cfc0d0 100644 --- a/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts +++ b/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts @@ -9,7 +9,7 @@ import { TelemetryInfo } from "./userAgentPolicy"; interface NavigatorEx extends Navigator { - readonly oscpu: string | undefined; + readonly oscpu: string; } export function getDefaultUserAgentKey(): string { diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index cdbab5bc81f1..e5c0e6903638 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -22,12 +22,12 @@ export function parseResultFromAtomResponse(atomResponseInJson: any): any { } function parseEntryResult(entry: any): any { - var contentElementName = Object.keys(entry.content).filter(function(key) { + const contentElementName = Object.keys(entry.content).filter(function(key) { return key !== Constants.XML_METADATA_MARKER; })[0]; delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; - var result = entry.content[contentElementName]; + const result = entry.content[contentElementName]; if (result) { if (entry[Constants.XML_METADATA_MARKER]) { @@ -48,8 +48,8 @@ function parseEntryResult(entry: any): any { return result; } -function parseFeedResult(feed: any): any { - var result = []; +function parseFeedResult(feed: any): any[] { + const result = []; if (feed.entry) { if (Array.isArray(feed.entry)) { feed.entry.forEach((entry: any) => { diff --git a/sdk/core/core-http/lib/util/constants.ts b/sdk/core/core-http/lib/util/constants.ts index 91fd0b4ace1d..ef5059845351 100644 --- a/sdk/core/core-http/lib/util/constants.ts +++ b/sdk/core/core-http/lib/util/constants.ts @@ -136,17 +136,17 @@ export const Constants = { XML_VALUE_MARKER: "_", HttpResponseCodes: { - Ok: 200, - Created: 201, - Accepted: 202, - NoContent: 204, - PartialContent: 206, - BadRequest: 400, - Unauthorized: 401, - Forbidden: 403, - NotFound: 404, - Conflict: 409, - LengthRequired: 411, - PreconditionFailed: 412 + 200: "Ok", + 201: "Created", + 202: "Accepted", + 204: "NoContent", + 206: "PartialContent", + 400: "BadRequest", + 401: "Unauthorized", + 403: "Forbidden", + 404: "NotFound", + 409: "Conflict", + 411: "LengthRequired", + 412: "PreconditionFailed" } }; diff --git a/sdk/core/core-http/lib/util/crypto.browser.ts b/sdk/core/core-http/lib/util/crypto.browser.ts index 38f8ad3cc3c8..6eb220e01cfc 100644 --- a/sdk/core/core-http/lib/util/crypto.browser.ts +++ b/sdk/core/core-http/lib/util/crypto.browser.ts @@ -15,7 +15,7 @@ export async function generateKey(secret: string, stringToSign: string): Promise ["sign"] ); - let signature = await window.crypto.subtle.sign("HMAC", key, convertToUint8Array(stringToSign)); + const signature = await window.crypto.subtle.sign("HMAC", key, convertToUint8Array(stringToSign)); const base64encodedString = encodeByteArray(new Uint8Array(signature)); const result = encodeURIComponent(base64encodedString); return result; diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 8dd5336e9304..4aaf88037330 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -111,7 +111,7 @@ export function objectValues(obj: { [key: string]: any }): any[] { obj, undefined, 2 - )} is not a valid object that can be ` + `enumerated to provide its values as an array.` + )} is not a valid object that can be enumerated to provide its values as an array.` ); } return result; @@ -293,7 +293,7 @@ export function isPrimitiveType(value: any): boolean { * @param text Input string * @return {boolean} - true if yes, false otherwise. */ -export function stringStartsWith(text: string, prefix: string) { +export function stringStartsWith(text: string, prefix: string): boolean { if (prefix == null) { return true; } @@ -306,7 +306,7 @@ export function stringStartsWith(text: string, prefix: string) { * @param {any} value Any entity * @return {boolean} - true if yes, false otherwise. */ -export function isDate(value: any) { +export function isDate(value: any): value is Date { return Object.prototype.toString.call(value) == "[object Date]"; } @@ -315,7 +315,7 @@ export function isDate(value: any) { * @param {any} value Any entity * @return {boolean} - true if yes, false otherwise. */ -export function isString(value: any) { +export function isString(value: any): value is string { return Object.prototype.toString.call(value) == "[object String]"; } @@ -324,91 +324,6 @@ export function isString(value: any) { * @param {any} value Any entity * @return {boolean} - true if yes, false otherwise. */ -export const isObject = function(value: any) { +export function isObject(value: any): value is Object { return value === Object(value); -}; - -/** - * Computes byte length of given string assuming the encoding to use is "utf-8" - * @param str - */ -export function byteLength(str: string) { - return utf8ToBytes(str).length; -} - -function utf8ToBytes(string: string, units?: any) { - units = units || Infinity; - let codePoint; - const length = string.length; - let leadSurrogate = null; - const bytes = []; - - for (let i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i); - - // is surrogate component - if (codePoint > 0xd7ff && codePoint < 0xe000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xdbff) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - continue; - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - continue; - } - - // valid lead - leadSurrogate = codePoint; - - continue; - } - - // 2 leads in a row - if (codePoint < 0xdc00) { - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - leadSurrogate = codePoint; - continue; - } - - // valid surrogate pair - codePoint = (((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000; - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - } - - leadSurrogate = null; - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break; - bytes.push(codePoint); - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break; - bytes.push((codePoint >> 0x6) | 0xc0, (codePoint & 0x3f) | 0x80); - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break; - bytes.push( - (codePoint >> 0xc) | 0xe0, - ((codePoint >> 0x6) & 0x3f) | 0x80, - (codePoint & 0x3f) | 0x80 - ); - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break; - bytes.push( - (codePoint >> 0x12) | 0xf0, - ((codePoint >> 0xc) & 0x3f) | 0x80, - ((codePoint >> 0x6) & 0x3f) | 0x80, - (codePoint & 0x3f) | 0x80 - ); - } else { - throw new Error("Invalid code point"); - } - } - - return bytes; } diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 90b022d77dbd..6b20e89ade52 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -184,6 +184,6 @@ function _writeElementValue(parentElement: any, name: any, value: any): any { * @param {any} value Any entity * @return {boolean} - true if it is equivalent to an empty string, false otherwise. */ -function contentIsUndefinedOrEmpty(content: any) { +function contentIsUndefinedOrEmpty(content: any): boolean { return content == null || content === ""; } diff --git a/sdk/core/core-http/test/cryptoTests.ts b/sdk/core/core-http/test/cryptoTests.ts new file mode 100644 index 000000000000..fcf9c0730633 --- /dev/null +++ b/sdk/core/core-http/test/cryptoTests.ts @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { generateKey } from "../lib/util/crypto"; +import { assert } from "chai"; + +describe("generateKey(secret, stringToSign)", function() { + it("generates valid key for secret as 'abc' and string to sign as 'def' ", async function() { + const key: string = await generateKey("abc", "def"); + assert.equal(key, "IOvA8JNERwE081BA9j6pix2OQUISlJ7lxQBCnRXqsIE%3D%3D"); + }); + + it("generates valid key when secret and stringToSign are empty", async function() { + const key: string = await generateKey("", ""); + assert.equal(key, "thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0%3D"); + }); +}); diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 6dd6821cd366..9be4481f3264 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -56,7 +56,7 @@ describe("atomSerializationPolicy", function() { const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); const response = await policy.sendRequest(request); assert.deepEqual(response.bodyAsText, `{ "simple": "JSONobject" }`); - assert.deepEqual(response.parsedBody.error.code, "Given object is not an Atom XML response"); + assert.deepEqual(response.parsedBody.error.code, "ResponseNotInAtomXMLFormat"); }); it("with xml response body, application/xml content-type and AtomXMLOperationSpec", async function() { @@ -122,7 +122,8 @@ class MockSerializer implements ResourceSerializer { return AtomResourceSerializerBase.serializeToAtomXmlRequest( "QueueDescription", resource, - properties + properties, + "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" ); } From 54fea8fb047744bfe7e1146526d6c35682f041d1 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 4 Sep 2019 14:21:53 -0700 Subject: [PATCH 11/72] Add copyrights --- sdk/core/core-http/lib/util/atomHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index e5c0e6903638..099e5151ae4b 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + import { Constants } from "./constants"; /** From 6e634c3e9229dfca542f5ed7e0d255939d8ffaba Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 4 Sep 2019 17:55:35 -0700 Subject: [PATCH 12/72] Address comments --- sdk/core/core-http/lib/util/utils.ts | 37 +++------------------------- sdk/core/core-http/lib/util/xml.ts | 6 ++--- 2 files changed, 6 insertions(+), 37 deletions(-) diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 4aaf88037330..6e33240374ac 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -7,13 +7,10 @@ import { RestError } from "../restError"; import { WebResource } from "../webResource"; import { Constants } from "./constants"; -const validUuidRegex = new RegExp( - "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", - "ig" -); +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}$/gi; + /** - -* A constant that indicates whether the environment is node.js or browser based. + * A constant that indicates whether the environment is node.js or browser based. */ export const isNode = typeof process !== "undefined" && @@ -145,21 +142,6 @@ export function executePromisesSequentially(promiseFactories: Array, kickst return result; } -/** - * Merges source object into the target object - * @param {object} source The object that needs to be merged - * - * @param {object} target The object to be merged into - * - * @returns {object} Returns the merged target object. - */ -export function mergeObjects(source: { [key: string]: any }, target: { [key: string]: any }) { - Object.keys(source).forEach((key) => { - target[key] = source[key]; - }); - return target; -} - /** * A wrapper for setTimeout that resolves a promise after t milliseconds. * @param {number} t The number of milliseconds to be delayed. @@ -288,19 +270,6 @@ export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } -/** - * Checks if given `text` starts with the specified `prefix` - * @param text Input string - * @return {boolean} - true if yes, false otherwise. - */ -export function stringStartsWith(text: string, prefix: string): boolean { - if (prefix == null) { - return true; - } - - return text.substr(0, prefix.length) === prefix; -} - /** * Determines whether the given `value` is a `Date` object or not. * @param {any} value Any entity diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 6b20e89ade52..ea9531ade7cc 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -3,7 +3,7 @@ import * as xml2js from "xml2js"; import { Constants } from "./constants"; -import { stringStartsWith, isDate, isObject } from "./utils"; +import { isDate, isObject } from "./utils"; const xmlbuilder: any = require("xmlbuilder"); export function stringifyXML(obj: any, opts?: { rootName?: string }) { @@ -135,7 +135,7 @@ function _writeElementValue(parentElement: any, name: any, value: any): any { parentElement = parentElement.ele(propertyTagName); if (!contentIsUndefinedOrEmpty(value[Constants.XML_VALUE_MARKER])) { - if (stringStartsWith(value[Constants.XML_VALUE_MARKER], " Date: Wed, 4 Sep 2019 20:35:13 -0700 Subject: [PATCH 13/72] Fix result parsing expectations --- .../lib/policies/atomSerializationPolicy.ts | 13 ++++++++----- sdk/core/core-http/lib/util/atomHandler.ts | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 7b018ae30527..aedca9dd3b5a 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -54,12 +54,15 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const responseInCustomJson: any = { error: parsedResponse.errorBody, response: parsedResponse.parsedBody, - result: undefined + result: shouldParseResponse ? [] : undefined }; - responseInCustomJson.result = - shouldParseResponse && serializer - ? serializer.parse(responseInCustomJson.response) - : undefined; + + if (responseInCustomJson.error == undefined) { + responseInCustomJson.result = + shouldParseResponse && serializer + ? serializer.parse(responseInCustomJson.response) + : undefined; + } response.parsedBody = responseInCustomJson; return response; diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index 099e5151ae4b..f09ac11d4636 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -21,7 +21,7 @@ export function parseResultFromAtomResponse(atomResponseInJson: any): any { return parseEntryResult(atomResponseInJson.entry); } - throw new Error("Unrecognized result: " + atomResponseInJson); + throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); } function parseEntryResult(entry: any): any { From 0d6070866691e4e4a62165f7818b6deb9f288291 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 4 Sep 2019 20:40:37 -0700 Subject: [PATCH 14/72] Export ProxySettings --- sdk/core/core-http/lib/coreHttp.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 65b4d3ea9e1a..03efb96af44e 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -108,3 +108,4 @@ export { SasServiceClientCredentials } from "./credentials/sasServiceClientCrede export { ResourceSerializer } from "./resourceSerializer"; export { AtomResourceSerializerBase } from "./atomResourceSerializerBase"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; +export { ProxySettings } from "./serviceClient"; From 207e980db629398e473c9e101bb8d482635fc65a Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 5 Sep 2019 12:47:11 -0700 Subject: [PATCH 15/72] Address comments, simplify implementation --- .../lib/policies/atomSerializationPolicy.ts | 67 ++++++++++--------- .../policies/msRestUserAgentPolicy.browser.ts | 2 +- sdk/core/core-http/lib/util/atomHandler.ts | 44 +++++++----- 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index aedca9dd3b5a..27b95276c215 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -70,58 +70,61 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } /** - * Process the response. * @ignore + * Utility to help transform the response to contain normalized JSON based information + * constructed from the raw Atom XML based data received. * - * @param {WebResource} webResource The web resource that made the request. - * @param {Response} response The response object. + * @param {Response} response The response object containing data in Atom XML format. * @return The normalized responseObject. */ private parseResponse(response: HttpOperationResponse): HttpOperationResponse { - const parsedResponse: HttpOperationResponse = this._parseXmlResponseToJson(response); + try { + if (response.bodyAsText && response.bodyAsText.toString().length > 0) { + response.parsedBody = deserializeAtomXmlToJson(response.bodyAsText); + } + } catch (e) { + response.errorBody = { + error: { code: "ResponseNotInAtomXMLFormat" } + }; + } if (response.status >= 200 && response.status < 300 && response.errorBody == undefined) { return response; } - const HttpResponseCodes: any = Constants.HttpResponseCodes; - - if (parsedResponse.errorBody == undefined) { + if (response.errorBody == undefined) { + const HttpResponseCodes: any = Constants.HttpResponseCodes; if (Object.keys(HttpResponseCodes).indexOf(response.status.toString()) < 0) { - parsedResponse.errorBody = { + response.errorBody = { error: { code: `UnrecognizedHttpResponseStatus: ${response.status}` } }; } else { - parsedResponse.errorBody = { error: { code: HttpResponseCodes[response.status] } }; + response.errorBody = { error: { code: HttpResponseCodes[response.status] } }; } } - const normalizedError = this._normalizeError(parsedResponse.errorBody, response); - parsedResponse.errorBody = normalizedError; - return parsedResponse; + // Transform the errorBody to a normalized one + const normalizedError = this._normalizeError(response.errorBody, response); + response.errorBody = normalizedError; + return response; } - private _parseXmlResponseToJson(responseInXml: HttpOperationResponse): HttpOperationResponse { - const parsedResponse = responseInXml; - try { - if (responseInXml.bodyAsText && responseInXml.bodyAsText.toString().length > 0) { - parsedResponse.parsedBody = deserializeAtomXmlToJson(responseInXml.bodyAsText); - } - } catch (e) { - parsedResponse.errorBody = { - error: { code: "ResponseNotInAtomXMLFormat" } - }; - } - return parsedResponse; - } - - private _normalizeError(error: any, response: HttpOperationResponse): any { - if (isString(error)) { - return new Error(error); - } else if (error) { + /** + * @ignore + * Utility to help construct the normalized error object based on given `errorBody` + * data and other data present in the received `response` object. + * + * @param errorBody + * @param response + */ + private _normalizeError(errorBody: any, response: HttpOperationResponse): any { + if (isString(errorBody)) { + return new Error(errorBody); + } else if (errorBody) { const normalizedError: any = {}; - const odataErrorFormat = !!error["odata.error"]; - const errorProperties = error.Error || error.error || error["odata.error"] || error; + const odataErrorFormat = !!errorBody["odata.error"]; + const errorProperties = + errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; if (odataErrorFormat) { Object.keys(errorProperties).forEach((property: string) => { diff --git a/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts b/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts index 5d5464cfc0d0..491cf5d13c19 100644 --- a/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts +++ b/sdk/core/core-http/lib/policies/msRestUserAgentPolicy.browser.ts @@ -9,7 +9,7 @@ import { TelemetryInfo } from "./userAgentPolicy"; interface NavigatorEx extends Navigator { - readonly oscpu: string; + readonly oscpu: string | undefined; } export function getDefaultUserAgentKey(): string { diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index f09ac11d4636..7634f872cf8b 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -24,33 +24,47 @@ export function parseResultFromAtomResponse(atomResponseInJson: any): any { throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); } +/** + * @ignore + * Utility to help parse given `entry` result + * @param entry + */ function parseEntryResult(entry: any): any { + let result: any; + const contentElementName = Object.keys(entry.content).filter(function(key) { return key !== Constants.XML_METADATA_MARKER; - })[0]; + }); - delete entry.content[contentElementName][Constants.XML_METADATA_MARKER]; - const result = entry.content[contentElementName]; + if (contentElementName && contentElementName[0]) { + delete entry.content[contentElementName[0]][Constants.XML_METADATA_MARKER]; + result = entry.content[contentElementName[0]]; - if (result) { - if (entry[Constants.XML_METADATA_MARKER]) { - result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; - } else { - result[Constants.ATOM_METADATA_MARKER] = {}; - } + if (result) { + if (entry[Constants.XML_METADATA_MARKER]) { + result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; + } else { + result[Constants.ATOM_METADATA_MARKER] = {}; + } - result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; + result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; - Object.keys(entry).forEach((property: string) => { - if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { - result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; - } - }); + Object.keys(entry).forEach((property: string) => { + if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { + result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; + } + }); + } } return result; } +/** + * @ignore + * Utility to help parse given `feed` result + * @param feed + */ function parseFeedResult(feed: any): any[] { const result = []; if (feed.entry) { From a78dce9809024fb664f9e5dcf3ecc22e99f13115 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 5 Sep 2019 13:30:04 -0700 Subject: [PATCH 16/72] Use parser in async mode --- .../lib/policies/atomSerializationPolicy.ts | 41 ++++++++++--------- sdk/core/core-http/lib/util/xml.ts | 4 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 27b95276c215..461580163d8b 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -38,7 +38,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { public async sendRequest(request: WebResource): Promise { let shouldParseResponse = false; - let serializer: ResourceSerializer; + let serializer: ResourceSerializer | undefined; if (request.atomXmlOperationSpec) { serializer = request.atomXmlOperationSpec.serializer; shouldParseResponse = request.atomXmlOperationSpec.shouldParseResponse; @@ -47,26 +47,27 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } } - return this._nextPolicy.sendRequest(request).then((response: HttpOperationResponse) => { - const parsedResponse: HttpOperationResponse = this.parseResponse(response); + let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); - // Construct response with 'result' to be backward compatibile - const responseInCustomJson: any = { - error: parsedResponse.errorBody, - response: parsedResponse.parsedBody, - result: shouldParseResponse ? [] : undefined - }; + // Transform response to contain the parsed data + response = await this.parseResponse(response); - if (responseInCustomJson.error == undefined) { - responseInCustomJson.result = - shouldParseResponse && serializer - ? serializer.parse(responseInCustomJson.response) - : undefined; - } + // Construct response with 'result' to be backward compatibile + const responseInCustomJson: any = { + error: response.errorBody, + response: response.parsedBody, + result: shouldParseResponse ? [] : undefined + }; - response.parsedBody = responseInCustomJson; - return response; - }); + if (responseInCustomJson.error == undefined) { + responseInCustomJson.result = + shouldParseResponse && serializer + ? serializer.parse(responseInCustomJson.response) + : undefined; + } + + response.parsedBody = responseInCustomJson; + return response; } /** @@ -77,10 +78,10 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { * @param {Response} response The response object containing data in Atom XML format. * @return The normalized responseObject. */ - private parseResponse(response: HttpOperationResponse): HttpOperationResponse { + private async parseResponse(response: HttpOperationResponse): Promise { try { if (response.bodyAsText && response.bodyAsText.toString().length > 0) { - response.parsedBody = deserializeAtomXmlToJson(response.bodyAsText); + response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); } } catch (e) { response.errorBody = { diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index ea9531ade7cc..b6b541e56bcc 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -39,10 +39,10 @@ export function parseXML(str: string): Promise { }); } -export function deserializeAtomXmlToJson(body: string): any { +export async function deserializeAtomXmlToJson(body: string): Promise { let parsed; const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); - parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { + await parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { throw err; } else { From c6ddd9f4b76dce480c5bbd0d66f755f9b41366ab Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 6 Sep 2019 12:29:25 -0700 Subject: [PATCH 17/72] Address comments --- .../lib/policies/atomSerializationPolicy.ts | 15 +++++++++++---- sdk/core/core-http/lib/util/xml.ts | 16 ++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 461580163d8b..dd7887c1312b 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -94,13 +94,14 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } if (response.errorBody == undefined) { - const HttpResponseCodes: any = Constants.HttpResponseCodes; - if (Object.keys(HttpResponseCodes).indexOf(response.status.toString()) < 0) { + const HttpResponseCodes = Constants.HttpResponseCodes; + const statusCode = response.status; + if (!this.isKnownResponseCode(statusCode)) { response.errorBody = { - error: { code: `UnrecognizedHttpResponseStatus: ${response.status}` } + error: { code: `UnrecognizedHttpResponseStatus: ${statusCode}` } }; } else { - response.errorBody = { error: { code: HttpResponseCodes[response.status] } }; + response.errorBody = { error: { code: HttpResponseCodes[statusCode] } }; } } @@ -110,6 +111,12 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { return response; } + private isKnownResponseCode( + statusCode: number + ): statusCode is keyof typeof Constants.HttpResponseCodes { + return !!(Constants.HttpResponseCodes as { [statusCode: number]: string })[statusCode]; + } + /** * @ignore * Utility to help construct the normalized error object based on given `errorBody` diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index b6b541e56bcc..562151892360 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -40,16 +40,16 @@ export function parseXML(str: string): Promise { } export async function deserializeAtomXmlToJson(body: string): Promise { - let parsed; const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); - await parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { - if (err) { - throw err; - } else { - parsed = parsedBody; - } + return await new Promise((resolve, reject) => { + parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { + if (err) { + reject(err); + } else { + resolve(parsedBody); + } + }); }); - return parsed; } /** From bf61ea0483fd6b5c882cc048721b4c0f44f3c3e6 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 6 Sep 2019 16:30:07 -0700 Subject: [PATCH 18/72] Remove isNode check around URL usage --- sdk/core/core-http/lib/atomResourceSerializerBase.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 38506264dc65..14e878b8e5a1 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { isNode } from "./util/utils"; import { Constants } from "./util/constants"; import { serializeJsonToAtomXml } from "./util/xml"; import { parseResultFromAtomResponse } from "./util/atomHandler"; @@ -49,12 +48,8 @@ export class AtomResourceSerializerBase { } private static setName(entry: any, nameProperty: any): any { - let parsedUrl: any; - if (isNode) { - parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); - } else { - parsedUrl = new window.URL(entry[Constants.ATOM_METADATA_MARKER].id); - } + const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); + const parts = parsedUrl.pathname!.split("/"); for (let i = 0; i * 2 < parts.length - 1; i++) { From 0995e3550d8a18a282800252295954040615ac44 Mon Sep 17 00:00:00 2001 From: ramya0820 <45977823+ramya0820@users.noreply.github.com> Date: Fri, 6 Sep 2019 16:34:57 -0700 Subject: [PATCH 19/72] Update sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts Co-Authored-By: Brian Terlson --- .../core-http/test/policies/atomSerializationPolicyTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 9be4481f3264..3caf9866a083 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -117,7 +117,7 @@ function getCustomResult(error: any, result: any, response: any): any { class MockSerializer implements ResourceSerializer { serialize(resource: any): any { - var properties = ["LockDuration", "MaxSizeInMegabytes"]; + const properties = ["LockDuration", "MaxSizeInMegabytes"]; return AtomResourceSerializerBase.serializeToAtomXmlRequest( "QueueDescription", From faa6a69831cc947c7889268758bb60cb0abe4d24 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 6 Sep 2019 16:37:58 -0700 Subject: [PATCH 20/72] Remove unused util --- sdk/core/core-http/lib/util/utils.ts | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 6e33240374ac..c22c63059c05 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -86,34 +86,6 @@ export function isValidUuid(uuid: string): boolean { return validUuidRegex.test(uuid); } -/** - * Provides an array of values of an object. For example - * for a given object { "a": "foo", "b": "bar" }, the method returns ["foo", "bar"]. - * - * @param {object} obj An object whose properties need to be enumerated so that it"s values can be provided as an array - * - * @return {any[]} An array of values of the given object. - */ -export function objectValues(obj: { [key: string]: any }): any[] { - const result: any[] = []; - if (obj && obj instanceof Object) { - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - result.push((obj)[key]); - } - } - } else { - throw new Error( - `The provided object ${JSON.stringify( - obj, - undefined, - 2 - )} is not a valid object that can be enumerated to provide its values as an array.` - ); - } - return result; -} - /** * Generated UUID * From 3d57613a3804128bdebb09a026b8f47aa672ab81 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 9 Sep 2019 14:21:58 -0700 Subject: [PATCH 21/72] Address comments --- .../lib/atomResourceSerializerBase.ts | 48 ++++++++++---- sdk/core/core-http/lib/util/atomHandler.ts | 65 +++++++++++++++---- sdk/core/core-http/lib/util/xml.ts | 6 +- 3 files changed, 92 insertions(+), 27 deletions(-) diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts index 14e878b8e5a1..a84988973fc8 100644 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ b/sdk/core/core-http/lib/atomResourceSerializerBase.ts @@ -3,7 +3,11 @@ import { Constants } from "./util/constants"; import { serializeJsonToAtomXml } from "./util/xml"; -import { parseResultFromAtomResponse } from "./util/atomHandler"; +import { + parseResultFromAtomResponse, + XMLRequestInJSON, + XMLResponseInJSON +} from "./util/atomHandler"; export class AtomResourceSerializerBase { static serializeToAtomXmlRequest( @@ -12,7 +16,7 @@ export class AtomResourceSerializerBase { properties: string[], xmlNamespace: string ): string { - const content: any = {}; + const content: XMLRequestInJSON = {}; content[resourceName] = { $: { xmlns: xmlNamespace @@ -31,29 +35,51 @@ export class AtomResourceSerializerBase { return serializeJsonToAtomXml(content); } - static deserializeAtomResponse(nameProperty: string[], atomResponseInJson: any): any { + /** + * Deserializes the JSON representation of Atom response to construct + * the final `result` to return + * + * @param nameProperties The set of 'name' properties to be constructed on the resultant object e.g., QueueName, TopicName, etc. + * @param atomResponseInJson + */ + static deserializeAtomResponse( + nameProperties: string[], + atomResponseInJson: any + ): XMLResponseInJSON[] | XMLResponseInJSON | undefined { const result = parseResultFromAtomResponse(atomResponseInJson); if (!result) { return undefined; } if (Array.isArray(result)) { - result.forEach((entry: any) => { - AtomResourceSerializerBase.setName(entry, nameProperty); + result.forEach((entry: XMLResponseInJSON) => { + AtomResourceSerializerBase.setName(entry, nameProperties); }); } else { - AtomResourceSerializerBase.setName(result, nameProperty); + AtomResourceSerializerBase.setName(result, nameProperties); } return result; } - private static setName(entry: any, nameProperty: any): any { - const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); + /** + * Extracts the applicable entity name(s) from the URL based on the known structure + * and instantiates the corresponding name properties to the deserialized response + * + * For instance, following is the URL structure for when creating a rule + * `//Subscriptions//Rules/` + * + * @param entry + * @param nameProperties + */ + private static setName(entry: XMLResponseInJSON, nameProperties: any): any { + if (entry[Constants.ATOM_METADATA_MARKER]) { + const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); - const parts = parsedUrl.pathname!.split("/"); + const parts = parsedUrl.pathname!.split("/"); - for (let i = 0; i * 2 < parts.length - 1; i++) { - entry[nameProperty[i]] = parts[i * 2 + 1]; + for (let i = 0; i * 2 < parts.length - 1; i++) { + entry[nameProperties[i]] = parts[i * 2 + 1]; + } } } } diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts index 7634f872cf8b..3a6a02e742b2 100644 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ b/sdk/core/core-http/lib/util/atomHandler.ts @@ -3,12 +3,31 @@ import { Constants } from "./constants"; +/** + * Type representing the JSON representation of XML request data + */ +export interface XMLRequestInJSON { + [key: string]: { + $: { xmlns: string }; + [key: string]: any; + }; +} + +/** + * Type representing the JSON representation of XML response data + */ +export interface XMLResponseInJSON { + [key: string]: any; +} + /** * Utility to deserialize the given JSON content even further based on * if it's a single `entry` or `feed` - * @param {object} xmlInJson + * @param {object} atomResponseInJson * */ -export function parseResultFromAtomResponse(atomResponseInJson: any): any { +export function parseResultFromAtomResponse( + atomResponseInJson: any +): XMLResponseInJSON[] | XMLResponseInJSON | undefined { if (!atomResponseInJson) { return; } @@ -29,16 +48,26 @@ export function parseResultFromAtomResponse(atomResponseInJson: any): any { * Utility to help parse given `entry` result * @param entry */ -function parseEntryResult(entry: any): any { - let result: any; +function parseEntryResult(entry: any): XMLResponseInJSON | undefined { + let result: XMLResponseInJSON; + + if ( + typeof entry !== "object" || + entry == null || + typeof entry.content !== "object" || + entry.content == null + ) { + return undefined; + } - const contentElementName = Object.keys(entry.content).filter(function(key) { + const contentElementNames = Object.keys(entry.content).filter(function(key) { return key !== Constants.XML_METADATA_MARKER; }); - if (contentElementName && contentElementName[0]) { - delete entry.content[contentElementName[0]][Constants.XML_METADATA_MARKER]; - result = entry.content[contentElementName[0]]; + if (contentElementNames && contentElementNames[0]) { + const contentRootElementName = contentElementNames[0]; + delete entry.content[contentRootElementName][Constants.XML_METADATA_MARKER]; + result = entry.content[contentRootElementName]; if (result) { if (entry[Constants.XML_METADATA_MARKER]) { @@ -47,17 +76,19 @@ function parseEntryResult(entry: any): any { result[Constants.ATOM_METADATA_MARKER] = {}; } - result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentElementName; + result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentRootElementName; Object.keys(entry).forEach((property: string) => { if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; } }); + + return result; } } - return result; + return undefined; } /** @@ -65,15 +96,21 @@ function parseEntryResult(entry: any): any { * Utility to help parse given `feed` result * @param feed */ -function parseFeedResult(feed: any): any[] { +function parseFeedResult(feed: any): XMLResponseInJSON[] { const result = []; - if (feed.entry) { + if (typeof feed === "object" && feed != null && feed.entry) { if (Array.isArray(feed.entry)) { feed.entry.forEach((entry: any) => { - result.push(parseEntryResult(entry)); + const parsedEntryResult = parseEntryResult(entry); + if (parsedEntryResult) { + result.push(parsedEntryResult); + } }); } else { - result.push(parseEntryResult(feed.entry)); + const parsedEntryResult = parseEntryResult(feed.entry); + if (parsedEntryResult) { + result.push(parsedEntryResult); + } } } return result; diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 562151892360..15e9cd3db66f 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -88,7 +88,7 @@ function _getDefaultSettingsForAtomXmlOperations(): any { } /** - * + * @ignore * @param str Helper utility to clean up unintended characters that get appended by OS. */ function _removeBOM(str: any) { @@ -99,7 +99,9 @@ function _removeBOM(str: any) { return str; } -/* +/** + * + * @ignore * Writes a single property for an entry or complex type. * * @param {object} parentElement Parent DOM element under which the property should be added. From a212ec299348a9fc8bad7647f6598822c4c28720 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 9 Sep 2019 15:15:42 -0700 Subject: [PATCH 22/72] Copy pnpm file from master --- common/config/rush/pnpm-lock.yaml | 2101 +++++++++++++++++++++-------- 1 file changed, 1554 insertions(+), 547 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 68572302b679..b66ff4873ef3 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -2,14 +2,15 @@ dependencies: '@azure/amqp-common': 1.0.0-preview.6_rhea-promise@0.1.15 '@azure/arm-servicebus': 3.2.0 '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 - '@azure/core-paging': 1.0.0-preview.1 - '@azure/core-tracing': 1.0.0-preview.1 + '@azure/cosmos-sign': 1.0.2 '@azure/event-hubs': 2.1.1 '@azure/logger-js': 1.3.2 '@azure/ms-rest-js': 2.0.4 '@azure/ms-rest-nodeauth': 0.9.3 + '@azure/storage-blob': 12.0.0-preview.2 '@microsoft/api-extractor': 7.3.8 '@rush-temp/abort-controller': 'file:projects/abort-controller.tgz' + '@rush-temp/app-configuration': 'file:projects/app-configuration.tgz' '@rush-temp/core-amqp': 'file:projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:projects/core-asynciterator-polyfill.tgz' @@ -17,8 +18,10 @@ dependencies: '@rush-temp/core-http': 'file:projects/core-http.tgz' '@rush-temp/core-paging': 'file:projects/core-paging.tgz' '@rush-temp/core-tracing': 'file:projects/core-tracing.tgz' + '@rush-temp/cosmos': 'file:projects/cosmos.tgz_webpack@4.39.2' '@rush-temp/event-hubs': 'file:projects/event-hubs.tgz' '@rush-temp/event-processor-host': 'file:projects/event-processor-host.tgz' + '@rush-temp/eventhubs-checkpointstore-blob': 'file:projects/eventhubs-checkpointstore-blob.tgz' '@rush-temp/identity': 'file:projects/identity.tgz' '@rush-temp/keyvault-certificates': 'file:projects/keyvault-certificates.tgz' '@rush-temp/keyvault-keys': 'file:projects/keyvault-keys.tgz' @@ -28,15 +31,17 @@ dependencies: '@rush-temp/storage-file': 'file:projects/storage-file.tgz' '@rush-temp/storage-queue': 'file:projects/storage-queue.tgz' '@rush-temp/template': 'file:projects/template.tgz' + '@rush-temp/test-utils-recorder': 'file:projects/test-utils-recorder.tgz' '@rush-temp/testhub': 'file:projects/testhub.tgz' '@trust/keyto': 0.3.7 '@types/async-lock': 1.1.1 '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 '@types/chai-string': 1.4.2 - '@types/debug': 0.0.31 + '@types/debug': 4.1.5 '@types/dotenv': 6.1.1 '@types/express': 4.17.1 + '@types/fast-json-stable-stringify': 2.0.0 '@types/fetch-mock': 7.3.1 '@types/fs-extra': 8.0.0 '@types/glob': 7.1.1 @@ -50,45 +55,55 @@ dependencies: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/node-fetch': 2.5.0 + '@types/priorityqueuejs': 1.0.1 '@types/qs': 6.5.3 '@types/query-string': 6.2.0 - '@types/semver': 5.5.0 + '@types/semaphore': 1.1.0 '@types/sinon': 7.0.13 '@types/tough-cookie': 2.3.5 '@types/tunnel': 0.0.1 + '@types/underscore': 1.9.2 '@types/uuid': 3.4.5 - '@types/webpack': 4.39.1 + '@types/webpack': 4.39.0 '@types/webpack-dev-middleware': 2.0.3 '@types/ws': 6.0.3 '@types/xml2js': 0.4.4 '@types/yargs': 13.0.2 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + abort-controller: 3.0.0 assert: 1.5.0 async-lock: 1.2.2 + atob: 2.1.2 azure-storage: 2.10.3 babel-runtime: 6.26.0 - buffer: 5.4.2 + binary-search-bounds: 2.0.3 + buffer: 5.4.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 cross-env: 5.2.0 + crypto-hash: 1.1.0 death: 1.1.0 - debug: 3.2.6 + debug: 4.1.1 delay: 4.3.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 + esm: 3.2.18 events: 3.0.0 + execa: 1.0.0 express: 4.17.1 + fast-json-stable-stringify: 2.0.0 fetch-mock: 7.3.9 form-data: 2.5.0 fs-extra: 8.1.0 glob: 7.1.4 + guid-typescript: 1.0.9 gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 https-proxy-agent: 2.2.2 @@ -96,24 +111,26 @@ dependencies: is-buffer: 2.0.3 jssha: 2.3.1 jws: 3.2.2 - karma: 4.3.0 - karma-chai: 0.1.0_chai@4.2.0+karma@4.3.0 + karma: 4.2.0 + karma-chai: 0.1.0_chai@4.2.0+karma@4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-cli: 2.0.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 - karma-rollup-preprocessor: 7.0.2_rollup@1.20.3 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 + karma-requirejs: 1.1.0_karma@4.2.0+requirejs@2.3.6 + karma-rollup-preprocessor: 7.0.2_rollup@1.20.1 karma-sourcemap-loader: 0.3.7 karma-typescript-es6-transform: 4.1.1 - karma-webpack: 4.0.2_webpack@4.39.3 + karma-webpack: 4.0.2_webpack@4.39.2 long: 4.0.0 mocha: 6.2.0 mocha-chrome: 2.0.0 @@ -121,71 +138,82 @@ dependencies: mocha-multi: 1.1.3_mocha@6.2.0 moment: 2.24.0 msal: 1.1.3 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 + node-abort-controller: 1.0.3 node-fetch: 2.6.0 npm-run-all: 4.1.5 nyc: 14.1.1 path-browserify: 1.0.0 prettier: 1.18.2 + priorityqueuejs: 1.0.0 process: 0.11.10 promise: 8.0.3 + proxy-agent: 3.0.3 puppeteer: 1.19.0 qs: 6.8.0 query-string: 5.1.1 regenerator-runtime: 0.13.3 + requirejs: 2.3.6 rhea: 1.0.8 rhea-promise: 0.1.15 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-alias: 1.5.2 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 + rollup-plugin-local-resolve: 1.0.7 rollup-plugin-multi-entry: 2.1.0 rollup-plugin-node-globals: 1.4.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-uglify: 6.0.2_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 - semver: 5.7.1 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-uglify: 6.0.2_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 + semaphore: 1.0.5 shx: 0.3.2 sinon: 7.4.1 source-map-support: 0.5.13 stream-browserify: 2.0.2 - terser: 4.2.1 + terser: 4.2.0 tough-cookie: 3.0.1 - ts-loader: 6.0.4_typescript@3.6.2 + ts-loader: 6.0.4_typescript@3.5.3 ts-mocha: 6.0.0_mocha@6.2.0 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 tunnel: 0.0.6 - typescript: 3.6.2 + typedoc: 0.15.0 + typescript: 3.5.3 uglify-js: 3.6.0 + universal-user-agent: 2.1.0 url: 0.11.0 util: 0.12.1 uuid: 3.3.3 - webpack: 4.39.3_webpack@4.39.3 - webpack-cli: 3.3.7_webpack@4.39.3 - webpack-dev-middleware: 3.7.0_webpack@4.39.3 + webpack: 4.39.2_webpack@4.39.2 + webpack-cli: 3.3.7_webpack@4.39.2 + webpack-dev-middleware: 3.7.0_webpack@4.39.2 ws: 7.1.2 xhr-mock: 2.5.0 xml2js: 0.4.19 - xmlbuilder: 0.4.3 - yargs: 13.3.0 + yargs: 14.0.0 yarn: 1.17.3 lockfileVersion: 5.1 packages: + /@azure/abort-controller/1.0.0-preview.1: + dependencies: + tslib: 1.10.0 + dev: false + resolution: + integrity: sha512-NnJqi6oHqt06Q2hz4nO1HO0QlyusBa3E/wezvn9flHEtl0IHYSmzGbtlb+MaAJ5GzxwqSevQ4q1+4B8fvVijOA== /@azure/amqp-common/1.0.0-preview.6_rhea-promise@0.1.15: dependencies: '@azure/ms-rest-nodeauth': 0.9.3 '@types/async-lock': 1.1.1 '@types/is-buffer': 2.0.0 async-lock: 1.2.2 - buffer: 5.4.2 + buffer: 5.4.0 debug: 3.2.6 events: 3.0.0 is-buffer: 2.0.3 @@ -213,6 +241,28 @@ packages: dev: false resolution: integrity: sha512-hMp0y+j/odkAyTa5TYewn4hUlFdEe3sR9uTd2Oq+se61RtuDsqM7UWrNNlyylPyjIENSZHJVWN7jte/jvvMN2Q== + /@azure/core-auth/1.0.0-preview.2: + dependencies: + '@azure/abort-controller': 1.0.0-preview.1 + tslib: 1.10.0 + dev: false + resolution: + integrity: sha512-QATxlKPP2Yld8+eg8Hz8mXmowlG/z9B53HTkjBz0oJIzR+dBm9HJY2bPnT7RB8nyqdnm8JpU2mIp8YVZZO6ubg== + /@azure/core-http/1.0.0-preview.2: + dependencies: + '@azure/core-auth': 1.0.0-preview.2 + '@types/tunnel': 0.0.1 + axios: 0.19.0 + form-data: 2.5.0 + process: 0.11.10 + tough-cookie: 3.0.1 + tslib: 1.10.0 + tunnel: 0.0.6 + uuid: 3.3.3 + xml2js: 0.4.19 + dev: false + resolution: + integrity: sha512-7zvbuMxwFjqvZ8knyEky+tWJYq6nK/pDIOI44nuCsdzdeCA8G9Ul3tXuQ+1lI4NOUfd2Scj8Ckgb4Xh9+ckOuw== /@azure/core-paging/1.0.0-preview.1: dependencies: '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 @@ -225,6 +275,12 @@ packages: dev: false resolution: integrity: sha512-nDfxQopw7lfJG5N845BOS6Vcl84GcB1Q3BHKJAHghLOmdHQjV9Z92M4ziFAQ60UnOj2zrUefM6yDZcKjANCcyg== + /@azure/cosmos-sign/1.0.2: + dependencies: + crypto-js: 3.1.9-1 + dev: false + resolution: + integrity: sha512-+y3EDcbSFuieOKqw9VyaX7D13LB4LycQIdmLwSqFnSUO0mWl+RBLCKW3RL6XiyWOHRV2sMNT9vwGzwiFZI70vQ== /@azure/event-hubs/2.1.1: dependencies: '@azure/amqp-common': 1.0.0-preview.6_rhea-promise@0.1.15 @@ -292,6 +348,16 @@ packages: dev: false resolution: integrity: sha512-aFHRw/IHhg3I9ZJW+Va4L+sCirFHMVIu6B7lFdL5mGLfG3xC5vDIdd957LRXFgy2OiKFRUC0QaKknd0YCsQIqA== + /@azure/storage-blob/12.0.0-preview.2: + dependencies: + '@azure/abort-controller': 1.0.0-preview.1 + '@azure/core-http': 1.0.0-preview.2 + '@azure/core-paging': 1.0.0-preview.1 + events: 3.0.0 + tslib: 1.10.0 + dev: false + resolution: + integrity: sha512-YOZ3l065gmnaLdcpkyY+C02x2yi9XFo5ARZQGtoDMUz7VD+QzIbDwWsYlWOArVEm5Dxhl3v1zKJ1V6bi06iHEQ== /@babel/code-frame/7.5.5: dependencies: '@babel/highlight': 7.5.0 @@ -381,6 +447,29 @@ packages: dev: false resolution: integrity: sha512-2yNbQsQl5PI36l5WzHQshwjBHPe5IeIcmidWad0E+wjyaAxGMLx5pBp5AgXY2JG9S9VQjFmmGmqJJBXn8tzu+w== + /@microsoft/api-extractor-model/7.3.4: + dependencies: + '@microsoft/node-core-library': 3.14.1 + '@microsoft/tsdoc': 0.12.14 + '@types/node': 8.5.8 + dev: false + resolution: + integrity: sha512-a9gXhWG7PWcUNpJRtxGZ/Vepq1ke5ES2B6NnBH0M3zT//vGYXymf7aOQepCHfmY4p1cJvvmJoJNGMwtoC0eF5A== + /@microsoft/api-extractor/7.3.11: + dependencies: + '@microsoft/api-extractor-model': 7.3.4 + '@microsoft/node-core-library': 3.14.1 + '@microsoft/ts-command-line': 4.2.7 + '@microsoft/tsdoc': 0.12.14 + colors: 1.2.5 + lodash: 4.17.15 + resolve: 1.8.1 + source-map: 0.6.1 + typescript: 3.5.3 + dev: false + hasBin: true + resolution: + integrity: sha512-i/hBovsbk1btBIQFWHHbAQdcXxL07+nYwF6wxDabtM+rJgySQ/flsjZJYXJV+ADlP0L3jyKdWZNF03M3zlQUlw== /@microsoft/api-extractor/7.3.8: dependencies: '@microsoft/api-extractor-model': 7.3.2 @@ -409,6 +498,19 @@ packages: dev: false resolution: integrity: sha512-+gbTXTRfvR40hTH+C3Vno/RJ51sU/RZAyHb2bo9af8GCdOgxCxCs+qp2KCXklbpuolmIPFfbCmdTwv90yH5tJw== + /@microsoft/node-core-library/3.14.1: + dependencies: + '@types/fs-extra': 5.0.4 + '@types/jju': 1.4.1 + '@types/node': 8.5.8 + '@types/z-schema': 3.16.31 + colors: 1.2.5 + fs-extra: 7.0.1 + jju: 1.4.0 + z-schema: 3.18.4 + dev: false + resolution: + integrity: sha512-KVYef9kjK6lmGOOjYRctYFX3ymZ71xobweBftwP8hQS5JTBX+QqpAOvfiFQmlMgfJ7/TS7u3u3QjVzeztuz5cg== /@microsoft/ts-command-line/4.2.7: dependencies: '@types/argparse': 1.0.33 @@ -422,6 +524,10 @@ packages: dev: false resolution: integrity: sha512-5EzH1gHIonvvgA/xWRmVAJmRkTQj/yayUXyr66hFwNZiFE4j7lP8is9YQeXhwxGZEjO1PVMblAmFF0CyjNtPGw== + /@microsoft/tsdoc/0.12.14: + dev: false + resolution: + integrity: sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q== /@sinonjs/commons/1.6.0: dependencies: type-detect: 4.0.8 @@ -494,16 +600,20 @@ packages: dev: false resolution: integrity: sha512-zw8UvoBEImn392tLjxoavuonblX/4Yb9ha4KBU10FirCfwgzhKO0dvyJSF9ByxV1xK1r2AgnAi/tvQaLgxQqxA== + /@types/chai/4.2.1: + dev: false + resolution: + integrity: sha512-LDKlQW/V8bQr5p9aoHye9p7x9faxq0GVeWAkn/Zgyyn848LIAzuR1sHQjGmUBFUpINuGWDG2NTM/ofA2aLMIew== /@types/connect/3.4.32: dependencies: '@types/node': 8.10.52 dev: false resolution: integrity: sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== - /@types/debug/0.0.31: + /@types/debug/4.1.5: dev: false resolution: - integrity: sha512-LS1MCPaQKqspg7FvexuhmDbWUhE2yIJ+4AgVIyObfc06/UKZ8REgxGNjZc82wPLWmbeOm7S+gSsLgo75TanG4A== + integrity: sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== /@types/dotenv/6.1.1: dependencies: '@types/node': 8.10.52 @@ -537,13 +647,17 @@ packages: dev: false resolution: integrity: sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w== + /@types/fast-json-stable-stringify/2.0.0: + dev: false + resolution: + integrity: sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ== /@types/fetch-mock/7.3.1: dev: false resolution: integrity: sha512-2U4vZWHNbsbK7TRmizgr/pbKe0FKopcxu+hNDtIBDiM1wvrKRItybaYj7VQ6w/hZJStU/JxRiNi5ww4YDEvKbA== /@types/fs-extra/5.0.4: dependencies: - '@types/node': 8.10.52 + '@types/node': 8.10.53 dev: false resolution: integrity: sha512-DsknoBvD8s+RFfSGjmERJ7ZOP1HI0UZRA3FSI+Zakhrc/Gy26YQsLI+m5V5DHxroHRJqCDLKJp7Hixn8zyaF7g== @@ -640,14 +754,26 @@ packages: dev: false resolution: integrity: sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== + /@types/node/12.7.4: + dev: false + resolution: + integrity: sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== /@types/node/8.10.52: dev: false resolution: integrity: sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== + /@types/node/8.10.53: + dev: false + resolution: + integrity: sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ== /@types/node/8.5.8: dev: false resolution: integrity: sha512-8KmlRxwbKZfjUHFIt3q8TF5S2B+/E5BaAoo/3mgc5h6FJzqxXkCK/VMetO+IRDtwtU6HUvovHMBn+XRj7SV9Qg== + /@types/priorityqueuejs/1.0.1: + dev: false + resolution: + integrity: sha1-bqrDJHpMXO/JRILl2Hw3MLNfUFM= /@types/qs/6.5.3: dev: false resolution: @@ -666,6 +792,10 @@ packages: dev: false resolution: integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + /@types/semaphore/1.1.0: + dev: false + resolution: + integrity: sha512-YD+lyrPhrsJdSOaxmA9K1lzsCoN0J29IsQGMKd67SbkPDXxJPdwdqpok1sytD19NEozUaFpjIsKOWnJDOYO/GA== /@types/semver/5.5.0: dev: false resolution: @@ -711,6 +841,10 @@ packages: dev: false resolution: integrity: sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + /@types/underscore/1.9.2: + dev: false + resolution: + integrity: sha512-KgOKTAD+9X+qvZnB5S1+onqKc4E+PZ+T6CM/NA5ohRPLHJXb+yCJMVf8pWOnvuBuKFNUAJW8N97IA6lba6mZGg== /@types/uuid/3.4.5: dependencies: '@types/node': 8.10.52 @@ -721,7 +855,7 @@ packages: dependencies: '@types/connect': 3.4.32 '@types/memory-fs': 0.3.2 - '@types/webpack': 4.39.1 + '@types/webpack': 4.39.0 loglevel: 1.6.3 dev: false resolution: @@ -734,7 +868,7 @@ packages: dev: false resolution: integrity: sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w== - /@types/webpack/4.39.1: + /@types/webpack/4.39.0: dependencies: '@types/anymatch': 1.3.1 '@types/node': 8.10.52 @@ -744,7 +878,7 @@ packages: source-map: 0.6.1 dev: false resolution: - integrity: sha512-rgO9ihNu/l72Sjx3shqwc9r6gi+tOMsqxhMEZhOEVIZt82GFOeUyEdpTk1BO2HqEHLS/XJW8ldUTIIfIMMyYFQ== + integrity: sha512-8gUiAl6RBI4IoCJVQ9AChp4k2Tcd4ocNei2S83goHKCj8WesBtlqp9/wPd29dArHIGMdHxICwBi8YMm8PD6PEg== /@types/ws/6.0.3: dependencies: '@types/node': 8.10.52 @@ -771,15 +905,15 @@ packages: dev: false resolution: integrity: sha1-LrHQCl5Ow/pYx2r94S4YK2bcXBw= - /@typescript-eslint/eslint-plugin/2.0.0_725fda8723c9f372c79013d5541f9bc5: + /@typescript-eslint/eslint-plugin/2.0.0_3cafee28902d96627d4743e014bc28ff: dependencies: - '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.2 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 - eslint: 6.2.2 + '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.1 + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + eslint: 6.2.1 eslint-utils: 1.4.2 functional-red-black-tree: 1.0.1 regexpp: 2.0.1 - tsutils: 3.17.1_typescript@3.6.2 + tsutils: 3.17.1_typescript@3.5.3 dev: false engines: node: ^8.10.0 || ^10.13.0 || >=11.10.1 @@ -789,11 +923,29 @@ packages: typescript: '*' resolution: integrity: sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA== - /@typescript-eslint/experimental-utils/2.0.0_eslint@6.2.2: + /@typescript-eslint/eslint-plugin/2.1.0_3a8cea979a77aa77c321dad4153067ce: + dependencies: + '@typescript-eslint/experimental-utils': 2.1.0_eslint@6.3.0 + '@typescript-eslint/parser': 2.1.0_eslint@6.3.0 + eslint: 6.3.0 + eslint-utils: 1.4.2 + functional-red-black-tree: 1.0.1 + regexpp: 2.0.1 + tsutils: 3.17.1_typescript@3.6.2 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + peerDependencies: + '@typescript-eslint/parser': ^2.0.0 + eslint: ^5.0.0 || ^6.0.0 + typescript: '*' + resolution: + integrity: sha512-3i/dLPwxaVfCsaLu3HkB8CAA1Uw3McAegrTs+VBJ0BrGRKW7nUwSqRfHfCS7sw7zSbf62q3v0v6pOS8MyaYItg== + /@typescript-eslint/experimental-utils/2.0.0_eslint@6.2.1: dependencies: '@types/json-schema': 7.0.3 '@typescript-eslint/typescript-estree': 2.0.0 - eslint: 6.2.2 + eslint: 6.2.1 eslint-scope: 4.0.3 dev: false engines: @@ -802,12 +954,25 @@ packages: eslint: '*' resolution: integrity: sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg== - /@typescript-eslint/parser/2.0.0_eslint@6.2.2: + /@typescript-eslint/experimental-utils/2.1.0_eslint@6.3.0: + dependencies: + '@types/json-schema': 7.0.3 + '@typescript-eslint/typescript-estree': 2.1.0 + eslint: 6.3.0 + eslint-scope: 4.0.3 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + peerDependencies: + eslint: '*' + resolution: + integrity: sha512-ZJGLYXa4nxjNzomaEk1qts38B/vludg2LOM7dRc7SppEKsMPTS1swaTKS/pom+x4d/luJGoG00BDIss7PR1NQA== + /@typescript-eslint/parser/2.0.0_eslint@6.2.1: dependencies: '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.2 + '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.1 '@typescript-eslint/typescript-estree': 2.0.0 - eslint: 6.2.2 + eslint: 6.2.1 eslint-visitor-keys: 1.1.0 dev: false engines: @@ -816,6 +981,20 @@ packages: eslint: ^5.0.0 || ^6.0.0 resolution: integrity: sha512-ibyMBMr0383ZKserIsp67+WnNVoM402HKkxqXGlxEZsXtnGGurbnY90pBO3e0nBUM7chEEOcxUhgw9aPq7fEBA== + /@typescript-eslint/parser/2.1.0_eslint@6.3.0: + dependencies: + '@types/eslint-visitor-keys': 1.0.0 + '@typescript-eslint/experimental-utils': 2.1.0_eslint@6.3.0 + '@typescript-eslint/typescript-estree': 2.1.0 + eslint: 6.3.0 + eslint-visitor-keys: 1.1.0 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 + resolution: + integrity: sha512-0+hzirRJoqE1T4lSSvCfKD+kWjIpDWfbGBiisK5CENcr+22pPkHB2sfV1giON+UxHV4A08SSrQonZk7X2zIQdw== /@typescript-eslint/typescript-estree/2.0.0: dependencies: lodash.unescape: 4.0.1 @@ -825,6 +1004,17 @@ packages: node: ^8.10.0 || ^10.13.0 || >=11.10.1 resolution: integrity: sha512-NXbmzA3vWrSgavymlzMWNecgNOuiMMp62MO3kI7awZRLRcsA1QrYWo6q08m++uuAGVbXH/prZi2y1AWuhSu63w== + /@typescript-eslint/typescript-estree/2.1.0: + dependencies: + glob: 7.1.4 + is-glob: 4.0.1 + lodash.unescape: 4.0.1 + semver: 6.3.0 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + resolution: + integrity: sha512-482ErJJ7QYghBh+KA9G+Fwcuk/PLTy+9NBMz8S+6UFrUUnVvHRNAL7I70kdws2te0FBYEZW7pkDaXoT+y8UARw== /@webassemblyjs/ast/1.8.5: dependencies: '@webassemblyjs/helper-module-context': 1.8.5 @@ -1041,6 +1231,14 @@ packages: dev: false resolution: integrity: sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + /agent-base/4.2.1: + dependencies: + es6-promisify: 5.0.0 + dev: false + engines: + node: '>= 4.0.0' + resolution: + integrity: sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== /agent-base/4.3.0: dependencies: es6-promisify: 5.0.0 @@ -1389,6 +1587,12 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + /ast-types/0.13.2: + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== /astral-regex/1.0.0: dev: false engines: @@ -1973,6 +2177,12 @@ packages: node: '>= 0.10' resolution: integrity: sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= + /backbone/1.4.0: + dependencies: + underscore: 1.9.1 + dev: false + resolution: + integrity: sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ== /backo2/1.0.2: dev: false resolution: @@ -2045,6 +2255,10 @@ packages: node: '>=8' resolution: integrity: sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + /binary-search-bounds/2.0.3: + dev: false + resolution: + integrity: sha1-X/hhbW3SylOIvIWy1iZuK52lAtw= /blob/0.0.5: dev: false resolution: @@ -2174,7 +2388,7 @@ packages: /browserslist/3.2.8: dependencies: caniuse-lite: 1.0.30000989 - electron-to-chromium: 1.3.243 + electron-to-chromium: 1.3.237 dev: false hasBin: true resolution: @@ -2228,13 +2442,13 @@ packages: dev: false resolution: integrity: sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= - /buffer/5.4.2: + /buffer/5.4.0: dependencies: base64-js: 1.3.1 ieee754: 1.1.13 dev: false resolution: - integrity: sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== + integrity: sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g== /builtin-modules/3.1.0: dev: false engines: @@ -2587,6 +2801,13 @@ packages: dev: false resolution: integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + /co/4.6.0: + dev: false + engines: + iojs: '>= 1.0.0' + node: '>= 0.12.0' + resolution: + integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= /code-point-at/1.1.0: dev: false engines: @@ -2835,6 +3056,15 @@ packages: hasBin: true resolution: integrity: sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== + /cross-env/5.2.1: + dependencies: + cross-spawn: 6.0.5 + dev: false + engines: + node: '>=4.0' + hasBin: true + resolution: + integrity: sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ== /cross-spawn/4.0.2: dependencies: lru-cache: 4.1.5 @@ -2874,6 +3104,16 @@ packages: dev: false resolution: integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + /crypto-hash/1.1.0: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-5DWmfCxQZHWocCpkOXVFmfYj7v5vZXF3ZNzMeyyJ6OzGfDTEEOm2CWA8KzZ578eA7j5VPCLOdGjOU8sGgi8BYw== + /crypto-js/3.1.9-1: + dev: false + resolution: + integrity: sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg= /currently-unhandled/0.4.1: dependencies: array-find-index: 1.0.2 @@ -2905,6 +3145,12 @@ packages: node: '>=0.10' resolution: integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + /data-uri-to-buffer/2.0.1: + dependencies: + '@types/node': 8.10.52 + dev: false + resolution: + integrity: sha512-OkVVLrerfAKZlW2ZZ3Ve2y65jgiWqBKsTfUIAFbn8nVbPcCZg6l6gikKlEYv0kXcmzqGm6mFq/Jf2vriuEkv8A== /date-format/1.2.0: dev: false engines: @@ -3005,17 +3251,6 @@ packages: node: '>=0.12' resolution: integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - /deep-equal/1.1.0: - dependencies: - is-arguments: 1.0.4 - is-date-object: 1.0.1 - is-regex: 1.0.4 - object-is: 1.0.1 - object-keys: 1.1.1 - regexp.prototype.flags: 1.2.0 - dev: false - resolution: - integrity: sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== /deep-is/0.1.3: dev: false resolution: @@ -3082,6 +3317,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + /degenerator/1.0.4: + dependencies: + ast-types: 0.13.2 + escodegen: 1.12.0 + esprima: 3.1.3 + dev: false + resolution: + integrity: sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= /delay/4.3.0: dev: false engines: @@ -3220,10 +3463,10 @@ packages: dev: false resolution: integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - /electron-to-chromium/1.3.243: + /electron-to-chromium/1.3.237: dev: false resolution: - integrity: sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== + integrity: sha512-SPAFjDr/7iiVK2kgTluwxela6eaWjjFkS9rO/iYpB/KGXgccUom5YC7OIf19c8m8GGptWxLU0Em8xM64A/N7Fg== /elliptic/6.5.0: dependencies: bn.js: 4.11.8 @@ -3411,6 +3654,20 @@ packages: node: '>=0.8.0' resolution: integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + /escodegen/1.12.0: + dependencies: + esprima: 3.1.3 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.2 + dev: false + engines: + node: '>=4.0' + hasBin: true + optionalDependencies: + source-map: 0.6.1 + resolution: + integrity: sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== /escodegen/1.8.1: dependencies: esprima: 2.7.3 @@ -3425,9 +3682,9 @@ packages: source-map: 0.2.0 resolution: integrity: sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= - /eslint-config-prettier/6.1.0_eslint@6.2.2: + /eslint-config-prettier/6.1.0_eslint@6.2.1: dependencies: - eslint: 6.2.2 + eslint: 6.2.1 get-stdin: 6.0.0 dev: false hasBin: true @@ -3435,9 +3692,29 @@ packages: eslint: '>=3.14.1' resolution: integrity: sha512-k9fny9sPjIBQ2ftFTesJV21Rg4R/7a7t7LCtZVrYQiHEp8Nnuk3EGaDmsKSAnsPj0BYcgB2zxzHa2NTkIxcOLg== - /eslint-plugin-no-null/1.0.2_eslint@6.2.2: + /eslint-config-prettier/6.2.0_eslint@6.3.0: + dependencies: + eslint: 6.3.0 + get-stdin: 6.0.0 + dev: false + hasBin: true + peerDependencies: + eslint: '>=3.14.1' + resolution: + integrity: sha512-VLsgK/D+S/FEsda7Um1+N8FThec6LqE3vhcMyp8mlmto97y3fGf3DX7byJexGuOb1QY0Z/zz222U5t+xSfcZDQ== + /eslint-plugin-no-null/1.0.2_eslint@6.2.1: dependencies: - eslint: 6.2.2 + eslint: 6.2.1 + dev: false + engines: + node: '>=5.0.0' + peerDependencies: + eslint: '>=3.0.0' + resolution: + integrity: sha1-EjaoEjkTkKGHetQAfCbnRTQclR8= + /eslint-plugin-no-null/1.0.2_eslint@6.3.0: + dependencies: + eslint: 6.3.0 dev: false engines: node: '>=5.0.0' @@ -3489,7 +3766,52 @@ packages: node: '>=4' resolution: integrity: sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - /eslint/6.2.2: + /eslint/6.2.1: + dependencies: + '@babel/code-frame': 7.5.5 + ajv: 6.10.2 + chalk: 2.4.2 + cross-spawn: 6.0.5 + debug: 4.1.1 + doctrine: 3.0.0 + eslint-scope: 5.0.0 + eslint-utils: 1.4.2 + eslint-visitor-keys: 1.1.0 + espree: 6.1.0 + esquery: 1.0.1 + esutils: 2.0.3 + file-entry-cache: 5.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.0.0 + globals: 11.12.0 + ignore: 4.0.6 + import-fresh: 3.1.0 + imurmurhash: 0.1.4 + inquirer: 6.5.2 + is-glob: 4.0.1 + js-yaml: 3.13.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.3.0 + lodash: 4.17.15 + minimatch: 3.0.4 + mkdirp: 0.5.1 + natural-compare: 1.4.0 + optionator: 0.8.2 + progress: 2.0.3 + regexpp: 2.0.1 + semver: 6.3.0 + strip-ansi: 5.2.0 + strip-json-comments: 3.0.1 + table: 5.4.6 + text-table: 0.2.0 + v8-compile-cache: 2.1.0 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + hasBin: true + resolution: + integrity: sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg== + /eslint/6.3.0: dependencies: '@babel/code-frame': 7.5.5 ajv: 6.10.2 @@ -3533,7 +3855,23 @@ packages: node: ^8.10.0 || ^10.13.0 || >=11.10.1 hasBin: true resolution: - integrity: sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== + integrity: sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow== + /esm/3.2.18: + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-1UENjnnI37UDp7KuOqKYjfqdaMim06eBWnDv37smaxTIzDl0ZWnlgoXwsVwD9+Lidw+q/f1gUf2diVMDCycoVw== + /espree/6.1.0: + dependencies: + acorn: 7.0.0 + acorn-jsx: 5.0.2_acorn@7.0.0 + eslint-visitor-keys: 1.1.0 + dev: false + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ== /espree/6.1.1: dependencies: acorn: 7.0.0 @@ -3551,6 +3889,13 @@ packages: hasBin: true resolution: integrity: sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + /esprima/3.1.3: + dev: false + engines: + node: '>=4' + hasBin: true + resolution: + integrity: sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= /esprima/4.0.1: dev: false engines: @@ -3840,6 +4185,10 @@ packages: node: '>=4' resolution: integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + /file-uri-to-path/1.0.0: + dev: false + resolution: + integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== /fill-range/4.0.0: dependencies: extend-shallow: 2.0.1 @@ -3984,14 +4333,14 @@ packages: node: '>=4.0' resolution: integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - /follow-redirects/1.8.1: + /follow-redirects/1.9.0: dependencies: debug: 3.2.6 dev: false engines: node: '>=4.0' resolution: - integrity: sha512-micCIbldHioIegeKs41DoH0KS3AXfFzgS30qVkM6z/XOE/GJgvmsoc839NUqa1B9udYe9dQxgv7KFwng6+p/dw== + integrity: sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A== /for-in/1.0.2: dev: false engines: @@ -4125,6 +4474,15 @@ packages: optional: true resolution: integrity: sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ== + /ftp/0.3.10: + dependencies: + readable-stream: 1.1.14 + xregexp: 2.0.0 + dev: false + engines: + node: '>=0.8.0' + resolution: + integrity: sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= /function-bind/1.1.1: dev: false resolution: @@ -4175,6 +4533,17 @@ packages: node: '>=8' resolution: integrity: sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + /get-uri/2.0.3: + dependencies: + data-uri-to-buffer: 2.0.1 + debug: 4.1.1 + extend: 3.0.2 + file-uri-to-path: 1.0.0 + ftp: 0.3.10 + readable-stream: 3.4.0 + dev: false + resolution: + integrity: sha512-x5j6Ks7FOgLD/GlvjKwgu7wdmMR55iuRHhn8hj/+gA+eSbxQvZ+AEomq+3MgVEZj1vpi738QahGbCCSIDtXtkw== /get-value/2.0.6: dev: false engines: @@ -4345,6 +4714,10 @@ packages: node: '>=4.x' resolution: integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + /guid-typescript/1.0.9: + dev: false + resolution: + integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ== /gulp-cli/2.2.0: dependencies: ansi-colors: 1.1.0 @@ -4406,7 +4779,7 @@ packages: node: '>= 0.10' resolution: integrity: sha1-4oxNRdBey77YGDY86PnFkmIp/+U= - /handlebars/4.1.2: + /handlebars/4.2.0: dependencies: neo-async: 2.6.1 optimist: 0.6.1 @@ -4418,7 +4791,7 @@ packages: optionalDependencies: uglify-js: 3.6.0 resolution: - integrity: sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + integrity: sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw== /har-schema/2.0.0: dev: false engines: @@ -4550,6 +4923,10 @@ packages: hasBin: true resolution: integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + /highlight.js/9.15.10: + dev: false + resolution: + integrity: sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw== /hmac-drbg/1.0.1: dependencies: hash.js: 1.1.7 @@ -4603,10 +4980,19 @@ packages: node: '>= 0.6' resolution: integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + /http-proxy-agent/2.1.0: + dependencies: + agent-base: 4.3.0 + debug: 3.1.0 + dev: false + engines: + node: '>= 4.5.0' + resolution: + integrity: sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== /http-proxy/1.17.0: dependencies: eventemitter3: 3.1.2 - follow-redirects: 1.8.1 + follow-redirects: 1.9.0 requires-port: 1.0.0 dev: false engines: @@ -4740,7 +5126,7 @@ packages: lodash: 4.17.15 mute-stream: 0.0.7 run-async: 2.3.0 - rxjs: 6.5.2 + rxjs: 6.5.3 string-width: 2.1.1 strip-ansi: 5.2.0 through: 2.3.8 @@ -4779,6 +5165,10 @@ packages: node: '>=4' resolution: integrity: sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + /ip/1.1.5: + dev: false + resolution: + integrity: sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= /ipaddr.js/1.9.0: dev: false engines: @@ -5188,7 +5578,7 @@ packages: integrity: sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== /istanbul-reports/2.2.6: dependencies: - handlebars: 4.1.2 + handlebars: 4.2.0 dev: false engines: node: '>=6' @@ -5201,7 +5591,7 @@ packages: escodegen: 1.8.1 esprima: 2.7.3 glob: 5.0.15 - handlebars: 4.1.2 + handlebars: 4.2.0 js-yaml: 3.13.1 mkdirp: 0.5.1 nopt: 3.0.6 @@ -5231,6 +5621,10 @@ packages: dev: false resolution: integrity: sha1-o6vicYryQaKykE+EpiWXDzia4yo= + /jquery/3.4.1: + dev: false + resolution: + integrity: sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== /js-tokens/3.0.2: dev: false resolution: @@ -5365,10 +5759,10 @@ packages: dev: false resolution: integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - /karma-chai/0.1.0_chai@4.2.0+karma@4.3.0: + /karma-chai/0.1.0_chai@4.2.0+karma@4.2.0: dependencies: chai: 4.2.0 - karma: 4.3.0 + karma: 4.2.0 dev: false peerDependencies: chai: '*' @@ -5381,16 +5775,43 @@ packages: dev: false resolution: integrity: sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== - /karma-coverage/1.1.2: + /karma-cli/2.0.0: + dependencies: + resolve: 1.12.0 + dev: false + engines: + node: '>= 6' + hasBin: true + resolution: + integrity: sha512-1Kb28UILg1ZsfqQmeELbPzuEb5C6GZJfVIk0qOr8LNYQuYWmAaqP16WpbpKEjhejDrDYyYOwwJXSZO6u7q5Pvw== + /karma-coverage/2.0.1: dependencies: dateformat: 1.0.12 istanbul: 0.4.5 + istanbul-lib-coverage: 2.0.5 + istanbul-lib-instrument: 3.3.0 + istanbul-lib-report: 2.0.8 + istanbul-lib-source-maps: 3.0.6 + istanbul-reports: 2.2.6 lodash: 4.17.15 minimatch: 3.0.4 source-map: 0.5.7 dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-SnFkHsnLsaXfxkey51rRN9JDLAEKYW2Lb0qOEvcruukk0NkSNDkjobNDZPt9Ni3kIhLZkLtpGOz661hN7OaZvQ== + /karma-edge-launcher/0.4.2_karma@4.2.0: + dependencies: + edge-launcher: 1.2.2 + karma: 4.2.0 + dev: false + engines: + node: '>=4' + peerDependencies: + karma: '>=0.9' resolution: - integrity: sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw== + integrity: sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw== /karma-edge-launcher/0.4.2_karma@4.3.0: dependencies: edge-launcher: 1.2.2 @@ -5412,6 +5833,15 @@ packages: dev: false resolution: integrity: sha512-j9Zp8M8+VLq1nI/5xZGfzeaEPtGQ/vk3G+Y8vpmFWLvKLNZ2TDjD6cu2dUu7lDbu1HXNgatsAX4jgCZTkR9qhQ== + /karma-ie-launcher/1.0.0_karma@4.2.0: + dependencies: + karma: 4.2.0 + lodash: 4.17.15 + dev: false + peerDependencies: + karma: '>=0.9' + resolution: + integrity: sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw= /karma-ie-launcher/1.0.0_karma@4.3.0: dependencies: karma: 4.3.0 @@ -5421,9 +5851,9 @@ packages: karma: '>=0.9' resolution: integrity: sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw= - /karma-json-preprocessor/0.3.3_karma@4.3.0: + /karma-json-preprocessor/0.3.3_karma@4.2.0: dependencies: - karma: 4.3.0 + karma: 4.2.0 dev: false peerDependencies: karma: '>=0.9' @@ -5435,6 +5865,16 @@ packages: dev: false resolution: integrity: sha512-kNCi+0UrXAeTJMpMsHkHNbfmlErsYT+/haNakJIhsE/gtj3Jx7zWRg7BTc1HHSbH5KeVXVRJr3/KLB/NHWY7Hg== + /karma-junit-reporter/1.2.0_karma@4.2.0: + dependencies: + karma: 4.2.0 + path-is-absolute: 1.0.1 + xmlbuilder: 8.2.2 + dev: false + peerDependencies: + karma: '>=0.9' + resolution: + integrity: sha1-T5xAzt+xo5X4rvh2q/lhiZF8Y5Y= /karma-junit-reporter/1.2.0_karma@4.3.0: dependencies: karma: 4.3.0 @@ -5445,6 +5885,17 @@ packages: karma: '>=0.9' resolution: integrity: sha1-T5xAzt+xo5X4rvh2q/lhiZF8Y5Y= + /karma-mocha-reporter/2.2.5_karma@4.2.0: + dependencies: + chalk: 2.4.2 + karma: 4.2.0 + log-symbols: 2.2.0 + strip-ansi: 4.0.0 + dev: false + peerDependencies: + karma: '>=0.13' + resolution: + integrity: sha1-FRIAlejtgZGG5HoLAS8810GJVWA= /karma-mocha-reporter/2.2.5_karma@4.3.0: dependencies: chalk: 2.4.2 @@ -5462,9 +5913,9 @@ packages: dev: false resolution: integrity: sha1-7qrH/8DiAetjxGdEDStpx883eL8= - /karma-remap-coverage/0.1.5_karma-coverage@1.1.2: + /karma-remap-coverage/0.1.5_karma-coverage@2.0.1: dependencies: - karma-coverage: 1.1.2 + karma-coverage: 2.0.1 remap-istanbul: 0.10.1 dev: false engines: @@ -5473,11 +5924,21 @@ packages: karma-coverage: '>=0.5.4' resolution: integrity: sha512-FM5h8eHcHbMMR+2INBUxD+4+wUbkCnobfn5uWprkLyj6Xcm2MRFQOuAJn9h2H13nNso6rk+QoNpHd5xCevlPOw== - /karma-rollup-preprocessor/7.0.2_rollup@1.20.3: + /karma-requirejs/1.1.0_karma@4.2.0+requirejs@2.3.6: + dependencies: + karma: 4.2.0 + requirejs: 2.3.6 + dev: false + peerDependencies: + karma: '>=0.9' + requirejs: ^2.1.0 + resolution: + integrity: sha1-/driy4fX68FvsCIok1ZNf+5Xh5g= + /karma-rollup-preprocessor/7.0.2_rollup@1.20.1: dependencies: chokidar: 3.0.2 debounce: 1.2.0 - rollup: 1.20.3 + rollup: 1.20.1 dev: false engines: node: '>= 8.0.0' @@ -5502,15 +5963,15 @@ packages: dev: false resolution: integrity: sha512-WTGGThwufBT73c20q30iTcXq8Jb3Wat/h+JW1lwKgMtymT5rVxLknoaUVNfenaV3+cRMiTEsBT773kz9jWk6IQ== - /karma-webpack/4.0.2_webpack@4.39.3: + /karma-webpack/4.0.2_webpack@4.39.2: dependencies: clone-deep: 4.0.1 loader-utils: 1.2.3 neo-async: 2.6.1 schema-utils: 1.0.0 source-map: 0.7.3 - webpack: 4.39.3_webpack@4.39.3 - webpack-dev-middleware: 3.7.0_webpack@4.39.3 + webpack: 4.39.2_webpack@4.39.2 + webpack-dev-middleware: 3.7.0_webpack@4.39.2 dev: false engines: node: '>= 8.9.0' @@ -5518,6 +5979,41 @@ packages: webpack: ^4.0.0 resolution: integrity: sha512-970/okAsdUOmiMOCY8sb17A2I8neS25Ad9uhyK3GHgmRSIFJbDcNEFE8dqqUhNe9OHiCC9k3DMrSmtd/0ymP1A== + /karma/4.2.0: + dependencies: + bluebird: 3.5.5 + body-parser: 1.19.0 + braces: 3.0.2 + chokidar: 3.0.2 + colors: 1.3.3 + connect: 3.7.0 + core-js: 3.2.1 + di: 0.0.1 + dom-serialize: 2.2.1 + flatted: 2.0.1 + glob: 7.1.4 + graceful-fs: 4.2.2 + http-proxy: 1.17.0 + isbinaryfile: 3.0.3 + lodash: 4.17.15 + log4js: 4.5.1 + mime: 2.4.4 + minimatch: 3.0.4 + optimist: 0.6.1 + qjobs: 1.2.0 + range-parser: 1.2.1 + rimraf: 2.7.1 + safe-buffer: 5.2.0 + socket.io: 2.1.1 + source-map: 0.6.1 + tmp: 0.0.33 + useragent: 2.3.0 + dev: false + engines: + node: '>= 8' + hasBin: true + resolution: + integrity: sha512-fmCuxN1rwJxTdZfOXK5LjlmS4Ana/OvzNMpkyLL/TLE8hmgSkpVpMYQ7RTVa8TNKRVQDZNl5W1oF5cfKfgIMlA== /karma/4.3.0: dependencies: bluebird: 3.5.5 @@ -5819,6 +6315,16 @@ packages: dev: false resolution: integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + /lunr/2.3.6: + dev: false + resolution: + integrity: sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q== + /macos-release/2.3.0: + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== /magic-string/0.22.5: dependencies: vlq: 0.2.3 @@ -5890,6 +6396,13 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + /marked/0.7.0: + dev: false + engines: + node: '>=0.10.0' + hasBin: true + resolution: + integrity: sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== /marky/1.2.1: dev: false resolution: @@ -6362,6 +6875,12 @@ packages: dev: false resolution: integrity: sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== + /netmask/1.0.6: + dev: false + engines: + node: '>= 0.4.0' + resolution: + integrity: sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= /next-tick/1.0.0: dev: false resolution: @@ -6370,7 +6889,7 @@ packages: dev: false resolution: integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - /nise/1.5.2: + /nise/1.5.1: dependencies: '@sinonjs/formatio': 3.2.1 '@sinonjs/text-encoding': 0.7.1 @@ -6379,23 +6898,24 @@ packages: path-to-regexp: 1.7.0 dev: false resolution: - integrity: sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA== - /nock/10.0.6: + integrity: sha512-edFWm0fsFG2n318rfEnKlTZTkjlbVOFF9XIA+fj+Ed+Qz1laYW2lobwavWoMzGrYDHH1EpiNJgDfvGnkZztR/g== + /nock/11.3.2: dependencies: chai: 4.2.0 debug: 4.1.1 - deep-equal: 1.1.0 json-stringify-safe: 5.0.1 lodash: 4.17.15 mkdirp: 0.5.1 - propagate: 1.0.0 - qs: 6.8.0 - semver: 5.7.1 + propagate: 2.0.1 dev: false engines: - node: '>= 6.0' + node: '>= 8.0' resolution: - integrity: sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w== + integrity: sha512-Bb00vTmuXyucMT9gcnMSiE2n6P5yrRoAyej0eF6ik6VUxG0FKp4RcSx1TzFusEDtY3hMNpsd7ZYUSIvwtNpTrw== + /node-abort-controller/1.0.3: + dev: false + resolution: + integrity: sha512-w07Dwqd/SWv9Lqrlhlx3mo4i4EWsuN3majbIIj4d6twBWGZUKtB9zvT9W+D5Rko56uas55CLO0YZ4zMrf6AKMw== /node-environment-flags/1.0.5: dependencies: object.getownpropertydescriptors: 2.0.3 @@ -6528,7 +7048,7 @@ packages: resolve-from: 4.0.0 rimraf: 2.7.1 signal-exit: 3.0.2 - spawn-wrap: 1.4.3 + spawn-wrap: 1.4.2 test-exclude: 5.2.3 uuid: 3.3.3 yargs: 13.3.0 @@ -6563,12 +7083,6 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - /object-is/1.0.1: - dev: false - engines: - node: '>= 0.4' - resolution: - integrity: sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= /object-keys/1.1.1: dev: false engines: @@ -6735,6 +7249,15 @@ packages: node: '>=6' resolution: integrity: sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + /os-name/3.1.0: + dependencies: + macos-release: 2.3.0 + windows-release: 3.2.0 + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== /os-tmpdir/1.0.2: dev: false engines: @@ -6803,6 +7326,29 @@ packages: node: '>=6' resolution: integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + /pac-proxy-agent/3.0.0: + dependencies: + agent-base: 4.3.0 + debug: 3.2.6 + get-uri: 2.0.3 + http-proxy-agent: 2.1.0 + https-proxy-agent: 2.2.2 + pac-resolver: 3.0.0 + raw-body: 2.4.1 + socks-proxy-agent: 4.0.2 + dev: false + resolution: + integrity: sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q== + /pac-resolver/3.0.0: + dependencies: + co: 4.6.0 + degenerator: 1.0.4 + ip: 1.1.5 + netmask: 1.0.6 + thunkify: 2.1.2 + dev: false + resolution: + integrity: sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== /package-hash/3.0.0: dependencies: graceful-fs: 4.2.2 @@ -7121,6 +7667,10 @@ packages: node: '>= 0.8' resolution: integrity: sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + /priorityqueuejs/1.0.0: + dev: false + resolution: + integrity: sha1-LuTyPCVgkT4IwHzlzN1t498sWvg= /private/0.1.8: dev: false engines: @@ -7161,12 +7711,12 @@ packages: dev: false resolution: integrity: sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw== - /propagate/1.0.0: + /propagate/2.0.1: dev: false engines: - '0': node >= 0.8.1 + node: '>= 8' resolution: - integrity: sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk= + integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== /proxy-addr/2.0.5: dependencies: forwarded: 0.1.2 @@ -7176,6 +7726,21 @@ packages: node: '>= 0.10' resolution: integrity: sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== + /proxy-agent/3.0.3: + dependencies: + agent-base: 4.3.0 + debug: 3.2.6 + http-proxy-agent: 2.1.0 + https-proxy-agent: 2.2.2 + lru-cache: 4.1.5 + pac-proxy-agent: 3.0.0 + proxy-from-env: 1.0.0 + socks-proxy-agent: 4.0.2 + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-PXVVVuH9tiQuxQltFJVSnXWuDtNr+8aNBP6XVDDCDiUuDN8eRCm+ii4/mFWmXWEA0w8jjJSlePa4LXlM4jIzNA== /proxy-from-env/1.0.0: dev: false resolution: @@ -7345,6 +7910,17 @@ packages: node: '>= 0.8' resolution: integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + /raw-body/2.4.1: + dependencies: + bytes: 3.1.0 + http-errors: 1.7.3 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== /read-pkg-up/1.0.1: dependencies: find-up: 1.1.2 @@ -7392,6 +7968,15 @@ packages: node: '>=4' resolution: integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + /readable-stream/1.1.14: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: false + resolution: + integrity: sha1-fPTFTvZI44EwhMY23SB54WbAgdk= /readable-stream/2.0.6: dependencies: core-util-is: 1.0.2 @@ -7502,14 +8087,6 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - /regexp.prototype.flags/1.2.0: - dependencies: - define-properties: 1.1.3 - dev: false - engines: - node: '>= 0.4' - resolution: - integrity: sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== /regexpp/2.0.1: dev: false engines: @@ -7659,6 +8236,13 @@ packages: dev: false resolution: integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + /requirejs/2.3.6: + dev: false + engines: + node: '>=0.4.0' + hasBin: true + resolution: + integrity: sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== /requires-port/1.0.0: dev: false resolution: @@ -7775,6 +8359,13 @@ packages: hasBin: true resolution: integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + /rimraf/3.0.0: + dependencies: + glob: 7.1.4 + dev: false + hasBin: true + resolution: + integrity: sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg== /ripemd160/2.0.2: dependencies: hash-base: 3.0.4 @@ -7788,6 +8379,19 @@ packages: dev: false resolution: integrity: sha512-ODeZXhTxpD48sfcYLAFc1BGrsXKDj7o1CSNH3uYbdK3o0NxyMmaQPTNgW+ko+am92DLC8QSTe4kyxTuEkI5S5w== + /rollup-plugin-commonjs/10.0.2_rollup@1.20.1: + dependencies: + estree-walker: 0.6.1 + is-reference: 1.1.3 + magic-string: 0.25.3 + resolve: 1.12.0 + rollup: 1.20.1 + rollup-pluginutils: 2.8.1 + dev: false + peerDependencies: + rollup: '>=1.12.0' + resolution: + integrity: sha512-DxeR4QXTgTOFseYls1V7vgKbrSJmPYNdEMOs0OvH+7+89C3GiIonU9gFrE0u39Vv1KWm3wepq8KAvKugtoM2Zw== /rollup-plugin-commonjs/10.1.0_rollup@1.20.3: dependencies: estree-walker: 0.6.1 @@ -7815,6 +8419,10 @@ packages: dev: false resolution: integrity: sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow== + /rollup-plugin-local-resolve/1.0.7: + dev: false + resolution: + integrity: sha1-xIZwFxbBWt0hJ1ZcLqoQESMyCIc= /rollup-plugin-multi-entry/2.1.0: dependencies: matched: 1.0.2 @@ -7832,6 +8440,19 @@ packages: dev: false resolution: integrity: sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g== + /rollup-plugin-node-resolve/5.2.0_rollup@1.20.1: + dependencies: + '@types/resolve': 0.0.8 + builtin-modules: 3.1.0 + is-module: 1.0.0 + resolve: 1.12.0 + rollup: 1.20.1 + rollup-pluginutils: 2.8.1 + dev: false + peerDependencies: + rollup: '>=1.11.0' + resolution: + integrity: sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw== /rollup-plugin-node-resolve/5.2.0_rollup@1.20.3: dependencies: '@types/resolve': 0.0.8 @@ -7856,6 +8477,19 @@ packages: dev: false resolution: integrity: sha512-rZqFD43y4U9nSqVq3iyWBiDwmBQJY8Txi04yI9jTKD3xcl7CbFjh1qRpQshUB3sONLubDzm7vJiwB+1MEGv67w== + /rollup-plugin-sourcemaps/0.4.2_rollup@1.20.1: + dependencies: + rollup: 1.20.1 + rollup-pluginutils: 2.8.1 + source-map-resolve: 0.5.2 + dev: false + engines: + node: '>=4.5.0' + npm: '>=2.15.9' + peerDependencies: + rollup: '>=0.31.2' + resolution: + integrity: sha1-YhJaqUCHqt97g+9N+vYptHMTXoc= /rollup-plugin-sourcemaps/0.4.2_rollup@1.20.3: dependencies: rollup: 1.20.3 @@ -7869,6 +8503,19 @@ packages: rollup: '>=0.31.2' resolution: integrity: sha1-YhJaqUCHqt97g+9N+vYptHMTXoc= + /rollup-plugin-terser/5.1.1_rollup@1.20.1: + dependencies: + '@babel/code-frame': 7.5.5 + jest-worker: 24.9.0 + rollup: 1.20.1 + rollup-pluginutils: 2.8.1 + serialize-javascript: 1.8.0 + terser: 4.2.0 + dev: false + peerDependencies: + rollup: '>=0.66.0 <2' + resolution: + integrity: sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ== /rollup-plugin-terser/5.1.1_rollup@1.20.3: dependencies: '@babel/code-frame': 7.5.5 @@ -7876,17 +8523,17 @@ packages: rollup: 1.20.3 rollup-pluginutils: 2.8.1 serialize-javascript: 1.8.0 - terser: 4.2.1 + terser: 4.2.0 dev: false peerDependencies: rollup: '>=0.66.0 <2' resolution: integrity: sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ== - /rollup-plugin-uglify/6.0.2_rollup@1.20.3: + /rollup-plugin-uglify/6.0.2_rollup@1.20.1: dependencies: '@babel/code-frame': 7.5.5 jest-worker: 24.9.0 - rollup: 1.20.3 + rollup: 1.20.1 serialize-javascript: 1.8.0 uglify-js: 3.6.0 dev: false @@ -7894,6 +8541,20 @@ packages: rollup: '>=0.66.0 <2' resolution: integrity: sha512-qwz2Tryspn5QGtPUowq5oumKSxANKdrnfz7C0jm4lKxvRDsNe/hSGsB9FntUul7UeC4TsZEWKErVgE1qWSO0gw== + /rollup-plugin-visualizer/2.5.4_rollup@1.20.1: + dependencies: + mkdirp: 0.5.1 + open: 6.4.0 + pupa: 2.0.1 + rollup: 1.20.1 + source-map: 0.7.3 + dev: false + engines: + node: '>=8.10' + peerDependencies: + rollup: '>=0.60.0' + resolution: + integrity: sha512-ehMX8Us4UmHmt9y6uvBdtW3ASAQDqCcmp07Qrm8dBqQMf1eAd89Rc/owGZr0cDp764dvLKQRA03W+nWlRajl4w== /rollup-plugin-visualizer/2.5.4_rollup@1.20.3: dependencies: mkdirp: 0.5.1 @@ -7914,13 +8575,22 @@ packages: dev: false resolution: integrity: sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg== - /rollup/1.20.3: + /rollup/1.20.1: dependencies: '@types/estree': 0.0.39 '@types/node': 12.7.2 acorn: 7.0.0 dev: false hasBin: true + resolution: + integrity: sha512-8DV8eWLq84fbJFRqkjWg8BWX4NTTdHpx9bxjmTl/83z54o6Ygo1OgUDjJGFq/xe5i0kDspnbjzw2V+ZPXD/BrQ== + /rollup/1.20.3: + dependencies: + '@types/estree': 0.0.39 + '@types/node': 12.7.4 + acorn: 7.0.0 + dev: false + hasBin: true resolution: integrity: sha512-/OMCkY0c6E8tleeVm4vQVDz24CkVgvueK3r8zTYu2AQNpjrcaPwO9hE+pWj5LTFrvvkaxt4MYIp2zha4y0lRvg== /run-async/2.3.0: @@ -7937,14 +8607,14 @@ packages: dev: false resolution: integrity: sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - /rxjs/6.5.2: + /rxjs/6.5.3: dependencies: tslib: 1.10.0 dev: false engines: npm: '>=2.0.0' resolution: - integrity: sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + integrity: sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== /safe-buffer/5.1.2: dev: false resolution: @@ -7981,6 +8651,12 @@ packages: node: '>= 4' resolution: integrity: sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + /semaphore/1.0.5: + dev: false + engines: + node: '>=0.8.0' + resolution: + integrity: sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA= /semver-greatest-satisfied-range/1.1.0: dependencies: sver-compat: 1.5.0 @@ -8124,7 +8800,7 @@ packages: '@sinonjs/samsam': 3.3.3 diff: 3.5.0 lolex: 4.2.0 - nise: 1.5.2 + nise: 1.5.1 supports-color: 5.5.0 dev: false resolution: @@ -8151,8 +8827,15 @@ packages: node: '>=6' resolution: integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - /snapdragon-node/2.1.1: - dependencies: + /smart-buffer/4.0.2: + dev: false + engines: + node: '>= 4.0.0' + npm: '>= 3.0.0' + resolution: + integrity: sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw== + /snapdragon-node/2.1.1: + dependencies: define-property: 1.0.0 isobject: 3.0.1 snapdragon-util: 3.0.1 @@ -8226,6 +8909,25 @@ packages: dev: false resolution: integrity: sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + /socks-proxy-agent/4.0.2: + dependencies: + agent-base: 4.2.1 + socks: 2.3.2 + dev: false + engines: + node: '>= 6' + resolution: + integrity: sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== + /socks/2.3.2: + dependencies: + ip: 1.1.5 + smart-buffer: 4.0.2 + dev: false + engines: + node: '>= 6.0.0' + npm: '>= 3.0.0' + resolution: + integrity: sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== /source-list-map/2.0.1: dev: false resolution: @@ -8294,7 +8996,7 @@ packages: node: '>= 0.10' resolution: integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== - /spawn-wrap/1.4.3: + /spawn-wrap/1.4.2: dependencies: foreground-child: 1.5.6 mkdirp: 0.5.1 @@ -8304,7 +9006,7 @@ packages: which: 1.3.1 dev: false resolution: - integrity: sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw== + integrity: sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== /spdx-correct/3.1.0: dependencies: spdx-expression-parse: 3.0.0 @@ -8630,7 +9332,7 @@ packages: node: '>=6' resolution: integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - /terser-webpack-plugin/1.4.1_webpack@4.39.3: + /terser-webpack-plugin/1.4.1_webpack@4.39.2: dependencies: cacache: 12.0.3 find-cache-dir: 2.1.0 @@ -8638,8 +9340,8 @@ packages: schema-utils: 1.0.0 serialize-javascript: 1.8.0 source-map: 0.6.1 - terser: 4.2.1 - webpack: 4.39.3_webpack@4.39.3 + terser: 4.2.0 + webpack: 4.39.2_webpack@4.39.2 webpack-sources: 1.4.3 worker-farm: 1.7.0 dev: false @@ -8649,7 +9351,7 @@ packages: webpack: ^4.0.0 resolution: integrity: sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg== - /terser/4.2.1: + /terser/4.2.0: dependencies: commander: 2.20.0 source-map: 0.6.1 @@ -8659,7 +9361,7 @@ packages: node: '>=6.0.0' hasBin: true resolution: - integrity: sha512-cGbc5utAcX4a9+2GGVX4DsenG6v0x3glnDi5hx8816X1McEAwPlPgRtXPJzSBsbpILxZ8MQMT0KvArLuE0HP5A== + integrity: sha512-6lPt7lZdZ/13icQJp8XasFOwZjFJkxFFIb/N1fhYEQNoNI3Ilo3KABZ9OocZvZoB39r6SiIk/0+v/bt8nZoSeA== /test-exclude/5.2.3: dependencies: glob: 7.1.4 @@ -8706,6 +9408,10 @@ packages: dev: false resolution: integrity: sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + /thunkify/2.1.2: + dev: false + resolution: + integrity: sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= /time-stamp/1.1.0: dev: false engines: @@ -8859,14 +9565,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - /ts-loader/6.0.4_typescript@3.6.2: + /ts-loader/6.0.4_typescript@3.5.3: dependencies: chalk: 2.4.2 enhanced-resolve: 4.1.0 loader-utils: 1.2.3 micromatch: 4.0.2 semver: 6.3.0 - typescript: 3.6.2 + typescript: 3.5.3 dev: false engines: node: '>=8.6' @@ -8904,6 +9610,22 @@ packages: hasBin: true resolution: integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + /ts-node/8.3.0_typescript@3.5.3: + dependencies: + arg: 4.1.1 + diff: 4.0.1 + make-error: 1.3.5 + source-map-support: 0.5.13 + typescript: 3.5.3 + yn: 3.1.1 + dev: false + engines: + node: '>=4.2.0' + hasBin: true + peerDependencies: + typescript: '>=2.0' + resolution: + integrity: sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ== /ts-node/8.3.0_typescript@3.6.2: dependencies: arg: 4.1.1 @@ -8935,6 +9657,17 @@ packages: dev: false resolution: integrity: sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + /tsutils/3.17.1_typescript@3.5.3: + dependencies: + tslib: 1.10.0 + typescript: 3.5.3 + dev: false + engines: + node: '>= 6' + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + resolution: + integrity: sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== /tsutils/3.17.1_typescript@3.6.2: dependencies: tslib: 1.10.0 @@ -8997,6 +9730,36 @@ packages: dev: false resolution: integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + /typedoc-default-themes/0.6.0: + dependencies: + backbone: 1.4.0 + jquery: 3.4.1 + lunr: 2.3.6 + underscore: 1.9.1 + dev: false + engines: + node: '>= 8' + resolution: + integrity: sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw== + /typedoc/0.15.0: + dependencies: + '@types/minimatch': 3.0.3 + fs-extra: 8.1.0 + handlebars: 4.2.0 + highlight.js: 9.15.10 + lodash: 4.17.15 + marked: 0.7.0 + minimatch: 3.0.4 + progress: 2.0.3 + shelljs: 0.8.3 + typedoc-default-themes: 0.6.0 + typescript: 3.5.3 + dev: false + engines: + node: '>= 6.0.0' + hasBin: true + resolution: + integrity: sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw== /typescript/3.5.3: dev: false engines: @@ -9091,6 +9854,12 @@ packages: dev: false resolution: integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + /universal-user-agent/2.1.0: + dependencies: + os-name: 3.1.0 + dev: false + resolution: + integrity: sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q== /universalify/0.1.2: dev: false engines: @@ -9319,7 +10088,7 @@ packages: dev: false resolution: integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - /webpack-cli/3.3.7_webpack@4.39.3: + /webpack-cli/3.3.7_webpack@4.39.2: dependencies: chalk: 2.4.2 cross-spawn: 6.0.5 @@ -9331,7 +10100,7 @@ packages: loader-utils: 1.2.3 supports-color: 6.1.0 v8-compile-cache: 2.0.3 - webpack: 4.39.3_webpack@4.39.3 + webpack: 4.39.2_webpack@4.39.2 yargs: 13.2.4 dev: false engines: @@ -9341,12 +10110,12 @@ packages: webpack: 4.x.x resolution: integrity: sha512-OhTUCttAsr+IZSMVwGROGRHvT+QAs8H6/mHIl4SvhAwYywjiylYjpwybGx7WQ9Hkb45FhjtsymkwiRRbGJ1SZQ== - /webpack-dev-middleware/3.7.0_webpack@4.39.3: + /webpack-dev-middleware/3.7.0_webpack@4.39.2: dependencies: memory-fs: 0.4.1 mime: 2.4.4 range-parser: 1.2.1 - webpack: 4.39.3_webpack@4.39.3 + webpack: 4.39.2_webpack@4.39.2 webpack-log: 2.0.0 dev: false engines: @@ -9371,7 +10140,7 @@ packages: dev: false resolution: integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - /webpack/4.39.3_webpack@4.39.3: + /webpack/4.39.2_webpack@4.39.2: dependencies: '@webassemblyjs/ast': 1.8.5 '@webassemblyjs/helper-module-context': 1.8.5 @@ -9393,7 +10162,7 @@ packages: node-libs-browser: 2.2.1 schema-utils: 1.0.0 tapable: 1.1.3 - terser-webpack-plugin: 1.4.1_webpack@4.39.3 + terser-webpack-plugin: 1.4.1_webpack@4.39.2 watchpack: 1.6.0 webpack-sources: 1.4.3 dev: false @@ -9403,7 +10172,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ== + integrity: sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA== /whatwg-url/6.5.0: dependencies: lodash.sortby: 4.7.0 @@ -9433,6 +10202,14 @@ packages: dev: false resolution: integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + /windows-release/3.2.0: + dependencies: + execa: 1.0.0 + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== /wordwrap/0.0.3: dev: false engines: @@ -9532,12 +10309,6 @@ packages: dev: false resolution: integrity: sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - /xmlbuilder/0.4.3: - dev: false - engines: - node: '>=0.2.0' - resolution: - integrity: sha1-xGFLp04K0ZbmCcknLNnh3bKKilg= /xmlbuilder/8.2.2: dev: false engines: @@ -9568,6 +10339,10 @@ packages: node: '>=0.4.0' resolution: integrity: sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ== + /xregexp/2.0.0: + dev: false + resolution: + integrity: sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= /xtend/4.0.2: dev: false engines: @@ -9697,6 +10472,22 @@ packages: dev: false resolution: integrity: sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== + /yargs/14.0.0: + dependencies: + cliui: 5.0.0 + decamelize: 1.2.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.0 + y18n: 4.0.0 + yargs-parser: 13.1.1 + dev: false + resolution: + integrity: sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow== /yargs/7.1.0: dependencies: camelcase: 3.0.0 @@ -9766,80 +10557,111 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 delay: 4.3.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 nyc: 14.1.1 prettier: 1.18.2 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + ts-node: 8.3.0_typescript@3.5.3 + tslib: 1.10.0 + typescript: 3.5.3 + dev: false + name: '@rush-temp/abort-controller' + resolution: + integrity: sha512-YwhAi/dV8QU4uVvddHEEchoJUG07D7QbKuQVf5jyvD5oklm8BnoIR5ONWo24G1jQnlIEaFrsFjYbboAt1Xl3bQ== + tarball: 'file:projects/abort-controller.tgz' + version: 0.0.0 + 'file:projects/app-configuration.tgz': + dependencies: + '@microsoft/api-extractor': 7.3.11 + '@types/dotenv': 6.1.1 + '@types/mocha': 5.2.7 + assert: 1.5.0 + dotenv: 8.1.0 + eslint: 6.3.0 + eslint-config-prettier: 6.2.0_eslint@6.3.0 + eslint-plugin-no-null: 1.0.2_eslint@6.3.0 + eslint-plugin-no-only-tests: 2.3.1 + eslint-plugin-promise: 4.2.1 + mocha: 6.2.0 + mocha-junit-reporter: 1.23.1_mocha@6.2.0 + mocha-multi: 1.1.3_mocha@6.2.0 + nyc: 14.1.1 + prettier: 1.18.2 + rimraf: 3.0.0 + rollup: 1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 typescript: 3.6.2 + uglify-js: 3.6.0 dev: false - name: '@rush-temp/abort-controller' + name: '@rush-temp/app-configuration' resolution: - integrity: sha512-W9CsoX+0a+9AAHje89SaMJSq4zFtlcVwA8KRQR6nf+e0aSBjmIiU4NAZUfRwvXE11vWhjo+YUcV2+ISBt/UvWQ== - tarball: 'file:projects/abort-controller.tgz' + integrity: sha512-/4I0pK3Mg83wRvPClyGYJ2tLtOdfrVgxy++7YG2grjKzDiu9zHyd5rsI2PNAwHKh3uffFwO7cMnnXJPX7HtoTA== + tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': dependencies: '@types/async-lock': 1.1.1 '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 - '@types/debug': 0.0.31 + '@types/debug': 4.1.5 '@types/dotenv': 6.1.1 '@types/is-buffer': 2.0.0 '@types/jssha': 2.0.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/sinon': 7.0.13 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 async-lock: 1.2.2 - buffer: 5.4.2 + buffer: 5.4.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 cross-env: 5.2.0 - debug: 3.2.6 + debug: 4.1.1 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 is-buffer: 2.0.3 jssha: 2.3.1 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 karma-mocha: 1.3.0 mocha: 6.2.0 @@ -9851,30 +10673,30 @@ packages: puppeteer: 1.19.0 rhea: 1.0.8 rhea-promise: 1.0.0 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 rollup-plugin-node-globals: 1.4.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 sinon: 7.4.1 stream-browserify: 2.0.2 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 url: 0.11.0 util: 0.12.1 ws: 7.1.2 dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-jJ88adCOOKofY9LnfVCihOXMnB467Q3PLZuj4GmJpM51DyFx0KdCic1n3TqTj7SQ9sj1rKtVWyVAVAaOJRwTTA== + integrity: sha512-Ea/iTbFAKk7cE3Eq8geKJ4Q/XYoIyoVgQSuPHsqPSFtVIgcZnGifdEJxE6tEcXIm1vcH6zrGTiNFRLgtnK//gA== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -9882,12 +10704,12 @@ packages: '@types/chai': 4.2.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 chai: 4.2.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 mocha: 6.2.0 @@ -9895,39 +10717,39 @@ packages: mocha-multi: 1.1.3_mocha@6.2.0 npm-run-all: 4.1.5 nyc: 14.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 shx: 0.3.2 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uglify-js: 3.6.0 yarn: 1.17.3 dev: false name: '@rush-temp/core-arm' resolution: - integrity: sha512-GVZI9FYYYQ4Jt0BkIi0OJ5vhcKGeoUhaUA8mw3XXNBvERXJqBZSpiWiJ03lXbnEgWvcz4Yn2EvgiWT0JSj2gkw== + integrity: sha512-YLO+Lu8+QdbGXNectrQzC9OCK5HlWogISjARKZSp+sU5/qxtkPpogIJUOctgReTgx3yK4bh/wNBegLsYeXVxvg== tarball: 'file:projects/core-arm.tgz' version: 0.0.0 'file:projects/core-asynciterator-polyfill.tgz': dependencies: '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 prettier: 1.18.2 - typescript: 3.6.2 + typescript: 3.5.3 dev: false name: '@rush-temp/core-asynciterator-polyfill' resolution: - integrity: sha512-hp2FjyoaLo9iJIGV0Aq7UI8oGzIr29OewVSFfuckKI+2aDUrh6Kamlg/hw/HrZ/a3ybccP3oqGjwA2uze4DoAg== + integrity: sha512-X2qR67x/Wgwcs8VjH/m3EA7HFB22mL2sf9YJCvpdIUXvz5ENGH54U4TC8IAc2AxcqlKjOi1pwFUAf9yBf4nAJQ== tarball: 'file:projects/core-asynciterator-polyfill.tgz' version: 0.0.0 'file:projects/core-auth.tgz': @@ -9935,13 +10757,13 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 inherits: 2.0.4 @@ -9949,23 +10771,23 @@ packages: mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/core-auth' resolution: - integrity: sha512-oVJYTPPuUZ3iD4kJtFBd0lRmS1aca8qhLXqlV3TtVIIw/MHZ+kQiFiy/bJTwjSpxOWzL4b4l8yeg2dAXjyuROg== + integrity: sha512-JoX/IlUf7c0++3R8YQsxpckD+FS0Qhiiixg9YrgCoQmTkMv9lUsi3LprMidIRbLY4Hos4HeOTshMZRL4PZz5Gg== tarball: 'file:projects/core-auth.tgz' version: 0.0.0 'file:projects/core-http.tgz': @@ -9984,31 +10806,30 @@ packages: '@types/tough-cookie': 2.3.5 '@types/tunnel': 0.0.1 '@types/uuid': 3.4.5 - '@types/webpack': 4.39.1 + '@types/webpack': 4.39.0 '@types/webpack-dev-middleware': 2.0.3 '@types/xml2js': 0.4.4 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 babel-runtime: 6.26.0 - buffer: 5.4.2 chai: 4.2.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 express: 4.17.1 fetch-mock: 7.3.9 form-data: 2.5.0 glob: 7.1.4 - karma: 4.3.0 - karma-chai: 0.1.0_chai@4.2.0+karma@4.3.0 + karma: 4.2.0 + karma-chai: 0.1.0_chai@4.2.0+karma@4.2.0 karma-chrome-launcher: 3.1.0 karma-mocha: 1.3.0 - karma-rollup-preprocessor: 7.0.2_rollup@1.20.3 + karma-rollup-preprocessor: 7.0.2_rollup@1.20.1 karma-sourcemap-loader: 0.3.7 karma-typescript-es6-transform: 4.1.1 - karma-webpack: 4.0.2_webpack@4.39.3 + karma-webpack: 4.0.2_webpack@4.39.2 mocha: 6.2.0 mocha-chrome: 2.0.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -10019,57 +10840,56 @@ packages: process: 0.11.10 puppeteer: 1.19.0 regenerator-runtime: 0.13.3 - rimraf: 2.7.1 - rollup: 1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 rollup-plugin-alias: 1.5.2 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 semver: 5.7.1 shx: 0.3.2 sinon: 7.4.1 - terser: 4.2.1 + terser: 4.2.0 tough-cookie: 3.0.1 - ts-loader: 6.0.4_typescript@3.6.2 - ts-node: 8.3.0_typescript@3.6.2 + ts-loader: 6.0.4_typescript@3.5.3 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 tunnel: 0.0.6 - typescript: 3.6.2 + typescript: 3.5.3 uglify-js: 3.6.0 uuid: 3.3.3 - webpack: 4.39.3_webpack@4.39.3 - webpack-cli: 3.3.7_webpack@4.39.3 - webpack-dev-middleware: 3.7.0_webpack@4.39.3 + webpack: 4.39.2_webpack@4.39.2 + webpack-cli: 3.3.7_webpack@4.39.2 + webpack-dev-middleware: 3.7.0_webpack@4.39.2 xhr-mock: 2.5.0 xml2js: 0.4.19 - xmlbuilder: 0.4.3 yarn: 1.17.3 dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-Dfkft2Q6+Vr7JtMQLUj/2cQXdbBiH8v7SExaEdbe+lz58f+lVgtThUV4lYpRXK162aTy7JlwT077zS1C0tJ1SA== + integrity: sha512-1pAdeKNcMVa/GMFCQPAjoB+PPY3IplADRCydkBe6poOJG3zEc774lLgK93hzIfHOitmoPCJHbXyqvBrS+vk70Q== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': dependencies: '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 prettier: 1.18.2 - typescript: 3.6.2 + typescript: 3.5.3 dev: false name: '@rush-temp/core-paging' resolution: - integrity: sha512-rorSx6Oeq/VsKWv3L8qwnHYihYjPZS/PiCZZrIlGt7WfSH8iS60XFPxRrAiP+zIhosvd1hDlSmQ8k30iIB10QA== + integrity: sha512-/l5SA2u/jUrYjvQBf24YFdaoYW4GAdU3iDoGDekLbjH2fSP8wOt/3oDlBM8pxGD54TB7s06Oi4OjBsQN6F5tgw== tarball: 'file:projects/core-paging.tgz' version: 0.0.0 'file:projects/core-tracing.tgz': @@ -10077,13 +10897,13 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 inherits: 2.0.4 @@ -10091,25 +10911,98 @@ packages: mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/core-tracing' resolution: - integrity: sha512-CRGjX9TjXCkXJMbYqwOpJxxMCDPq3ZUqJML0wdJD/1dUX84mu9aD0iMi6QjPxMPiuYmlvbqJ+aLaNXcZPoNY3A== + integrity: sha512-78rkxAffDWO3NFQY96u6b+9tqe/jsn1oB6qcAQs0V+7cgzcTSfpZyO/giuyZlD7KCeVJfMXQAAEj8XdZ27Hl6A== tarball: 'file:projects/core-tracing.tgz' version: 0.0.0 + 'file:projects/cosmos.tgz_webpack@4.39.2': + dependencies: + '@azure/cosmos-sign': 1.0.2 + '@microsoft/api-extractor': 7.3.8 + '@types/debug': 4.1.5 + '@types/fast-json-stable-stringify': 2.0.0 + '@types/mocha': 5.2.7 + '@types/node': 8.10.52 + '@types/node-fetch': 2.5.0 + '@types/priorityqueuejs': 1.0.1 + '@types/semaphore': 1.1.0 + '@types/sinon': 7.0.13 + '@types/tunnel': 0.0.1 + '@types/underscore': 1.9.2 + '@types/uuid': 3.4.5 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + abort-controller: 3.0.0 + atob: 2.1.2 + binary-search-bounds: 2.0.3 + cross-env: 5.2.0 + crypto-hash: 1.1.0 + debug: 4.1.1 + dotenv: 8.1.0 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 + eslint-plugin-no-only-tests: 2.3.1 + eslint-plugin-promise: 4.2.1 + esm: 3.2.18 + execa: 1.0.0 + fast-json-stable-stringify: 2.0.0 + karma: 4.2.0 + karma-chrome-launcher: 3.1.0 + karma-cli: 2.0.0 + karma-firefox-launcher: 1.2.0 + karma-mocha: 1.3.0 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-requirejs: 1.1.0_karma@4.2.0+requirejs@2.3.6 + karma-sourcemap-loader: 0.3.7 + karma-webpack: 4.0.2_webpack@4.39.2 + mocha: 6.2.0 + mocha-junit-reporter: 1.23.1_mocha@6.2.0 + mocha-multi: 1.1.3_mocha@6.2.0 + node-abort-controller: 1.0.3 + node-fetch: 2.6.0 + prettier: 1.18.2 + priorityqueuejs: 1.0.0 + proxy-agent: 3.0.3 + requirejs: 2.3.6 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-json: 4.0.0 + rollup-plugin-local-resolve: 1.0.7 + rollup-plugin-multi-entry: 2.1.0 + semaphore: 1.0.5 + sinon: 7.4.1 + source-map-support: 0.5.13 + ts-node: 8.3.0_typescript@3.5.3 + tslib: 1.10.0 + typedoc: 0.15.0 + typescript: 3.5.3 + universal-user-agent: 2.1.0 + uuid: 3.3.3 + dev: false + id: 'file:projects/cosmos.tgz' + name: '@rush-temp/cosmos' + peerDependencies: + webpack: '*' + resolution: + integrity: sha512-xV8UTlWFCDc+LwkakTOYk4k9WiacCGSBQU/f0sRUT53nlHJuanH6Rm0/8nAHMR8ft9xIqmaE3fhT2GsDnMasjg== + tarball: 'file:projects/cosmos.tgz' + version: 0.0.0 'file:projects/event-hubs.tgz': dependencies: '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 @@ -10118,43 +11011,43 @@ packages: '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 '@types/chai-string': 1.4.2 - '@types/debug': 0.0.31 + '@types/debug': 4.1.5 '@types/dotenv': 6.1.1 '@types/long': 4.0.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/uuid': 3.4.5 '@types/ws': 6.0.3 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 async-lock: 1.2.2 - buffer: 5.4.2 + buffer: 5.4.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 cross-env: 5.2.0 - debug: 3.2.6 + debug: 4.1.1 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 is-buffer: 2.0.3 jssha: 2.3.1 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 @@ -10163,27 +11056,27 @@ packages: process: 0.11.10 puppeteer: 1.19.0 rhea-promise: 1.0.0 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 ts-mocha: 6.0.0_mocha@6.2.0 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uuid: 3.3.3 ws: 7.1.2 dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-TMdz6KTaNgEH8tAeEntd48I6dIV5yZbYrDxgW0cLV4eR+agvLKFa3XPx6H8iiwF/Jyn/eMKu56iLP/nwnxUVFw== + integrity: sha512-bPjNkHnC5Sq/ecnjbGhLTyQR9D/eoBsZvZUIevDEeUj9HYGmFGgA9kAOykDMkgo4anLKYt/m8sqnt9lQmX9/sw== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -10195,25 +11088,25 @@ packages: '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 '@types/chai-string': 1.4.2 - '@types/debug': 0.0.31 + '@types/debug': 4.1.5 '@types/dotenv': 6.1.1 '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/uuid': 3.4.5 '@types/ws': 6.0.3 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 async-lock: 1.2.2 azure-storage: 2.10.3 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 cross-env: 5.2.0 - debug: 3.2.6 + debug: 4.1.1 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 @@ -10223,7 +11116,70 @@ packages: nyc: 14.1.1 path-browserify: 1.0.0 prettier: 1.18.2 - rimraf: 2.7.1 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 + rollup-plugin-json: 4.0.0 + rollup-plugin-multi-entry: 2.1.0 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 + rollup-plugin-replace: 2.2.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-uglify: 6.0.2_rollup@1.20.1 + ts-node: 8.3.0_typescript@3.5.3 + tslib: 1.10.0 + typescript: 3.5.3 + uuid: 3.3.3 + ws: 7.1.2 + dev: false + name: '@rush-temp/event-processor-host' + resolution: + integrity: sha512-p3sNIrFFM3fCUUYcXbrj4RLVMuh84XX8jipT7xc9Nyd+4pVouE11Xewed7jDfUjHm9CeVCBFqReHpd2OgcnTAw== + tarball: 'file:projects/event-processor-host.tgz' + version: 0.0.0 + 'file:projects/eventhubs-checkpointstore-blob.tgz': + dependencies: + '@azure/storage-blob': 12.0.0-preview.2 + '@microsoft/api-extractor': 7.3.11 + '@types/chai': 4.2.1 + '@types/chai-as-promised': 7.1.2 + '@types/chai-string': 1.4.2 + '@types/debug': 4.1.5 + '@types/dotenv': 6.1.1 + '@types/mocha': 5.2.7 + '@types/node': 8.10.53 + '@typescript-eslint/eslint-plugin': 2.1.0_3a8cea979a77aa77c321dad4153067ce + '@typescript-eslint/parser': 2.1.0_eslint@6.3.0 + assert: 1.5.0 + chai: 4.2.0 + chai-as-promised: 7.1.1_chai@4.2.0 + chai-string: 1.5.0_chai@4.2.0 + cross-env: 5.2.1 + debug: 4.1.1 + dotenv: 8.1.0 + eslint: 6.3.0 + eslint-config-prettier: 6.2.0_eslint@6.3.0 + eslint-plugin-no-null: 1.0.2_eslint@6.3.0 + eslint-plugin-no-only-tests: 2.3.1 + eslint-plugin-promise: 4.2.1 + events: 3.0.0 + guid-typescript: 1.0.9 + inherits: 2.0.4 + karma: 4.3.0 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.2.0 + karma-ie-launcher: 1.0.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-mocha: 1.3.0 + karma-mocha-reporter: 2.2.5_karma@4.3.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 + mocha: 6.2.0 + mocha-junit-reporter: 1.23.1_mocha@6.2.0 + mocha-multi: 1.1.3_mocha@6.2.0 + prettier: 1.18.2 + rimraf: 3.0.0 rollup: 1.20.3 rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 rollup-plugin-json: 4.0.0 @@ -10231,17 +11187,17 @@ packages: rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 rollup-plugin-replace: 2.2.0 rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-uglify: 6.0.2_rollup@1.20.3 + rollup-plugin-terser: 5.1.1_rollup@1.20.3 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 ts-node: 8.3.0_typescript@3.6.2 tslib: 1.10.0 typescript: 3.6.2 - uuid: 3.3.3 - ws: 7.1.2 + util: 0.12.1 dev: false - name: '@rush-temp/event-processor-host' + name: '@rush-temp/eventhubs-checkpointstore-blob' resolution: - integrity: sha512-c/puCLm/oWyCMxHOUHQ3ZszUEyoBpeoPBnpMiLYhdqGIl1cXBYxOzXJaN3MN4EgzztvbG/kUtOZt2h+tAoP7NA== - tarball: 'file:projects/event-processor-host.tgz' + integrity: sha512-a4DFIZqUpqFKGFIc0UTtxEf0hp54o26uT6JivOP/Qr/uk+Nyml2OkllwnlciRdk8fhrBZFw/JRnUKgE6pM844A== + tarball: 'file:projects/eventhubs-checkpointstore-blob.tgz' version: 0.0.0 'file:projects/identity.tgz': dependencies: @@ -10250,24 +11206,24 @@ packages: '@types/node': 8.10.52 '@types/qs': 6.5.3 '@types/uuid': 3.4.5 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.2 + eslint: 6.2.1 events: 3.0.0 inherits: 2.0.4 jws: 3.2.2 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 + karma-coverage: 2.0.1 karma-env-preprocessor: 0.1.1 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 @@ -10275,24 +11231,24 @@ packages: prettier: 1.18.2 puppeteer: 1.19.0 qs: 6.8.0 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 uuid: 3.3.3 dev: false name: '@rush-temp/identity' resolution: - integrity: sha512-aVvXmz3WeYJqmGGqVVfQOL30VQi09y/31viVZ6CfXy0MzUtrSmCwX9sfKDR3RnbvjtULGivZvJp7OY5Pwv2EPw== + integrity: sha512-yITMvnD9EnzaWxVx7KrQhQ7BftiFe8/i3ykh/ZUi5V8TBOcIhMEYwd3vFoahVqO1TJdo7TCv5KW9+WpKRAByYA== tarball: 'file:projects/identity.tgz' version: 0.0.0 'file:projects/keyvault-certificates.tgz': @@ -10308,59 +11264,59 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uglify-js: 3.6.0 url: 0.11.0 dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-8YOlO6QG3YkvNcFPbJL8nbroNLJpDcxGdBXukPxgNcw74wWIEGACMb77FRZbsviTl4Fm882+yJTVl6q4xNZHww== + integrity: sha512-XPhWKxld+/jgf/0b1E5QGdwL6R0/S54jls2f5jBRrtjsyNgDMgy1PzVAhpTqXTMhCYGV/VV45ughTk39Jh0IDw== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -10377,59 +11333,59 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uglify-js: 3.6.0 url: 0.11.0 dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-DjVpS2TWUSIbp4acVsnz9mklUM/foZjjrVIs1Vo86HzF28igiFanj74BoWmiVzfubanC9+KwdEjQQ8U9CsWIXA== + integrity: sha512-lHBEyOi83aAJ6tN7B0sAHclfgqR2MhKY6S6PpPHmq9A+IhjbO7ZN6Dk9MZBbEhdjPOlOZDrrpkkmD8uKf1/2NQ== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -10444,59 +11400,59 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 chai: 4.2.0 cross-env: 5.2.0 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uglify-js: 3.6.0 url: 0.11.0 dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-Sml9gYtRdzXKZ/tiXOrFJebP7VayBC8dZmiCGWeypwyeME7KfNUu7RS1/SoVL3FICnoG9DGBOhuW4Hitmzx8yA== + integrity: sha512-AYH0OHeU4yfHkhUDgmIb+08v8G8Bdt/rw4RotP+0XXycSmrEdvef1qmDOtbNtgEO/GV1RvwO6rgRf3sDnxuGtg== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/service-bus.tgz': @@ -10508,41 +11464,41 @@ packages: '@types/async-lock': 1.1.1 '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 - '@types/debug': 0.0.31 + '@types/debug': 4.1.5 '@types/dotenv': 6.1.1 '@types/is-buffer': 2.0.0 '@types/long': 4.0.0 '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@types/ws': 6.0.3 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 - buffer: 5.4.2 + buffer: 5.4.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 cross-env: 5.2.0 - debug: 3.2.6 + debug: 4.1.1 delay: 4.3.0 dotenv: 8.1.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 https-proxy-agent: 2.2.2 is-buffer: 2.0.3 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 long: 4.0.0 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 @@ -10555,25 +11511,25 @@ packages: puppeteer: 1.19.0 rhea: 1.0.8 rhea-promise: 0.1.15 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-inject: 3.0.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - ts-node: 8.3.0_typescript@3.6.2 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 ws: 7.1.2 dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-T1C1Z51gQB4jheztKHYtaVy343I9ljyH70RintWH0IQN6pseu93pIU4jiBMaAYQH1HFZK7SLIEInKFN8YkVdEg== + integrity: sha512-0l9q26d5/j34d4j6GxcDMOqwi95aPH9NqqivTuTVkdeNYsCxR+N1AGfknQdbtx2Eu81HJ3OsATdM590LqTTF6g== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -10587,15 +11543,15 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 @@ -10603,47 +11559,47 @@ packages: gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/storage-blob' resolution: - integrity: sha512-kn2byrHTxQIDWXEwQS14S523e/NgrUkWWdtk/EyQb11NWHZJGzqWOR7soCXQgZfmWIGgjKfPFM/Xwrqf3vECMA== + integrity: sha512-6JJFDGUj5AY8R/wStkv05OdRkLSE05ZPbX03uIJefY4QTxdtaqyCi5s+2lrxbuxE9UGduVSnlB3qh0tgdH2Jhw== tarball: 'file:projects/storage-blob.tgz' version: 0.0.0 'file:projects/storage-file.tgz': @@ -10657,15 +11613,15 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 @@ -10673,47 +11629,47 @@ packages: gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/storage-file' resolution: - integrity: sha512-oj8bSAecZKtBXtPot5VqiCMqKQx5sQIjbNgGg1IyGwsdfgeTJKgMYOJpPK8MSMqvYK9EZudw3jkeFOIA378j1w== + integrity: sha512-Ss14Pm4zCFh4fqOHc2QzsbpTFHkuqkZo+qVXASJvsE7sqzuqFg+W09M2D+uT23k45l44d+x5G5D1dyg1OWmjwA== tarball: 'file:projects/storage-file.tgz' version: 0.0.0 'file:projects/storage-queue.tgz': @@ -10727,62 +11683,62 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.52 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 dotenv: 8.1.0 es6-promise: 4.2.8 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 fs-extra: 8.1.0 gulp: 4.0.2 gulp-zip: 5.0.0_gulp@4.0.2 inherits: 2.0.4 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-json-preprocessor: 0.3.3_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-json-preprocessor: 0.3.3_karma@4.2.0 karma-json-to-file-reporter: 1.0.1 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 - nise: 1.5.2 - nock: 10.0.6 + nise: 1.5.1 + nock: 11.3.2 nyc: 14.1.1 prettier: 1.18.2 puppeteer: 1.19.0 query-string: 5.1.1 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 source-map-support: 0.5.13 - ts-node: 8.3.0_typescript@3.6.2 + ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/storage-queue' resolution: - integrity: sha512-73zOl+s2xrm/5cQo1kRzdupjV451qFHM1SMEHnZMNG5uX8NlLPFy3A5qPcj5dGcrBwdA33JdZKYhMkLCLk48fQ== + integrity: sha512-xOXI5NLw/G1ylX0iLrbEsmmANf7/8l1yoKhZ9rcpcFVHj5Jnz0bXEU9RNHK12mAGYRanQ/AJK1HBOJoeNQk9CA== tarball: 'file:projects/storage-queue.tgz' version: 0.0.0 'file:projects/template.tgz': @@ -10790,51 +11746,79 @@ packages: '@microsoft/api-extractor': 7.3.8 '@types/mocha': 5.2.7 '@types/node': 8.10.52 - '@typescript-eslint/eslint-plugin': 2.0.0_725fda8723c9f372c79013d5541f9bc5 - '@typescript-eslint/parser': 2.0.0_eslint@6.2.2 + '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 assert: 1.5.0 cross-env: 5.2.0 - eslint: 6.2.2 - eslint-config-prettier: 6.1.0_eslint@6.2.2 - eslint-plugin-no-null: 1.0.2_eslint@6.2.2 + eslint: 6.2.1 + eslint-config-prettier: 6.1.0_eslint@6.2.1 + eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 events: 3.0.0 inherits: 2.0.4 - karma: 4.3.0 + karma: 4.2.0 karma-chrome-launcher: 3.1.0 - karma-coverage: 1.1.2 - karma-edge-launcher: 0.4.2_karma@4.3.0 + karma-coverage: 2.0.1 + karma-edge-launcher: 0.4.2_karma@4.2.0 karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.2.0 - karma-ie-launcher: 1.0.0_karma@4.3.0 - karma-junit-reporter: 1.2.0_karma@4.3.0 + karma-ie-launcher: 1.0.0_karma@4.2.0 + karma-junit-reporter: 1.2.0_karma@4.2.0 karma-mocha: 1.3.0 - karma-mocha-reporter: 2.2.5_karma@4.3.0 - karma-remap-coverage: 0.1.5_karma-coverage@1.1.2 + karma-mocha-reporter: 2.2.5_karma@4.2.0 + karma-remap-coverage: 0.1.5_karma-coverage@2.0.1 mocha: 6.2.0 mocha-junit-reporter: 1.23.1_mocha@6.2.0 mocha-multi: 1.1.3_mocha@6.2.0 prettier: 1.18.2 - rimraf: 2.7.1 - rollup: 1.20.3 - rollup-plugin-commonjs: 10.1.0_rollup@1.20.3 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 rollup-plugin-json: 4.0.0 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.20.3 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 rollup-plugin-replace: 2.2.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.3 - rollup-plugin-terser: 5.1.1_rollup@1.20.3 - rollup-plugin-visualizer: 2.5.4_rollup@1.20.3 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 util: 0.12.1 dev: false name: '@rush-temp/template' resolution: - integrity: sha512-gMekh0FZCuSys6TamLN8h1nt7hJ/ah6Ryu7nR26ETWqXzxQnsnZrq27JRWgA2x5QFv5XBXXZJayhpUId9K+8bA== + integrity: sha512-Mr5kH/fT37U2+FhWBOOteBh5HPN07yLkRD2MlYGQ1Y3z6sVRO9H9ruwnSeZXg5xxWvUNsQW77YVOqbgFRzavLQ== tarball: 'file:projects/template.tgz' version: 0.0.0 + 'file:projects/test-utils-recorder.tgz': + dependencies: + '@types/fs-extra': 8.0.0 + '@types/mocha': 5.2.7 + '@types/nise': 1.4.0 + '@types/nock': 10.0.3 + '@types/query-string': 6.2.0 + fs-extra: 8.1.0 + nise: 1.5.1 + nock: 11.3.2 + query-string: 5.1.1 + rimraf: 3.0.0 + rollup: 1.20.1 + rollup-plugin-commonjs: 10.0.2_rollup@1.20.1 + rollup-plugin-multi-entry: 2.1.0 + rollup-plugin-node-resolve: 5.2.0_rollup@1.20.1 + rollup-plugin-replace: 2.2.0 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.20.1 + rollup-plugin-terser: 5.1.1_rollup@1.20.1 + rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 + tslib: 1.10.0 + dev: false + name: '@rush-temp/test-utils-recorder' + resolution: + integrity: sha512-5X0CLSRbJrplwH5JFkcDlSfzxzFeT/veoYhb9NB+q2hTDd9rXRjwePn76IWcVBtUzq2siSgvgrSsioDYiXMUsw== + tarball: 'file:projects/test-utils-recorder.tgz' + version: 0.0.0 'file:projects/testhub.tgz': dependencies: '@azure/event-hubs': 2.1.1 @@ -10843,31 +11827,33 @@ packages: '@types/yargs': 13.0.2 async-lock: 1.2.2 death: 1.1.0 - debug: 3.2.6 + debug: 4.1.1 rhea: 1.0.8 - rimraf: 2.7.1 + rimraf: 3.0.0 tslib: 1.10.0 - typescript: 3.6.2 + typescript: 3.5.3 uuid: 3.3.3 - yargs: 13.3.0 + yargs: 14.0.0 dev: false name: '@rush-temp/testhub' resolution: - integrity: sha512-5P+X3IwgFa9rlq+jbtHxWVZWF1kDmRZwV8jQfHMYV5CLsJjXKw1yISIRSFmCmuXDdHYEnxO1bnRGi34QeZ+63g== + integrity: sha512-RkYcAmpRKuAXwbssMJGmc8uzm3LoQikdGvIqdwioQqURgLagimtd01yH+757XDMvMyOfVwejTTSCZHpqa2Bf6Q== tarball: 'file:projects/testhub.tgz' version: 0.0.0 +registry: '' specifiers: '@azure/amqp-common': 1.0.0-preview.6 '@azure/arm-servicebus': ^3.2.0 '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 - '@azure/core-paging': 1.0.0-preview.1 - '@azure/core-tracing': 1.0.0-preview.1 + '@azure/cosmos-sign': 1.0.2 '@azure/event-hubs': ^2.1.1 '@azure/logger-js': ^1.0.2 '@azure/ms-rest-js': ^2.0.0 '@azure/ms-rest-nodeauth': ^0.9.2 + '@azure/storage-blob': 12.0.0-preview.2 '@microsoft/api-extractor': ^7.1.5 '@rush-temp/abort-controller': 'file:./projects/abort-controller.tgz' + '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' '@rush-temp/core-amqp': 'file:./projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:./projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:./projects/core-asynciterator-polyfill.tgz' @@ -10875,8 +11861,10 @@ specifiers: '@rush-temp/core-http': 'file:./projects/core-http.tgz' '@rush-temp/core-paging': 'file:./projects/core-paging.tgz' '@rush-temp/core-tracing': 'file:./projects/core-tracing.tgz' + '@rush-temp/cosmos': 'file:./projects/cosmos.tgz' '@rush-temp/event-hubs': 'file:./projects/event-hubs.tgz' '@rush-temp/event-processor-host': 'file:./projects/event-processor-host.tgz' + '@rush-temp/eventhubs-checkpointstore-blob': 'file:./projects/eventhubs-checkpointstore-blob.tgz' '@rush-temp/identity': 'file:./projects/identity.tgz' '@rush-temp/keyvault-certificates': 'file:./projects/keyvault-certificates.tgz' '@rush-temp/keyvault-keys': 'file:./projects/keyvault-keys.tgz' @@ -10886,15 +11874,17 @@ specifiers: '@rush-temp/storage-file': 'file:./projects/storage-file.tgz' '@rush-temp/storage-queue': 'file:./projects/storage-queue.tgz' '@rush-temp/template': 'file:./projects/template.tgz' + '@rush-temp/test-utils-recorder': 'file:./projects/test-utils-recorder.tgz' '@rush-temp/testhub': 'file:./projects/testhub.tgz' '@trust/keyto': 0.3.7 '@types/async-lock': ^1.1.0 '@types/chai': ^4.1.6 '@types/chai-as-promised': ^7.1.0 '@types/chai-string': ^1.4.1 - '@types/debug': ^0.0.31 + '@types/debug': ^4.1.4 '@types/dotenv': ^6.1.0 '@types/express': ^4.16.0 + '@types/fast-json-stable-stringify': 2.0.0 '@types/fetch-mock': ^7.3.1 '@types/fs-extra': ^8.0.0 '@types/glob': ^7.1.1 @@ -10908,12 +11898,14 @@ specifiers: '@types/nock': ^10.0.1 '@types/node': ^8.0.0 '@types/node-fetch': ^2.5.0 + '@types/priorityqueuejs': ^1.0.1 '@types/qs': ^6.5.3 '@types/query-string': 6.2.0 - '@types/semver': ^5.5.0 + '@types/semaphore': ^1.1.0 '@types/sinon': ^7.0.13 '@types/tough-cookie': ^2.3.5 '@types/tunnel': ^0.0.1 + '@types/underscore': ^1.8.8 '@types/uuid': ^3.4.3 '@types/webpack': ^4.4.13 '@types/webpack-dev-middleware': ^2.0.2 @@ -10922,17 +11914,21 @@ specifiers: '@types/yargs': ^13.0.0 '@typescript-eslint/eslint-plugin': ^2.0.0 '@typescript-eslint/parser': ^2.0.0 + abort-controller: 3.0.0 assert: ^1.4.1 async-lock: ^1.1.3 + atob: 2.1.2 azure-storage: ^2.10.2 babel-runtime: ^6.26.0 + binary-search-bounds: 2.0.3 buffer: ^5.2.1 chai: ^4.2.0 chai-as-promised: ^7.1.1 chai-string: ^1.5.0 cross-env: ^5.2.0 + crypto-hash: 1.1.0 death: ^1.1.0 - debug: ^3.1.0 + debug: ^4.1.1 delay: ^4.2.0 dotenv: ^8.0.0 es6-promise: ^4.2.5 @@ -10941,12 +11937,16 @@ specifiers: eslint-plugin-no-null: ^1.0.2 eslint-plugin-no-only-tests: ^2.3.0 eslint-plugin-promise: ^4.1.1 + esm: 3.2.18 events: ^3.0.0 + execa: 1.0.0 express: ^4.16.3 + fast-json-stable-stringify: 2.0.0 fetch-mock: ^7.3.9 form-data: ^2.5.0 fs-extra: ^8.1.0 glob: ^7.1.2 + guid-typescript: 1.0.9 gulp: ^4.0.0 gulp-zip: ^5.0.0 https-proxy-agent: ^2.2.1 @@ -10957,7 +11957,8 @@ specifiers: karma: ^4.0.1 karma-chai: ^0.1.0 karma-chrome-launcher: ^3.0.0 - karma-coverage: ^1.1.2 + karma-cli: ^2.0.0 + karma-coverage: ^2.0.0 karma-edge-launcher: ^0.4.2 karma-env-preprocessor: ^0.1.1 karma-firefox-launcher: ^1.1.0 @@ -10968,6 +11969,7 @@ specifiers: karma-mocha: ^1.3.0 karma-mocha-reporter: ^2.2.5 karma-remap-coverage: ^0.1.5 + karma-requirejs: ^1.1.0 karma-rollup-preprocessor: ^7.0.0 karma-sourcemap-loader: ^0.3.7 karma-typescript-es6-transform: ^4.0.0 @@ -10980,26 +11982,30 @@ specifiers: moment: ^2.24.0 msal: ^1.0.2 nise: ^1.4.10 - nock: ^10.0.6 + nock: ^11.3.2 + node-abort-controller: 1.0.3 node-fetch: ^2.6.0 npm-run-all: ^4.1.5 nyc: ^14.0.0 path-browserify: ^1.0.0 prettier: ^1.16.4 + priorityqueuejs: 1.0.0 process: ^0.11.10 promise: ^8.0.3 + proxy-agent: 3.0.3 puppeteer: ^1.11.0 qs: ^6.7.0 query-string: ^5.0.0 regenerator-runtime: ^0.13.3 + requirejs: ^2.3.5 rhea: ^1.0.4 rhea-promise: ^0.1.15 - rimraf: ^2.6.2 + rimraf: ^3.0.0 rollup: ^1.16.3 - rollup-plugin-alias: ^1.4.0 rollup-plugin-commonjs: ^10.0.0 rollup-plugin-inject: ^3.0.0 rollup-plugin-json: ^4.0.0 + rollup-plugin-local-resolve: ^1.0.7 rollup-plugin-multi-entry: ^2.1.0 rollup-plugin-node-globals: ^1.4.0 rollup-plugin-node-resolve: ^5.0.2 @@ -11009,7 +12015,7 @@ specifiers: rollup-plugin-terser: ^5.1.1 rollup-plugin-uglify: ^6.0.0 rollup-plugin-visualizer: ^2.0.0 - semver: ^5.5.0 + semaphore: 1.0.5 shx: ^0.3.2 sinon: ^7.1.0 source-map-support: ^0.5.9 @@ -11021,8 +12027,10 @@ specifiers: ts-node: ^8.3.0 tslib: ^1.9.3 tunnel: ^0.0.6 + typedoc: ^0.15.0 typescript: ^3.2.2 uglify-js: ^3.4.9 + universal-user-agent: 2.1.0 url: ^0.11.0 util: ^0.12.1 uuid: ^3.3.2 @@ -11032,6 +12040,5 @@ specifiers: ws: ^7.1.1 xhr-mock: ^2.4.1 xml2js: ^0.4.19 - xmlbuilder: ^0.4.3 - yargs: ^13.0.0 - yarn: ^1.6.0 + yargs: ^14.0.0 + yarn: ^1.6.0 \ No newline at end of file From 2b2d9d0849fe3a23e504f4eda07a28e176e25322 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 9 Sep 2019 15:22:55 -0700 Subject: [PATCH 23/72] Generate pnpm file using 'rush update' --- common/config/rush/pnpm-lock.yaml | 60 ++++++++++++++++++------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index b66ff4873ef3..8b72c14d3b87 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -197,6 +197,7 @@ dependencies: ws: 7.1.2 xhr-mock: 2.5.0 xml2js: 0.4.19 + xmlbuilder: 0.4.3 yargs: 14.0.0 yarn: 1.17.3 lockfileVersion: 5.1 @@ -10309,6 +10310,12 @@ packages: dev: false resolution: integrity: sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + /xmlbuilder/0.4.3: + dev: false + engines: + node: '>=0.2.0' + resolution: + integrity: sha1-xGFLp04K0ZbmCcknLNnh3bKKilg= /xmlbuilder/8.2.2: dev: false engines: @@ -10597,7 +10604,7 @@ packages: dev: false name: '@rush-temp/abort-controller' resolution: - integrity: sha512-YwhAi/dV8QU4uVvddHEEchoJUG07D7QbKuQVf5jyvD5oklm8BnoIR5ONWo24G1jQnlIEaFrsFjYbboAt1Xl3bQ== + integrity: sha512-vDcC9ZxFHAZ1GK8i63eC7rnBVBbGN6JKPNgMETz4CGHji31lXhMdMMx0sjZNiDN1HMv9lojK3KtW+mhsZmEfZQ== tarball: 'file:projects/abort-controller.tgz' version: 0.0.0 'file:projects/app-configuration.tgz': @@ -10628,7 +10635,7 @@ packages: dev: false name: '@rush-temp/app-configuration' resolution: - integrity: sha512-/4I0pK3Mg83wRvPClyGYJ2tLtOdfrVgxy++7YG2grjKzDiu9zHyd5rsI2PNAwHKh3uffFwO7cMnnXJPX7HtoTA== + integrity: sha512-AsrRtW+zZhSvmerSwQd+BZLgQxuvS/a9QFiRjycytLD6nOKIqDfpBLjaPT2TbLmJ6geQ7hGpTZVPEAetB/wTew== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': @@ -10696,7 +10703,7 @@ packages: dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-Ea/iTbFAKk7cE3Eq8geKJ4Q/XYoIyoVgQSuPHsqPSFtVIgcZnGifdEJxE6tEcXIm1vcH6zrGTiNFRLgtnK//gA== + integrity: sha512-1h8l3bCuZc0m0JmT28x5fMb9T6EtZgU7TpPQ1aPWSozxPqj/S1OabRCkenkMGufmSy3Eup5rWBCkM6Ly2bNyiw== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -10731,7 +10738,7 @@ packages: dev: false name: '@rush-temp/core-arm' resolution: - integrity: sha512-YLO+Lu8+QdbGXNectrQzC9OCK5HlWogISjARKZSp+sU5/qxtkPpogIJUOctgReTgx3yK4bh/wNBegLsYeXVxvg== + integrity: sha512-CUyFXyNU8RXwK7x40YPYiqbXLI++JBNuUBKUvLtGOaoe53QhyCr8ehLXWdgPmoz689vNApf0JLcyxFVlthNzbA== tarball: 'file:projects/core-arm.tgz' version: 0.0.0 'file:projects/core-asynciterator-polyfill.tgz': @@ -10749,7 +10756,7 @@ packages: dev: false name: '@rush-temp/core-asynciterator-polyfill' resolution: - integrity: sha512-X2qR67x/Wgwcs8VjH/m3EA7HFB22mL2sf9YJCvpdIUXvz5ENGH54U4TC8IAc2AxcqlKjOi1pwFUAf9yBf4nAJQ== + integrity: sha512-hp2FjyoaLo9iJIGV0Aq7UI8oGzIr29OewVSFfuckKI+2aDUrh6Kamlg/hw/HrZ/a3ybccP3oqGjwA2uze4DoAg== tarball: 'file:projects/core-asynciterator-polyfill.tgz' version: 0.0.0 'file:projects/core-auth.tgz': @@ -10787,7 +10794,7 @@ packages: dev: false name: '@rush-temp/core-auth' resolution: - integrity: sha512-JoX/IlUf7c0++3R8YQsxpckD+FS0Qhiiixg9YrgCoQmTkMv9lUsi3LprMidIRbLY4Hos4HeOTshMZRL4PZz5Gg== + integrity: sha512-nswzAoZmQ+VTKYH15KXBCLYfFh1fy7Aox0AzSvCcRLCW7ERC1cT6nksMUFwKcuXNQ5X/1T18hlsPLq/IORg0lw== tarball: 'file:projects/core-auth.tgz' version: 0.0.0 'file:projects/core-http.tgz': @@ -10812,6 +10819,7 @@ packages: '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 babel-runtime: 6.26.0 + buffer: 5.4.0 chai: 4.2.0 eslint: 6.2.1 eslint-config-prettier: 6.1.0_eslint@6.2.1 @@ -10866,11 +10874,12 @@ packages: webpack-dev-middleware: 3.7.0_webpack@4.39.2 xhr-mock: 2.5.0 xml2js: 0.4.19 + xmlbuilder: 0.4.3 yarn: 1.17.3 dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-1pAdeKNcMVa/GMFCQPAjoB+PPY3IplADRCydkBe6poOJG3zEc774lLgK93hzIfHOitmoPCJHbXyqvBrS+vk70Q== + integrity: sha512-paeJIjRutERJ29tuVLp4m7Bivom28/JbIWqrXPf1kdytdox270TnC6j1CAwG/GxhBri+e1PYCRn3YCX4EivXdA== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': @@ -10889,7 +10898,7 @@ packages: dev: false name: '@rush-temp/core-paging' resolution: - integrity: sha512-/l5SA2u/jUrYjvQBf24YFdaoYW4GAdU3iDoGDekLbjH2fSP8wOt/3oDlBM8pxGD54TB7s06Oi4OjBsQN6F5tgw== + integrity: sha512-rorSx6Oeq/VsKWv3L8qwnHYihYjPZS/PiCZZrIlGt7WfSH8iS60XFPxRrAiP+zIhosvd1hDlSmQ8k30iIB10QA== tarball: 'file:projects/core-paging.tgz' version: 0.0.0 'file:projects/core-tracing.tgz': @@ -10927,7 +10936,7 @@ packages: dev: false name: '@rush-temp/core-tracing' resolution: - integrity: sha512-78rkxAffDWO3NFQY96u6b+9tqe/jsn1oB6qcAQs0V+7cgzcTSfpZyO/giuyZlD7KCeVJfMXQAAEj8XdZ27Hl6A== + integrity: sha512-uc1Cbuqt6Du7IUnDJlVDqJ7QT2jD2VGTKIoM+I6wJdi+zGM5WZJkN6SG8JULMLCNhQbUdbWu+poakWgRCL/1HA== tarball: 'file:projects/core-tracing.tgz' version: 0.0.0 'file:projects/cosmos.tgz_webpack@4.39.2': @@ -11000,7 +11009,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-xV8UTlWFCDc+LwkakTOYk4k9WiacCGSBQU/f0sRUT53nlHJuanH6Rm0/8nAHMR8ft9xIqmaE3fhT2GsDnMasjg== + integrity: sha512-1EcBFBLV9RPghS3tRfctehM8wXq4kGxl9ww0O6c+PqDwulLNJxnRGGd9mfOCm5/1LT6bEEQB7im+Fqxp+XcJOw== tarball: 'file:projects/cosmos.tgz' version: 0.0.0 'file:projects/event-hubs.tgz': @@ -11076,7 +11085,7 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-bPjNkHnC5Sq/ecnjbGhLTyQR9D/eoBsZvZUIevDEeUj9HYGmFGgA9kAOykDMkgo4anLKYt/m8sqnt9lQmX9/sw== + integrity: sha512-dSWFaHnJUtZJSbLgV7ilycvSBV/SaYksr3eY+rVS6JVs0SfbcaKCkiBnYrhBzfbkU+bsVRPSoQMat5X8vU9Qyw== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -11133,7 +11142,7 @@ packages: dev: false name: '@rush-temp/event-processor-host' resolution: - integrity: sha512-p3sNIrFFM3fCUUYcXbrj4RLVMuh84XX8jipT7xc9Nyd+4pVouE11Xewed7jDfUjHm9CeVCBFqReHpd2OgcnTAw== + integrity: sha512-6vtDVnWkivQ+k24fNOjeYlpHei8qaqVfhfE3f1ouAVBX6xW+pThwd+i19o5wwa3UDj5y7wvBPXYwtnSqk7i9xw== tarball: 'file:projects/event-processor-host.tgz' version: 0.0.0 'file:projects/eventhubs-checkpointstore-blob.tgz': @@ -11196,7 +11205,7 @@ packages: dev: false name: '@rush-temp/eventhubs-checkpointstore-blob' resolution: - integrity: sha512-a4DFIZqUpqFKGFIc0UTtxEf0hp54o26uT6JivOP/Qr/uk+Nyml2OkllwnlciRdk8fhrBZFw/JRnUKgE6pM844A== + integrity: sha512-Dut7dpUK/OvTBW/rHqAkX8xY+AZKgkS94U6NNfKjrwOQzmTQ0TEmIxtRer6ee5ig2aZY2lPb+3OxLnUydRu/Bw== tarball: 'file:projects/eventhubs-checkpointstore-blob.tgz' version: 0.0.0 'file:projects/identity.tgz': @@ -11248,7 +11257,7 @@ packages: dev: false name: '@rush-temp/identity' resolution: - integrity: sha512-yITMvnD9EnzaWxVx7KrQhQ7BftiFe8/i3ykh/ZUi5V8TBOcIhMEYwd3vFoahVqO1TJdo7TCv5KW9+WpKRAByYA== + integrity: sha512-bVFvN9S6o3c3YHXwiTDfwRhXIIYxh3i5qvYhPOJlLVTsmHgsmmQjx0hiF3cE4JayFN91MHtMDJw3pu5BmkovNw== tarball: 'file:projects/identity.tgz' version: 0.0.0 'file:projects/keyvault-certificates.tgz': @@ -11316,7 +11325,7 @@ packages: dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-XPhWKxld+/jgf/0b1E5QGdwL6R0/S54jls2f5jBRrtjsyNgDMgy1PzVAhpTqXTMhCYGV/VV45ughTk39Jh0IDw== + integrity: sha512-avax/uC8PPEm+kWOCmP06q0GvKDMnkTcANMIzYL/Ric+WjWF0kL9d1h5znhDGMRSK3r3jH+Udl0xf95EE9AQ0w== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -11385,7 +11394,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-lHBEyOi83aAJ6tN7B0sAHclfgqR2MhKY6S6PpPHmq9A+IhjbO7ZN6Dk9MZBbEhdjPOlOZDrrpkkmD8uKf1/2NQ== + integrity: sha512-rlialD+RKXVu8yAG96jyTXm4yxVHJC3pOeBbqgorhU7uV+1SI0v3nIpS42lgY8BD+i128NGVrvVx5xuH/N6wVg== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -11452,7 +11461,7 @@ packages: dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-AYH0OHeU4yfHkhUDgmIb+08v8G8Bdt/rw4RotP+0XXycSmrEdvef1qmDOtbNtgEO/GV1RvwO6rgRf3sDnxuGtg== + integrity: sha512-jW8cvugQoElGaP1cCJedFVyf2cIQss/IHFuQLz9viGplBh19otACdCbhppaNmDr+Lc92B3Nr9ikMcryU2I2SdQ== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/service-bus.tgz': @@ -11529,7 +11538,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-0l9q26d5/j34d4j6GxcDMOqwi95aPH9NqqivTuTVkdeNYsCxR+N1AGfknQdbtx2Eu81HJ3OsATdM590LqTTF6g== + integrity: sha512-OJxyb0jtxDQ9KQ4DyrkW1tDPWN+xSQnsXcEFfRQpkkH+1gCClWwVrfsyqtJ1P0/G135HDZJJ2qdjoey6pNJhDw== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -11599,7 +11608,7 @@ packages: dev: false name: '@rush-temp/storage-blob' resolution: - integrity: sha512-6JJFDGUj5AY8R/wStkv05OdRkLSE05ZPbX03uIJefY4QTxdtaqyCi5s+2lrxbuxE9UGduVSnlB3qh0tgdH2Jhw== + integrity: sha512-76kxW4mT5QbNSGd1oOkcZxqa2ZoZYn5E8LSoui/rWtH3tX1i0lCT/FJhSgcnOQXYMM56Gdno8AqEI5CT9dFRmg== tarball: 'file:projects/storage-blob.tgz' version: 0.0.0 'file:projects/storage-file.tgz': @@ -11669,7 +11678,7 @@ packages: dev: false name: '@rush-temp/storage-file' resolution: - integrity: sha512-Ss14Pm4zCFh4fqOHc2QzsbpTFHkuqkZo+qVXASJvsE7sqzuqFg+W09M2D+uT23k45l44d+x5G5D1dyg1OWmjwA== + integrity: sha512-1vuu96rlT8OLbWybGYkV7wXK2iRYEAg9JBdTFS2VbcYWztw2/L5gXM/HrRrnDN891SpDW1KsHNng0oj880UL/Q== tarball: 'file:projects/storage-file.tgz' version: 0.0.0 'file:projects/storage-queue.tgz': @@ -11738,7 +11747,7 @@ packages: dev: false name: '@rush-temp/storage-queue' resolution: - integrity: sha512-xOXI5NLw/G1ylX0iLrbEsmmANf7/8l1yoKhZ9rcpcFVHj5Jnz0bXEU9RNHK12mAGYRanQ/AJK1HBOJoeNQk9CA== + integrity: sha512-Sva5UkbRrEXShOKLaZ4ALhk/2RdGETd4oKVAmgRmeo1CACidcSPDvHQC/MJhEgdmM/47YJLMOyKkP/mVSgZqjw== tarball: 'file:projects/storage-queue.tgz' version: 0.0.0 'file:projects/template.tgz': @@ -11788,7 +11797,7 @@ packages: dev: false name: '@rush-temp/template' resolution: - integrity: sha512-Mr5kH/fT37U2+FhWBOOteBh5HPN07yLkRD2MlYGQ1Y3z6sVRO9H9ruwnSeZXg5xxWvUNsQW77YVOqbgFRzavLQ== + integrity: sha512-kVQvLrvxsA1WMbSQpOpcTQTIN0HwJKD9PvpY7ZONaZIKwgWTuUM2u0euzQMU4qYBkfvqrAiPSviNf99s2pFjQQ== tarball: 'file:projects/template.tgz' version: 0.0.0 'file:projects/test-utils-recorder.tgz': @@ -11816,7 +11825,7 @@ packages: dev: false name: '@rush-temp/test-utils-recorder' resolution: - integrity: sha512-5X0CLSRbJrplwH5JFkcDlSfzxzFeT/veoYhb9NB+q2hTDd9rXRjwePn76IWcVBtUzq2siSgvgrSsioDYiXMUsw== + integrity: sha512-SJjlxlVlW3QPkHFCP+M3QSAgrlVC50hl/ePd/Xmfixx8pl4uiLwm/ZOMmzQ59IfM1zryQw55BNPv2qu5/1hJXA== tarball: 'file:projects/test-utils-recorder.tgz' version: 0.0.0 'file:projects/testhub.tgz': @@ -11837,7 +11846,7 @@ packages: dev: false name: '@rush-temp/testhub' resolution: - integrity: sha512-RkYcAmpRKuAXwbssMJGmc8uzm3LoQikdGvIqdwioQqURgLagimtd01yH+757XDMvMyOfVwejTTSCZHpqa2Bf6Q== + integrity: sha512-XZB/wnNqz04DCZBqyhzkkYG8c/XduwpKK8uJbRcnJrvTthx844ix8Cn3nDHaoLlxODmoxP4xosiCiKTIn7EuBw== tarball: 'file:projects/testhub.tgz' version: 0.0.0 registry: '' @@ -12040,5 +12049,6 @@ specifiers: ws: ^7.1.1 xhr-mock: ^2.4.1 xml2js: ^0.4.19 + xmlbuilder: ^0.4.3 yargs: ^14.0.0 - yarn: ^1.6.0 \ No newline at end of file + yarn: ^1.6.0 From 1d062d1f4848372b1117f5909cedaba484ad52e3 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 9 Sep 2019 17:42:13 -0700 Subject: [PATCH 24/72] Move out sasServiceClientCredentials --- sdk/core/core-http/lib/coreHttp.ts | 2 - .../sasServiceClientCredentials.ts | 65 ------------------- sdk/core/core-http/lib/util/crypto.browser.ts | 30 --------- sdk/core/core-http/lib/util/crypto.ts | 14 ---- sdk/core/core-http/package.json | 1 - sdk/core/core-http/rollup.config.ts | 1 - sdk/core/core-http/test/cryptoTests.ts | 17 ----- sdk/core/core-http/tsconfig.json | 10 +-- sdk/core/core-http/webpack.testconfig.ts | 4 -- 9 files changed, 2 insertions(+), 142 deletions(-) delete mode 100644 sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts delete mode 100644 sdk/core/core-http/lib/util/crypto.browser.ts delete mode 100644 sdk/core/core-http/lib/util/crypto.ts delete mode 100644 sdk/core/core-http/test/cryptoTests.ts diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index dfb8b872f439..74e140dde9d9 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -110,9 +110,7 @@ export { atomSerializationPolicy, AtomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { SasServiceClientCredentials } from "./credentials/sasServiceClientCredentials"; export { ResourceSerializer } from "./resourceSerializer"; export { AtomResourceSerializerBase } from "./atomResourceSerializerBase"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; -export { ProxySettings } from "./serviceClient"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts b/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts deleted file mode 100644 index 46f550ef4d01..000000000000 --- a/sdk/core/core-http/lib/credentials/sasServiceClientCredentials.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { HttpHeaders } from "../httpHeaders"; -import { WebResource } from "../webResource"; -import { ServiceClientCredentials } from "./serviceClientCredentials"; -import { Constants } from "../util/constants"; -import { generateKey } from "../util/crypto"; - -const HeaderConstants = Constants.HeaderConstants; - -export class SasServiceClientCredentials implements ServiceClientCredentials { - keyName: string; - keyValue: string; - - /** - * Creates a new sasServiceClientCredentials object. - * - * @constructor - * @param {string} sharedAccessKeyName The SAS key name to use. - * @param {string} sharedAccessKey The SAS key value to use - */ - constructor(sharedAccessKeyName: string, sharedAccessKey: string) { - if (typeof sharedAccessKeyName !== "string") { - throw new Error( - "sharedAccessKeyName cannot be null or undefined and must be of type string." - ); - } - - if (typeof sharedAccessKey !== "string") { - throw new Error("sharedAccessKey cannot be null or undefined and must be of type string."); - } - - this.keyName = sharedAccessKeyName; - this.keyValue = sharedAccessKey; - } - - private async _generateSignature(targetUri: string, expirationDate: number): Promise { - const stringToSign = `${targetUri}\n${expirationDate}`; - const result = await generateKey(this.keyValue, stringToSign); - return result; - } - - /** - * Signs a request with the Authentication header. - * - * @param {WebResource} webResource The WebResource to be signed. - * @returns {Promise} The signed request object. - */ - async signRequest(webResource: WebResource): Promise { - if (!webResource.headers) webResource.headers = new HttpHeaders(); - - const targetUri = encodeURIComponent(webResource.url.toLowerCase()).toLowerCase(); - - const date = new Date(); - date.setMinutes(date.getMinutes() + 5); - const expirationDate = Math.round(date.getTime() / 1000); - const signature = await this._generateSignature(targetUri, expirationDate); - webResource.headers.set( - HeaderConstants.AUTHORIZATION, - `SharedAccessSignature sig=${signature}&se=${expirationDate}&skn=${this.keyName}&sr=${targetUri}` - ); - return webResource; - } -} diff --git a/sdk/core/core-http/lib/util/crypto.browser.ts b/sdk/core/core-http/lib/util/crypto.browser.ts deleted file mode 100644 index 6eb220e01cfc..000000000000 --- a/sdk/core/core-http/lib/util/crypto.browser.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { encodeByteArray } from "./base64"; - -export async function generateKey(secret: string, stringToSign: string): Promise { - const key = await window.crypto.subtle.importKey( - "raw", - convertToUint8Array(secret), - { - name: "HMAC", - hash: { name: "SHA-256" } - }, - false, - ["sign"] - ); - - const signature = await window.crypto.subtle.sign("HMAC", key, convertToUint8Array(stringToSign)); - const base64encodedString = encodeByteArray(new Uint8Array(signature)); - const result = encodeURIComponent(base64encodedString); - return result; -} - -function convertToUint8Array(value: string) { - const arr = new Uint8Array(value.length); - for (let i = 0; i < value.length; i++) { - arr[i] = value.charCodeAt(i); - } - return arr; -} diff --git a/sdk/core/core-http/lib/util/crypto.ts b/sdk/core/core-http/lib/util/crypto.ts deleted file mode 100644 index e19abf7691b4..000000000000 --- a/sdk/core/core-http/lib/util/crypto.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import crypto from "crypto"; - -export async function generateKey(secret: string, stringToSign: string) { - const result = encodeURIComponent( - crypto - .createHmac("sha256", secret) - .update(stringToSign) - .digest("base64") - ); - return result; -} diff --git a/sdk/core/core-http/package.json b/sdk/core/core-http/package.json index 8231b4bb060f..fada898c6b80 100644 --- a/sdk/core/core-http/package.json +++ b/sdk/core/core-http/package.json @@ -46,7 +46,6 @@ "./es/lib/policies/proxyPolicy.js": "./es/lib/policies/proxyPolicy.browser.js", "./es/lib/util/base64.js": "./es/lib/util/base64.browser.js", "./es/lib/util/xml.js": "./es/lib/util/xml.browser.js", - "./es/lib/util/crypto.js": "./es/lib/util/crypto.browser.js", "./es/lib/defaultHttpClient.js": "./es/lib/defaultHttpClient.browser.js" }, "license": "MIT", diff --git a/sdk/core/core-http/rollup.config.ts b/sdk/core/core-http/rollup.config.ts index 91dd0f361108..66c141e84a5a 100644 --- a/sdk/core/core-http/rollup.config.ts +++ b/sdk/core/core-http/rollup.config.ts @@ -58,7 +58,6 @@ const nodeConfig = { */ const browserConfig = { input: "./es/lib/coreHttp.js", - external: ["crypto"], output: { file: "./dist/coreHttp.browser.js", format: "umd", diff --git a/sdk/core/core-http/test/cryptoTests.ts b/sdk/core/core-http/test/cryptoTests.ts deleted file mode 100644 index fcf9c0730633..000000000000 --- a/sdk/core/core-http/test/cryptoTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { generateKey } from "../lib/util/crypto"; -import { assert } from "chai"; - -describe("generateKey(secret, stringToSign)", function() { - it("generates valid key for secret as 'abc' and string to sign as 'def' ", async function() { - const key: string = await generateKey("abc", "def"); - assert.equal(key, "IOvA8JNERwE081BA9j6pix2OQUISlJ7lxQBCnRXqsIE%3D%3D"); - }); - - it("generates valid key when secret and stringToSign are empty", async function() { - const key: string = await generateKey("", ""); - assert.equal(key, "thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0%3D"); - }); -}); diff --git a/sdk/core/core-http/tsconfig.json b/sdk/core/core-http/tsconfig.json index 418bf57b79b6..c4ea5684971d 100644 --- a/sdk/core/core-http/tsconfig.json +++ b/sdk/core/core-http/tsconfig.json @@ -27,12 +27,6 @@ ] }, "compileOnSave": true, - "exclude": [ - "node_modules" - ], - "include": [ - "./lib/**/*.ts", - "./samples/**/*.ts", - "./test/**/*.ts" - ] + "exclude": ["node_modules"], + "include": ["./lib/**/*.ts", "./samples/**/*.ts", "./test/**/*.ts"] } diff --git a/sdk/core/core-http/webpack.testconfig.ts b/sdk/core/core-http/webpack.testconfig.ts index 8db036d2f54b..89ea3b890d7c 100644 --- a/sdk/core/core-http/webpack.testconfig.ts +++ b/sdk/core/core-http/webpack.testconfig.ts @@ -35,10 +35,6 @@ const config: webpack.Configuration = { /(\.).+util\/xml/, path.resolve(__dirname, "./lib/util/xml.browser.ts") ), - new webpack.NormalModuleReplacementPlugin( - /(\.).+util\/crypto/, - path.resolve(__dirname, "./lib/util/crypto.browser.ts") - ), new webpack.NormalModuleReplacementPlugin( /(\.).+defaultHttpClient/, path.resolve(__dirname, "./lib/defaultHttpClient.browser.ts") From 156fbc1cc57b2c92b98011e06d8ae461ecaec42a Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 16 Sep 2019 16:04:43 -0700 Subject: [PATCH 25/72] Refactor atom serializer interface --- .../lib/atomResourceSerializerBase.ts | 85 ----- .../core-http/lib/atomXmlOperationSpec.ts | 4 +- sdk/core/core-http/lib/coreHttp.ts | 7 +- .../lib/policies/atomSerializationPolicy.ts | 169 +-------- sdk/core/core-http/lib/resourceSerializer.ts | 8 - sdk/core/core-http/lib/util/atomHandler.ts | 117 ------ sdk/core/core-http/lib/util/atomXmlHelper.ts | 338 ++++++++++++++++++ .../policies/atomSerializationPolicyTests.ts | 15 +- 8 files changed, 366 insertions(+), 377 deletions(-) delete mode 100644 sdk/core/core-http/lib/atomResourceSerializerBase.ts delete mode 100644 sdk/core/core-http/lib/resourceSerializer.ts delete mode 100644 sdk/core/core-http/lib/util/atomHandler.ts create mode 100644 sdk/core/core-http/lib/util/atomXmlHelper.ts diff --git a/sdk/core/core-http/lib/atomResourceSerializerBase.ts b/sdk/core/core-http/lib/atomResourceSerializerBase.ts deleted file mode 100644 index a84988973fc8..000000000000 --- a/sdk/core/core-http/lib/atomResourceSerializerBase.ts +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { Constants } from "./util/constants"; -import { serializeJsonToAtomXml } from "./util/xml"; -import { - parseResultFromAtomResponse, - XMLRequestInJSON, - XMLResponseInJSON -} from "./util/atomHandler"; - -export class AtomResourceSerializerBase { - static serializeToAtomXmlRequest( - resourceName: string, - resource: any, - properties: string[], - xmlNamespace: string - ): string { - const content: XMLRequestInJSON = {}; - content[resourceName] = { - $: { - xmlns: xmlNamespace - } - }; - - if (resource) { - // Sort properties according to what is allowed by the service - properties.forEach((property: string) => { - if (resource[property] !== undefined) { - content[resourceName][property] = resource[property]; - } - }); - } - - return serializeJsonToAtomXml(content); - } - - /** - * Deserializes the JSON representation of Atom response to construct - * the final `result` to return - * - * @param nameProperties The set of 'name' properties to be constructed on the resultant object e.g., QueueName, TopicName, etc. - * @param atomResponseInJson - */ - static deserializeAtomResponse( - nameProperties: string[], - atomResponseInJson: any - ): XMLResponseInJSON[] | XMLResponseInJSON | undefined { - const result = parseResultFromAtomResponse(atomResponseInJson); - - if (!result) { - return undefined; - } - if (Array.isArray(result)) { - result.forEach((entry: XMLResponseInJSON) => { - AtomResourceSerializerBase.setName(entry, nameProperties); - }); - } else { - AtomResourceSerializerBase.setName(result, nameProperties); - } - return result; - } - - /** - * Extracts the applicable entity name(s) from the URL based on the known structure - * and instantiates the corresponding name properties to the deserialized response - * - * For instance, following is the URL structure for when creating a rule - * `//Subscriptions//Rules/` - * - * @param entry - * @param nameProperties - */ - private static setName(entry: XMLResponseInJSON, nameProperties: any): any { - if (entry[Constants.ATOM_METADATA_MARKER]) { - const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); - - const parts = parsedUrl.pathname!.split("/"); - - for (let i = 0; i * 2 < parts.length - 1; i++) { - entry[nameProperties[i]] = parts[i * 2 + 1]; - } - } - } -} diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 8c1f334d4ba7..2f973536c8cc 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -1,10 +1,10 @@ -import { ResourceSerializer } from "./resourceSerializer"; +import { AtomResourceSerializer } from "./util/atomXmlHelper"; export interface AtomXmlOperationSpec { /** * The serializer to use in this operation. */ - serializer: ResourceSerializer; + serializer: AtomResourceSerializer; /** * Indicates whether the response needs to be parsed. diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 74e140dde9d9..25c910768a65 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -110,7 +110,10 @@ export { atomSerializationPolicy, AtomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { ResourceSerializer } from "./resourceSerializer"; -export { AtomResourceSerializerBase } from "./atomResourceSerializerBase"; +export { + AtomResourceSerializer, + serializeToAtomXmlRequest, + deserializeAtomXmlResponse +} from "./util/atomXmlHelper"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index dd7887c1312b..b9afe9b31c20 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,10 +9,7 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { Constants } from "../util/constants"; -import { deserializeAtomXmlToJson } from "../util/xml"; -import { isString } from "../util/utils"; -import { ResourceSerializer } from "../resourceSerializer"; +import { AtomResourceSerializer } from "../util/atomXmlHelper"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -37,163 +34,23 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } public async sendRequest(request: WebResource): Promise { - let shouldParseResponse = false; - let serializer: ResourceSerializer | undefined; - if (request.atomXmlOperationSpec) { - serializer = request.atomXmlOperationSpec.serializer; - shouldParseResponse = request.atomXmlOperationSpec.shouldParseResponse; - if (request.body) { - request.body = serializer.serialize(JSON.parse(request.body)); - } + if ( + request.atomXmlOperationSpec == undefined || + request.atomXmlOperationSpec.serializer == undefined + ) { + throw new Error( + "atomXmlOperationSpec and atomXmlOperationSpec.serializer must be supplied on the requests when using this policy." + ); } - let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); - - // Transform response to contain the parsed data - response = await this.parseResponse(response); - - // Construct response with 'result' to be backward compatibile - const responseInCustomJson: any = { - error: response.errorBody, - response: response.parsedBody, - result: shouldParseResponse ? [] : undefined - }; - - if (responseInCustomJson.error == undefined) { - responseInCustomJson.result = - shouldParseResponse && serializer - ? serializer.parse(responseInCustomJson.response) - : undefined; - } - - response.parsedBody = responseInCustomJson; - return response; - } - - /** - * @ignore - * Utility to help transform the response to contain normalized JSON based information - * constructed from the raw Atom XML based data received. - * - * @param {Response} response The response object containing data in Atom XML format. - * @return The normalized responseObject. - */ - private async parseResponse(response: HttpOperationResponse): Promise { - try { - if (response.bodyAsText && response.bodyAsText.toString().length > 0) { - response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); - } - } catch (e) { - response.errorBody = { - error: { code: "ResponseNotInAtomXMLFormat" } - }; - } - - if (response.status >= 200 && response.status < 300 && response.errorBody == undefined) { - return response; - } + const serializer: AtomResourceSerializer = request.atomXmlOperationSpec.serializer; - if (response.errorBody == undefined) { - const HttpResponseCodes = Constants.HttpResponseCodes; - const statusCode = response.status; - if (!this.isKnownResponseCode(statusCode)) { - response.errorBody = { - error: { code: `UnrecognizedHttpResponseStatus: ${statusCode}` } - }; - } else { - response.errorBody = { error: { code: HttpResponseCodes[statusCode] } }; - } + if (request.body) { + request.body = serializer.serialize(JSON.parse(request.body)); } - // Transform the errorBody to a normalized one - const normalizedError = this._normalizeError(response.errorBody, response); - response.errorBody = normalizedError; - return response; - } - - private isKnownResponseCode( - statusCode: number - ): statusCode is keyof typeof Constants.HttpResponseCodes { - return !!(Constants.HttpResponseCodes as { [statusCode: number]: string })[statusCode]; - } - - /** - * @ignore - * Utility to help construct the normalized error object based on given `errorBody` - * data and other data present in the received `response` object. - * - * @param errorBody - * @param response - */ - private _normalizeError(errorBody: any, response: HttpOperationResponse): any { - if (isString(errorBody)) { - return new Error(errorBody); - } else if (errorBody) { - const normalizedError: any = {}; - const odataErrorFormat = !!errorBody["odata.error"]; - const errorProperties = - errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; - - if (odataErrorFormat) { - Object.keys(errorProperties).forEach((property: string) => { - let value = null; - if ( - property === Constants.ODATA_ERROR_MESSAGE && - !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) - ) { - if ( - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE] - ) { - value = - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; - } else { - value = "missing value in the message property of the odata error format"; - } - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - }); - } else { - Object.keys(errorProperties).forEach((property: any) => { - { - let value = null; - if (property !== Constants.XML_METADATA_MARKER) { - if ( - errorProperties[property] && - errorProperties[property][Constants.XML_VALUE_MARKER] - ) { - value = errorProperties[property][Constants.XML_VALUE_MARKER]; - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - } - } - }); - } - let errorMessage = normalizedError.code; - if (normalizedError.detail) { - errorMessage += " - " + normalizedError.detail; - } - - if (response) { - if (response.status) { - normalizedError.statusCode = response.status; - } - - if (response.headers && response.headers.get("x-ms-request-id")) { - normalizedError.requestId = response.headers.get("x-ms-request-id"); - } - } - - const errorObject: any = { error: { code: errorMessage } }; - Object.keys(normalizedError).forEach((property: string) => { - errorObject[property] = normalizedError[property]; - }); - return errorObject; - } + let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); - return undefined; + return await serializer.deserialize(response, request.atomXmlOperationSpec.shouldParseResponse); } } diff --git a/sdk/core/core-http/lib/resourceSerializer.ts b/sdk/core/core-http/lib/resourceSerializer.ts deleted file mode 100644 index f3c2140bcbc5..000000000000 --- a/sdk/core/core-http/lib/resourceSerializer.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -export interface ResourceSerializer { - serialize(resourceDataInJson: any): string; - - parse(atomResponseInJson: any): any; -} diff --git a/sdk/core/core-http/lib/util/atomHandler.ts b/sdk/core/core-http/lib/util/atomHandler.ts deleted file mode 100644 index 3a6a02e742b2..000000000000 --- a/sdk/core/core-http/lib/util/atomHandler.ts +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { Constants } from "./constants"; - -/** - * Type representing the JSON representation of XML request data - */ -export interface XMLRequestInJSON { - [key: string]: { - $: { xmlns: string }; - [key: string]: any; - }; -} - -/** - * Type representing the JSON representation of XML response data - */ -export interface XMLResponseInJSON { - [key: string]: any; -} - -/** - * Utility to deserialize the given JSON content even further based on - * if it's a single `entry` or `feed` - * @param {object} atomResponseInJson - * */ -export function parseResultFromAtomResponse( - atomResponseInJson: any -): XMLResponseInJSON[] | XMLResponseInJSON | undefined { - if (!atomResponseInJson) { - return; - } - - if (atomResponseInJson.feed) { - return parseFeedResult(atomResponseInJson.feed); - } - - if (atomResponseInJson.entry) { - return parseEntryResult(atomResponseInJson.entry); - } - - throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); -} - -/** - * @ignore - * Utility to help parse given `entry` result - * @param entry - */ -function parseEntryResult(entry: any): XMLResponseInJSON | undefined { - let result: XMLResponseInJSON; - - if ( - typeof entry !== "object" || - entry == null || - typeof entry.content !== "object" || - entry.content == null - ) { - return undefined; - } - - const contentElementNames = Object.keys(entry.content).filter(function(key) { - return key !== Constants.XML_METADATA_MARKER; - }); - - if (contentElementNames && contentElementNames[0]) { - const contentRootElementName = contentElementNames[0]; - delete entry.content[contentRootElementName][Constants.XML_METADATA_MARKER]; - result = entry.content[contentRootElementName]; - - if (result) { - if (entry[Constants.XML_METADATA_MARKER]) { - result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; - } else { - result[Constants.ATOM_METADATA_MARKER] = {}; - } - - result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentRootElementName; - - Object.keys(entry).forEach((property: string) => { - if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { - result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; - } - }); - - return result; - } - } - - return undefined; -} - -/** - * @ignore - * Utility to help parse given `feed` result - * @param feed - */ -function parseFeedResult(feed: any): XMLResponseInJSON[] { - const result = []; - if (typeof feed === "object" && feed != null && feed.entry) { - if (Array.isArray(feed.entry)) { - feed.entry.forEach((entry: any) => { - const parsedEntryResult = parseEntryResult(entry); - if (parsedEntryResult) { - result.push(parsedEntryResult); - } - }); - } else { - const parsedEntryResult = parseEntryResult(feed.entry); - if (parsedEntryResult) { - result.push(parsedEntryResult); - } - } - } - return result; -} diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts new file mode 100644 index 000000000000..30aeb6976083 --- /dev/null +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -0,0 +1,338 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { Constants } from "./constants"; +import { isString } from "./utils"; +import { serializeJsonToAtomXml, deserializeAtomXmlToJson } from "./xml"; +import { HttpOperationResponse } from "../httpOperationResponse"; + +export interface AtomResourceSerializer { + serialize(resourceDataInJson: any): string; + + deserialize( + response: HttpOperationResponse, + shouldParseResponse: boolean + ): Promise; +} + +/** + * @ignore + * Type representing the JSON representation of XML request data + */ +interface XMLRequestInJSON { + [key: string]: { + $: { xmlns: string }; + [key: string]: any; + }; +} + +/** + * @ignore + * Type representing the JSON representation of XML response data + */ +interface XMLResponseInJSON { + [key: string]: any; +} + +/** + * Serializes input information to construct the Atom XML request + * @param resourceName + * @param resource + * @param properties + * @param xmlNamespace + */ +export function serializeToAtomXmlRequest( + resourceName: string, + resource: any, + properties: string[], + xmlNamespace: string +): string { + const content: XMLRequestInJSON = {}; + content[resourceName] = { + $: { + xmlns: xmlNamespace + } + }; + + if (resource) { + // Sort properties according to what is allowed by the service + properties.forEach((property: string) => { + if (resource[property] !== undefined) { + content[resourceName][property] = resource[property]; + } + }); + } + + return serializeJsonToAtomXml(content); +} + +/** + * @ignore + * Utility to deserialize the given JSON content even further based on + * if it's a single `entry` or `feed` + * @param {object} atomResponseInJson + * */ +function parseAtomResult( + atomResponseInJson: any +): XMLResponseInJSON[] | XMLResponseInJSON | undefined { + if (!atomResponseInJson) { + return; + } + + if (atomResponseInJson.feed) { + return parseFeedResult(atomResponseInJson.feed); + } + + if (atomResponseInJson.entry) { + return parseEntryResult(atomResponseInJson.entry); + } + + throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); +} + +/** + * @ignore + * Utility to help parse given `entry` result + * @param entry + */ +function parseEntryResult(entry: any): XMLResponseInJSON | undefined { + let result: XMLResponseInJSON; + + if ( + typeof entry !== "object" || + entry == null || + typeof entry.content !== "object" || + entry.content == null + ) { + return undefined; + } + + const contentElementNames = Object.keys(entry.content).filter(function(key) { + return key !== Constants.XML_METADATA_MARKER; + }); + + if (contentElementNames && contentElementNames[0]) { + const contentRootElementName = contentElementNames[0]; + delete entry.content[contentRootElementName][Constants.XML_METADATA_MARKER]; + result = entry.content[contentRootElementName]; + + if (result) { + if (entry[Constants.XML_METADATA_MARKER]) { + result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; + } else { + result[Constants.ATOM_METADATA_MARKER] = {}; + } + + result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentRootElementName; + + Object.keys(entry).forEach((property: string) => { + if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { + result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; + } + }); + + return result; + } + } + + return undefined; +} + +/** + * @ignore + * Utility to help parse given `feed` result + * @param feed + */ +function parseFeedResult(feed: any): XMLResponseInJSON[] { + const result = []; + if (typeof feed === "object" && feed != null && feed.entry) { + if (Array.isArray(feed.entry)) { + feed.entry.forEach((entry: any) => { + const parsedEntryResult = parseEntryResult(entry); + if (parsedEntryResult) { + result.push(parsedEntryResult); + } + }); + } else { + const parsedEntryResult = parseEntryResult(feed.entry); + if (parsedEntryResult) { + result.push(parsedEntryResult); + } + } + } + return result; +} + +/** + * Transforms response to contain the parsed data. + * @param nameProperties The set of 'name' properties to be constructed on the + * resultant object e.g., QueueName, TopicName, etc. + * @param response + * @param shouldParseResponse + */ +export async function deserializeAtomXmlResponse( + nameProperties: string[], + response: HttpOperationResponse, + shouldParseResponse: boolean +): Promise { + let atomResponseInJson: any; + try { + if (response.bodyAsText && response.bodyAsText.toString().length > 0) { + atomResponseInJson = await deserializeAtomXmlToJson(response.bodyAsText); + response.parsedBody = atomResponseInJson; + } + } catch (e) { + response.errorBody = { + error: { code: "ResponseNotInAtomXMLFormat" } + }; + } + + if (response.status < 200 || response.status > 300) { + if (response.errorBody == undefined) { + const HttpResponseCodes = Constants.HttpResponseCodes; + const statusCode = response.status; + if (!isKnownResponseCode(statusCode)) { + response.errorBody = { + error: { code: `UnrecognizedHttpResponseStatus: ${statusCode}` } + }; + } else { + response.errorBody = { error: { code: HttpResponseCodes[statusCode] } }; + } + } + } + + // Transform the errorBody to a normalized one + const normalizedError = normalizeError(response.errorBody, response); + response.errorBody = normalizedError; + + // Construct response with 'result' to be backward compatibile + const responseInCustomJson: any = { + error: response.errorBody, + response: response.parsedBody, + result: shouldParseResponse ? [] : undefined + }; + + if (responseInCustomJson.error == undefined) { + const result = shouldParseResponse ? parseAtomResult(atomResponseInJson) : undefined; + if (result) { + if (Array.isArray(result)) { + result.forEach((entry: XMLResponseInJSON) => { + setName(entry, nameProperties); + }); + } else { + setName(result, nameProperties); + } + } + responseInCustomJson.result = result; + } + + response.parsedBody = responseInCustomJson; + return response; +} + +function isKnownResponseCode( + statusCode: number +): statusCode is keyof typeof Constants.HttpResponseCodes { + return !!(Constants.HttpResponseCodes as { [statusCode: number]: string })[statusCode]; +} + +/** + * @ignore + * Extracts the applicable entity name(s) from the URL based on the known structure + * and instantiates the corresponding name properties to the deserialized response + * + * For instance, following is the URL structure for when creating a rule + * `//Subscriptions//Rules/` + * + * @param entry + * @param nameProperties + */ +function setName(entry: XMLResponseInJSON, nameProperties: any): any { + if (entry[Constants.ATOM_METADATA_MARKER]) { + const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); + + const parts = parsedUrl.pathname!.split("/"); + + for (let i = 0; i * 2 < parts.length - 1; i++) { + entry[nameProperties[i]] = parts[i * 2 + 1]; + } + } +} + +/** + * @ignore + * Utility to help construct the normalized error object based on given `errorBody` + * data and other data present in the received `response` object. + * + * @param errorBody + * @param response + */ +function normalizeError(errorBody: any, response: HttpOperationResponse): any { + if (isString(errorBody)) { + return new Error(errorBody); + } else if (errorBody) { + const normalizedError: any = {}; + const odataErrorFormat = !!errorBody["odata.error"]; + const errorProperties = + errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; + + if (odataErrorFormat) { + Object.keys(errorProperties).forEach((property: string) => { + let value = null; + if ( + property === Constants.ODATA_ERROR_MESSAGE && + !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + ) { + if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { + value = + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; + } else { + value = "missing value in the message property of the odata error format"; + } + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + }); + } else { + Object.keys(errorProperties).forEach((property: any) => { + { + let value = null; + if (property !== Constants.XML_METADATA_MARKER) { + if ( + errorProperties[property] && + errorProperties[property][Constants.XML_VALUE_MARKER] + ) { + value = errorProperties[property][Constants.XML_VALUE_MARKER]; + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + } + } + }); + } + let errorMessage = normalizedError.code; + if (normalizedError.detail) { + errorMessage += " - " + normalizedError.detail; + } + + if (response) { + if (response.status) { + normalizedError.statusCode = response.status; + } + + if (response.headers && response.headers.get("x-ms-request-id")) { + normalizedError.requestId = response.headers.get("x-ms-request-id"); + } + } + + const errorObject: any = { error: { code: errorMessage } }; + Object.keys(normalizedError).forEach((property: string) => { + errorObject[property] = normalizedError[property]; + }); + return errorObject; + } + + return undefined; +} diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 3caf9866a083..2663830bfd72 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -7,8 +7,9 @@ import { HttpOperationResponse } from "../../lib/httpOperationResponse"; import { HttpClient, AtomXmlOperationSpec, - AtomResourceSerializerBase, - ResourceSerializer + AtomResourceSerializer, + deserializeAtomXmlResponse, + serializeToAtomXmlRequest } from "../../lib/coreHttp"; import { AtomSerializationPolicy, @@ -115,11 +116,11 @@ function getCustomResult(error: any, result: any, response: any): any { }; } -class MockSerializer implements ResourceSerializer { - serialize(resource: any): any { +class MockSerializer implements AtomResourceSerializer { + serialize(resource: any): string { const properties = ["LockDuration", "MaxSizeInMegabytes"]; - return AtomResourceSerializerBase.serializeToAtomXmlRequest( + return serializeToAtomXmlRequest( "QueueDescription", resource, properties, @@ -127,7 +128,7 @@ class MockSerializer implements ResourceSerializer { ); } - parse(xml: any): any { - return AtomResourceSerializerBase.deserializeAtomResponse(["QueueName"], xml); + deserialize(response: HttpOperationResponse, shouldParseResponse: boolean): any { + return deserializeAtomXmlResponse(["QueueName"], response, shouldParseResponse); } } From 1acfe0df19d29c6059d5ae6f24dee24da58dc058 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 16 Sep 2019 16:56:29 -0700 Subject: [PATCH 26/72] Use name AtomXmlSerializer for the interface --- sdk/core/core-http/lib/atomXmlOperationSpec.ts | 4 ++-- sdk/core/core-http/lib/coreHttp.ts | 2 +- sdk/core/core-http/lib/policies/atomSerializationPolicy.ts | 4 ++-- sdk/core/core-http/lib/util/atomXmlHelper.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 2f973536c8cc..777bd8fd2ad0 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -1,10 +1,10 @@ -import { AtomResourceSerializer } from "./util/atomXmlHelper"; +import { AtomXmlSerializer } from "./util/atomXmlHelper"; export interface AtomXmlOperationSpec { /** * The serializer to use in this operation. */ - serializer: AtomResourceSerializer; + serializer: AtomXmlSerializer; /** * Indicates whether the response needs to be parsed. diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 25c910768a65..076e09aad624 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -111,7 +111,7 @@ export { AtomSerializationPolicy } from "./policies/atomSerializationPolicy"; export { - AtomResourceSerializer, + AtomXmlSerializer, serializeToAtomXmlRequest, deserializeAtomXmlResponse } from "./util/atomXmlHelper"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index b9afe9b31c20..7aaa8ffce204 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,7 +9,7 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { AtomResourceSerializer } from "../util/atomXmlHelper"; +import { AtomXmlSerializer } from "../util/atomXmlHelper"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -43,7 +43,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { ); } - const serializer: AtomResourceSerializer = request.atomXmlOperationSpec.serializer; + const serializer: AtomXmlSerializer = request.atomXmlOperationSpec.serializer; if (request.body) { request.body = serializer.serialize(JSON.parse(request.body)); diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts index 30aeb6976083..29a0cbc5abb3 100644 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -6,7 +6,7 @@ import { isString } from "./utils"; import { serializeJsonToAtomXml, deserializeAtomXmlToJson } from "./xml"; import { HttpOperationResponse } from "../httpOperationResponse"; -export interface AtomResourceSerializer { +export interface AtomXmlSerializer { serialize(resourceDataInJson: any): string; deserialize( From ecff0e123305682324a81ba3d16c45683b2220c4 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 16 Sep 2019 17:22:27 -0700 Subject: [PATCH 27/72] Fix reference --- .../core-http/test/policies/atomSerializationPolicyTests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 2663830bfd72..8a65857a9651 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -7,7 +7,7 @@ import { HttpOperationResponse } from "../../lib/httpOperationResponse"; import { HttpClient, AtomXmlOperationSpec, - AtomResourceSerializer, + AtomXmlSerializer, deserializeAtomXmlResponse, serializeToAtomXmlRequest } from "../../lib/coreHttp"; @@ -116,7 +116,7 @@ function getCustomResult(error: any, result: any, response: any): any { }; } -class MockSerializer implements AtomResourceSerializer { +class MockSerializer implements AtomXmlSerializer { serialize(resource: any): string { const properties = ["LockDuration", "MaxSizeInMegabytes"]; From 1fd3ce5e76721c38f6541ed6cc22937617d4f2c8 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 17 Sep 2019 10:23:39 -0700 Subject: [PATCH 28/72] Address comments --- sdk/core/core-http/lib/coreHttp.ts | 5 +---- .../lib/policies/atomSerializationPolicy.ts | 2 +- sdk/core/core-http/lib/util/atomXmlHelper.ts | 15 ++++++++------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 076e09aad624..e84355370232 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -106,10 +106,7 @@ export { ServiceClientCredentials } from "./credentials/serviceClientCredentials export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; -export { - atomSerializationPolicy, - AtomSerializationPolicy -} from "./policies/atomSerializationPolicy"; +export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; export { AtomXmlSerializer, serializeToAtomXmlRequest, diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 7aaa8ffce204..695c88860081 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -49,7 +49,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { request.body = serializer.serialize(JSON.parse(request.body)); } - let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); + const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); return await serializer.deserialize(response, request.atomXmlOperationSpec.shouldParseResponse); } diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts index 29a0cbc5abb3..b1b4b0907638 100644 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -191,13 +191,14 @@ export async function deserializeAtomXmlResponse( if (response.errorBody == undefined) { const HttpResponseCodes = Constants.HttpResponseCodes; const statusCode = response.status; - if (!isKnownResponseCode(statusCode)) { - response.errorBody = { - error: { code: `UnrecognizedHttpResponseStatus: ${statusCode}` } - }; - } else { - response.errorBody = { error: { code: HttpResponseCodes[statusCode] } }; - } + const errorCode = isKnownResponseCode(statusCode) + ? HttpResponseCodes[statusCode] + : `UnrecognizedHttpResponseStatus: ${statusCode}`; + response.errorBody = { + error: { + code: errorCode + } + }; } } From 119e5b44bcd299527127b71cc80eeb636d117d9e Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 19 Sep 2019 11:39:10 -0700 Subject: [PATCH 29/72] Streamline result structure, fix tests --- .../core-http/lib/atomXmlOperationSpec.ts | 6 -- .../lib/policies/atomSerializationPolicy.ts | 4 +- sdk/core/core-http/lib/util/atomXmlHelper.ts | 79 ++++++++++++------- sdk/core/core-http/lib/util/xml.ts | 30 ++++--- .../policies/atomSerializationPolicyTests.ts | 65 +++++---------- 5 files changed, 96 insertions(+), 88 deletions(-) diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 777bd8fd2ad0..2744b7efc465 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -5,10 +5,4 @@ export interface AtomXmlOperationSpec { * The serializer to use in this operation. */ serializer: AtomXmlSerializer; - - /** - * Indicates whether the response needs to be parsed. - * Applicable for GET / LIST operations. - */ - shouldParseResponse: boolean; } diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 695c88860081..e31b11f2099b 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -49,8 +49,8 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { request.body = serializer.serialize(JSON.parse(request.body)); } - const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); + let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); - return await serializer.deserialize(response, request.atomXmlOperationSpec.shouldParseResponse); + return await serializer.deserialize(response); } } diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts index b1b4b0907638..69f4f7b6f55a 100644 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -9,10 +9,7 @@ import { HttpOperationResponse } from "../httpOperationResponse"; export interface AtomXmlSerializer { serialize(resourceDataInJson: any): string; - deserialize( - response: HttpOperationResponse, - shouldParseResponse: boolean - ): Promise; + deserialize(response: HttpOperationResponse): Promise; } /** @@ -172,22 +169,22 @@ function parseFeedResult(feed: any): XMLResponseInJSON[] { */ export async function deserializeAtomXmlResponse( nameProperties: string[], - response: HttpOperationResponse, - shouldParseResponse: boolean + response: HttpOperationResponse ): Promise { let atomResponseInJson: any; try { - if (response.bodyAsText && response.bodyAsText.toString().length > 0) { + if (response.bodyAsText) { atomResponseInJson = await deserializeAtomXmlToJson(response.bodyAsText); response.parsedBody = atomResponseInJson; } } catch (e) { - response.errorBody = { - error: { code: "ResponseNotInAtomXMLFormat" } - }; + response.errorBody = { code: "ResponseNotInAtomXMLFormat" }; + return response; } - if (response.status < 200 || response.status > 300) { + // If received data is a non-valid HTTP response, the body is expected to contain error information + if (response.status < 200 || response.status >= 300) { + response.errorBody = atomResponseInJson; if (response.errorBody == undefined) { const HttpResponseCodes = Constants.HttpResponseCodes; const statusCode = response.status; @@ -195,26 +192,27 @@ export async function deserializeAtomXmlResponse( ? HttpResponseCodes[statusCode] : `UnrecognizedHttpResponseStatus: ${statusCode}`; response.errorBody = { - error: { - code: errorCode - } + code: errorCode }; + } else { + // Transform the error info in response body to a normalized one + const normalizedError = normalizeError(response); + response.errorBody = normalizedError; } } - // Transform the errorBody to a normalized one - const normalizedError = normalizeError(response.errorBody, response); - response.errorBody = normalizedError; - // Construct response with 'result' to be backward compatibile const responseInCustomJson: any = { - error: response.errorBody, - response: response.parsedBody, - result: shouldParseResponse ? [] : undefined + error: response.errorBody ? response.errorBody : null, + response: null, + result: [] }; + let isSuccessful = false; + if (responseInCustomJson.error == undefined) { - const result = shouldParseResponse ? parseAtomResult(atomResponseInJson) : undefined; + isSuccessful = true; + const result = parseAtomResult(atomResponseInJson); if (result) { if (Array.isArray(result)) { result.forEach((entry: XMLResponseInJSON) => { @@ -227,6 +225,13 @@ export async function deserializeAtomXmlResponse( responseInCustomJson.result = result; } + responseInCustomJson.response = buildResponse( + isSuccessful, + response.parsedBody, + response.headers.rawHeaders(), + response.status + ); + response.parsedBody = responseInCustomJson; return response; } @@ -268,7 +273,8 @@ function setName(entry: XMLResponseInJSON, nameProperties: any): any { * @param errorBody * @param response */ -function normalizeError(errorBody: any, response: HttpOperationResponse): any { +function normalizeError(response: HttpOperationResponse): any { + const errorBody: any = response.errorBody; if (isString(errorBody)) { return new Error(errorBody); } else if (errorBody) { @@ -318,17 +324,17 @@ function normalizeError(errorBody: any, response: HttpOperationResponse): any { errorMessage += " - " + normalizedError.detail; } + const errorObject: any = { code: errorMessage }; + if (response) { if (response.status) { - normalizedError.statusCode = response.status; + errorObject["statusCode"] = response.status; } if (response.headers && response.headers.get("x-ms-request-id")) { - normalizedError.requestId = response.headers.get("x-ms-request-id"); + errorObject["requestId"] = response.headers.get("x-ms-request-id"); } } - - const errorObject: any = { error: { code: errorMessage } }; Object.keys(normalizedError).forEach((property: string) => { errorObject[property] = normalizedError[property]; }); @@ -337,3 +343,22 @@ function normalizeError(errorBody: any, response: HttpOperationResponse): any { return undefined; } + +/** + * Builds a response object with normalized key names. + * @ignore + * + * @param isSuccessful Boolean value indicating if the request was successful + * @param body The response body. + * @param headers The response headers. + * @param statusCode The response status code. + */ + +function buildResponse(isSuccessful: boolean, body: any, headers: any, statusCode: number) { + return { + isSuccessful: isSuccessful, + statusCode: statusCode, + body: body, + headers: headers + }; +} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 15e9cd3db66f..57a17483adc4 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -19,12 +19,8 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { } export function parseXML(str: string): Promise { - const xmlParser = new xml2js.Parser({ - explicitArray: false, - explicitCharkey: false, - explicitRoot: false - }); - return new Promise((resolve, reject) => { + const xmlParser = new xml2js.Parser(_getDefaultSettings()); + const result = new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); } else { @@ -37,11 +33,12 @@ export function parseXML(str: string): Promise { }); } }); + return result; } export async function deserializeAtomXmlToJson(body: string): Promise { const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); - return await new Promise((resolve, reject) => { + const result = await new Promise((resolve, reject) => { parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { reject(err); @@ -50,9 +47,11 @@ export async function deserializeAtomXmlToJson(body: string): Promise { } }); }); + return result; } /** + * @ignore * @param {object} content The content payload as it is to be serialized. It should include any root node(s). */ export function serializeJsonToAtomXml(content: any): string { @@ -71,9 +70,8 @@ export function serializeJsonToAtomXml(content: any): string { } /** - * Gets the default xml2js settings applicable for Atom based XML operations. * @ignore - * @return {object} The default settings + * Gets the default xml2js settings applicable for Atom based XML operations. */ function _getDefaultSettingsForAtomXmlOperations(): any { const xml2jsSettings = xml2js.defaults["0.2"]; @@ -81,9 +79,23 @@ function _getDefaultSettingsForAtomXmlOperations(): any { xml2jsSettings.trim = false; xml2jsSettings.attrkey = "$"; xml2jsSettings.charkey = "_"; + xml2jsSettings.explicitCharkey = false; xml2jsSettings.explicitArray = false; xml2jsSettings.ignoreAttrs = true; + return xml2jsSettings; +} +/** + * @ignore + * Gets the default settings applicable for general XML operations. + */ +function _getDefaultSettings(): any { + const xml2jsSettings = xml2js.defaults["0.2"]; + xml2jsSettings.explicitArray = false; + xml2jsSettings.ignoreAttrs = false; + xml2jsSettings.explicitCharkey = false; + xml2jsSettings.explicitRoot = false; + xml2jsSettings.normalize = true; return xml2jsSettings; } diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 8a65857a9651..8b2ac5c063de 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -11,39 +11,15 @@ import { deserializeAtomXmlResponse, serializeToAtomXmlRequest } from "../../lib/coreHttp"; -import { - AtomSerializationPolicy, - atomSerializationPolicy -} from "../../lib/policies/atomSerializationPolicy"; -import { RequestPolicy, RequestPolicyOptions } from "../../lib/policies/requestPolicy"; +import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; +import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; describe("atomSerializationPolicy", function() { - const mockPolicy: RequestPolicy = { - sendRequest(request: WebResource): Promise { - return Promise.resolve({ - request: request, - status: 200, - headers: new HttpHeaders() - }); - } - }; - - it(`should not modify a request that has no request body serializer`, async function() { - const atomSerializationPolicy = new AtomSerializationPolicy( - mockPolicy, - new RequestPolicyOptions() - ); - - const request = createRequest(); - request.body = "hello there!"; - - await atomSerializationPolicy.sendRequest(request); - assert.strictEqual(request.body, "hello there!"); - }); - it("should return an error if receiving a non-XML response body", async function() { - const request: WebResource = createRequest(); + const request: WebResource = createRequest({ + serializer: new MockSerializer() + }); const mockClient: HttpClient = { sendRequest: (req) => Promise.resolve({ @@ -57,13 +33,12 @@ describe("atomSerializationPolicy", function() { const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); const response = await policy.sendRequest(request); assert.deepEqual(response.bodyAsText, `{ "simple": "JSONobject" }`); - assert.deepEqual(response.parsedBody.error.code, "ResponseNotInAtomXMLFormat"); + assert.deepEqual(response.errorBody.code, "ResponseNotInAtomXMLFormat"); }); it("with xml response body, application/xml content-type and AtomXMLOperationSpec", async function() { const request: WebResource = createRequest({ - serializer: new MockSerializer(), - shouldParseResponse: false + serializer: new MockSerializer() }); const expectedResult = { @@ -74,7 +49,17 @@ describe("atomSerializationPolicy", function() { content: { QueueDescription: { LockDuration: "PT2M", - MaxSizeInMegabytes: "1024" + MaxSizeInMegabytes: "1024", + QueueName: "testQueuePath4", + _: { + ContentRootElement: "QueueDescription", + author: { + name: "servicebuslocalperftestspremium1" + }, + id: + "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", + title: "testQueuePath4" + } } }, id: @@ -98,7 +83,7 @@ describe("atomSerializationPolicy", function() { const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); const response = await policy.sendRequest(request); - assert.deepEqual(response.parsedBody, getCustomResult(undefined, undefined, expectedResult)); + assert.deepEqual(response.parsedBody.response.body, expectedResult); }); }); @@ -108,14 +93,6 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource return request; } -function getCustomResult(error: any, result: any, response: any): any { - return { - error: error, - result: result, - response: response - }; -} - class MockSerializer implements AtomXmlSerializer { serialize(resource: any): string { const properties = ["LockDuration", "MaxSizeInMegabytes"]; @@ -128,7 +105,7 @@ class MockSerializer implements AtomXmlSerializer { ); } - deserialize(response: HttpOperationResponse, shouldParseResponse: boolean): any { - return deserializeAtomXmlResponse(["QueueName"], response, shouldParseResponse); + deserialize(response: HttpOperationResponse): any { + return deserializeAtomXmlResponse(["QueueName"], response); } } From e415e944486199009546d09bfbf3835f809a26d1 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 19 Sep 2019 16:02:29 -0700 Subject: [PATCH 30/72] Update pnpm lock file --- common/config/rush/pnpm-lock.yaml | 298 +++++++++++++++++++++++++----- 1 file changed, 248 insertions(+), 50 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 24c2b6a63aed..23a80fe23f88 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -3,10 +3,12 @@ dependencies: '@azure/arm-servicebus': 3.2.0 '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 '@azure/cosmos-sign': 1.0.2 + '@azure/eslint-plugin-azure-sdk': 2.0.1_9e8391ca70fb0408a9da4393803aa477 + '@azure/event-hubs': 2.1.1 '@azure/logger-js': 1.3.2 '@azure/ms-rest-js': 2.0.4 '@azure/ms-rest-nodeauth': 0.9.3 - '@azure/storage-blob': 12.0.0-preview.2 + '@azure/storage-blob': 12.0.0-preview.3 '@microsoft/api-extractor': 7.3.8 '@rush-temp/abort-controller': 'file:projects/abort-controller.tgz' '@rush-temp/app-configuration': 'file:projects/app-configuration.tgz' @@ -32,7 +34,6 @@ dependencies: '@rush-temp/template': 'file:projects/template.tgz' '@rush-temp/test-utils-recorder': 'file:projects/test-utils-recorder.tgz' '@rush-temp/testhub': 'file:projects/testhub.tgz' - '@trust/keyto': 0.3.7 '@types/async-lock': 1.1.1 '@types/chai': 4.2.0 '@types/chai-as-promised': 7.1.2 @@ -69,6 +70,7 @@ dependencies: '@types/xml2js': 0.4.4 '@types/yargs': 13.0.2 '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/eslint-plugin-tslint': 2.3.0_b840da7ae58bd563f8e3899e03f6a2da '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 abort-controller: 3.0.0 assert: 1.5.0 @@ -76,13 +78,13 @@ dependencies: atob: 2.1.2 azure-storage: 2.10.3 babel-runtime: 6.26.0 - binary-search-bounds: 2.0.3 + binary-search-bounds: 2.0.4 buffer: 5.4.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 chai-string: 1.5.0_chai@4.2.0 cross-env: 5.2.0 - crypto-hash: 1.1.0 + crypto-hash: 1.2.2 death: 1.1.0 debug: 4.1.1 delay: 4.3.0 @@ -93,7 +95,7 @@ dependencies: eslint-plugin-no-null: 1.0.2_eslint@6.2.1 eslint-plugin-no-only-tests: 2.3.1 eslint-plugin-promise: 4.2.1 - esm: 3.2.18 + esm: 3.2.25 events: 3.0.0 execa: 1.0.0 express: 4.17.1 @@ -139,7 +141,7 @@ dependencies: msal: 1.1.3 nise: 1.5.1 nock: 11.3.2 - node-abort-controller: 1.0.3 + node-abort-controller: 1.0.4 node-fetch: 2.6.0 npm-run-all: 4.1.5 nyc: 14.1.1 @@ -171,7 +173,7 @@ dependencies: rollup-plugin-terser: 5.1.1_rollup@1.20.1 rollup-plugin-uglify: 6.0.2_rollup@1.20.1 rollup-plugin-visualizer: 2.5.4_rollup@1.20.1 - semaphore: 1.0.5 + semaphore: 1.1.0 shx: 0.3.2 sinon: 7.4.1 source-map-support: 0.5.13 @@ -182,11 +184,12 @@ dependencies: ts-mocha: 6.0.0_mocha@6.2.0 ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 + tslint: 5.20.0_typescript@3.5.3 tunnel: 0.0.6 typedoc: 0.15.0 typescript: 3.5.3 uglify-js: 3.6.0 - universal-user-agent: 2.1.0 + universal-user-agent: 4.0.0 url: 0.11.0 util: 0.12.1 uuid: 3.3.3 @@ -201,19 +204,19 @@ dependencies: yarn: 1.17.3 lockfileVersion: 5.1 packages: - /@azure/abort-controller/1.0.0-preview.1: + /@azure/abort-controller/1.0.0-preview.2: dependencies: tslib: 1.10.0 dev: false resolution: - integrity: sha512-NnJqi6oHqt06Q2hz4nO1HO0QlyusBa3E/wezvn9flHEtl0IHYSmzGbtlb+MaAJ5GzxwqSevQ4q1+4B8fvVijOA== + integrity: sha512-pd2MVcHaitEC0ZoeixSTkJqTJFkIUVglosV//P2C/VwLg+9moGyx/P+WH2onDYukEOL5CCEuF0LBDfnTeL0gVA== /@azure/amqp-common/1.0.0-preview.6_rhea-promise@0.1.15: dependencies: '@azure/ms-rest-nodeauth': 0.9.3 '@types/async-lock': 1.1.1 '@types/is-buffer': 2.0.0 async-lock: 1.2.2 - buffer: 5.4.0 + buffer: 5.4.3 debug: 3.2.6 events: 3.0.0 is-buffer: 2.0.3 @@ -264,46 +267,76 @@ packages: dev: false resolution: integrity: sha512-hMp0y+j/odkAyTa5TYewn4hUlFdEe3sR9uTd2Oq+se61RtuDsqM7UWrNNlyylPyjIENSZHJVWN7jte/jvvMN2Q== - /@azure/core-auth/1.0.0-preview.2: + /@azure/core-auth/1.0.0-preview.3: dependencies: - '@azure/abort-controller': 1.0.0-preview.1 + '@azure/abort-controller': 1.0.0-preview.2 tslib: 1.10.0 dev: false resolution: - integrity: sha512-QATxlKPP2Yld8+eg8Hz8mXmowlG/z9B53HTkjBz0oJIzR+dBm9HJY2bPnT7RB8nyqdnm8JpU2mIp8YVZZO6ubg== - /@azure/core-http/1.0.0-preview.2: + integrity: sha512-SUG/ccOMGjPVUwKvwAW6r543bd66UOHu66N/jycr0hMVLI/46TuMZJIMjA2AN2+Gc+IrxSXQeJbN2VBFiJBWvA== + /@azure/core-http/1.0.0-preview.3: dependencies: - '@azure/core-auth': 1.0.0-preview.2 + '@azure/abort-controller': 1.0.0-preview.2 + '@azure/core-auth': 1.0.0-preview.3 + '@azure/core-tracing': 1.0.0-preview.2 + '@types/node-fetch': 2.5.1 '@types/tunnel': 0.0.1 - axios: 0.19.0 - form-data: 2.5.0 + form-data: 2.5.1 + node-fetch: 2.6.0 process: 0.11.10 tough-cookie: 3.0.1 tslib: 1.10.0 tunnel: 0.0.6 uuid: 3.3.3 - xml2js: 0.4.19 + xml2js: 0.4.22 dev: false resolution: - integrity: sha512-7zvbuMxwFjqvZ8knyEky+tWJYq6nK/pDIOI44nuCsdzdeCA8G9Ul3tXuQ+1lI4NOUfd2Scj8Ckgb4Xh9+ckOuw== + integrity: sha512-YxZPXG0xYRvBhkAtNVD18VG3i6JyS2dH7QtkiYoi9yAc/x7HUMcKg7FmOD/Nf/++OVGoTQcJ9QpG34MggWuHEQ== /@azure/core-paging/1.0.0-preview.1: dependencies: '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 dev: false resolution: integrity: sha512-mZHkadyAbhV1+brHEsWICnURW6E72D2HReM+8MWDn5oVJdlxD51w14PeqsOZC4UDYv4x2Eww5+PFRTEOrNB1Uw== + /@azure/core-paging/1.0.0-preview.2: + dependencies: + '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 + dev: false + resolution: + integrity: sha512-D0oiOmg82AnhTT3xkIyTpEhCesHtlpV2rTVVlCQmQPbfzAWh8eBZp1QAgNQcBdF6uXZrp69znpXSnICmtfH23Q== /@azure/core-tracing/1.0.0-preview.1: dependencies: tslib: 1.10.0 dev: false resolution: integrity: sha512-nDfxQopw7lfJG5N845BOS6Vcl84GcB1Q3BHKJAHghLOmdHQjV9Z92M4ziFAQ60UnOj2zrUefM6yDZcKjANCcyg== + /@azure/core-tracing/1.0.0-preview.2: + dependencies: + tslib: 1.10.0 + dev: false + resolution: + integrity: sha512-ID/kDVax0uYlw1HVBNsLv6JuE8NbgLUrKrmvVqyuvtbNk+Gk+IKbpUbrDMAoauDAd1CHifs+fkg210LD2JWSEQ== /@azure/cosmos-sign/1.0.2: dependencies: crypto-js: 3.1.9-1 dev: false resolution: integrity: sha512-+y3EDcbSFuieOKqw9VyaX7D13LB4LycQIdmLwSqFnSUO0mWl+RBLCKW3RL6XiyWOHRV2sMNT9vwGzwiFZI70vQ== + /@azure/eslint-plugin-azure-sdk/2.0.1_9e8391ca70fb0408a9da4393803aa477: + dependencies: + '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 + eslint: 6.2.1 + fast-levenshtein: 2.0.6 + glob: 7.1.4 + typescript: 3.6.3 + dev: false + engines: + node: '>=8.0.0' + peerDependencies: + '@typescript-eslint/parser': ^2.0.0 + eslint: ^6.1.0 + resolution: + integrity: sha512-HszGr6szVke1FOr07hy+JojKm36qh9n3IfYdehZRx7Wi19cY1EUmFq1PT5OasbNC/DoVqB3yx8Olfw4t5YBxVA== /@azure/event-hubs/2.1.1: dependencies: '@azure/amqp-common': 1.0.0-preview.6_rhea-promise@0.1.15 @@ -388,16 +421,16 @@ packages: dev: false resolution: integrity: sha512-aFHRw/IHhg3I9ZJW+Va4L+sCirFHMVIu6B7lFdL5mGLfG3xC5vDIdd957LRXFgy2OiKFRUC0QaKknd0YCsQIqA== - /@azure/storage-blob/12.0.0-preview.2: + /@azure/storage-blob/12.0.0-preview.3: dependencies: - '@azure/abort-controller': 1.0.0-preview.1 - '@azure/core-http': 1.0.0-preview.2 - '@azure/core-paging': 1.0.0-preview.1 + '@azure/abort-controller': 1.0.0-preview.2 + '@azure/core-http': 1.0.0-preview.3 + '@azure/core-paging': 1.0.0-preview.2 events: 3.0.0 tslib: 1.10.0 dev: false resolution: - integrity: sha512-YOZ3l065gmnaLdcpkyY+C02x2yi9XFo5ARZQGtoDMUz7VD+QzIbDwWsYlWOArVEm5Dxhl3v1zKJ1V6bi06iHEQ== + integrity: sha512-vbxCCy1VZuuLHsEFgmQK9+dtyuUjKB2+/u+AiVfQPwp4X1K7t2JbpfOd6jFEIvng7qOFJCftLr65x0UwbY085A== /@babel/code-frame/7.5.5: dependencies: '@babel/highlight': 7.5.0 @@ -790,6 +823,12 @@ packages: dev: false resolution: integrity: sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw== + /@types/node-fetch/2.5.1: + dependencies: + '@types/node': 8.10.54 + dev: false + resolution: + integrity: sha512-nYsC20tHanaNa4coFvCDcuIvtdvu8YkQz0XQOoBHL1X1y1QxeNe73dg1PaLGqsJNWiVwK0bjn5Jf+ZQpE6acJg== /@types/node/12.7.2: dev: false resolution: @@ -806,6 +845,10 @@ packages: dev: false resolution: integrity: sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ== + /@types/node/8.10.54: + dev: false + resolution: + integrity: sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== /@types/node/8.5.8: dev: false resolution: @@ -945,6 +988,22 @@ packages: dev: false resolution: integrity: sha1-LrHQCl5Ow/pYx2r94S4YK2bcXBw= + /@typescript-eslint/eslint-plugin-tslint/2.3.0_b840da7ae58bd563f8e3899e03f6a2da: + dependencies: + '@typescript-eslint/experimental-utils': 2.3.0_eslint@6.2.1 + eslint: 6.2.1 + lodash.memoize: 4.1.2 + tslint: 5.20.0_typescript@3.5.3 + typescript: 3.5.3 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 + tslint: ^5.0.0 + typescript: '*' + resolution: + integrity: sha512-dhkJtS40dkjPcYlTMNWRMsjz6zOTeT8ZTyNeNZqibc3HfD51LoPj6oYVWrngc4aVCzw/FabEZVu+gRKg+lvlDg== /@typescript-eslint/eslint-plugin/2.0.0_3cafee28902d96627d4743e014bc28ff: dependencies: '@typescript-eslint/experimental-utils': 2.0.0_eslint@6.2.1 @@ -1007,6 +1066,19 @@ packages: eslint: '*' resolution: integrity: sha512-ZJGLYXa4nxjNzomaEk1qts38B/vludg2LOM7dRc7SppEKsMPTS1swaTKS/pom+x4d/luJGoG00BDIss7PR1NQA== + /@typescript-eslint/experimental-utils/2.3.0_eslint@6.2.1: + dependencies: + '@types/json-schema': 7.0.3 + '@typescript-eslint/typescript-estree': 2.3.0 + eslint: 6.2.1 + eslint-scope: 5.0.0 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + peerDependencies: + eslint: '*' + resolution: + integrity: sha512-ry+fgd0Hh33LyzS30bIhX/a1HJpvtnecjQjWxxsZTavrRa1ymdmX7tz+7lPrPAxB018jnNzwNtog6s3OhxPTAg== /@typescript-eslint/parser/2.0.0_eslint@6.2.1: dependencies: '@types/eslint-visitor-keys': 1.0.0 @@ -1055,6 +1127,17 @@ packages: node: ^8.10.0 || ^10.13.0 || >=11.10.1 resolution: integrity: sha512-482ErJJ7QYghBh+KA9G+Fwcuk/PLTy+9NBMz8S+6UFrUUnVvHRNAL7I70kdws2te0FBYEZW7pkDaXoT+y8UARw== + /@typescript-eslint/typescript-estree/2.3.0: + dependencies: + glob: 7.1.4 + is-glob: 4.0.1 + lodash.unescape: 4.0.1 + semver: 6.3.0 + dev: false + engines: + node: ^8.10.0 || ^10.13.0 || >=11.10.1 + resolution: + integrity: sha512-WBxfwsTeCOsmQ7cLjow7lgysviBKUW34npShu7dxJYUQCbSG5nfZWZTgmQPKEc+3flpbSM7tjXjQOgETYp+njQ== /@webassemblyjs/ast/1.8.5: dependencies: '@webassemblyjs/helper-module-context': 1.8.5 @@ -2299,6 +2382,10 @@ packages: dev: false resolution: integrity: sha1-X/hhbW3SylOIvIWy1iZuK52lAtw= + /binary-search-bounds/2.0.4: + dev: false + resolution: + integrity: sha512-2hg5kgdKql5ClF2ErBcSx0U5bnl5hgS4v7wMnLFodyR47yMtj2w+UAZB+0CiqyHct2q543i7Bi4/aMIegorCCg== /blob/0.0.5: dev: false resolution: @@ -2496,6 +2583,12 @@ packages: dev: false resolution: integrity: sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== + /builtin-modules/1.1.1: + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= /builtin-modules/3.1.0: dev: false engines: @@ -3157,6 +3250,12 @@ packages: node: '>=8' resolution: integrity: sha512-5DWmfCxQZHWocCpkOXVFmfYj7v5vZXF3ZNzMeyyJ6OzGfDTEEOm2CWA8KzZ578eA7j5VPCLOdGjOU8sGgi8BYw== + /crypto-hash/1.2.2: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-rXXMXepuKg9gIfqE7I1jtVa6saLhzIkDQ2u3kTGUWYiUGsHcUa3LTsfrjPEdOY8kxKlryQtsOmJOU0F23yRJTg== /crypto-js/3.1.9-1: dev: false resolution: @@ -3909,6 +4008,12 @@ packages: node: '>=6' resolution: integrity: sha512-1UENjnnI37UDp7KuOqKYjfqdaMim06eBWnDv37smaxTIzDl0ZWnlgoXwsVwD9+Lidw+q/f1gUf2diVMDCycoVw== + /esm/3.2.25: + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== /espree/6.1.0: dependencies: acorn: 7.0.0 @@ -4433,6 +4538,16 @@ packages: node: '>= 0.12' resolution: integrity: sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== + /form-data/2.5.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.24 + dev: false + engines: + node: '>= 0.12' + resolution: + integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== /forwarded/0.1.2: dev: false engines: @@ -6271,6 +6386,10 @@ packages: dev: false resolution: integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA= + /lodash.memoize/4.1.2: + dev: false + resolution: + integrity: sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= /lodash.once/4.1.1: dev: false resolution: @@ -6963,6 +7082,10 @@ packages: dev: false resolution: integrity: sha512-w07Dwqd/SWv9Lqrlhlx3mo4i4EWsuN3majbIIj4d6twBWGZUKtB9zvT9W+D5Rko56uas55CLO0YZ4zMrf6AKMw== + /node-abort-controller/1.0.4: + dev: false + resolution: + integrity: sha512-7cNtLKTAg0LrW3ViS2C7UfIzbL3rZd8L0++5MidbKqQVJ8yrH6+1VRSHl33P0ZjBTbOJd37d9EYekvHyKkB0QQ== /node-environment-flags/1.0.5: dependencies: object.getownpropertydescriptors: 2.0.3 @@ -8704,6 +8827,12 @@ packages: node: '>=0.8.0' resolution: integrity: sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA= + /semaphore/1.1.0: + dev: false + engines: + node: '>=0.8.0' + resolution: + integrity: sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== /semver-greatest-satisfied-range/1.1.0: dependencies: sver-compat: 1.5.0 @@ -9704,6 +9833,39 @@ packages: dev: false resolution: integrity: sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + /tslint/5.20.0_typescript@3.5.3: + dependencies: + '@babel/code-frame': 7.5.5 + builtin-modules: 1.1.1 + chalk: 2.4.2 + commander: 2.20.0 + diff: 4.0.1 + glob: 7.1.4 + js-yaml: 3.13.1 + minimatch: 3.0.4 + mkdirp: 0.5.1 + resolve: 1.12.0 + semver: 5.7.1 + tslib: 1.10.0 + tsutils: 2.29.0_typescript@3.5.3 + typescript: 3.5.3 + dev: false + engines: + node: '>=4.8.0' + hasBin: true + peerDependencies: + typescript: '>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev' + resolution: + integrity: sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g== + /tsutils/2.29.0_typescript@3.5.3: + dependencies: + tslib: 1.10.0 + typescript: 3.5.3 + dev: false + peerDependencies: + typescript: '>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev' + resolution: + integrity: sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== /tsutils/3.17.1_typescript@3.5.3: dependencies: tslib: 1.10.0 @@ -9821,6 +9983,13 @@ packages: hasBin: true resolution: integrity: sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw== + /typescript/3.6.3: + dev: false + engines: + node: '>=4.2.0' + hasBin: true + resolution: + integrity: sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw== /uglify-js/3.6.0: dependencies: commander: 2.20.0 @@ -9901,12 +10070,12 @@ packages: dev: false resolution: integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== - /universal-user-agent/2.1.0: + /universal-user-agent/4.0.0: dependencies: os-name: 3.1.0 dev: false resolution: - integrity: sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q== + integrity: sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA== /universalify/0.1.2: dev: false engines: @@ -9968,6 +10137,13 @@ packages: dev: false resolution: integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + /util.promisify/1.0.0: + dependencies: + define-properties: 1.1.3 + object.getownpropertydescriptors: 2.0.3 + dev: false + resolution: + integrity: sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== /util/0.10.3: dependencies: inherits: 2.0.1 @@ -10356,12 +10532,28 @@ packages: dev: false resolution: integrity: sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + /xml2js/0.4.22: + dependencies: + sax: 1.2.4 + util.promisify: 1.0.0 + xmlbuilder: 11.0.1 + dev: false + engines: + node: '>=4.0.0' + resolution: + integrity: sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw== /xmlbuilder/0.4.3: dev: false engines: node: '>=0.2.0' resolution: integrity: sha1-xGFLp04K0ZbmCcknLNnh3bKKilg= + /xmlbuilder/11.0.1: + dev: false + engines: + node: '>=4.0' + resolution: + integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== /xmlbuilder/8.2.2: dev: false engines: @@ -10681,7 +10873,7 @@ packages: dev: false name: '@rush-temp/app-configuration' resolution: - integrity: sha512-AsrRtW+zZhSvmerSwQd+BZLgQxuvS/a9QFiRjycytLD6nOKIqDfpBLjaPT2TbLmJ6geQ7hGpTZVPEAetB/wTew== + integrity: sha512-E7iNSp6sfIjCXmpK7lNDqAY00UoMz+ZZ4zgIO5v32Y78tx0D9dq+UrreQEytDR14GUwPyh3uLesptZMwADKlNg== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': @@ -10988,6 +11180,7 @@ packages: 'file:projects/cosmos.tgz_webpack@4.39.2': dependencies: '@azure/cosmos-sign': 1.0.2 + '@azure/eslint-plugin-azure-sdk': 2.0.1_9e8391ca70fb0408a9da4393803aa477 '@microsoft/api-extractor': 7.3.8 '@types/debug': 4.1.5 '@types/fast-json-stable-stringify': 2.0.0 @@ -11001,6 +11194,7 @@ packages: '@types/underscore': 1.9.2 '@types/uuid': 3.4.5 '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff + '@typescript-eslint/eslint-plugin-tslint': 2.3.0_b840da7ae58bd563f8e3899e03f6a2da '@typescript-eslint/parser': 2.0.0_eslint@6.2.1 abort-controller: 3.0.0 atob: 2.1.2 @@ -11045,9 +11239,10 @@ packages: source-map-support: 0.5.13 ts-node: 8.3.0_typescript@3.5.3 tslib: 1.10.0 + tslint: 5.20.0_typescript@3.5.3 typedoc: 0.15.0 typescript: 3.5.3 - universal-user-agent: 2.1.0 + universal-user-agent: 4.0.0 uuid: 3.3.3 dev: false id: 'file:projects/cosmos.tgz' @@ -11055,7 +11250,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-1EcBFBLV9RPghS3tRfctehM8wXq4kGxl9ww0O6c+PqDwulLNJxnRGGd9mfOCm5/1LT6bEEQB7im+Fqxp+XcJOw== + integrity: sha512-hJJjJj86BUBSS228e9VU4XteZDdYMSqrPOGC+woAZvpX6dfwyZbZSfKAscourcyo9RaWeFZjP9aPCeibqmuzqA== tarball: 'file:projects/cosmos.tgz' version: 0.0.0 'file:projects/event-hubs.tgz': @@ -11131,7 +11326,7 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-n99KsSk9JmZJ3GxLYLDkoqsrNx9ySKRAMpN11aexaw6MiG6phFl3g52aqvA6XRLfcxtnnK5Wi53UvaaiHDKnCA== + integrity: sha512-dMpcMQmTDQu5ziIUmDs5eCdZ1kJhXXrIEbf0QO4SkJY06TsJc5MR1Qgb7X7OZaOhOAMlGcT1BceOkCT478tjWA== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -11252,7 +11447,7 @@ packages: dev: false name: '@rush-temp/eventhubs-checkpointstore-blob' resolution: - integrity: sha512-ti5aGtIrZB4gYyuqm+qC47KOAHJC8hAVDaULUVhxiJBQROi+zBJvkQJAfwkOftY6UCLFTzFgW9bvTvQIyhTUoQ== + integrity: sha512-hoS0oalZm7WOQ3YNGBakiuzU+zGVjAJHAaUSR5RiazFPaBMYmnbwr4epZXQRFi0FOEz5oDw+fhaoCZVi9rJYLQ== tarball: 'file:projects/eventhubs-checkpointstore-blob.tgz' version: 0.0.0 'file:projects/identity.tgz': @@ -11372,7 +11567,7 @@ packages: dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-avax/uC8PPEm+kWOCmP06q0GvKDMnkTcANMIzYL/Ric+WjWF0kL9d1h5znhDGMRSK3r3jH+Udl0xf95EE9AQ0w== + integrity: sha512-foswxnaf00WMfmdCSMw01QGa2w9Ax7smZs044wX3NyQET4LZhSG1Bik/605iK3W7JVHHnx059MjxT+vczT3fsw== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -11441,7 +11636,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-rlialD+RKXVu8yAG96jyTXm4yxVHJC3pOeBbqgorhU7uV+1SI0v3nIpS42lgY8BD+i128NGVrvVx5xuH/N6wVg== + integrity: sha512-Mpa4sYDsg5BGbzo+S+KguWfDnjW2UPuBW+1pRkXTTnDibuWH/TbYFM/aq/Y2jrA7DNv9IZH/ku0V0qPS6NzPGg== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -11508,7 +11703,7 @@ packages: dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-jW8cvugQoElGaP1cCJedFVyf2cIQss/IHFuQLz9viGplBh19otACdCbhppaNmDr+Lc92B3Nr9ikMcryU2I2SdQ== + integrity: sha512-PN1/U0hdyQRpbzbGMitJfvE2Y4z8xMtIyLCvBITT2pdIgdNgla3bHGncgbwNrPLG8kEHVPBMf+gRcZqFQaBxxQ== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/service-bus.tgz': @@ -11901,11 +12096,13 @@ specifiers: '@azure/amqp-common': 1.0.0-preview.6 '@azure/arm-servicebus': ^3.2.0 '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 - '@azure/cosmos-sign': 1.0.2 + '@azure/cosmos-sign': ^1.0.2 + '@azure/eslint-plugin-azure-sdk': ^2.0.1 + '@azure/event-hubs': ^2.1.1 '@azure/logger-js': ^1.0.2 '@azure/ms-rest-js': ^2.0.0 '@azure/ms-rest-nodeauth': ^0.9.2 - '@azure/storage-blob': 12.0.0-preview.2 + '@azure/storage-blob': 12.0.0-preview.3 '@microsoft/api-extractor': ^7.1.5 '@rush-temp/abort-controller': 'file:./projects/abort-controller.tgz' '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' @@ -11931,7 +12128,6 @@ specifiers: '@rush-temp/template': 'file:./projects/template.tgz' '@rush-temp/test-utils-recorder': 'file:./projects/test-utils-recorder.tgz' '@rush-temp/testhub': 'file:./projects/testhub.tgz' - '@trust/keyto': 0.3.7 '@types/async-lock': ^1.1.0 '@types/chai': ^4.1.6 '@types/chai-as-promised': ^7.1.0 @@ -11939,7 +12135,7 @@ specifiers: '@types/debug': ^4.1.4 '@types/dotenv': ^6.1.0 '@types/express': ^4.16.0 - '@types/fast-json-stable-stringify': 2.0.0 + '@types/fast-json-stable-stringify': ^2.0.0 '@types/fetch-mock': ^7.3.1 '@types/fs-extra': ^8.0.0 '@types/glob': ^7.1.1 @@ -11968,20 +12164,21 @@ specifiers: '@types/xml2js': ^0.4.3 '@types/yargs': ^13.0.0 '@typescript-eslint/eslint-plugin': ^2.0.0 + '@typescript-eslint/eslint-plugin-tslint': ~2.3.0 '@typescript-eslint/parser': ^2.0.0 - abort-controller: 3.0.0 + abort-controller: ^3.0.0 assert: ^1.4.1 async-lock: ^1.1.3 - atob: 2.1.2 + atob: ^2.1.2 azure-storage: ^2.10.2 babel-runtime: ^6.26.0 - binary-search-bounds: 2.0.3 + binary-search-bounds: ^2.0.3 buffer: ^5.2.1 chai: ^4.2.0 chai-as-promised: ^7.1.1 chai-string: ^1.5.0 cross-env: ^5.2.0 - crypto-hash: 1.1.0 + crypto-hash: ^1.1.0 death: ^1.1.0 debug: ^4.1.1 delay: ^4.2.0 @@ -11992,11 +12189,11 @@ specifiers: eslint-plugin-no-null: ^1.0.2 eslint-plugin-no-only-tests: ^2.3.0 eslint-plugin-promise: ^4.1.1 - esm: 3.2.18 + esm: ^3.2.18 events: ^3.0.0 - execa: 1.0.0 + execa: ^1.0.0 express: ^4.16.3 - fast-json-stable-stringify: 2.0.0 + fast-json-stable-stringify: ^2.0.0 fetch-mock: ^7.3.9 form-data: ^2.5.0 fs-extra: ^8.1.0 @@ -12038,13 +12235,13 @@ specifiers: msal: ^1.0.2 nise: ^1.4.10 nock: ^11.3.2 - node-abort-controller: 1.0.3 + node-abort-controller: ^1.0.3 node-fetch: ^2.6.0 npm-run-all: ^4.1.5 nyc: ^14.0.0 path-browserify: ^1.0.0 prettier: ^1.16.4 - priorityqueuejs: 1.0.0 + priorityqueuejs: ^1.0.0 process: ^0.11.10 promise: ^8.0.3 proxy-agent: 3.0.3 @@ -12070,7 +12267,7 @@ specifiers: rollup-plugin-terser: ^5.1.1 rollup-plugin-uglify: ^6.0.0 rollup-plugin-visualizer: ^2.0.0 - semaphore: 1.0.5 + semaphore: ^1.0.5 shx: ^0.3.2 sinon: ^7.1.0 source-map-support: ^0.5.9 @@ -12081,11 +12278,12 @@ specifiers: ts-mocha: ^6.0.0 ts-node: ^8.3.0 tslib: ^1.9.3 + tslint: ^5.0.0 tunnel: ^0.0.6 typedoc: ^0.15.0 typescript: ^3.2.2 uglify-js: ^3.4.9 - universal-user-agent: 2.1.0 + universal-user-agent: ^4.0.0 url: ^0.11.0 util: ^0.12.1 uuid: ^3.3.2 From 052f89935ae38fa0d63e3f494cbc77cb7afdaa22 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 24 Sep 2019 18:01:07 -0700 Subject: [PATCH 31/72] Address comments --- sdk/core/core-http/lib/atomError.ts | 18 +++ .../core-http/lib/httpOperationResponse.ts | 5 - sdk/core/core-http/lib/util/atomXmlHelper.ts | 134 +++++++++--------- sdk/core/core-http/package.json | 1 - .../policies/atomSerializationPolicyTests.ts | 8 +- 5 files changed, 88 insertions(+), 78 deletions(-) create mode 100644 sdk/core/core-http/lib/atomError.ts diff --git a/sdk/core/core-http/lib/atomError.ts b/sdk/core/core-http/lib/atomError.ts new file mode 100644 index 000000000000..9b2834134534 --- /dev/null +++ b/sdk/core/core-http/lib/atomError.ts @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Represents custom `Error` information returned by ATOM based services. + */ +export class AtomError extends Error { + code?: string; + statusCode?: number; + additionalProperties?: any; + requestId?: string; + + constructor(message: string) { + super(message); + this.additionalProperties = {}; + Object.setPrototypeOf(this, AtomError.prototype); + } +} diff --git a/sdk/core/core-http/lib/httpOperationResponse.ts b/sdk/core/core-http/lib/httpOperationResponse.ts index 26d325f712f5..3def9cbdcfae 100644 --- a/sdk/core/core-http/lib/httpOperationResponse.ts +++ b/sdk/core/core-http/lib/httpOperationResponse.ts @@ -52,11 +52,6 @@ export interface HttpOperationResponse extends HttpResponse { */ parsedBody?: any; - /** - * The error information in JSON or XML - */ - errorBody?: any; - /** * BROWSER ONLY * diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts index 69f4f7b6f55a..bd912c17c653 100644 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -5,6 +5,7 @@ import { Constants } from "./constants"; import { isString } from "./utils"; import { serializeJsonToAtomXml, deserializeAtomXmlToJson } from "./xml"; import { HttpOperationResponse } from "../httpOperationResponse"; +import { AtomError } from "../atomError"; export interface AtomXmlSerializer { serialize(resourceDataInJson: any): string; @@ -172,45 +173,41 @@ export async function deserializeAtomXmlResponse( response: HttpOperationResponse ): Promise { let atomResponseInJson: any; + let errorBody: any; try { if (response.bodyAsText) { atomResponseInJson = await deserializeAtomXmlToJson(response.bodyAsText); response.parsedBody = atomResponseInJson; } } catch (e) { - response.errorBody = { code: "ResponseNotInAtomXMLFormat" }; + errorBody = { code: "ResponseNotInAtomXMLFormat" }; return response; } // If received data is a non-valid HTTP response, the body is expected to contain error information if (response.status < 200 || response.status >= 300) { - response.errorBody = atomResponseInJson; - if (response.errorBody == undefined) { + errorBody = atomResponseInJson; + if (errorBody == undefined) { const HttpResponseCodes = Constants.HttpResponseCodes; const statusCode = response.status; const errorCode = isKnownResponseCode(statusCode) ? HttpResponseCodes[statusCode] : `UnrecognizedHttpResponseStatus: ${statusCode}`; - response.errorBody = { + errorBody = { code: errorCode }; - } else { - // Transform the error info in response body to a normalized one - const normalizedError = normalizeError(response); - response.errorBody = normalizedError; } } // Construct response with 'result' to be backward compatibile - const responseInCustomJson: any = { - error: response.errorBody ? response.errorBody : null, + const responseInCustomJson: { response: any; result: any } = { response: null, result: [] }; let isSuccessful = false; - if (responseInCustomJson.error == undefined) { + if (errorBody == undefined) { isSuccessful = true; const result = parseAtomResult(atomResponseInJson); if (result) { @@ -223,6 +220,9 @@ export async function deserializeAtomXmlResponse( } } responseInCustomJson.result = result; + } else { + // Transform the error info in response body to a normalized one + throw buildAtomError(errorBody, response); } responseInCustomJson.response = buildResponse( @@ -273,75 +273,71 @@ function setName(entry: XMLResponseInJSON, nameProperties: any): any { * @param errorBody * @param response */ -function normalizeError(response: HttpOperationResponse): any { - const errorBody: any = response.errorBody; +function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomError { if (isString(errorBody)) { return new Error(errorBody); - } else if (errorBody) { - const normalizedError: any = {}; - const odataErrorFormat = !!errorBody["odata.error"]; - const errorProperties = - errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; - - if (odataErrorFormat) { - Object.keys(errorProperties).forEach((property: string) => { - let value = null; - if ( - property === Constants.ODATA_ERROR_MESSAGE && - !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) - ) { - if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { - value = - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; - } else { - value = "missing value in the message property of the odata error format"; - } + } + const normalizedError: any = {}; + const odataErrorFormat = !!errorBody["odata.error"]; + const errorProperties = + errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; + + if (odataErrorFormat) { + Object.keys(errorProperties).forEach((property: string) => { + let value = null; + if ( + property === Constants.ODATA_ERROR_MESSAGE && + !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + ) { + if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { + value = + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; } else { - value = errorProperties[property]; + value = "missing value in the message property of the odata error format"; } - normalizedError[property.toLowerCase()] = value; - }); - } else { - Object.keys(errorProperties).forEach((property: any) => { - { - let value = null; - if (property !== Constants.XML_METADATA_MARKER) { - if ( - errorProperties[property] && - errorProperties[property][Constants.XML_VALUE_MARKER] - ) { - value = errorProperties[property][Constants.XML_VALUE_MARKER]; - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + }); + } else { + Object.keys(errorProperties).forEach((property: any) => { + { + let value = null; + if (property !== Constants.XML_METADATA_MARKER) { + if (errorProperties[property] && errorProperties[property][Constants.XML_VALUE_MARKER]) { + value = errorProperties[property][Constants.XML_VALUE_MARKER]; + } else { + value = errorProperties[property]; } + normalizedError[property.toLowerCase()] = value; } - }); - } - let errorMessage = normalizedError.code; - if (normalizedError.detail) { - errorMessage += " - " + normalizedError.detail; - } + } + }); + } + let errorMessage = normalizedError.code; + if (normalizedError.detail) { + errorMessage += " - " + normalizedError.detail; + } - const errorObject: any = { code: errorMessage }; + const errorObject: AtomError = new AtomError( + `Error returned by service while performing the management operation` + ); + errorObject.code = errorMessage; - if (response) { - if (response.status) { - errorObject["statusCode"] = response.status; - } + if (response) { + if (response.status) { + errorObject["statusCode"] = response.status; + } - if (response.headers && response.headers.get("x-ms-request-id")) { - errorObject["requestId"] = response.headers.get("x-ms-request-id"); - } + if (response.headers && response.headers.get("x-ms-request-id")) { + errorObject["requestId"] = response.headers.get("x-ms-request-id"); } - Object.keys(normalizedError).forEach((property: string) => { - errorObject[property] = normalizedError[property]; - }); - return errorObject; } - - return undefined; + Object.keys(normalizedError).forEach((property: string) => { + errorObject.additionalProperties[property] = normalizedError[property]; + }); + return errorObject; } /** diff --git a/sdk/core/core-http/package.json b/sdk/core/core-http/package.json index 2ab35135ffb7..849fb7a53abf 100644 --- a/sdk/core/core-http/package.json +++ b/sdk/core/core-http/package.json @@ -115,7 +115,6 @@ "@azure/core-tracing": "1.0.0-preview.2", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.1", - "buffer": "^5.2.1", "form-data": "^2.5.0", "node-fetch": "^2.6.0", "process": "^0.11.10", diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 8b2ac5c063de..f275c3c94405 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -31,9 +31,11 @@ describe("atomSerializationPolicy", function() { }; const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); - const response = await policy.sendRequest(request); - assert.deepEqual(response.bodyAsText, `{ "simple": "JSONobject" }`); - assert.deepEqual(response.errorBody.code, "ResponseNotInAtomXMLFormat"); + try { + await policy.sendRequest(request); + } catch (err) { + assert.deepEqual(err.code, "ResponseNotInAtomXMLFormat"); + } }); it("with xml response body, application/xml content-type and AtomXMLOperationSpec", async function() { From 3e247e85798dd0693420a548bcb1622726ccebf9 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 25 Sep 2019 10:22:28 -0700 Subject: [PATCH 32/72] Address comments --- .../lib/policies/atomSerializationPolicy.ts | 2 +- sdk/core/core-http/lib/util/atomXmlHelper.ts | 73 ++++++++++--------- sdk/core/core-http/lib/util/xml.browser.ts | 20 ++--- sdk/core/core-http/lib/util/xml.ts | 3 +- .../policies/atomSerializationPolicyTests.ts | 3 +- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index e31b11f2099b..082b53df5f09 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -39,7 +39,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { request.atomXmlOperationSpec.serializer == undefined ) { throw new Error( - "atomXmlOperationSpec and atomXmlOperationSpec.serializer must be supplied on the requests when using this policy." + "Failed to send request in the AtomSerializationPolicy due to missing serializer." ); } diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts index bd912c17c653..d17f4172c2e0 100644 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ b/sdk/core/core-http/lib/util/atomXmlHelper.ts @@ -8,7 +8,7 @@ import { HttpOperationResponse } from "../httpOperationResponse"; import { AtomError } from "../atomError"; export interface AtomXmlSerializer { - serialize(resourceDataInJson: any): string; + serialize(requestBodyInJson: any): string; deserialize(response: HttpOperationResponse): Promise; } @@ -71,18 +71,29 @@ export function serializeToAtomXmlRequest( * @param {object} atomResponseInJson * */ function parseAtomResult( - atomResponseInJson: any + atomResponseInJson: any, + nameProperties: string[] ): XMLResponseInJSON[] | XMLResponseInJSON | undefined { + let result: any; if (!atomResponseInJson) { return; } if (atomResponseInJson.feed) { - return parseFeedResult(atomResponseInJson.feed); + result = parseFeedResult(atomResponseInJson.feed); + } else if (atomResponseInJson.entry) { + result = parseEntryResult(atomResponseInJson.entry); } - if (atomResponseInJson.entry) { - return parseEntryResult(atomResponseInJson.entry); + if (result) { + if (Array.isArray(result)) { + result.forEach((entry: XMLResponseInJSON) => { + setName(entry, nameProperties); + }); + } else { + setName(result, nameProperties); + } + return result; } throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); @@ -180,8 +191,7 @@ export async function deserializeAtomXmlResponse( response.parsedBody = atomResponseInJson; } } catch (e) { - errorBody = { code: "ResponseNotInAtomXMLFormat" }; - return response; + throw buildAtomError({ code: "ResponseNotInAtomXMLFormat" }, response); } // If received data is a non-valid HTTP response, the body is expected to contain error information @@ -190,12 +200,23 @@ export async function deserializeAtomXmlResponse( if (errorBody == undefined) { const HttpResponseCodes = Constants.HttpResponseCodes; const statusCode = response.status; - const errorCode = isKnownResponseCode(statusCode) - ? HttpResponseCodes[statusCode] - : `UnrecognizedHttpResponseStatus: ${statusCode}`; - errorBody = { - code: errorCode - }; + if (isKnownResponseCode(statusCode)) { + throw buildAtomError( + { + code: HttpResponseCodes[statusCode] + }, + response + ); + } else { + throw buildAtomError( + { + code: `UnrecognizedHttpResponseStatus: ${statusCode}` + }, + response + ); + } + } else { + throw buildAtomError(errorBody, response); } } @@ -205,28 +226,11 @@ export async function deserializeAtomXmlResponse( result: [] }; - let isSuccessful = false; + const result = parseAtomResult(atomResponseInJson, nameProperties); - if (errorBody == undefined) { - isSuccessful = true; - const result = parseAtomResult(atomResponseInJson); - if (result) { - if (Array.isArray(result)) { - result.forEach((entry: XMLResponseInJSON) => { - setName(entry, nameProperties); - }); - } else { - setName(result, nameProperties); - } - } - responseInCustomJson.result = result; - } else { - // Transform the error info in response body to a normalized one - throw buildAtomError(errorBody, response); - } + responseInCustomJson.result = result; responseInCustomJson.response = buildResponse( - isSuccessful, response.parsedBody, response.headers.rawHeaders(), response.status @@ -344,15 +348,14 @@ function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomEr * Builds a response object with normalized key names. * @ignore * - * @param isSuccessful Boolean value indicating if the request was successful * @param body The response body. * @param headers The response headers. * @param statusCode The response status code. */ -function buildResponse(isSuccessful: boolean, body: any, headers: any, statusCode: number) { +function buildResponse(body: any, headers: any, statusCode: number) { return { - isSuccessful: isSuccessful, + isSuccessful: true, statusCode: statusCode, body: body, headers: headers diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index f0b6995abd2a..2f172e4c5d68 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -108,6 +108,16 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { ); } +function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { + const result = []; + for (const key of Object.keys(attrs)) { + const attr = doc.createAttribute(key); + attr.value = attrs[key].toString(); + result.push(attr); + } + return result; +} + function buildNode(doc: any, obj: any, elementName: string): Node[] { if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { const elem = doc.createElement(elementName); @@ -140,16 +150,6 @@ function buildNode(doc: any, obj: any, elementName: string): Node[] { } } -function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { - const result = []; - for (const key of Object.keys(attrs)) { - const attr = doc.createAttribute(key); - attr.value = attrs[key].toString(); - result.push(attr); - } - return result; -} - export function deserializeAtomXmlToJson(body: string): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 57a17483adc4..1f26d0cf2efa 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -101,7 +101,8 @@ function _getDefaultSettings(): any { /** * @ignore - * @param str Helper utility to clean up unintended characters that get appended by OS. + * Helper utility to clean up unintended characters that get appended by OS. + * @param str */ function _removeBOM(str: any) { if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index f275c3c94405..bf7354afb583 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -16,7 +16,7 @@ import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; describe("atomSerializationPolicy", function() { - it("should return an error if receiving a non-XML response body", async function() { + it("should throw an error if receiving a non-XML response body", async function() { const request: WebResource = createRequest({ serializer: new MockSerializer() }); @@ -33,6 +33,7 @@ describe("atomSerializationPolicy", function() { const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); try { await policy.sendRequest(request); + assert.deepEqual(true, false, "Error must be thrown"); } catch (err) { assert.deepEqual(err.code, "ResponseNotInAtomXMLFormat"); } From c9a847ec388d822730d93cabc0ae90e08a6d796a Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 25 Sep 2019 20:04:29 -0700 Subject: [PATCH 33/72] Refactor and address comments --- sdk/core/core-http/lib/atomError.ts | 75 ++++ .../core-http/lib/atomXmlOperationSpec.ts | 2 +- sdk/core/core-http/lib/atomXmlSerializer.ts | 10 + sdk/core/core-http/lib/coreHttp.ts | 8 +- .../lib/policies/atomSerializationPolicy.ts | 12 +- sdk/core/core-http/lib/util/atomXmlHelper.ts | 363 ------------------ sdk/core/core-http/lib/util/xml.ts | 4 +- .../policies/atomSerializationPolicyTests.ts | 85 ++-- 8 files changed, 146 insertions(+), 413 deletions(-) create mode 100644 sdk/core/core-http/lib/atomXmlSerializer.ts delete mode 100644 sdk/core/core-http/lib/util/atomXmlHelper.ts diff --git a/sdk/core/core-http/lib/atomError.ts b/sdk/core/core-http/lib/atomError.ts index 9b2834134534..84a7a4ba3991 100644 --- a/sdk/core/core-http/lib/atomError.ts +++ b/sdk/core/core-http/lib/atomError.ts @@ -1,5 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { Constants } from "./util/constants"; +import { isString } from "./util/utils"; +import { HttpOperationResponse } from "./httpOperationResponse"; /** * Represents custom `Error` information returned by ATOM based services. @@ -16,3 +19,75 @@ export class AtomError extends Error { Object.setPrototypeOf(this, AtomError.prototype); } } + +/** + * + * Utility to help construct the normalized `AtomError` object based on given `errorBody` + * data and other data present in the received `response` object. + * + * @param errorBody + * @param response + */ +export function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomError { + if (isString(errorBody)) { + return new Error(errorBody); + } + const normalizedError: any = {}; + const odataErrorFormat = !!errorBody["odata.error"]; + const errorProperties = + errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; + + if (odataErrorFormat) { + Object.keys(errorProperties).forEach((property: string) => { + let value = null; + if ( + property === Constants.ODATA_ERROR_MESSAGE && + !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + ) { + if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { + value = + errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; + } else { + value = "missing value in the message property of the odata error format"; + } + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + }); + } else { + Object.keys(errorProperties).forEach((property: any) => { + { + let value = null; + if (property !== Constants.XML_METADATA_MARKER) { + if (errorProperties[property] && errorProperties[property][Constants.XML_VALUE_MARKER]) { + value = errorProperties[property][Constants.XML_VALUE_MARKER]; + } else { + value = errorProperties[property]; + } + normalizedError[property.toLowerCase()] = value; + } + } + }); + } + let errorMessage = normalizedError.code; + if (normalizedError.detail) { + errorMessage += " - " + normalizedError.detail; + } + + const errorObject: AtomError = new AtomError(`ATOM Service Error: ${errorMessage}`); + + if (response) { + if (response.status) { + errorObject["statusCode"] = response.status; + } + + if (response.headers && response.headers.get("x-ms-request-id")) { + errorObject["requestId"] = response.headers.get("x-ms-request-id"); + } + } + Object.keys(normalizedError).forEach((property: string) => { + errorObject.additionalProperties[property] = normalizedError[property]; + }); + return errorObject; +} diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 2744b7efc465..3f60589df70e 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -1,4 +1,4 @@ -import { AtomXmlSerializer } from "./util/atomXmlHelper"; +import { AtomXmlSerializer } from "./atomXmlSerializer"; export interface AtomXmlOperationSpec { /** diff --git a/sdk/core/core-http/lib/atomXmlSerializer.ts b/sdk/core/core-http/lib/atomXmlSerializer.ts new file mode 100644 index 000000000000..fa5654def9e9 --- /dev/null +++ b/sdk/core/core-http/lib/atomXmlSerializer.ts @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { HttpOperationResponse } from "./httpOperationResponse"; + +export interface AtomXmlSerializer { + serialize(requestBodyInJson: any): string; + + deserialize(response: HttpOperationResponse): Promise; +} diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index e84355370232..e312f5a47f0a 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,10 +107,8 @@ export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { - AtomXmlSerializer, - serializeToAtomXmlRequest, - deserializeAtomXmlResponse -} from "./util/atomXmlHelper"; +export { AtomXmlSerializer } from "./atomXmlSerializer"; +export { deserializeAtomXmlToJson, serializeJsonToAtomXml } from "./util/xml"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; +export { buildAtomError, AtomError } from "./atomError"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 082b53df5f09..8feaa0d38832 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,7 +9,9 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { AtomXmlSerializer } from "../util/atomXmlHelper"; +import { AtomXmlSerializer } from "../atomXmlSerializer"; +import { buildAtomError } from "../atomError"; +import { deserializeAtomXmlToJson } from "../util/xml"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -51,6 +53,14 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); + try { + if (response.bodyAsText) { + response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); + } + } catch (e) { + throw buildAtomError({ code: "ResponseNotInAtomXMLFormat" }, response); + } + return await serializer.deserialize(response); } } diff --git a/sdk/core/core-http/lib/util/atomXmlHelper.ts b/sdk/core/core-http/lib/util/atomXmlHelper.ts deleted file mode 100644 index d17f4172c2e0..000000000000 --- a/sdk/core/core-http/lib/util/atomXmlHelper.ts +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { Constants } from "./constants"; -import { isString } from "./utils"; -import { serializeJsonToAtomXml, deserializeAtomXmlToJson } from "./xml"; -import { HttpOperationResponse } from "../httpOperationResponse"; -import { AtomError } from "../atomError"; - -export interface AtomXmlSerializer { - serialize(requestBodyInJson: any): string; - - deserialize(response: HttpOperationResponse): Promise; -} - -/** - * @ignore - * Type representing the JSON representation of XML request data - */ -interface XMLRequestInJSON { - [key: string]: { - $: { xmlns: string }; - [key: string]: any; - }; -} - -/** - * @ignore - * Type representing the JSON representation of XML response data - */ -interface XMLResponseInJSON { - [key: string]: any; -} - -/** - * Serializes input information to construct the Atom XML request - * @param resourceName - * @param resource - * @param properties - * @param xmlNamespace - */ -export function serializeToAtomXmlRequest( - resourceName: string, - resource: any, - properties: string[], - xmlNamespace: string -): string { - const content: XMLRequestInJSON = {}; - content[resourceName] = { - $: { - xmlns: xmlNamespace - } - }; - - if (resource) { - // Sort properties according to what is allowed by the service - properties.forEach((property: string) => { - if (resource[property] !== undefined) { - content[resourceName][property] = resource[property]; - } - }); - } - - return serializeJsonToAtomXml(content); -} - -/** - * @ignore - * Utility to deserialize the given JSON content even further based on - * if it's a single `entry` or `feed` - * @param {object} atomResponseInJson - * */ -function parseAtomResult( - atomResponseInJson: any, - nameProperties: string[] -): XMLResponseInJSON[] | XMLResponseInJSON | undefined { - let result: any; - if (!atomResponseInJson) { - return; - } - - if (atomResponseInJson.feed) { - result = parseFeedResult(atomResponseInJson.feed); - } else if (atomResponseInJson.entry) { - result = parseEntryResult(atomResponseInJson.entry); - } - - if (result) { - if (Array.isArray(result)) { - result.forEach((entry: XMLResponseInJSON) => { - setName(entry, nameProperties); - }); - } else { - setName(result, nameProperties); - } - return result; - } - - throw new Error("Unrecognized result: " + JSON.stringify(atomResponseInJson)); -} - -/** - * @ignore - * Utility to help parse given `entry` result - * @param entry - */ -function parseEntryResult(entry: any): XMLResponseInJSON | undefined { - let result: XMLResponseInJSON; - - if ( - typeof entry !== "object" || - entry == null || - typeof entry.content !== "object" || - entry.content == null - ) { - return undefined; - } - - const contentElementNames = Object.keys(entry.content).filter(function(key) { - return key !== Constants.XML_METADATA_MARKER; - }); - - if (contentElementNames && contentElementNames[0]) { - const contentRootElementName = contentElementNames[0]; - delete entry.content[contentRootElementName][Constants.XML_METADATA_MARKER]; - result = entry.content[contentRootElementName]; - - if (result) { - if (entry[Constants.XML_METADATA_MARKER]) { - result[Constants.ATOM_METADATA_MARKER] = entry[Constants.XML_METADATA_MARKER]; - } else { - result[Constants.ATOM_METADATA_MARKER] = {}; - } - - result[Constants.ATOM_METADATA_MARKER]["ContentRootElement"] = contentRootElementName; - - Object.keys(entry).forEach((property: string) => { - if (property !== "content" && property !== Constants.XML_METADATA_MARKER) { - result[Constants.ATOM_METADATA_MARKER][property] = entry[property]; - } - }); - - return result; - } - } - - return undefined; -} - -/** - * @ignore - * Utility to help parse given `feed` result - * @param feed - */ -function parseFeedResult(feed: any): XMLResponseInJSON[] { - const result = []; - if (typeof feed === "object" && feed != null && feed.entry) { - if (Array.isArray(feed.entry)) { - feed.entry.forEach((entry: any) => { - const parsedEntryResult = parseEntryResult(entry); - if (parsedEntryResult) { - result.push(parsedEntryResult); - } - }); - } else { - const parsedEntryResult = parseEntryResult(feed.entry); - if (parsedEntryResult) { - result.push(parsedEntryResult); - } - } - } - return result; -} - -/** - * Transforms response to contain the parsed data. - * @param nameProperties The set of 'name' properties to be constructed on the - * resultant object e.g., QueueName, TopicName, etc. - * @param response - * @param shouldParseResponse - */ -export async function deserializeAtomXmlResponse( - nameProperties: string[], - response: HttpOperationResponse -): Promise { - let atomResponseInJson: any; - let errorBody: any; - try { - if (response.bodyAsText) { - atomResponseInJson = await deserializeAtomXmlToJson(response.bodyAsText); - response.parsedBody = atomResponseInJson; - } - } catch (e) { - throw buildAtomError({ code: "ResponseNotInAtomXMLFormat" }, response); - } - - // If received data is a non-valid HTTP response, the body is expected to contain error information - if (response.status < 200 || response.status >= 300) { - errorBody = atomResponseInJson; - if (errorBody == undefined) { - const HttpResponseCodes = Constants.HttpResponseCodes; - const statusCode = response.status; - if (isKnownResponseCode(statusCode)) { - throw buildAtomError( - { - code: HttpResponseCodes[statusCode] - }, - response - ); - } else { - throw buildAtomError( - { - code: `UnrecognizedHttpResponseStatus: ${statusCode}` - }, - response - ); - } - } else { - throw buildAtomError(errorBody, response); - } - } - - // Construct response with 'result' to be backward compatibile - const responseInCustomJson: { response: any; result: any } = { - response: null, - result: [] - }; - - const result = parseAtomResult(atomResponseInJson, nameProperties); - - responseInCustomJson.result = result; - - responseInCustomJson.response = buildResponse( - response.parsedBody, - response.headers.rawHeaders(), - response.status - ); - - response.parsedBody = responseInCustomJson; - return response; -} - -function isKnownResponseCode( - statusCode: number -): statusCode is keyof typeof Constants.HttpResponseCodes { - return !!(Constants.HttpResponseCodes as { [statusCode: number]: string })[statusCode]; -} - -/** - * @ignore - * Extracts the applicable entity name(s) from the URL based on the known structure - * and instantiates the corresponding name properties to the deserialized response - * - * For instance, following is the URL structure for when creating a rule - * `//Subscriptions//Rules/` - * - * @param entry - * @param nameProperties - */ -function setName(entry: XMLResponseInJSON, nameProperties: any): any { - if (entry[Constants.ATOM_METADATA_MARKER]) { - const parsedUrl = new URL(entry[Constants.ATOM_METADATA_MARKER].id); - - const parts = parsedUrl.pathname!.split("/"); - - for (let i = 0; i * 2 < parts.length - 1; i++) { - entry[nameProperties[i]] = parts[i * 2 + 1]; - } - } -} - -/** - * @ignore - * Utility to help construct the normalized error object based on given `errorBody` - * data and other data present in the received `response` object. - * - * @param errorBody - * @param response - */ -function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomError { - if (isString(errorBody)) { - return new Error(errorBody); - } - const normalizedError: any = {}; - const odataErrorFormat = !!errorBody["odata.error"]; - const errorProperties = - errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; - - if (odataErrorFormat) { - Object.keys(errorProperties).forEach((property: string) => { - let value = null; - if ( - property === Constants.ODATA_ERROR_MESSAGE && - !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) - ) { - if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { - value = - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; - } else { - value = "missing value in the message property of the odata error format"; - } - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - }); - } else { - Object.keys(errorProperties).forEach((property: any) => { - { - let value = null; - if (property !== Constants.XML_METADATA_MARKER) { - if (errorProperties[property] && errorProperties[property][Constants.XML_VALUE_MARKER]) { - value = errorProperties[property][Constants.XML_VALUE_MARKER]; - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - } - } - }); - } - let errorMessage = normalizedError.code; - if (normalizedError.detail) { - errorMessage += " - " + normalizedError.detail; - } - - const errorObject: AtomError = new AtomError( - `Error returned by service while performing the management operation` - ); - errorObject.code = errorMessage; - - if (response) { - if (response.status) { - errorObject["statusCode"] = response.status; - } - - if (response.headers && response.headers.get("x-ms-request-id")) { - errorObject["requestId"] = response.headers.get("x-ms-request-id"); - } - } - Object.keys(normalizedError).forEach((property: string) => { - errorObject.additionalProperties[property] = normalizedError[property]; - }); - return errorObject; -} - -/** - * Builds a response object with normalized key names. - * @ignore - * - * @param body The response body. - * @param headers The response headers. - * @param statusCode The response status code. - */ - -function buildResponse(body: any, headers: any, statusCode: number) { - return { - isSuccessful: true, - statusCode: statusCode, - body: body, - headers: headers - }; -} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 1f26d0cf2efa..882e146a9fb2 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -104,7 +104,7 @@ function _getDefaultSettings(): any { * Helper utility to clean up unintended characters that get appended by OS. * @param str */ -function _removeBOM(str: any) { +function _removeBOM(str: string) { if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { str = str.substring(1); } @@ -121,8 +121,6 @@ function _removeBOM(str: any) { * @param {string} name Property name. * @param {object} value Property value. * @return {object} The current DOM element. - * - * {Deprecated} */ function _writeElementValue(parentElement: any, name: any, value: any): any { let ignored = false; diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index bf7354afb583..49269ff15d97 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -4,13 +4,7 @@ import { assert } from "chai"; import { HttpHeaders } from "../../lib/httpHeaders"; import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { - HttpClient, - AtomXmlOperationSpec, - AtomXmlSerializer, - deserializeAtomXmlResponse, - serializeToAtomXmlRequest -} from "../../lib/coreHttp"; +import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; @@ -45,30 +39,16 @@ describe("atomSerializationPolicy", function() { }); const expectedResult = { - entry: { - author: { - name: "servicebuslocalperftestspremium1" - }, - content: { - QueueDescription: { - LockDuration: "PT2M", - MaxSizeInMegabytes: "1024", - QueueName: "testQueuePath4", - _: { - ContentRootElement: "QueueDescription", - author: { - name: "servicebuslocalperftestspremium1" - }, - id: - "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", - title: "testQueuePath4" - } - } - }, + LockDuration: "PT2M", + MaxSizeInMegabytes: "1024", + _: { + ContentRootElement: "QueueDescription", id: "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", - title: "testQueuePath4" - } + title: "testQueuePath4", + author: { name: "servicebuslocalperftestspremium1" } + }, + QueueName: "testQueuePath4" }; const mockClient: HttpClient = { @@ -86,7 +66,7 @@ describe("atomSerializationPolicy", function() { const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); const response = await policy.sendRequest(request); - assert.deepEqual(response.parsedBody.response.body, expectedResult); + assert.deepEqual(response.parsedBody, expectedResult); }); }); @@ -97,18 +77,43 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource } class MockSerializer implements AtomXmlSerializer { + // @ts-ignore serialize(resource: any): string { - const properties = ["LockDuration", "MaxSizeInMegabytes"]; - - return serializeToAtomXmlRequest( - "QueueDescription", - resource, - properties, - "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" - ); + return 'https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024'; } - deserialize(response: HttpOperationResponse): any { - return deserializeAtomXmlResponse(["QueueName"], response); + async deserialize(response: HttpOperationResponse): Promise { + const result = { + request: { + url: "", + method: "GET", + headers: { _headersMap: {} }, + withCredentials: false, + timeout: 0, + atomXmlOperationSpec: { serializer: {} } + }, + status: 200, + headers: { + _headersMap: { "content-type": { name: "content-type", value: "application/xml" } } + }, + bodyAsText: + 'https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024', + parsedBody: { + LockDuration: "PT2M", + MaxSizeInMegabytes: "1024", + _: { + ContentRootElement: "QueueDescription", + id: + "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", + title: "testQueuePath4", + author: { name: "servicebuslocalperftestspremium1" } + }, + QueueName: "testQueuePath4" + } + }; + response.parsedBody = result.parsedBody; + return new Promise((resolve) => { + resolve(response); + }); } } From 3fd41c2bde515175c6e5d336898ca9badc0d64c1 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 26 Sep 2019 13:29:18 -0700 Subject: [PATCH 34/72] More cleanup --- sdk/core/core-http/lib/atomError.ts | 5 ++-- sdk/core/core-http/lib/util/utils.ts | 9 ------- sdk/core/core-http/lib/util/xml.ts | 37 +++++++++++++--------------- 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/sdk/core/core-http/lib/atomError.ts b/sdk/core/core-http/lib/atomError.ts index 84a7a4ba3991..7cfa27647831 100644 --- a/sdk/core/core-http/lib/atomError.ts +++ b/sdk/core/core-http/lib/atomError.ts @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Constants } from "./util/constants"; -import { isString } from "./util/utils"; import { HttpOperationResponse } from "./httpOperationResponse"; /** @@ -29,7 +28,7 @@ export class AtomError extends Error { * @param response */ export function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomError { - if (isString(errorBody)) { + if (typeof errorBody === "string") { return new Error(errorBody); } const normalizedError: any = {}; @@ -42,7 +41,7 @@ export function buildAtomError(errorBody: any, response: HttpOperationResponse): let value = null; if ( property === Constants.ODATA_ERROR_MESSAGE && - !isString(errorProperties[Constants.ODATA_ERROR_MESSAGE]) + typeof errorProperties[Constants.ODATA_ERROR_MESSAGE] !== "string" ) { if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { value = diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index c22c63059c05..f858de581448 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -251,15 +251,6 @@ export function isDate(value: any): value is Date { return Object.prototype.toString.call(value) == "[object Date]"; } -/** - * Determines whether the given `value` is a `string` object or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export function isString(value: any): value is string { - return Object.prototype.toString.call(value) == "[object String]"; -} - /** * Determines whether the given `value` is a `Object` or not. * @param {any} value Any entity diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 882e146a9fb2..821b272edb0a 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -39,7 +39,7 @@ export function parseXML(str: string): Promise { export async function deserializeAtomXmlToJson(body: string): Promise { const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); const result = await new Promise((resolve, reject) => { - parser.parseString(_removeBOM(body.toString()), function(err: any, parsedBody: any) { + parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { reject(err); } else { @@ -65,7 +65,7 @@ export function serializeJsonToAtomXml(content: any): string { doc = doc.ele("updated", new Date().toISOString()).up(); - doc = _writeElementValue(doc, "content", content); + doc = writeElementValue(doc, "content", content); return doc.doc().toString(); } @@ -104,7 +104,7 @@ function _getDefaultSettings(): any { * Helper utility to clean up unintended characters that get appended by OS. * @param str */ -function _removeBOM(str: string) { +function removeBOM(str: string) { if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { str = str.substring(1); } @@ -121,19 +121,20 @@ function _removeBOM(str: string) { * @param {string} name Property name. * @param {object} value Property value. * @return {object} The current DOM element. + * */ -function _writeElementValue(parentElement: any, name: any, value: any): any { +function writeElementValue(parentElement: any, name: any, value: any): any { let ignored = false; const propertyTagName = name; - if (!contentIsUndefinedOrEmpty(value) && isObject(value) && !isDate(value)) { + if (value && isObject(value) && !isDate(value)) { if (Array.isArray(value) && value.length > 0) { // Example: // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] // XML: hi therehello there Object.keys(value).forEach(function(i: any) { - parentElement = _writeElementValue(parentElement, name, value[i]); + parentElement = writeElementValue(parentElement, name, value[i]); }); // For an array no element was actually added at this level, so skip uping level. @@ -147,8 +148,8 @@ function _writeElementValue(parentElement: any, name: any, value: any): any { // XML: hi there parentElement = parentElement.ele(propertyTagName); - if (!contentIsUndefinedOrEmpty(value[Constants.XML_VALUE_MARKER])) { - if (new String(value[Constants.XML_VALUE_MARKER]).startsWith(" { if (propertyName !== Constants.XML_METADATA_MARKER && value.hasOwnProperty(propertyName)) { - parentElement = _writeElementValue(parentElement, propertyName, value[propertyName]); + parentElement = writeElementValue(parentElement, propertyName, value[propertyName]); } }); } } else { parentElement = parentElement.ele(propertyTagName); - if (!contentIsUndefinedOrEmpty(value)) { - if (new String(value.toString().trim()).startsWith(" Date: Fri, 27 Sep 2019 15:05:08 -0700 Subject: [PATCH 35/72] Address comments --- sdk/core/core-http/lib/atomError.ts | 92 ------------------- .../core-http/lib/atomXmlOperationSpec.ts | 3 + sdk/core/core-http/lib/coreHttp.ts | 1 - .../lib/policies/atomSerializationPolicy.ts | 11 ++- sdk/core/core-http/lib/util/xml.browser.ts | 4 +- sdk/core/core-http/rollup.config.ts | 2 +- .../policies/atomSerializationPolicyTests.ts | 3 +- 7 files changed, 16 insertions(+), 100 deletions(-) delete mode 100644 sdk/core/core-http/lib/atomError.ts diff --git a/sdk/core/core-http/lib/atomError.ts b/sdk/core/core-http/lib/atomError.ts deleted file mode 100644 index 7cfa27647831..000000000000 --- a/sdk/core/core-http/lib/atomError.ts +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -import { Constants } from "./util/constants"; -import { HttpOperationResponse } from "./httpOperationResponse"; - -/** - * Represents custom `Error` information returned by ATOM based services. - */ -export class AtomError extends Error { - code?: string; - statusCode?: number; - additionalProperties?: any; - requestId?: string; - - constructor(message: string) { - super(message); - this.additionalProperties = {}; - Object.setPrototypeOf(this, AtomError.prototype); - } -} - -/** - * - * Utility to help construct the normalized `AtomError` object based on given `errorBody` - * data and other data present in the received `response` object. - * - * @param errorBody - * @param response - */ -export function buildAtomError(errorBody: any, response: HttpOperationResponse): AtomError { - if (typeof errorBody === "string") { - return new Error(errorBody); - } - const normalizedError: any = {}; - const odataErrorFormat = !!errorBody["odata.error"]; - const errorProperties = - errorBody.Error || errorBody.error || errorBody["odata.error"] || errorBody; - - if (odataErrorFormat) { - Object.keys(errorProperties).forEach((property: string) => { - let value = null; - if ( - property === Constants.ODATA_ERROR_MESSAGE && - typeof errorProperties[Constants.ODATA_ERROR_MESSAGE] !== "string" - ) { - if (errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]) { - value = - errorProperties[Constants.ODATA_ERROR_MESSAGE][Constants.ODATA_ERROR_MESSAGE_VALUE]; - } else { - value = "missing value in the message property of the odata error format"; - } - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - }); - } else { - Object.keys(errorProperties).forEach((property: any) => { - { - let value = null; - if (property !== Constants.XML_METADATA_MARKER) { - if (errorProperties[property] && errorProperties[property][Constants.XML_VALUE_MARKER]) { - value = errorProperties[property][Constants.XML_VALUE_MARKER]; - } else { - value = errorProperties[property]; - } - normalizedError[property.toLowerCase()] = value; - } - } - }); - } - let errorMessage = normalizedError.code; - if (normalizedError.detail) { - errorMessage += " - " + normalizedError.detail; - } - - const errorObject: AtomError = new AtomError(`ATOM Service Error: ${errorMessage}`); - - if (response) { - if (response.status) { - errorObject["statusCode"] = response.status; - } - - if (response.headers && response.headers.get("x-ms-request-id")) { - errorObject["requestId"] = response.headers.get("x-ms-request-id"); - } - } - Object.keys(normalizedError).forEach((property: string) => { - errorObject.additionalProperties[property] = normalizedError[property]; - }); - return errorObject; -} diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 3f60589df70e..fd78625149ac 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + import { AtomXmlSerializer } from "./atomXmlSerializer"; export interface AtomXmlOperationSpec { diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index e312f5a47f0a..322178095ac1 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -110,5 +110,4 @@ export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; export { AtomXmlSerializer } from "./atomXmlSerializer"; export { deserializeAtomXmlToJson, serializeJsonToAtomXml } from "./util/xml"; export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; -export { buildAtomError, AtomError } from "./atomError"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 8feaa0d38832..d2ee07c6d6b6 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -10,8 +10,9 @@ import { RequestPolicyOptions } from "./requestPolicy"; import { AtomXmlSerializer } from "../atomXmlSerializer"; -import { buildAtomError } from "../atomError"; import { deserializeAtomXmlToJson } from "../util/xml"; +import { RestError } from "../restError"; +import * as utils from "../util/utils"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -51,14 +52,18 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { request.body = serializer.serialize(JSON.parse(request.body)); } - let response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); + const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); try { if (response.bodyAsText) { response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); } } catch (e) { - throw buildAtomError({ code: "ResponseNotInAtomXMLFormat" }, response); + const error = new RestError("ResponseNotInAtomXMLFormat", RestError.PARSE_ERROR); + error.statusCode = 400; + error.request = utils.stripRequest(response.request); + error.response = utils.stripResponse(response); + throw error; } return await serializer.deserialize(response); diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 2f172e4c5d68..c5d2d4de37c7 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -108,7 +108,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { ); } -function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string } }): Attr[] { +function buildAttributes(doc: Document, attrs: { [key: string]: { toString(): string } }): Attr[] { const result = []; for (const key of Object.keys(attrs)) { const attr = doc.createAttribute(key); @@ -118,7 +118,7 @@ function buildAttributes(doc: any, attrs: { [key: string]: { toString(): string return result; } -function buildNode(doc: any, obj: any, elementName: string): Node[] { +function buildNode(doc: Document, obj: any, elementName: string): Node[] { if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { const elem = doc.createElement(elementName); elem.textContent = obj.toString(); diff --git a/sdk/core/core-http/rollup.config.ts b/sdk/core/core-http/rollup.config.ts index 66c141e84a5a..11914084ba16 100644 --- a/sdk/core/core-http/rollup.config.ts +++ b/sdk/core/core-http/rollup.config.ts @@ -67,7 +67,7 @@ const browserConfig = { }, plugins: [ nodeResolve({ - mainFields: ["module", "browser"], + mainFields: ["module", "main", "browser"], preferBuiltins: false }), commonjs(), diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 49269ff15d97..99e39594753a 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -29,7 +29,8 @@ describe("atomSerializationPolicy", function() { await policy.sendRequest(request); assert.deepEqual(true, false, "Error must be thrown"); } catch (err) { - assert.deepEqual(err.code, "ResponseNotInAtomXMLFormat"); + assert.deepEqual(err.message, "ResponseNotInAtomXMLFormat"); + assert.deepEqual(err.code, "PARSE_ERROR"); } }); From efa066d52467df41a6d187b78b8d95e1a5ec2865 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 30 Sep 2019 14:23:50 -0700 Subject: [PATCH 36/72] Generate pnpm-lock.yaml file --- common/config/rush/pnpm-lock.yaml | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5eea2d6edfe8..ea3ad00a39ea 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -10,6 +10,7 @@ dependencies: '@azure/ms-rest-nodeauth': 0.9.3 '@azure/storage-blob': 12.0.0-preview.3 '@microsoft/api-extractor': 7.3.8 + '@opencensus/web-types': 0.0.7 '@rush-temp/abort-controller': 'file:projects/abort-controller.tgz' '@rush-temp/app-configuration': 'file:projects/app-configuration.tgz' '@rush-temp/core-amqp': 'file:projects/core-amqp.tgz' @@ -601,6 +602,12 @@ packages: dev: false resolution: integrity: sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q== + /@opencensus/web-types/0.0.7: + dev: false + engines: + node: '>=6.0' + resolution: + integrity: sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g== /@sinonjs/commons/1.6.0: dependencies: type-detect: 4.0.8 @@ -10825,6 +10832,7 @@ packages: version: 0.0.0 'file:projects/app-configuration.tgz': dependencies: + '@azure/core-asynciterator-polyfill': 1.0.0-preview.1 '@microsoft/api-extractor': 7.3.11 '@types/dotenv': 6.1.1 '@types/mocha': 5.2.7 @@ -10851,7 +10859,7 @@ packages: dev: false name: '@rush-temp/app-configuration' resolution: - integrity: sha512-E7iNSp6sfIjCXmpK7lNDqAY00UoMz+ZZ4zgIO5v32Y78tx0D9dq+UrreQEytDR14GUwPyh3uLesptZMwADKlNg== + integrity: sha512-V6j7CkJfrkbSzSNbVUTR3nEn8ft8kkEXqNjEYQ8vWIhVnJW4vB1/dj8glOLcjqfsC0GRYiqGT+F6Qoc+sOOUyQ== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': @@ -10920,7 +10928,7 @@ packages: dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-1h8l3bCuZc0m0JmT28x5fMb9T6EtZgU7TpPQ1aPWSozxPqj/S1OabRCkenkMGufmSy3Eup5rWBCkM6Ly2bNyiw== + integrity: sha512-DasjGL3VvHyphyi0JX91olVAdiOce2XvrjiDAfj9ubz1GkolMFvaNr4zh2MAW/KRzpk4RjJxbHSJcr3NnJxUvg== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -11012,7 +11020,7 @@ packages: dev: false name: '@rush-temp/core-auth' resolution: - integrity: sha512-nswzAoZmQ+VTKYH15KXBCLYfFh1fy7Aox0AzSvCcRLCW7ERC1cT6nksMUFwKcuXNQ5X/1T18hlsPLq/IORg0lw== + integrity: sha512-OP2+mfrkgls9JxdoKEagMyvsoOujHFoTpzMYpMEsezWb5UgOIkl4et7bu+pR+/rffT8kwI+0KKBy2t+tyWqk/A== tarball: 'file:projects/core-auth.tgz' version: 0.0.0 'file:projects/core-http.tgz': @@ -11098,7 +11106,7 @@ packages: dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-paeJIjRutERJ29tuVLp4m7Bivom28/JbIWqrXPf1kdytdox270TnC6j1CAwG/GxhBri+e1PYCRn3YCX4EivXdA== + integrity: sha512-0dJC9qUTz+P1eM22vVv7ZYe9Q9MKd3XGRxq9O0SGUMXpuAOn9GEGoaYKPOi/wY7vGCORSlddR64FbXunNVwyVg== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-paging.tgz': @@ -11124,6 +11132,7 @@ packages: dependencies: '@azure/eslint-plugin-azure-sdk': 2.0.1_9e8391ca70fb0408a9da4393803aa477 '@microsoft/api-extractor': 7.3.8 + '@opencensus/web-types': 0.0.7 '@types/mocha': 5.2.7 '@types/node': 8.10.52 '@typescript-eslint/eslint-plugin': 2.0.0_3cafee28902d96627d4743e014bc28ff @@ -11156,7 +11165,7 @@ packages: dev: false name: '@rush-temp/core-tracing' resolution: - integrity: sha512-uc1Cbuqt6Du7IUnDJlVDqJ7QT2jD2VGTKIoM+I6wJdi+zGM5WZJkN6SG8JULMLCNhQbUdbWu+poakWgRCL/1HA== + integrity: sha512-WbDQ5f4zD46H6VTA08PWErEnRHfmY2apDbXp7O40neaCgwcgY83jSXOetohvCEOdyqAaSahSPY6E0hjfq4WGwA== tarball: 'file:projects/core-tracing.tgz' version: 0.0.0 'file:projects/cosmos.tgz_webpack@4.39.2': @@ -11309,7 +11318,7 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-dMpcMQmTDQu5ziIUmDs5eCdZ1kJhXXrIEbf0QO4SkJY06TsJc5MR1Qgb7X7OZaOhOAMlGcT1BceOkCT478tjWA== + integrity: sha512-j/OY8KHU0zD+bWlRhK5yp711OcS7oQYsRNmELlYAeishEnoPeWE+2mm104Ck2osCQa1w2HcYIqs9NJD9TSQzqA== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -11367,7 +11376,7 @@ packages: dev: false name: '@rush-temp/event-processor-host' resolution: - integrity: sha512-6vtDVnWkivQ+k24fNOjeYlpHei8qaqVfhfE3f1ouAVBX6xW+pThwd+i19o5wwa3UDj5y7wvBPXYwtnSqk7i9xw== + integrity: sha512-7Qk5AOasHTZrxBj7bDBlChwSFImEDSYG2yQJ4m6kdAKG6Byxg1OtL0ojBzf74UK1R4A+Bqz66pjBnhbI0MT6kA== tarball: 'file:projects/event-processor-host.tgz' version: 0.0.0 'file:projects/eventhubs-checkpointstore-blob.tgz': @@ -11552,7 +11561,7 @@ packages: dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-foswxnaf00WMfmdCSMw01QGa2w9Ax7smZs044wX3NyQET4LZhSG1Bik/605iK3W7JVHHnx059MjxT+vczT3fsw== + integrity: sha512-0VO+0a4YgpvmpSb4BjjcBTCmjwg7j22kHrasZWWnbeKbQp9CzguDgknIYwd5l4gh9fRMjFWtPS9b7UuB4Wx4lw== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -11621,7 +11630,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-Mpa4sYDsg5BGbzo+S+KguWfDnjW2UPuBW+1pRkXTTnDibuWH/TbYFM/aq/Y2jrA7DNv9IZH/ku0V0qPS6NzPGg== + integrity: sha512-UJmV8ySBuvZ9KrQDtZrIxojC5d7P41qemrY9ichk08lXfmBc5bRJFlcMLE+Sld32FX4AKaSjPXZt4wCgzT1dww== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -11689,7 +11698,7 @@ packages: dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-PN1/U0hdyQRpbzbGMitJfvE2Y4z8xMtIyLCvBITT2pdIgdNgla3bHGncgbwNrPLG8kEHVPBMf+gRcZqFQaBxxQ== + integrity: sha512-VfTsDKuJ1iaGdchDP4rF/1HXNW/g4QtjWNhoVvA6rlJetUn6Teyh5Eb5E52Vauqte57kS6m7qLYP/k92UfwGGA== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/service-bus.tgz': @@ -11767,7 +11776,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-OJxyb0jtxDQ9KQ4DyrkW1tDPWN+xSQnsXcEFfRQpkkH+1gCClWwVrfsyqtJ1P0/G135HDZJJ2qdjoey6pNJhDw== + integrity: sha512-cU9aNsoGM3njJPQ8HHDLjv5DJGJOLnTrVa9WbmlOaf7dEbFdgMdSqUh5FW6TdR9E80uy9juqCzvCJLE+E1Qy0g== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -12091,6 +12100,7 @@ specifiers: '@azure/ms-rest-nodeauth': ^0.9.2 '@azure/storage-blob': 12.0.0-preview.3 '@microsoft/api-extractor': ^7.1.5 + '@opencensus/web-types': 0.0.7 '@rush-temp/abort-controller': 'file:./projects/abort-controller.tgz' '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' '@rush-temp/core-amqp': 'file:./projects/core-amqp.tgz' From 01f3f9b90b130e18b183156c84f164dc362d5805 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 30 Sep 2019 16:43:32 -0700 Subject: [PATCH 37/72] Update error handling --- sdk/core/core-http/lib/policies/atomSerializationPolicy.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index d2ee07c6d6b6..f69ecc96c9d5 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -60,7 +60,10 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } } catch (e) { const error = new RestError("ResponseNotInAtomXMLFormat", RestError.PARSE_ERROR); - error.statusCode = 400; + error.statusCode = + response.status && (response.status < 200 || response.status >= 300) + ? response.status + : 400; error.request = utils.stripRequest(response.request); error.response = utils.stripResponse(response); throw error; From b260829fda0d1b57fd87780c4783ade0ea1614a3 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 30 Sep 2019 18:53:28 -0700 Subject: [PATCH 38/72] Address comments --- .../lib/policies/atomSerializationPolicy.ts | 5 +-- sdk/core/core-http/lib/util/constants.ts | 40 +------------------ 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index f69ecc96c9d5..93057e5f3802 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -60,10 +60,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } } catch (e) { const error = new RestError("ResponseNotInAtomXMLFormat", RestError.PARSE_ERROR); - error.statusCode = - response.status && (response.status < 200 || response.status >= 300) - ? response.status - : 400; + error.statusCode = response.status; error.request = utils.stripRequest(response.request); error.response = utils.stripResponse(response); throw error; diff --git a/sdk/core/core-http/lib/util/constants.ts b/sdk/core/core-http/lib/util/constants.ts index ef5059845351..73f9f121c015 100644 --- a/sdk/core/core-http/lib/util/constants.ts +++ b/sdk/core/core-http/lib/util/constants.ts @@ -96,29 +96,6 @@ export const Constants = { USER_AGENT: "User-Agent" }, - /** - * Constant representing the Odata Error 'message' property - * - * @const - * @type {string} - */ - ODATA_ERROR_MESSAGE: "message", - /** - * Constant representing the 'value' property of Odata Error 'message' property - * - * @const - * @type {string} - */ - ODATA_ERROR_MESSAGE_VALUE: "value", - - /** - * Constant representing the property where the atom default elements are stored. - * - * @const - * @type {string} - */ - ATOM_METADATA_MARKER: "_", - /** * Marker for atom metadata. * @@ -133,20 +110,5 @@ export const Constants = { * @const * @type {string} */ - XML_VALUE_MARKER: "_", - - HttpResponseCodes: { - 200: "Ok", - 201: "Created", - 202: "Accepted", - 204: "NoContent", - 206: "PartialContent", - 400: "BadRequest", - 401: "Unauthorized", - 403: "Forbidden", - 404: "NotFound", - 409: "Conflict", - 411: "LengthRequired", - 412: "PreconditionFailed" - } + XML_VALUE_MARKER: "_" }; From 420d804098b04abe6fd757fd79ede715b1a6dcb9 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 1 Oct 2019 18:13:21 -0700 Subject: [PATCH 39/72] Address comments --- .../core-http/lib/atomXmlOperationSpec.ts | 8 +- sdk/core/core-http/lib/atomXmlSerializer.ts | 10 -- sdk/core/core-http/lib/coreHttp.ts | 3 +- .../lib/policies/atomSerializationPolicy.ts | 9 +- .../policies/atomSerializationPolicyTests.ts | 122 +++++++++++------- 5 files changed, 87 insertions(+), 65 deletions(-) delete mode 100644 sdk/core/core-http/lib/atomXmlSerializer.ts diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index fd78625149ac..988ccf196aea 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -1,7 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { AtomXmlSerializer } from "./atomXmlSerializer"; +import { HttpOperationResponse } from "./httpOperationResponse"; + +export interface AtomXmlSerializer { + serialize(requestBodyInJson: any): string; + + deserialize(response: HttpOperationResponse): Promise; +} export interface AtomXmlOperationSpec { /** diff --git a/sdk/core/core-http/lib/atomXmlSerializer.ts b/sdk/core/core-http/lib/atomXmlSerializer.ts deleted file mode 100644 index fa5654def9e9..000000000000 --- a/sdk/core/core-http/lib/atomXmlSerializer.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { HttpOperationResponse } from "./httpOperationResponse"; - -export interface AtomXmlSerializer { - serialize(requestBodyInJson: any): string; - - deserialize(response: HttpOperationResponse): Promise; -} diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 322178095ac1..1b7c9e254e4f 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,7 +107,6 @@ export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { AtomXmlSerializer } from "./atomXmlSerializer"; export { deserializeAtomXmlToJson, serializeJsonToAtomXml } from "./util/xml"; -export { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; +export { AtomXmlSerializer, AtomXmlOperationSpec } from "./atomXmlOperationSpec"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 93057e5f3802..80fa3e9f6bf2 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,7 +9,7 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { AtomXmlSerializer } from "../atomXmlSerializer"; +import { AtomXmlSerializer } from "../atomXmlOperationSpec"; import { deserializeAtomXmlToJson } from "../util/xml"; import { RestError } from "../restError"; import * as utils from "../util/utils"; @@ -58,8 +58,11 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { if (response.bodyAsText) { response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); } - } catch (e) { - const error = new RestError("ResponseNotInAtomXMLFormat", RestError.PARSE_ERROR); + } catch (err) { + const error = new RestError( + `ResponseNotInAtomXMLFormat - ${err.message}`, + RestError.PARSE_ERROR + ); error.statusCode = response.status; error.request = utils.stripRequest(response.request); error.response = utils.stripResponse(response); diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 99e39594753a..d03f085ad982 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -8,11 +8,12 @@ import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/c import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; +import { serializeJsonToAtomXml } from "../../lib/util/xml"; describe("atomSerializationPolicy", function() { it("should throw an error if receiving a non-XML response body", async function() { const request: WebResource = createRequest({ - serializer: new MockSerializer() + serializer: new TestSerializer() }); const mockClient: HttpClient = { sendRequest: (req) => @@ -29,28 +30,55 @@ describe("atomSerializationPolicy", function() { await policy.sendRequest(request); assert.deepEqual(true, false, "Error must be thrown"); } catch (err) { - assert.deepEqual(err.message, "ResponseNotInAtomXMLFormat"); + assert.deepEqual(err.message.startsWith("ResponseNotInAtomXMLFormat"), true); assert.deepEqual(err.code, "PARSE_ERROR"); } }); - it("with xml response body, application/xml content-type and AtomXMLOperationSpec", async function() { + it("should properly serialize when using valid inputs and serializer", async function() { const request: WebResource = createRequest({ - serializer: new MockSerializer() + serializer: new TestSerializer() }); + const mockClient: HttpClient = { + sendRequest: (req) => + Promise.resolve({ + request: req, + status: 200, + headers: new HttpHeaders({ "Content-Type": "application/xml" }), + bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT2M1024` + }) + }; - const expectedResult = { + assert.equal(request.atomXmlOperationSpec == undefined, false); + request.body = JSON.stringify({ LockDuration: "PT2M", - MaxSizeInMegabytes: "1024", - _: { - ContentRootElement: "QueueDescription", - id: - "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", - title: "testQueuePath4", - author: { name: "servicebuslocalperftestspremium1" } - }, - QueueName: "testQueuePath4" - }; + MaxSizeInMegabytes: "1024" + }); + + const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); + + await policy.sendRequest(request); + const expectedRequestBody = + '2019-10-02T00:55:40.280ZPT2M1024'; + + const indexOfOpenUpdateTag = request.body.indexOf(""); + const indexOfCloseUpdateTag = request.body.indexOf(""); + assert.equal( + request.body.substring(0, indexOfOpenUpdateTag), + expectedRequestBody.substring(0, indexOfOpenUpdateTag), + "Atom XML serialization failure" + ); + assert.equal( + request.body.substring(indexOfCloseUpdateTag), + expectedRequestBody.substring(indexOfCloseUpdateTag), + "Atom XML serialization failure" + ); + }); + + it("should deserialize properly with xml response body and given AtomXMLOperationSpec", async function() { + const request: WebResource = createRequest({ + serializer: new TestSerializer() + }); const mockClient: HttpClient = { sendRequest: (req) => @@ -60,14 +88,12 @@ describe("atomSerializationPolicy", function() { headers: new HttpHeaders({ "content-type": "application/xml" }), - bodyAsText: `https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024`, - parsedBody: `https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024` + bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT2M1024` }) }; const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); - const response = await policy.sendRequest(request); - assert.deepEqual(response.parsedBody, expectedResult); + await policy.sendRequest(request); }); }); @@ -77,42 +103,40 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource return request; } -class MockSerializer implements AtomXmlSerializer { - // @ts-ignore +class TestSerializer implements AtomXmlSerializer { serialize(resource: any): string { - return 'https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024'; + const property1 = "LockDuration"; + const property2 = "MaxSizeInMegabytes"; + + const resourceName = "QueueDescription"; + const content: any = {}; + content[resourceName] = { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" + } + }; + + content[resourceName][property1] = resource[property1]; + content[resourceName][property2] = resource[property2]; + + return serializeJsonToAtomXml(content); } async deserialize(response: HttpOperationResponse): Promise { - const result = { - request: { - url: "", - method: "GET", - headers: { _headersMap: {} }, - withCredentials: false, - timeout: 0, - atomXmlOperationSpec: { serializer: {} } - }, - status: 200, - headers: { - _headersMap: { "content-type": { name: "content-type", value: "application/xml" } } - }, - bodyAsText: - 'https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04testQueuePath4servicebuslocalperftestspremium1PT2M1024', - parsedBody: { - LockDuration: "PT2M", - MaxSizeInMegabytes: "1024", - _: { - ContentRootElement: "QueueDescription", - id: - "https://servicebuslocalperftestspremium1.servicebus.windows.net/testQueuePath4?api-version=2017-04", - title: "testQueuePath4", - author: { name: "servicebuslocalperftestspremium1" } - }, - QueueName: "testQueuePath4" + const expectedParsedBody = { + entry: { + author: { name: "dummy" }, + id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", + title: "dummy", + content: { + QueueDescription: { + LockDuration: "PT2M", + MaxSizeInMegabytes: "1024" + } + } } }; - response.parsedBody = result.parsedBody; + assert.deepEqual(response.parsedBody, expectedParsedBody); return new Promise((resolve) => { resolve(response); }); From 1456cae0faf40fe364342e5f10aba8cf1584d847 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 2 Oct 2019 11:08:32 -0700 Subject: [PATCH 40/72] Refactor --- .../core-http/lib/atomXmlOperationSpec.ts | 21 ++++++++++++++++++- sdk/core/core-http/lib/coreHttp.ts | 8 +++++-- .../lib/policies/atomSerializationPolicy.ts | 6 ++++-- .../policies/atomSerializationPolicyTests.ts | 12 +++++++---- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 988ccf196aea..99033045340f 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -3,8 +3,27 @@ import { HttpOperationResponse } from "./httpOperationResponse"; +/** + * @ignore + * Type representing the JSON representation of XML request data + */ +export interface XMLRequestInJSON { + [key: string]: { + $: { xmlns: string }; + [key: string]: any; + }; +} + +/** + * @ignore + * Type representing the JSON representation of XML response data + */ +export interface XMLResponseInJSON { + [key: string]: any; +} + export interface AtomXmlSerializer { - serialize(requestBodyInJson: any): string; + serialize(requestBodyInJson: any): XMLRequestInJSON; deserialize(response: HttpOperationResponse): Promise; } diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 1b7c9e254e4f..8f8812346a67 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,6 +107,10 @@ export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { deserializeAtomXmlToJson, serializeJsonToAtomXml } from "./util/xml"; -export { AtomXmlSerializer, AtomXmlOperationSpec } from "./atomXmlOperationSpec"; +export { + AtomXmlSerializer, + AtomXmlOperationSpec, + XMLRequestInJSON, + XMLResponseInJSON +} from "./atomXmlOperationSpec"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 80fa3e9f6bf2..8d2e5979dbb0 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,10 +9,11 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { AtomXmlSerializer } from "../atomXmlOperationSpec"; +import { AtomXmlSerializer, XMLRequestInJSON } from "../atomXmlOperationSpec"; import { deserializeAtomXmlToJson } from "../util/xml"; import { RestError } from "../restError"; import * as utils from "../util/utils"; +import { serializeJsonToAtomXml } from "../util/xml"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -49,7 +50,8 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const serializer: AtomXmlSerializer = request.atomXmlOperationSpec.serializer; if (request.body) { - request.body = serializer.serialize(JSON.parse(request.body)); + const content: XMLRequestInJSON = serializer.serialize(JSON.parse(request.body)); + request.body = serializeJsonToAtomXml(content); } const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index d03f085ad982..80d9f401514a 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -4,11 +4,15 @@ import { assert } from "chai"; import { HttpHeaders } from "../../lib/httpHeaders"; import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; +import { + HttpClient, + AtomXmlOperationSpec, + AtomXmlSerializer, + XMLRequestInJSON +} from "../../lib/coreHttp"; import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; -import { serializeJsonToAtomXml } from "../../lib/util/xml"; describe("atomSerializationPolicy", function() { it("should throw an error if receiving a non-XML response body", async function() { @@ -104,7 +108,7 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource } class TestSerializer implements AtomXmlSerializer { - serialize(resource: any): string { + serialize(resource: any): XMLRequestInJSON { const property1 = "LockDuration"; const property2 = "MaxSizeInMegabytes"; @@ -119,7 +123,7 @@ class TestSerializer implements AtomXmlSerializer { content[resourceName][property1] = resource[property1]; content[resourceName][property2] = resource[property2]; - return serializeJsonToAtomXml(content); + return content; } async deserialize(response: HttpOperationResponse): Promise { From 30509afa5d80713b928eec5c041d14845eec3bc0 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 2 Oct 2019 11:17:57 -0700 Subject: [PATCH 41/72] Rename --- .../core-http/lib/policies/atomSerializationPolicy.ts | 8 ++++---- sdk/core/core-http/lib/util/xml.browser.ts | 4 ++-- sdk/core/core-http/lib/util/xml.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 8d2e5979dbb0..a42f79763b2b 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -10,10 +10,10 @@ import { RequestPolicyOptions } from "./requestPolicy"; import { AtomXmlSerializer, XMLRequestInJSON } from "../atomXmlOperationSpec"; -import { deserializeAtomXmlToJson } from "../util/xml"; +import { convertAtomXmlToJson } from "../util/xml"; import { RestError } from "../restError"; import * as utils from "../util/utils"; -import { serializeJsonToAtomXml } from "../util/xml"; +import { convertJsonToAtomXml } from "../util/xml"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize @@ -51,14 +51,14 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { if (request.body) { const content: XMLRequestInJSON = serializer.serialize(JSON.parse(request.body)); - request.body = serializeJsonToAtomXml(content); + request.body = convertJsonToAtomXml(content); } const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); try { if (response.bodyAsText) { - response.parsedBody = await deserializeAtomXmlToJson(response.bodyAsText); + response.parsedBody = await convertAtomXmlToJson(response.bodyAsText); } } catch (err) { const error = new RestError( diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index c5d2d4de37c7..d5fe4b8fca21 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -150,7 +150,7 @@ function buildNode(doc: Document, obj: any, elementName: string): Node[] { } } -export function deserializeAtomXmlToJson(body: string): any { +export function convertAtomXmlToJson(body: string): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); const result = domToObject(dom); @@ -160,7 +160,7 @@ export function deserializeAtomXmlToJson(body: string): any { /** * @param {object} content The content payload as it is to be serialized. It should include any root node(s). */ -export function serializeJsonToAtomXml(content: any): string { +export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; const serializer = new XMLSerializer(); diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 821b272edb0a..f50023b059a6 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -36,7 +36,7 @@ export function parseXML(str: string): Promise { return result; } -export async function deserializeAtomXmlToJson(body: string): Promise { +export async function convertAtomXmlToJson(body: string): Promise { const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); const result = await new Promise((resolve, reject) => { parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { @@ -54,7 +54,7 @@ export async function deserializeAtomXmlToJson(body: string): Promise { * @ignore * @param {object} content The content payload as it is to be serialized. It should include any root node(s). */ -export function serializeJsonToAtomXml(content: any): string { +export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; let doc = xmlbuilder.create(); From a36b705c1cc6dfaf2dba7d1273717aedef73b11c Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 12:59:29 -0700 Subject: [PATCH 42/72] Fix serialization issues --- sdk/core/core-http/lib/util/utils.ts | 18 ------------------ sdk/core/core-http/lib/util/xml.ts | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index f858de581448..2f076be25a7a 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -241,21 +241,3 @@ export function replaceAll( export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } - -/** - * Determines whether the given `value` is a `Date` object or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export function isDate(value: any): value is Date { - return Object.prototype.toString.call(value) == "[object Date]"; -} - -/** - * Determines whether the given `value` is a `Object` or not. - * @param {any} value Any entity - * @return {boolean} - true if yes, false otherwise. - */ -export function isObject(value: any): value is Object { - return value === Object(value); -} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index f50023b059a6..80897ed1e64a 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -3,7 +3,6 @@ import * as xml2js from "xml2js"; import { Constants } from "./constants"; -import { isDate, isObject } from "./utils"; const xmlbuilder: any = require("xmlbuilder"); export function stringifyXML(obj: any, opts?: { rootName?: string }) { @@ -74,7 +73,7 @@ export function convertJsonToAtomXml(content: any): string { * Gets the default xml2js settings applicable for Atom based XML operations. */ function _getDefaultSettingsForAtomXmlOperations(): any { - const xml2jsSettings = xml2js.defaults["0.2"]; + const xml2jsSettings = Object.assign({}, xml2js.defaults["0.2"]); xml2jsSettings.normalize = false; xml2jsSettings.trim = false; xml2jsSettings.attrkey = "$"; @@ -90,7 +89,7 @@ function _getDefaultSettingsForAtomXmlOperations(): any { * Gets the default settings applicable for general XML operations. */ function _getDefaultSettings(): any { - const xml2jsSettings = xml2js.defaults["0.2"]; + const xml2jsSettings = Object.assign({}, xml2js.defaults["0.2"]); xml2jsSettings.explicitArray = false; xml2jsSettings.ignoreAttrs = false; xml2jsSettings.explicitCharkey = false; @@ -127,7 +126,11 @@ function writeElementValue(parentElement: any, name: any, value: any): any { let ignored = false; const propertyTagName = name; - if (value && isObject(value) && !isDate(value)) { + if ( + typeof value !== "string" && + typeof value === "object" && + Object.prototype.toString.call(value) == "[object Date]" + ) { if (Array.isArray(value) && value.length > 0) { // Example: // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] @@ -168,8 +171,8 @@ function writeElementValue(parentElement: any, name: any, value: any): any { }); } } else { - parentElement = parentElement.ele(propertyTagName); - if (value) { + if (value != undefined) { + parentElement = parentElement.ele(propertyTagName); if ( value .toString() @@ -180,10 +183,12 @@ function writeElementValue(parentElement: any, name: any, value: any): any { } else { parentElement = parentElement.txt(value.toString()); } + } else { + parentElement = parentElement.ele(propertyTagName, {}, undefined); } } - if (value && value[Constants.XML_METADATA_MARKER]) { + if (value != undefined && value[Constants.XML_METADATA_MARKER]) { // include the metadata const attributeList = value[Constants.XML_METADATA_MARKER]; Object.keys(attributeList).forEach(function(attribute) { From 790f14c406779e8c48604eebb424177373f28ac8 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 13:07:47 -0700 Subject: [PATCH 43/72] Export Atom XML helpers --- sdk/core/core-http/lib/coreHttp.ts | 1 + sdk/core/core-http/lib/util/xml.ts | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 8f8812346a67..b0432c8a644f 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -113,4 +113,5 @@ export { XMLRequestInJSON, XMLResponseInJSON } from "./atomXmlOperationSpec"; +export { convertAtomXmlToJson, convertJsonToAtomXml } from "./util/xml"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 80897ed1e64a..bd2c54019a74 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -35,6 +35,10 @@ export function parseXML(str: string): Promise { return result; } +/** + * The XML body to convert to JSON + * @param body + */ export async function convertAtomXmlToJson(body: string): Promise { const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); const result = await new Promise((resolve, reject) => { @@ -50,8 +54,7 @@ export async function convertAtomXmlToJson(body: string): Promise { } /** - * @ignore - * @param {object} content The content payload as it is to be serialized. It should include any root node(s). + * @param content The content as it is to be serialized. It should include any root node(s). */ export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; From 3fac8f4e3839eca56bc08c89d80c9b2c03e24a2e Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 13:36:38 -0700 Subject: [PATCH 44/72] Fix boolean check --- sdk/core/core-http/lib/util/xml.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index bd2c54019a74..0f0012a7d532 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -132,7 +132,7 @@ function writeElementValue(parentElement: any, name: any, value: any): any { if ( typeof value !== "string" && typeof value === "object" && - Object.prototype.toString.call(value) == "[object Date]" + Object.prototype.toString.call(value) !== "[object Date]" ) { if (Array.isArray(value) && value.length > 0) { // Example: From 033d86e35d055ecfa50c7c48a604ac56f0d4d0b7 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 13:48:29 -0700 Subject: [PATCH 45/72] Safeguard xml2js settings --- sdk/core/core-http/lib/util/xml.ts | 46 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 0f0012a7d532..527c42a6142f 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -5,6 +5,48 @@ import * as xml2js from "xml2js"; import { Constants } from "./constants"; const xmlbuilder: any = require("xmlbuilder"); +const xml2jsDefaults = { + explicitCharkey: false, + trim: false, + normalize: false, + normalizeTags: false, + attrkey: "$", + charkey: "_", + explicitArray: true, + ignoreAttrs: false, + mergeAttrs: false, + explicitRoot: true, + validator: null, + xmlns: false, + explicitChildren: false, + preserveChildrenOrder: false, + childkey: "$$", + charsAsChildren: false, + includeWhiteChars: false, + async: false, + strict: true, + attrNameProcessors: null, + attrValueProcessors: null, + tagNameProcessors: null, + valueProcessors: null, + rootName: "root", + xmldec: { + version: "1.0", + encoding: "UTF-8", + standalone: true + }, + doctype: null, + renderOpts: { + pretty: true, + indent: " ", + newline: "\n" + }, + headless: false, + chunkSize: 10000, + emptyTag: "", + cdata: false +}; + export function stringifyXML(obj: any, opts?: { rootName?: string }) { const builder = new xml2js.Builder({ explicitArray: false, @@ -76,7 +118,7 @@ export function convertJsonToAtomXml(content: any): string { * Gets the default xml2js settings applicable for Atom based XML operations. */ function _getDefaultSettingsForAtomXmlOperations(): any { - const xml2jsSettings = Object.assign({}, xml2js.defaults["0.2"]); + const xml2jsSettings = Object.assign({}, xml2jsDefaults); xml2jsSettings.normalize = false; xml2jsSettings.trim = false; xml2jsSettings.attrkey = "$"; @@ -92,7 +134,7 @@ function _getDefaultSettingsForAtomXmlOperations(): any { * Gets the default settings applicable for general XML operations. */ function _getDefaultSettings(): any { - const xml2jsSettings = Object.assign({}, xml2js.defaults["0.2"]); + const xml2jsSettings = Object.assign({}, xml2jsDefaults); xml2jsSettings.explicitArray = false; xml2jsSettings.ignoreAttrs = false; xml2jsSettings.explicitCharkey = false; From e646da0848df279af043aa9b1f11be5744613e1d Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 17:07:53 -0700 Subject: [PATCH 46/72] Revert empty tag change --- sdk/core/core-http/lib/util/xml.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 527c42a6142f..01ee10f7f94e 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -228,8 +228,6 @@ function writeElementValue(parentElement: any, name: any, value: any): any { } else { parentElement = parentElement.txt(value.toString()); } - } else { - parentElement = parentElement.ele(propertyTagName, {}, undefined); } } From ac14e7d946261922ca03b16873e9c0f30a160046 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 17:11:02 -0700 Subject: [PATCH 47/72] Restore rollup changes --- sdk/core/core-http/rollup.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/rollup.config.ts b/sdk/core/core-http/rollup.config.ts index 11914084ba16..d8adcb13baa6 100644 --- a/sdk/core/core-http/rollup.config.ts +++ b/sdk/core/core-http/rollup.config.ts @@ -58,6 +58,7 @@ const nodeConfig = { */ const browserConfig = { input: "./es/lib/coreHttp.js", + external: [], output: { file: "./dist/coreHttp.browser.js", format: "umd", @@ -67,8 +68,7 @@ const browserConfig = { }, plugins: [ nodeResolve({ - mainFields: ["module", "main", "browser"], - preferBuiltins: false + mainFields: ["module", "main", "browser"] }), commonjs(), sourcemaps(), From b67c2cbf52d7fd311779f42cbf91e40a51c8dce7 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 3 Oct 2019 17:29:36 -0700 Subject: [PATCH 48/72] Clean up and revert parseXML config --- sdk/core/core-http/lib/util/xml.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 01ee10f7f94e..e26851d9bb12 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -60,7 +60,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { } export function parseXML(str: string): Promise { - const xmlParser = new xml2js.Parser(_getDefaultSettings()); + const xmlParser = new xml2js.Parser(getDefaultSettings()); const result = new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); @@ -82,7 +82,7 @@ export function parseXML(str: string): Promise { * @param body */ export async function convertAtomXmlToJson(body: string): Promise { - const parser = new xml2js.Parser(_getDefaultSettingsForAtomXmlOperations()); + const parser = new xml2js.Parser(getDefaultSettingsForAtomXmlOperations()); const result = await new Promise((resolve, reject) => { parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { @@ -117,7 +117,7 @@ export function convertJsonToAtomXml(content: any): string { * @ignore * Gets the default xml2js settings applicable for Atom based XML operations. */ -function _getDefaultSettingsForAtomXmlOperations(): any { +function getDefaultSettingsForAtomXmlOperations(): any { const xml2jsSettings = Object.assign({}, xml2jsDefaults); xml2jsSettings.normalize = false; xml2jsSettings.trim = false; @@ -133,13 +133,11 @@ function _getDefaultSettingsForAtomXmlOperations(): any { * @ignore * Gets the default settings applicable for general XML operations. */ -function _getDefaultSettings(): any { +function getDefaultSettings(): any { const xml2jsSettings = Object.assign({}, xml2jsDefaults); xml2jsSettings.explicitArray = false; - xml2jsSettings.ignoreAttrs = false; xml2jsSettings.explicitCharkey = false; xml2jsSettings.explicitRoot = false; - xml2jsSettings.normalize = true; return xml2jsSettings; } From dec6e9bce877bed32735d65383f0220c568f4c52 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 8 Oct 2019 18:52:30 -0700 Subject: [PATCH 49/72] Updates to Atom XML serialization --- sdk/core/core-http/lib/util/xml.ts | 24 +++++++------------ .../policies/atomSerializationPolicyTests.ts | 12 +++++++++- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index e26851d9bb12..0bad0688804e 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -5,6 +5,10 @@ import * as xml2js from "xml2js"; import { Constants } from "./constants"; const xmlbuilder: any = require("xmlbuilder"); +// Note: The reason we re-define all of the xml2js default settings (version 2.0) here is because the default settings object exposed +// by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 +// By creating a new copy of the settings each time we instantiate the parser, +// we are safeguarding against the possibility of the default settings being mutated elsewhere unintentionally. const xml2jsDefaults = { explicitCharkey: false, trim: false, @@ -125,7 +129,6 @@ function getDefaultSettingsForAtomXmlOperations(): any { xml2jsSettings.charkey = "_"; xml2jsSettings.explicitCharkey = false; xml2jsSettings.explicitArray = false; - xml2jsSettings.ignoreAttrs = true; return xml2jsSettings; } @@ -195,11 +198,7 @@ function writeElementValue(parentElement: any, name: any, value: any): any { parentElement = parentElement.ele(propertyTagName); if (value[Constants.XML_VALUE_MARKER]) { - if (value[Constants.XML_VALUE_MARKER].toString().startsWith(" { const expectedParsedBody = { entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, author: { name: "dummy" }, id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", - title: "dummy", + title: { $: { type: "text" }, _: "dummy" }, content: { + $: { + type: "application/xml" + }, QueueDescription: { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", + "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" + }, LockDuration: "PT2M", MaxSizeInMegabytes: "1024" } From 5b8739b00d6450c842f371cd6b78837a41633aa8 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 9 Oct 2019 11:54:51 -0700 Subject: [PATCH 50/72] Address comments --- .../core-http/lib/atomXmlOperationSpec.ts | 21 +-------- sdk/core/core-http/lib/coreHttp.ts | 8 +--- .../lib/policies/atomSerializationPolicy.ts | 4 +- sdk/core/core-http/lib/util/xml.browser.ts | 38 +++++++-------- sdk/core/core-http/lib/util/xml.ts | 46 +++++++------------ .../policies/atomSerializationPolicyTests.ts | 9 +--- 6 files changed, 40 insertions(+), 86 deletions(-) diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index 99033045340f..e27f4afa34b8 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -3,27 +3,8 @@ import { HttpOperationResponse } from "./httpOperationResponse"; -/** - * @ignore - * Type representing the JSON representation of XML request data - */ -export interface XMLRequestInJSON { - [key: string]: { - $: { xmlns: string }; - [key: string]: any; - }; -} - -/** - * @ignore - * Type representing the JSON representation of XML response data - */ -export interface XMLResponseInJSON { - [key: string]: any; -} - export interface AtomXmlSerializer { - serialize(requestBodyInJson: any): XMLRequestInJSON; + serialize(requestBodyInJson: any): object; deserialize(response: HttpOperationResponse): Promise; } diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index b0432c8a644f..ffcfeb3b0ff1 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,11 +107,5 @@ export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { - AtomXmlSerializer, - AtomXmlOperationSpec, - XMLRequestInJSON, - XMLResponseInJSON -} from "./atomXmlOperationSpec"; -export { convertAtomXmlToJson, convertJsonToAtomXml } from "./util/xml"; +export { AtomXmlSerializer, AtomXmlOperationSpec } from "./atomXmlOperationSpec"; export * from "@azure/core-tracing"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index a42f79763b2b..b0ecbeed3d7d 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -9,7 +9,7 @@ import { RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy"; -import { AtomXmlSerializer, XMLRequestInJSON } from "../atomXmlOperationSpec"; +import { AtomXmlSerializer } from "../atomXmlOperationSpec"; import { convertAtomXmlToJson } from "../util/xml"; import { RestError } from "../restError"; import * as utils from "../util/utils"; @@ -50,7 +50,7 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { const serializer: AtomXmlSerializer = request.atomXmlOperationSpec.serializer; if (request.body) { - const content: XMLRequestInJSON = serializer.serialize(JSON.parse(request.body)); + const content: object = serializer.serialize(JSON.parse(request.body)); request.body = convertJsonToAtomXml(content); } diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index d5fe4b8fca21..addc9db95025 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -3,6 +3,9 @@ import { Constants } from "./constants"; +// tslint:disable-next-line:no-null-keyword +const doc = document.implementation.createDocument(null, null, null); + const parser = new DOMParser(); export function parseXML(str: string): Promise { try { @@ -98,17 +101,7 @@ function domToObject(node: Node): any { const serializer = new XMLSerializer(); -export function stringifyXML(obj: any, opts?: { rootName?: string }) { - const rootName = (opts && opts.rootName) || "root"; - // tslint:disable-next-line:no-null-keyword - const doc = document.implementation.createDocument(null, null, null); - const dom = buildNode(doc, obj, rootName)[0]; - return ( - '' + serializer.serializeToString(dom) - ); -} - -function buildAttributes(doc: Document, attrs: { [key: string]: { toString(): string } }): Attr[] { +function buildAttributes(attrs: { [key: string]: { toString(): string } }): Attr[] { const result = []; for (const key of Object.keys(attrs)) { const attr = doc.createAttribute(key); @@ -118,7 +111,7 @@ function buildAttributes(doc: Document, attrs: { [key: string]: { toString(): st return result; } -function buildNode(doc: Document, obj: any, elementName: string): Node[] { +function buildNode(obj: any, elementName: string): Node[] { if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { const elem = doc.createElement(elementName); elem.textContent = obj.toString(); @@ -126,7 +119,7 @@ function buildNode(doc: Document, obj: any, elementName: string): Node[] { } else if (Array.isArray(obj)) { const result = []; for (const arrayElem of obj) { - for (const child of buildNode(doc, arrayElem, elementName)) { + for (const child of buildNode(arrayElem, elementName)) { result.push(child); } } @@ -135,11 +128,11 @@ function buildNode(doc: Document, obj: any, elementName: string): Node[] { const elem = doc.createElement(elementName); for (const key of Object.keys(obj)) { if (key === "$") { - for (const attr of buildAttributes(doc, obj[key])) { + for (const attr of buildAttributes(obj[key])) { elem.attributes.setNamedItem(attr); } } else { - for (const child of buildNode(doc, obj[key], key)) { + for (const child of buildNode(obj[key], key)) { elem.appendChild(child); } } @@ -162,12 +155,7 @@ export function convertAtomXmlToJson(body: string): any { */ export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - - const serializer = new XMLSerializer(); - - // tslint:disable-next-line:no-null-keyword - const doc = document.implementation.createDocument(null, null, null); - const res = buildNode(doc, content, "content"); + const res = buildNode(content, "content"); const dom = res[0]; const result = @@ -176,3 +164,11 @@ export function convertJsonToAtomXml(content: any): string { ``; return result; } + +export function stringifyXML(obj: any, opts?: { rootName?: string }) { + const rootName = (opts && opts.rootName) || "root"; + const dom = buildNode(obj, rootName)[0]; + return ( + '' + serializer.serializeToString(dom) + ); +} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 0bad0688804e..dbd19dba613f 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -51,6 +51,21 @@ const xml2jsDefaults = { cdata: false }; +// The default xml2js settings applicable for Atom based XML operations. +const xml2jsSettingsForAtomXmlOperations: any = Object.assign({}, xml2jsDefaults); +xml2jsSettingsForAtomXmlOperations.normalize = false; +xml2jsSettingsForAtomXmlOperations.trim = false; +xml2jsSettingsForAtomXmlOperations.attrkey = "$"; +xml2jsSettingsForAtomXmlOperations.charkey = "_"; +xml2jsSettingsForAtomXmlOperations.explicitCharkey = false; +xml2jsSettingsForAtomXmlOperations.explicitArray = false; + +// The default settings applicable for general XML operations. +const xml2jsSettingsForXmlOperations: any = Object.assign({}, xml2jsDefaults); +xml2jsSettingsForXmlOperations.explicitArray = false; +xml2jsSettingsForXmlOperations.explicitCharkey = false; +xml2jsSettingsForXmlOperations.explicitRoot = false; + export function stringifyXML(obj: any, opts?: { rootName?: string }) { const builder = new xml2js.Builder({ explicitArray: false, @@ -64,7 +79,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { } export function parseXML(str: string): Promise { - const xmlParser = new xml2js.Parser(getDefaultSettings()); + const xmlParser = new xml2js.Parser(xml2jsSettingsForXmlOperations); const result = new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); @@ -86,7 +101,7 @@ export function parseXML(str: string): Promise { * @param body */ export async function convertAtomXmlToJson(body: string): Promise { - const parser = new xml2js.Parser(getDefaultSettingsForAtomXmlOperations()); + const parser = new xml2js.Parser(xml2jsSettingsForAtomXmlOperations); const result = await new Promise((resolve, reject) => { parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { @@ -117,33 +132,6 @@ export function convertJsonToAtomXml(content: any): string { return doc.doc().toString(); } -/** - * @ignore - * Gets the default xml2js settings applicable for Atom based XML operations. - */ -function getDefaultSettingsForAtomXmlOperations(): any { - const xml2jsSettings = Object.assign({}, xml2jsDefaults); - xml2jsSettings.normalize = false; - xml2jsSettings.trim = false; - xml2jsSettings.attrkey = "$"; - xml2jsSettings.charkey = "_"; - xml2jsSettings.explicitCharkey = false; - xml2jsSettings.explicitArray = false; - return xml2jsSettings; -} - -/** - * @ignore - * Gets the default settings applicable for general XML operations. - */ -function getDefaultSettings(): any { - const xml2jsSettings = Object.assign({}, xml2jsDefaults); - xml2jsSettings.explicitArray = false; - xml2jsSettings.explicitCharkey = false; - xml2jsSettings.explicitRoot = false; - return xml2jsSettings; -} - /** * @ignore * Helper utility to clean up unintended characters that get appended by OS. diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 546d9fa1fee0..6a049089728c 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -4,12 +4,7 @@ import { assert } from "chai"; import { HttpHeaders } from "../../lib/httpHeaders"; import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { - HttpClient, - AtomXmlOperationSpec, - AtomXmlSerializer, - XMLRequestInJSON -} from "../../lib/coreHttp"; +import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; @@ -108,7 +103,7 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource } class TestSerializer implements AtomXmlSerializer { - serialize(resource: any): XMLRequestInJSON { + serialize(resource: any): object { const property1 = "LockDuration"; const property2 = "MaxSizeInMegabytes"; From af95c89583b9c07a957543fc8f0ce9ed152ef0fa Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 9 Oct 2019 12:01:00 -0700 Subject: [PATCH 51/72] Inline parameters --- .../core-http/lib/policies/atomSerializationPolicy.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index b0ecbeed3d7d..53d59026a016 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -63,11 +63,12 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { } catch (err) { const error = new RestError( `ResponseNotInAtomXMLFormat - ${err.message}`, - RestError.PARSE_ERROR + RestError.PARSE_ERROR, + response.status, + utils.stripRequest(response.request), + utils.stripResponse(response) ); - error.statusCode = response.status; - error.request = utils.stripRequest(response.request); - error.response = utils.stripResponse(response); + throw error; } From 13b81c83fb9e3568ca573cc500b506c3f31ba5ff Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 9 Oct 2019 16:41:53 -0700 Subject: [PATCH 52/72] Address comments --- sdk/core/core-http/lib/util/xml.browser.ts | 20 ++++++++++---------- sdk/core/core-http/lib/util/xml.ts | 3 +-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index addc9db95025..5671f6583cf1 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -101,6 +101,14 @@ function domToObject(node: Node): any { const serializer = new XMLSerializer(); +export function stringifyXML(obj: any, opts?: { rootName?: string }) { + const rootName = (opts && opts.rootName) || "root"; + const dom = buildNode(obj, rootName)[0]; + return ( + '' + serializer.serializeToString(dom) + ); +} + function buildAttributes(attrs: { [key: string]: { toString(): string } }): Attr[] { const result = []; for (const key of Object.keys(attrs)) { @@ -158,17 +166,9 @@ export function convertJsonToAtomXml(content: any): string { const res = buildNode(content, "content"); const dom = res[0]; - const result = + return ( `${new Date().toISOString()}` + serializer.serializeToString(dom) + - ``; - return result; -} - -export function stringifyXML(obj: any, opts?: { rootName?: string }) { - const rootName = (opts && opts.rootName) || "root"; - const dom = buildNode(obj, rootName)[0]; - return ( - '' + serializer.serializeToString(dom) + `` ); } diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index b90be6dfc8be..51c2ab6f7b12 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -98,7 +98,7 @@ export function parseXML(str: string): Promise { */ export async function convertAtomXmlToJson(body: string): Promise { const parser = new xml2js.Parser(xml2jsSettingsForAtomXmlOperations); - const result = await new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { reject(err); @@ -107,7 +107,6 @@ export async function convertAtomXmlToJson(body: string): Promise { } }); }); - return result; } /** From 898ade96f450f97d53c3150405f0d5494c505b72 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 9 Oct 2019 17:21:06 -0700 Subject: [PATCH 53/72] Remove unused constants --- sdk/core/core-http/lib/util/constants.ts | 40 +----------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/sdk/core/core-http/lib/util/constants.ts b/sdk/core/core-http/lib/util/constants.ts index ef5059845351..73f9f121c015 100644 --- a/sdk/core/core-http/lib/util/constants.ts +++ b/sdk/core/core-http/lib/util/constants.ts @@ -96,29 +96,6 @@ export const Constants = { USER_AGENT: "User-Agent" }, - /** - * Constant representing the Odata Error 'message' property - * - * @const - * @type {string} - */ - ODATA_ERROR_MESSAGE: "message", - /** - * Constant representing the 'value' property of Odata Error 'message' property - * - * @const - * @type {string} - */ - ODATA_ERROR_MESSAGE_VALUE: "value", - - /** - * Constant representing the property where the atom default elements are stored. - * - * @const - * @type {string} - */ - ATOM_METADATA_MARKER: "_", - /** * Marker for atom metadata. * @@ -133,20 +110,5 @@ export const Constants = { * @const * @type {string} */ - XML_VALUE_MARKER: "_", - - HttpResponseCodes: { - 200: "Ok", - 201: "Created", - 202: "Accepted", - 204: "NoContent", - 206: "PartialContent", - 400: "BadRequest", - 401: "Unauthorized", - 403: "Forbidden", - 404: "NotFound", - 409: "Conflict", - 411: "LengthRequired", - 412: "PreconditionFailed" - } + XML_VALUE_MARKER: "_" }; From 45352aab8464d31a517ed22b27feed657b610e83 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 12:28:29 -0700 Subject: [PATCH 54/72] Remove fine grained XML builder --- sdk/core/core-http/lib/util/xml.ts | 106 +++++------------------------ sdk/core/core-http/package.json | 3 +- 2 files changed, 17 insertions(+), 92 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 51c2ab6f7b12..ce863f4b239f 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -3,7 +3,6 @@ import * as xml2js from "xml2js"; import { Constants } from "./constants"; -const xmlbuilder: any = require("xmlbuilder"); // Note: The reason we re-define all of the xml2js default settings (version 2.0) here is because the default settings object exposed // by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 @@ -114,17 +113,24 @@ export async function convertAtomXmlToJson(body: string): Promise { */ export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + const builder = new xml2js.Builder({ + explicitRoot: false, + renderOpts: { + pretty: false + } + }); - let doc = xmlbuilder.create(); - - doc = doc - .begin("entry", { version: "1.0", encoding: "utf-8", standalone: "yes" }) - .att("xmlns", "http://www.w3.org/2005/Atom"); - - doc = doc.ele("updated", new Date().toISOString()).up(); + content = { + entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, + updated: new Date().toISOString(), + content: content + } + }; - doc = writeElementValue(doc, "content", content); - return doc.doc().toString(); + return builder.buildObject(content); } /** @@ -136,85 +142,5 @@ function removeBOM(str: string) { if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { str = str.substring(1); } - return str; } - -/** - * - * @ignore - * Writes a single property for an entry or complex type. - * - * @param {object} parentElement Parent DOM element under which the property should be added. - * @param {string} name Property name. - * @param {object} value Property value. - * @return {object} The current DOM element. - * - */ -function writeElementValue(parentElement: any, name: any, value: any): any { - let ignored = false; - const propertyTagName = name; - - if ( - typeof value !== "string" && - typeof value === "object" && - Object.prototype.toString.call(value) !== "[object Date]" - ) { - if (Array.isArray(value) && value.length > 0) { - // Example: - // JSON: element: [ { property1: 'hi there' }, { property2: 'hello there' } ] - // XML: hi therehello there - - Object.keys(value).forEach(function(i: any) { - parentElement = writeElementValue(parentElement, name, value[i]); - }); - - // For an array no element was actually added at this level, so skip uping level. - ignored = true; - } else if ( - value[Constants.XML_METADATA_MARKER] !== undefined && - value[Constants.XML_VALUE_MARKER] !== undefined - ) { - // Example: - // JSON: element: { '$': { 'm:type' = 'Edm.String' }, '_': 'hi there' } - // XML: hi there - - parentElement = parentElement.ele(propertyTagName); - if (value[Constants.XML_VALUE_MARKER]) { - parentElement = parentElement.raw(value[Constants.XML_VALUE_MARKER]); - } - } else { - // Example: - // JSON: element: { '$': { 'metadata' = 'value' }, 'property1': 'hi there', 'property2': 'hello there' } - // XML: hi therehello there - - parentElement = parentElement.ele(propertyTagName); - Object.keys(value).forEach((propertyName: string) => { - if (propertyName !== Constants.XML_METADATA_MARKER && value.hasOwnProperty(propertyName)) { - parentElement = writeElementValue(parentElement, propertyName, value[propertyName]); - } - }); - } - } else { - if (value != undefined) { - parentElement = parentElement.ele(propertyTagName); - parentElement = parentElement.raw(value.toString()); - } else { - parentElement = parentElement.ele(propertyTagName, {}, undefined); - } - } - - if (value != undefined && value[Constants.XML_METADATA_MARKER]) { - // include the metadata - const attributeList = value[Constants.XML_METADATA_MARKER]; - Object.keys(attributeList).forEach(function(attribute) { - parentElement = parentElement.att(attribute, attributeList[attribute]); - }); - } - - if (!ignored) { - parentElement = parentElement.up(); - } - - return parentElement; -} diff --git a/sdk/core/core-http/package.json b/sdk/core/core-http/package.json index c10b9d15c501..a820020e5da3 100644 --- a/sdk/core/core-http/package.json +++ b/sdk/core/core-http/package.json @@ -122,8 +122,7 @@ "tslib": "^1.9.3", "tunnel": "^0.0.6", "uuid": "^3.3.2", - "xml2js": "^0.4.19", - "xmlbuilder": "^0.4.3" + "xml2js": "^0.4.19" }, "devDependencies": { "@azure/eslint-plugin-azure-sdk": "^2.0.1", From 59047bab5e7683a47bf0d2a0757d44fed99a9d4f Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 14:28:53 -0700 Subject: [PATCH 55/72] Fix XML declaration casing --- sdk/core/core-http/lib/util/xml.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index ce863f4b239f..59c21575a7c0 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -117,6 +117,11 @@ export function convertJsonToAtomXml(content: any): string { explicitRoot: false, renderOpts: { pretty: false + }, + xmldec: { + version: "1.0", + encoding: "utf-8", + standalone: true } }); From f8ae7ecb41bca2ef859599b6230a308cb98d9ae4 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 16:40:04 -0700 Subject: [PATCH 56/72] Fix XML serialization in browser --- sdk/core/core-http/lib/util/xml.browser.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 5671f6583cf1..0cb0009fe60a 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -139,6 +139,8 @@ function buildNode(obj: any, elementName: string): Node[] { for (const attr of buildAttributes(obj[key])) { elem.attributes.setNamedItem(attr); } + } else if (key === "_") { + elem.textContent = obj[key].toString(); } else { for (const child of buildNode(obj[key], key)) { elem.appendChild(child); From 4108fa056236d26711e72a14e64889be96c1a6b2 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 17:48:39 -0700 Subject: [PATCH 57/72] Streamline XML utilities --- sdk/core/core-http/lib/util/xml.ts | 66 +++++++++++++++--------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 59c21575a7c0..b4655b523b27 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -8,7 +8,7 @@ import { Constants } from "./constants"; // by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 // By creating a new copy of the settings each time we instantiate the parser, // we are safeguarding against the possibility of the default settings being mutated elsewhere unintentionally. -const xml2jsDefaults = { +const xml2jsDefaultOptionsV2 = { explicitCharkey: false, trim: false, normalize: false, @@ -50,31 +50,42 @@ const xml2jsDefaults = { cdata: false }; -// The default xml2js settings applicable for Atom based XML operations. -const xml2jsSettingsForAtomXmlOperations: any = Object.assign({}, xml2jsDefaults); -xml2jsSettingsForAtomXmlOperations.explicitCharkey = false; -xml2jsSettingsForAtomXmlOperations.explicitArray = false; +// The xml2js settings for general XML parsing operations. +const xml2jsParserSettings: any = Object.assign({}, xml2jsDefaultOptionsV2); +xml2jsParserSettings.explicitArray = false; +xml2jsParserSettings.explicitRoot = false; -// The default settings applicable for general XML operations. -const xml2jsSettingsForXmlOperations: any = Object.assign({}, xml2jsDefaults); -xml2jsSettingsForXmlOperations.explicitArray = false; -xml2jsSettingsForXmlOperations.explicitCharkey = false; -xml2jsSettingsForXmlOperations.explicitRoot = false; +// The xml2js settings for ATOM XML parsing operations. +const xml2jsParserSettingsForAtomXml: any = Object.assign({}, xml2jsDefaultOptionsV2); +xml2jsParserSettingsForAtomXml.explicitArray = false; + +// The xml2js settings for general XML building operations. +const xml2jsBuilderSettings: any = Object.assign({}, xml2jsDefaultOptionsV2); +xml2jsBuilderSettings.explicitArray = false; +xml2jsBuilderSettings.renderOpts = { + pretty: false +}; + +// The xml2js settings for ATOM XML building operations. +const xml2jsBuilderSettingsForAtomXML: any = Object.assign({}, xml2jsDefaultOptionsV2); +xml2jsBuilderSettingsForAtomXML.explicitRoot = false; +xml2jsBuilderSettingsForAtomXML.renderOpts = { + pretty: false +}; +xml2jsBuilderSettingsForAtomXML.xmldec = { + version: "1.0", + encoding: "utf-8", + standalone: true +}; export function stringifyXML(obj: any, opts?: { rootName?: string }) { - const builder = new xml2js.Builder({ - explicitArray: false, - explicitCharkey: false, - rootName: (opts || {}).rootName, - renderOpts: { - pretty: false - } - }); + xml2jsBuilderSettings.rootName = (opts || {}).rootName; + const builder = new xml2js.Builder(xml2jsBuilderSettings); return builder.buildObject(obj); } export function parseXML(str: string): Promise { - const xmlParser = new xml2js.Parser(xml2jsSettingsForXmlOperations); + const xmlParser = new xml2js.Parser(xml2jsParserSettings); const result = new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); @@ -96,8 +107,8 @@ export function parseXML(str: string): Promise { * @param body */ export async function convertAtomXmlToJson(body: string): Promise { - const parser = new xml2js.Parser(xml2jsSettingsForAtomXmlOperations); - return new Promise((resolve, reject) => { + const parser = new xml2js.Parser(xml2jsParserSettingsForAtomXml); + return await new Promise((resolve, reject) => { parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { if (err) { reject(err); @@ -113,17 +124,7 @@ export async function convertAtomXmlToJson(body: string): Promise { */ export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - const builder = new xml2js.Builder({ - explicitRoot: false, - renderOpts: { - pretty: false - }, - xmldec: { - version: "1.0", - encoding: "utf-8", - standalone: true - } - }); + const builder = new xml2js.Builder(xml2jsBuilderSettingsForAtomXML); content = { entry: { @@ -134,7 +135,6 @@ export function convertJsonToAtomXml(content: any): string { content: content } }; - return builder.buildObject(content); } From bebcc4900c1dcd50c5295de8739e3a97f95401d0 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 17:58:58 -0700 Subject: [PATCH 58/72] Handle undefined --- sdk/core/core-http/lib/util/xml.browser.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 0cb0009fe60a..2017fcf0edf7 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -120,9 +120,14 @@ function buildAttributes(attrs: { [key: string]: { toString(): string } }): Attr } function buildNode(obj: any, elementName: string): Node[] { - if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") { + if ( + obj == undefined || + typeof obj === "string" || + typeof obj === "number" || + typeof obj === "boolean" + ) { const elem = doc.createElement(elementName); - elem.textContent = obj.toString(); + elem.textContent = obj == undefined ? "" : obj.toString(); return [elem]; } else if (Array.isArray(obj)) { const result = []; From 38451082dc92512c1dca653d0ccba4c52229ed12 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 18:45:00 -0700 Subject: [PATCH 59/72] Address comments --- .../core-http/lib/policies/atomSerializationPolicy.ts | 3 +-- sdk/core/core-http/lib/util/xml.ts | 10 ---------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index 53d59026a016..f6e555598603 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -10,10 +10,9 @@ import { RequestPolicyOptions } from "./requestPolicy"; import { AtomXmlSerializer } from "../atomXmlOperationSpec"; -import { convertAtomXmlToJson } from "../util/xml"; import { RestError } from "../restError"; import * as utils from "../util/utils"; -import { convertJsonToAtomXml } from "../util/xml"; +import { convertJsonToAtomXml, convertAtomXmlToJson } from "../util/xml"; /** * Create a new serialization RequestPolicyCreator that will serialize/deserialize diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index b4655b523b27..83000968e14b 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -125,16 +125,6 @@ export async function convertAtomXmlToJson(body: string): Promise { export function convertJsonToAtomXml(content: any): string { content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; const builder = new xml2js.Builder(xml2jsBuilderSettingsForAtomXML); - - content = { - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - updated: new Date().toISOString(), - content: content - } - }; return builder.buildObject(content); } From 26f22bd61c9e72cfd64a3649dd1441dd00b56432 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 18:58:22 -0700 Subject: [PATCH 60/72] Move Atom XML things --- sdk/core/core-http/lib/util/xml.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 83000968e14b..9f87928564d6 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -2,7 +2,6 @@ // Licensed under the MIT License. import * as xml2js from "xml2js"; -import { Constants } from "./constants"; // Note: The reason we re-define all of the xml2js default settings (version 2.0) here is because the default settings object exposed // by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 @@ -123,7 +122,6 @@ export async function convertAtomXmlToJson(body: string): Promise { * @param content The content as it is to be serialized. It should include any root node(s). */ export function convertJsonToAtomXml(content: any): string { - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; const builder = new xml2js.Builder(xml2jsBuilderSettingsForAtomXML); return builder.buildObject(content); } From 368646b77534fd107f9bd4730b998a5e9c091db4 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Thu, 10 Oct 2019 19:07:43 -0700 Subject: [PATCH 61/72] Update interface --- sdk/core/core-http/lib/atomXmlOperationSpec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts index e27f4afa34b8..568af512d3d2 100644 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ b/sdk/core/core-http/lib/atomXmlOperationSpec.ts @@ -4,7 +4,7 @@ import { HttpOperationResponse } from "./httpOperationResponse"; export interface AtomXmlSerializer { - serialize(requestBodyInJson: any): object; + serialize(requestBodyInJson: object): object; deserialize(response: HttpOperationResponse): Promise; } From d65d2da9e5551c64bf67b2e4be32cd6195376823 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 11 Oct 2019 10:48:54 -0700 Subject: [PATCH 62/72] Fix test --- .../test/policies/atomSerializationPolicyTests.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 6a049089728c..9da63531de7b 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -4,7 +4,7 @@ import { assert } from "chai"; import { HttpHeaders } from "../../lib/httpHeaders"; import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; +import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer, Constants } from "../../lib/coreHttp"; import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; @@ -117,8 +117,17 @@ class TestSerializer implements AtomXmlSerializer { content[resourceName][property1] = resource[property1]; content[resourceName][property2] = resource[property2]; + content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - return content; + return { + entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, + updated: new Date().toISOString(), + content: content + } + }; } async deserialize(response: HttpOperationResponse): Promise { From 35624655d2a9c0c42b98b9bf8c12176250bf5e3e Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 11 Oct 2019 11:19:28 -0700 Subject: [PATCH 63/72] Fix browser test --- sdk/core/core-http/lib/util/xml.browser.ts | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 2017fcf0edf7..52ba3d3f1a8c 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { Constants } from "./constants"; - // tslint:disable-next-line:no-null-keyword const doc = document.implementation.createDocument(null, null, null); @@ -169,13 +167,19 @@ export function convertAtomXmlToJson(body: string): any { * @param {object} content The content payload as it is to be serialized. It should include any root node(s). */ export function convertJsonToAtomXml(content: any): string { - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; - const res = buildNode(content, "content"); - const dom = res[0]; + let res: Node[] | undefined = undefined; + if (content.entry) { + res = buildNode(content.entry, "entry"); + } else if (content.feed) { + res = buildNode(content.feed, "feed"); + } - return ( - `${new Date().toISOString()}` + - serializer.serializeToString(dom) + - `` - ); + if (res && res.length) { + const dom = res[0]; + return ( + `` + serializer.serializeToString(dom) + ); + } else { + throw new Error("Unrecognized Atom XML result: " + JSON.stringify(content)); + } } From ec0597eda8d258bdbccc379e3b93fc73852a9e12 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Fri, 11 Oct 2019 11:33:36 -0700 Subject: [PATCH 64/72] Minor clean up --- sdk/core/core-http/lib/util/xml.browser.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index 52ba3d3f1a8c..c25527723ccf 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -159,8 +159,7 @@ function buildNode(obj: any, elementName: string): Node[] { export function convertAtomXmlToJson(body: string): any { const dom = parser.parseFromString(body, "text/xml"); throwIfError(dom); - const result = domToObject(dom); - return result; + return domToObject(dom); } /** From 772f12b44449c41ce4d2f5c9eb5bf74ec84abbc3 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 14 Oct 2019 11:03:47 -0700 Subject: [PATCH 65/72] Address comments --- .../lib/policies/atomSerializationPolicy.ts | 2 +- sdk/core/core-http/lib/util/xml.ts | 3 +- .../policies/atomSerializationPolicyTests.ts | 131 ++++++++++++------ 3 files changed, 87 insertions(+), 49 deletions(-) diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts index f6e555598603..c49da755cd30 100644 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts @@ -71,6 +71,6 @@ export class AtomSerializationPolicy extends BaseRequestPolicy { throw error; } - return await serializer.deserialize(response); + return serializer.deserialize(response); } } diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 9f87928564d6..c323706c53a5 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -85,7 +85,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { export function parseXML(str: string): Promise { const xmlParser = new xml2js.Parser(xml2jsParserSettings); - const result = new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); } else { @@ -98,7 +98,6 @@ export function parseXML(str: string): Promise { }); } }); - return result; } /** diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index 9da63531de7b..e13ca3682ffa 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -4,7 +4,7 @@ import { assert } from "chai"; import { HttpHeaders } from "../../lib/httpHeaders"; import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer, Constants } from "../../lib/coreHttp"; +import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; import { WebResource } from "../../lib/webResource"; @@ -12,7 +12,29 @@ import { WebResource } from "../../lib/webResource"; describe("atomSerializationPolicy", function() { it("should throw an error if receiving a non-XML response body", async function() { const request: WebResource = createRequest({ - serializer: new TestSerializer() + serializer: new TestSerializer({ + entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, + author: { name: "dummy" }, + id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", + title: { $: { type: "text" }, _: "dummy" }, + content: { + $: { + type: "application/xml" + }, + QueueDescription: { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", + "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" + }, + LockDuration: "PT3M", + MaxSizeInMegabytes: "2048" + } + } + } + }) }); const mockClient: HttpClient = { sendRequest: (req) => @@ -36,22 +58,45 @@ describe("atomSerializationPolicy", function() { it("should properly serialize when using valid inputs and serializer", async function() { const request: WebResource = createRequest({ - serializer: new TestSerializer() + serializer: new TestSerializer({ + entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, + author: { name: "dummy" }, + id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", + title: { $: { type: "text" }, _: "dummy" }, + content: { + $: { + type: "application/xml" + }, + QueueDescription: { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", + "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" + }, + LockDuration: "PT3M", + MaxSizeInMegabytes: "2048" + } + } + } + }) }); + const mockClient: HttpClient = { sendRequest: (req) => Promise.resolve({ request: req, status: 200, headers: new HttpHeaders({ "Content-Type": "application/xml" }), - bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT2M1024` + bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT3M2048` }) }; assert.equal(request.atomXmlOperationSpec == undefined, false); request.body = JSON.stringify({ - LockDuration: "PT2M", - MaxSizeInMegabytes: "1024" + LockDuration: "PT3M", + MaxSizeInMegabytes: "2048" }); const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); @@ -76,7 +121,29 @@ describe("atomSerializationPolicy", function() { it("should deserialize properly with xml response body and given AtomXMLOperationSpec", async function() { const request: WebResource = createRequest({ - serializer: new TestSerializer() + serializer: new TestSerializer({ + entry: { + $: { + xmlns: "http://www.w3.org/2005/Atom" + }, + author: { name: "dummy" }, + id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", + title: { $: { type: "text" }, _: "dummy" }, + content: { + $: { + type: "application/xml" + }, + QueueDescription: { + $: { + xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", + "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" + }, + LockDuration: "PT2M", + MaxSizeInMegabytes: "1024" + } + } + } + }) }); const mockClient: HttpClient = { @@ -103,21 +170,18 @@ function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource } class TestSerializer implements AtomXmlSerializer { + expectedParsedBody: any; + constructor(parsedBody: any) { + this.expectedParsedBody = parsedBody; + } + serialize(resource: any): object { const property1 = "LockDuration"; const property2 = "MaxSizeInMegabytes"; - const resourceName = "QueueDescription"; - const content: any = {}; - content[resourceName] = { - $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" - } - }; - - content[resourceName][property1] = resource[property1]; - content[resourceName][property2] = resource[property2]; - content[Constants.XML_METADATA_MARKER] = { type: "application/xml" }; + const serializedContent = this.expectedParsedBody.entry.content; + serializedContent.entry.content.QueueDescription[property1] = resource[property1]; + serializedContent.entry.content.QueueDescription[property2] = resource[property2]; return { entry: { @@ -125,38 +189,13 @@ class TestSerializer implements AtomXmlSerializer { xmlns: "http://www.w3.org/2005/Atom" }, updated: new Date().toISOString(), - content: content + content: serializedContent } }; } async deserialize(response: HttpOperationResponse): Promise { - const expectedParsedBody = { - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - author: { name: "dummy" }, - id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", - title: { $: { type: "text" }, _: "dummy" }, - content: { - $: { - type: "application/xml" - }, - QueueDescription: { - $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", - "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" - }, - LockDuration: "PT2M", - MaxSizeInMegabytes: "1024" - } - } - } - }; - assert.deepEqual(response.parsedBody, expectedParsedBody); - return new Promise((resolve) => { - resolve(response); - }); + assert.deepEqual(response.parsedBody, this.expectedParsedBody); + return response; } } From 929e289d6aba771a30e8eba5734d4a02a362e841 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 14 Oct 2019 11:14:38 -0700 Subject: [PATCH 66/72] Fix test --- .../core-http/test/policies/atomSerializationPolicyTests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts index e13ca3682ffa..e8a0eaf10da2 100644 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts @@ -103,7 +103,7 @@ describe("atomSerializationPolicy", function() { await policy.sendRequest(request); const expectedRequestBody = - '2019-10-02T00:55:40.280ZPT2M1024'; + '2019-10-02T00:55:40.280Zdummyhttps://dummy.servicebus.windows.net/dummy?api-version=2017-04dummyPT3M2048'; const indexOfOpenUpdateTag = request.body.indexOf(""); const indexOfCloseUpdateTag = request.body.indexOf(""); @@ -179,7 +179,7 @@ class TestSerializer implements AtomXmlSerializer { const property1 = "LockDuration"; const property2 = "MaxSizeInMegabytes"; - const serializedContent = this.expectedParsedBody.entry.content; + const serializedContent = this.expectedParsedBody; serializedContent.entry.content.QueueDescription[property1] = resource[property1]; serializedContent.entry.content.QueueDescription[property2] = resource[property2]; From 4746c3236ff0b68099bb56b3d79f522281977438 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Mon, 14 Oct 2019 16:09:10 -0700 Subject: [PATCH 67/72] Move out atomSerializationPolicy --- .../core-http/lib/atomXmlOperationSpec.ts | 17 -- sdk/core/core-http/lib/coreHttp.ts | 3 +- .../lib/policies/atomSerializationPolicy.ts | 76 ------- sdk/core/core-http/lib/webResource.ts | 6 - .../policies/atomSerializationPolicyTests.ts | 201 ------------------ 5 files changed, 1 insertion(+), 302 deletions(-) delete mode 100644 sdk/core/core-http/lib/atomXmlOperationSpec.ts delete mode 100644 sdk/core/core-http/lib/policies/atomSerializationPolicy.ts delete mode 100644 sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts diff --git a/sdk/core/core-http/lib/atomXmlOperationSpec.ts b/sdk/core/core-http/lib/atomXmlOperationSpec.ts deleted file mode 100644 index 568af512d3d2..000000000000 --- a/sdk/core/core-http/lib/atomXmlOperationSpec.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { HttpOperationResponse } from "./httpOperationResponse"; - -export interface AtomXmlSerializer { - serialize(requestBodyInJson: object): object; - - deserialize(response: HttpOperationResponse): Promise; -} - -export interface AtomXmlOperationSpec { - /** - * The serializer to use in this operation. - */ - serializer: AtomXmlSerializer; -} diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 4914f2ab82a1..228604a44de4 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,5 +107,4 @@ export { ServiceClientCredentials } from "./credentials/serviceClientCredentials export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; -export { atomSerializationPolicy } from "./policies/atomSerializationPolicy"; -export { AtomXmlSerializer, AtomXmlOperationSpec } from "./atomXmlOperationSpec"; +export { convertAtomXmlToJson, convertJsonToAtomXml } from "./util/xml"; diff --git a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts b/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts deleted file mode 100644 index c49da755cd30..000000000000 --- a/sdk/core/core-http/lib/policies/atomSerializationPolicy.ts +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { HttpOperationResponse } from "../httpOperationResponse"; -import { WebResource } from "../webResource"; -import { - BaseRequestPolicy, - RequestPolicy, - RequestPolicyFactory, - RequestPolicyOptions -} from "./requestPolicy"; -import { AtomXmlSerializer } from "../atomXmlOperationSpec"; -import { RestError } from "../restError"; -import * as utils from "../util/utils"; -import { convertJsonToAtomXml, convertAtomXmlToJson } from "../util/xml"; - -/** - * Create a new serialization RequestPolicyCreator that will serialize/deserialize - * HTTP request bodies as they pass through the HTTP pipeline. - */ -export function atomSerializationPolicy(): RequestPolicyFactory { - return { - create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => { - return new AtomSerializationPolicy(nextPolicy, options); - } - }; -} - -/** - * A RequestPolicy that will - * - serialize HTTP requests with input in JSON to ATOM based XML requests, and - * - deserialize the ATOM based XML responses as they pass through the HTTP pipeline. - */ -export class AtomSerializationPolicy extends BaseRequestPolicy { - constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptions) { - super(nextPolicy, options); - } - - public async sendRequest(request: WebResource): Promise { - if ( - request.atomXmlOperationSpec == undefined || - request.atomXmlOperationSpec.serializer == undefined - ) { - throw new Error( - "Failed to send request in the AtomSerializationPolicy due to missing serializer." - ); - } - - const serializer: AtomXmlSerializer = request.atomXmlOperationSpec.serializer; - - if (request.body) { - const content: object = serializer.serialize(JSON.parse(request.body)); - request.body = convertJsonToAtomXml(content); - } - - const response: HttpOperationResponse = await this._nextPolicy.sendRequest(request); - - try { - if (response.bodyAsText) { - response.parsedBody = await convertAtomXmlToJson(response.bodyAsText); - } - } catch (err) { - const error = new RestError( - `ResponseNotInAtomXMLFormat - ${err.message}`, - RestError.PARSE_ERROR, - response.status, - utils.stripRequest(response.request), - utils.stripResponse(response) - ); - - throw error; - } - - return serializer.deserialize(response); - } -} diff --git a/sdk/core/core-http/lib/webResource.ts b/sdk/core/core-http/lib/webResource.ts index 9be1597a079e..2daf254d5f8a 100644 --- a/sdk/core/core-http/lib/webResource.ts +++ b/sdk/core/core-http/lib/webResource.ts @@ -9,7 +9,6 @@ import { HttpOperationResponse } from "./httpOperationResponse"; import { OperationResponse } from "./operationResponse"; import { ProxySettings } from "./serviceClient"; import { AbortSignalLike } from "@azure/abort-controller"; -import { AtomXmlOperationSpec } from "./atomXmlOperationSpec"; import { SpanOptions } from "@azure/core-tracing"; export type HttpMethods = @@ -72,7 +71,6 @@ export class WebResource { formData?: any; query?: { [key: string]: any }; operationSpec?: OperationSpec; - atomXmlOperationSpec?: AtomXmlOperationSpec; withCredentials: boolean; timeout: number; proxySettings?: ProxySettings; @@ -373,10 +371,6 @@ export class WebResource { result.operationSpec = this.operationSpec; } - if (this.atomXmlOperationSpec) { - result.atomXmlOperationSpec = this.atomXmlOperationSpec; - } - if (this.shouldDeserialize) { result.shouldDeserialize = this.shouldDeserialize; } diff --git a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts b/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts deleted file mode 100644 index e8a0eaf10da2..000000000000 --- a/sdk/core/core-http/test/policies/atomSerializationPolicyTests.ts +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { assert } from "chai"; -import { HttpHeaders } from "../../lib/httpHeaders"; -import { HttpOperationResponse } from "../../lib/httpOperationResponse"; -import { HttpClient, AtomXmlOperationSpec, AtomXmlSerializer } from "../../lib/coreHttp"; -import { atomSerializationPolicy } from "../../lib/policies/atomSerializationPolicy"; -import { RequestPolicyOptions } from "../../lib/policies/requestPolicy"; -import { WebResource } from "../../lib/webResource"; - -describe("atomSerializationPolicy", function() { - it("should throw an error if receiving a non-XML response body", async function() { - const request: WebResource = createRequest({ - serializer: new TestSerializer({ - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - author: { name: "dummy" }, - id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", - title: { $: { type: "text" }, _: "dummy" }, - content: { - $: { - type: "application/xml" - }, - QueueDescription: { - $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", - "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" - }, - LockDuration: "PT3M", - MaxSizeInMegabytes: "2048" - } - } - } - }) - }); - const mockClient: HttpClient = { - sendRequest: (req) => - Promise.resolve({ - request: req, - status: 200, - headers: new HttpHeaders({ "Content-Type": "application/json" }), - bodyAsText: `{ "simple": "JSONobject" }` - }) - }; - - const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); - try { - await policy.sendRequest(request); - assert.deepEqual(true, false, "Error must be thrown"); - } catch (err) { - assert.deepEqual(err.message.startsWith("ResponseNotInAtomXMLFormat"), true); - assert.deepEqual(err.code, "PARSE_ERROR"); - } - }); - - it("should properly serialize when using valid inputs and serializer", async function() { - const request: WebResource = createRequest({ - serializer: new TestSerializer({ - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - author: { name: "dummy" }, - id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", - title: { $: { type: "text" }, _: "dummy" }, - content: { - $: { - type: "application/xml" - }, - QueueDescription: { - $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", - "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" - }, - LockDuration: "PT3M", - MaxSizeInMegabytes: "2048" - } - } - } - }) - }); - - const mockClient: HttpClient = { - sendRequest: (req) => - Promise.resolve({ - request: req, - status: 200, - headers: new HttpHeaders({ "Content-Type": "application/xml" }), - bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT3M2048` - }) - }; - - assert.equal(request.atomXmlOperationSpec == undefined, false); - request.body = JSON.stringify({ - LockDuration: "PT3M", - MaxSizeInMegabytes: "2048" - }); - - const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); - - await policy.sendRequest(request); - const expectedRequestBody = - '2019-10-02T00:55:40.280Zdummyhttps://dummy.servicebus.windows.net/dummy?api-version=2017-04dummyPT3M2048'; - - const indexOfOpenUpdateTag = request.body.indexOf(""); - const indexOfCloseUpdateTag = request.body.indexOf(""); - assert.equal( - request.body.substring(0, indexOfOpenUpdateTag), - expectedRequestBody.substring(0, indexOfOpenUpdateTag), - "Atom XML serialization failure" - ); - assert.equal( - request.body.substring(indexOfCloseUpdateTag), - expectedRequestBody.substring(indexOfCloseUpdateTag), - "Atom XML serialization failure" - ); - }); - - it("should deserialize properly with xml response body and given AtomXMLOperationSpec", async function() { - const request: WebResource = createRequest({ - serializer: new TestSerializer({ - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - author: { name: "dummy" }, - id: "https://dummy.servicebus.windows.net/dummy?api-version=2017-04", - title: { $: { type: "text" }, _: "dummy" }, - content: { - $: { - type: "application/xml" - }, - QueueDescription: { - $: { - xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect", - "xmlns:i": "http://www.w3.org/2001/XMLSchema-instance" - }, - LockDuration: "PT2M", - MaxSizeInMegabytes: "1024" - } - } - } - }) - }); - - const mockClient: HttpClient = { - sendRequest: (req) => - Promise.resolve({ - request: req, - status: 200, - headers: new HttpHeaders({ - "content-type": "application/xml" - }), - bodyAsText: `https://dummy.servicebus.windows.net/dummy?api-version=2017-04dummydummyPT2M1024` - }) - }; - - const policy = atomSerializationPolicy().create(mockClient, new RequestPolicyOptions()); - await policy.sendRequest(request); - }); -}); - -function createRequest(atomXmlOperationSpec?: AtomXmlOperationSpec): WebResource { - const request = new WebResource(); - request.atomXmlOperationSpec = atomXmlOperationSpec; - return request; -} - -class TestSerializer implements AtomXmlSerializer { - expectedParsedBody: any; - constructor(parsedBody: any) { - this.expectedParsedBody = parsedBody; - } - - serialize(resource: any): object { - const property1 = "LockDuration"; - const property2 = "MaxSizeInMegabytes"; - - const serializedContent = this.expectedParsedBody; - serializedContent.entry.content.QueueDescription[property1] = resource[property1]; - serializedContent.entry.content.QueueDescription[property2] = resource[property2]; - - return { - entry: { - $: { - xmlns: "http://www.w3.org/2005/Atom" - }, - updated: new Date().toISOString(), - content: serializedContent - } - }; - } - - async deserialize(response: HttpOperationResponse): Promise { - assert.deepEqual(response.parsedBody, this.expectedParsedBody); - return response; - } -} From faa4809cad94f6bfebbf8d87e6d8429034e4ea11 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 15 Oct 2019 14:31:20 -0700 Subject: [PATCH 68/72] Fixes for XML serialization, add tests --- sdk/core/core-http/lib/coreHttp.ts | 2 +- sdk/core/core-http/lib/util/utils.ts | 14 + sdk/core/core-http/lib/util/xml.browser.ts | 57 ++- sdk/core/core-http/lib/util/xml.ts | 75 ++-- sdk/core/core-http/test/xmlTests.ts | 394 ++++++++++++++++++++- 5 files changed, 455 insertions(+), 87 deletions(-) diff --git a/sdk/core/core-http/lib/coreHttp.ts b/sdk/core/core-http/lib/coreHttp.ts index 228604a44de4..ce83bc164a65 100644 --- a/sdk/core/core-http/lib/coreHttp.ts +++ b/sdk/core/core-http/lib/coreHttp.ts @@ -107,4 +107,4 @@ export { ServiceClientCredentials } from "./credentials/serviceClientCredentials export { TopicCredentials } from "./credentials/topicCredentials"; export { Authenticator } from "./credentials/credentials"; -export { convertAtomXmlToJson, convertJsonToAtomXml } from "./util/xml"; +export { parseXML, stringifyXML } from "./util/xml"; diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 2f076be25a7a..c94671da526e 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -241,3 +241,17 @@ export function replaceAll( export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } + +/** + * @ignore + * Helper utility to clean up unintended characters that get appended by OS. + * @param str + */ +export function removeBOM(str: any) { + if (typeof str == "string") { + if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { + str = str.substring(1); + } + } + return str; +} diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index c25527723ccf..beecc19cf7d3 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -1,16 +1,32 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { removeBOM } from "./utils"; + // tslint:disable-next-line:no-null-keyword const doc = document.implementation.createDocument(null, null, null); const parser = new DOMParser(); -export function parseXML(str: string): Promise { +export function parseXML(str: string, opts?: { includeRoot?: boolean }): Promise { try { + if (str == undefined || str == "") { + throw new Error("Document is empty"); + } + + if (!removeBOM(str).startsWith("<")) { + throw new Error("Non-whitespace before first tag"); + } + const dom = parser.parseFromString(str, "application/xml"); throwIfError(dom); - const obj = domToObject(dom.childNodes[0]); + let obj; + if (opts && opts.includeRoot) { + obj = domToObject(dom); + } else { + obj = domToObject(dom.childNodes[0]); + } + return Promise.resolve(obj); } catch (err) { return Promise.reject(err); @@ -99,9 +115,15 @@ function domToObject(node: Node): any { const serializer = new XMLSerializer(); -export function stringifyXML(obj: any, opts?: { rootName?: string }) { +export function stringifyXML(content: any, opts?: { rootName?: string }): string { + if (content == undefined) { + throw new Error("Cannot convert undefined or null to object"); + } + if (content == "") { + throw new Error("Missing element text"); + } const rootName = (opts && opts.rootName) || "root"; - const dom = buildNode(obj, rootName)[0]; + const dom = buildNode(removeBOM(content), rootName)[0]; return ( '' + serializer.serializeToString(dom) ); @@ -155,30 +177,3 @@ function buildNode(obj: any, elementName: string): Node[] { throw new Error(`Illegal value passed to buildObject: ${obj}`); } } - -export function convertAtomXmlToJson(body: string): any { - const dom = parser.parseFromString(body, "text/xml"); - throwIfError(dom); - return domToObject(dom); -} - -/** - * @param {object} content The content payload as it is to be serialized. It should include any root node(s). - */ -export function convertJsonToAtomXml(content: any): string { - let res: Node[] | undefined = undefined; - if (content.entry) { - res = buildNode(content.entry, "entry"); - } else if (content.feed) { - res = buildNode(content.feed, "feed"); - } - - if (res && res.length) { - const dom = res[0]; - return ( - `` + serializer.serializeToString(dom) - ); - } else { - throw new Error("Unrecognized Atom XML result: " + JSON.stringify(content)); - } -} diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index c323706c53a5..d373cd875581 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -3,6 +3,8 @@ import * as xml2js from "xml2js"; +import { removeBOM } from "./utils"; + // Note: The reason we re-define all of the xml2js default settings (version 2.0) here is because the default settings object exposed // by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 // By creating a new copy of the settings each time we instantiate the parser, @@ -55,8 +57,8 @@ xml2jsParserSettings.explicitArray = false; xml2jsParserSettings.explicitRoot = false; // The xml2js settings for ATOM XML parsing operations. -const xml2jsParserSettingsForAtomXml: any = Object.assign({}, xml2jsDefaultOptionsV2); -xml2jsParserSettingsForAtomXml.explicitArray = false; +const xml2jsParserSettingsWithRoot: any = Object.assign({}, xml2jsDefaultOptionsV2); +xml2jsParserSettingsWithRoot.explicitArray = false; // The xml2js settings for general XML building operations. const xml2jsBuilderSettings: any = Object.assign({}, xml2jsDefaultOptionsV2); @@ -65,26 +67,28 @@ xml2jsBuilderSettings.renderOpts = { pretty: false }; -// The xml2js settings for ATOM XML building operations. -const xml2jsBuilderSettingsForAtomXML: any = Object.assign({}, xml2jsDefaultOptionsV2); -xml2jsBuilderSettingsForAtomXML.explicitRoot = false; -xml2jsBuilderSettingsForAtomXML.renderOpts = { - pretty: false -}; -xml2jsBuilderSettingsForAtomXML.xmldec = { - version: "1.0", - encoding: "utf-8", - standalone: true -}; - +/** + * Converts given JSON object to XML string + * @param obj JSON object to be converted into XML string + * @param opts Options that govern the parsing of given JSON object. + * `rootName` indicates the name of the root element in the resulting XML + */ export function stringifyXML(obj: any, opts?: { rootName?: string }) { xml2jsBuilderSettings.rootName = (opts || {}).rootName; const builder = new xml2js.Builder(xml2jsBuilderSettings); - return builder.buildObject(obj); + return builder.buildObject(removeBOM(obj)); } -export function parseXML(str: string): Promise { - const xmlParser = new xml2js.Parser(xml2jsParserSettings); +/** + * Converts given XML string into JSON + * @param str String containg the XML content to be parsed into JSON + * @param opts Options that govern the parsing of given xml string. + * `includeRoot` indicates whether the root element is to be included or not in the output + */ +export function parseXML(str: string, opts?: { includeRoot?: boolean }): Promise { + const xml2jsSettings = + opts && opts.includeRoot ? xml2jsParserSettingsWithRoot : xml2jsParserSettings; + const xmlParser = new xml2js.Parser(xml2jsSettings); return new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); @@ -99,40 +103,3 @@ export function parseXML(str: string): Promise { } }); } - -/** - * The XML body to convert to JSON - * @param body - */ -export async function convertAtomXmlToJson(body: string): Promise { - const parser = new xml2js.Parser(xml2jsParserSettingsForAtomXml); - return await new Promise((resolve, reject) => { - parser.parseString(removeBOM(body.toString()), function(err: any, parsedBody: any) { - if (err) { - reject(err); - } else { - resolve(parsedBody); - } - }); - }); -} - -/** - * @param content The content as it is to be serialized. It should include any root node(s). - */ -export function convertJsonToAtomXml(content: any): string { - const builder = new xml2js.Builder(xml2jsBuilderSettingsForAtomXML); - return builder.buildObject(content); -} - -/** - * @ignore - * Helper utility to clean up unintended characters that get appended by OS. - * @param str - */ -function removeBOM(str: string) { - if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { - str = str.substring(1); - } - return str; -} diff --git a/sdk/core/core-http/test/xmlTests.ts b/sdk/core/core-http/test/xmlTests.ts index 200720fc74cc..05ddab716dec 100644 --- a/sdk/core/core-http/test/xmlTests.ts +++ b/sdk/core/core-http/test/xmlTests.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { parseXML } from "../lib/util/xml"; +import { parseXML, stringifyXML } from "../lib/util/xml"; import { assert } from "chai"; import * as msAssert from "./msAssert"; @@ -113,6 +113,398 @@ describe("XML serializer", function() { } }); }); + + it("with unwanted BOM characters", async function() { + const xml: any = await parseXML("\uFEFFapple"); + assert.deepStrictEqual(xml, { fruit: "apple" }); + }); + }); + + describe("parseXML(string) with root", function() { + it("with undefined", async function() { + try { + await parseXML(undefined as any, { includeRoot: true }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Document is empty"), + -1, + `error.message ("${err.message}") should have contained "Document is empty"` + ); + } + }); + + it("with null", async function() { + try { + // tslint:disable-next-line:no-null-keyword + await parseXML(null as any, { includeRoot: true }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Document is empty"), + -1, + `error.message ("${err.message}") should have contained "Document is empty"` + ); + } + }); + + it("with empty", async function() { + try { + await parseXML("", { includeRoot: true }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Document is empty"), + -1, + `error.message ("${err.message}") should have contained "Document is empty"` + ); + } + }); + + it("with text", async function() { + try { + await parseXML("Hello World!", { includeRoot: true }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Non-whitespace before first tag"), + -1, + `error.message ("${err.message}") should have contained "Non-whitespace before first tag"` + ); + } + }); + + it("with empty element", async function() { + const json: any = await parseXML("", { includeRoot: true }); + assert.deepStrictEqual(json, { fruit: `` }); + }); + + it("with empty element with attribute", async function() { + const json: any = await parseXML(``, { + includeRoot: true + }); + assert.deepStrictEqual(json, { + fruit: { + $: { + healthy: "true" + } + } + }); + }); + + it("with element", async function() { + const json: any = await parseXML("", { includeRoot: true }); + assert.deepStrictEqual(json, { fruit: `` }); + }); + + it("with element with value", async function() { + const json: any = await parseXML("hurray", { includeRoot: true }); + assert.deepStrictEqual(json, { fruit: `hurray` }); + }); + + it("with unwanted BOM characters", async function() { + const json: any = await parseXML("\uFEFFapple", { + includeRoot: true + }); + assert.deepStrictEqual(json, { fruit: "apple" }); + }); + + it("with element with attribute", async function() { + const json: any = await parseXML(``, { + includeRoot: true + }); + assert.deepStrictEqual(json, { + fruit: { + $: { + healthy: "true" + } + } + }); + }); + + it("with element with attribute and value", async function() { + const json: any = await parseXML(`yum`, { + includeRoot: true + }); + assert.deepStrictEqual(json, { + fruit: { + $: { + healthy: "true" + }, + _: "yum" + } + }); + }); + + it("with element with child empty element", async function() { + const json: any = await parseXML(``, { + includeRoot: true + }); + assert.deepStrictEqual(json, { + fruit: { + apples: `` + } + }); + }); + + it("with element with child empty element with attribute", async function() { + const json: any = await parseXML(``, { includeRoot: true }); + assert.deepStrictEqual(json, { + apples: { + $: { + tasty: "true" + } + } + }); + }); + + it("with element with child element with value", async function() { + const json: any = await parseXML(`yum`, { includeRoot: true }); + assert.deepStrictEqual(json, { + apples: "yum" + }); + }); + + it("with element with child element with attribute and value", async function() { + const json: any = await parseXML(`yum`, { + includeRoot: true + }); + assert.deepStrictEqual(json, { + apples: { + $: { + tasty: "true" + }, + _: "yum" + } + }); + }); + + it("should handle errors gracefully", async function() { + try { + await parseXML("INVALID", { includeRoot: true }); + throw new Error("did not throw"); + } catch (err) { + if (err.message === "did not throw") { + throw err; + } + } + }); + }); + + describe("stringifyXML(JSON) with root", function() { + it("with undefined", async function() { + try { + await stringifyXML(undefined as any); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Cannot convert undefined or null to object"), + -1, + `error.message ("${err.message}") should have contained "Cannot convert undefined or null to object"` + ); + } + }); + + it("with null", async function() { + try { + // tslint:disable-next-line:no-null-keyword + await stringifyXML(null as any); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Cannot convert undefined or null to object"), + -1, + `error.message ("${err.message}") should have contained "Cannot convert undefined or null to object"` + ); + } + }); + + it("with empty", async function() { + try { + await stringifyXML("", { rootName: "fruits" }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Missing element text"), + -1, + `error.message ("${err.message}") should have contained "Missing element text"` + ); + } + }); + + it("with text", async function() { + try { + await stringifyXML("Hello World!", { rootName: "fruits" }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Document is empty"), + -1, + `error.message ("${err.message}") should have contained "Document is empty"` + ); + } + }); + + it("with empty element", async function() { + try { + await stringifyXML({}, { rootName: "fruits" }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Missing element text"), + -1, + `error.message ("${err.message}") should have contained "Missing element text"` + ); + } + }); + + it("with no root element name", async function() { + try { + await stringifyXML({ + fruit: { + $: { + healthy: "true" + } + } + }); + } catch (err) { + assert.notStrictEqual( + err.message.indexOf("Root element needs a name"), + -1, + `error.message ("${err.message}") should have contained "Root element needs a name"` + ); + } + }); + + it("with empty element with attribute", async function() { + const xml: any = await stringifyXML( + { + fruit: { + $: { + healthy: "true" + } + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `` + ); + }); + + it("with element", async function() { + const xml: any = await stringifyXML({ fruit: `` }, { rootName: "fruits" }); + assert.deepStrictEqual( + xml, + `` + ); + }); + + it("with element with value", async function() { + const xml: any = await stringifyXML({ fruit: `hurray` }, { rootName: "fruits" }); + assert.deepStrictEqual( + xml, + `hurray` + ); + }); + + it("with unwanted BOM characters", async function() { + const xml: any = await stringifyXML(`\uFEFFtext`, { rootName: "fruits" }); + assert.equal( + xml, + `text` + ); + }); + + it("with element with attribute", async function() { + const xml: any = await stringifyXML( + { + fruit: { + $: { + healthy: "true" + } + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `` + ); + }); + + it("with element with attribute and value", async function() { + const xml: any = await stringifyXML( + { + fruit: { + $: { + healthy: "true" + }, + _: "yum" + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `yum` + ); + }); + + it("with element with child empty element", async function() { + const xml: any = await stringifyXML( + { + fruit: { + apples: `` + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `` + ); + }); + + it("with element with child empty element with attribute", async function() { + const xml: any = await stringifyXML( + { + apples: { + $: { + tasty: "true" + } + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `` + ); + }); + + it("with element with child element with value", async function() { + const xml: any = await stringifyXML( + { + apples: "yum" + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `yum` + ); + }); + + it("with element with child element with attribute and value", async function() { + const xml: any = await stringifyXML( + { + apples: { + $: { + tasty: "true" + }, + _: "yum" + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( + xml, + `yum` + ); + }); }); it("should handle errors gracefully", async function() { From 2ca993fc069fcf3ae7b603fdf82153eaf1393a4f Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 15 Oct 2019 16:26:52 -0700 Subject: [PATCH 69/72] Address comments --- sdk/core/core-http/lib/util/constants.ts | 18 +----------------- sdk/core/core-http/lib/util/xml.ts | 10 ++-------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/sdk/core/core-http/lib/util/constants.ts b/sdk/core/core-http/lib/util/constants.ts index 73f9f121c015..909d2d21149f 100644 --- a/sdk/core/core-http/lib/util/constants.ts +++ b/sdk/core/core-http/lib/util/constants.ts @@ -94,21 +94,5 @@ export const Constants = { * @type {string} */ USER_AGENT: "User-Agent" - }, - - /** - * Marker for atom metadata. - * - * @const - * @type {string} - */ - XML_METADATA_MARKER: "$", - - /** - * Marker for atom value. - * - * @const - * @type {string} - */ - XML_VALUE_MARKER: "_" + } }; diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index d373cd875581..3bdd42bca0d5 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -54,11 +54,6 @@ const xml2jsDefaultOptionsV2 = { // The xml2js settings for general XML parsing operations. const xml2jsParserSettings: any = Object.assign({}, xml2jsDefaultOptionsV2); xml2jsParserSettings.explicitArray = false; -xml2jsParserSettings.explicitRoot = false; - -// The xml2js settings for ATOM XML parsing operations. -const xml2jsParserSettingsWithRoot: any = Object.assign({}, xml2jsDefaultOptionsV2); -xml2jsParserSettingsWithRoot.explicitArray = false; // The xml2js settings for general XML building operations. const xml2jsBuilderSettings: any = Object.assign({}, xml2jsDefaultOptionsV2); @@ -86,9 +81,8 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { * `includeRoot` indicates whether the root element is to be included or not in the output */ export function parseXML(str: string, opts?: { includeRoot?: boolean }): Promise { - const xml2jsSettings = - opts && opts.includeRoot ? xml2jsParserSettingsWithRoot : xml2jsParserSettings; - const xmlParser = new xml2js.Parser(xml2jsSettings); + xml2jsParserSettings.explicitRoot = !!(opts && opts.includeRoot); + const xmlParser = new xml2js.Parser(xml2jsParserSettings); return new Promise((resolve, reject) => { if (!str) { reject(new Error("Document is empty")); From 151ed1d9a4779d300b3f577b8b572946171e18d2 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Tue, 15 Oct 2019 19:04:16 -0700 Subject: [PATCH 70/72] Remove test coverage and BOM handling --- sdk/core/core-http/lib/util/utils.ts | 14 -- sdk/core/core-http/lib/util/xml.browser.ts | 18 +-- sdk/core/core-http/lib/util/xml.ts | 4 +- sdk/core/core-http/test/xmlTests.ts | 161 +++------------------ 4 files changed, 21 insertions(+), 176 deletions(-) diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index c94671da526e..2f076be25a7a 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -241,17 +241,3 @@ export function replaceAll( export function isPrimitiveType(value: any): boolean { return (typeof value !== "object" && typeof value !== "function") || value === null; } - -/** - * @ignore - * Helper utility to clean up unintended characters that get appended by OS. - * @param str - */ -export function removeBOM(str: any) { - if (typeof str == "string") { - if (str.charCodeAt(0) === 0xfeff || str.charCodeAt(0) === 0xffef) { - str = str.substring(1); - } - } - return str; -} diff --git a/sdk/core/core-http/lib/util/xml.browser.ts b/sdk/core/core-http/lib/util/xml.browser.ts index beecc19cf7d3..a63f33f667ec 100644 --- a/sdk/core/core-http/lib/util/xml.browser.ts +++ b/sdk/core/core-http/lib/util/xml.browser.ts @@ -1,22 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { removeBOM } from "./utils"; - // tslint:disable-next-line:no-null-keyword const doc = document.implementation.createDocument(null, null, null); const parser = new DOMParser(); export function parseXML(str: string, opts?: { includeRoot?: boolean }): Promise { try { - if (str == undefined || str == "") { - throw new Error("Document is empty"); - } - - if (!removeBOM(str).startsWith("<")) { - throw new Error("Non-whitespace before first tag"); - } - const dom = parser.parseFromString(str, "application/xml"); throwIfError(dom); @@ -116,14 +106,8 @@ function domToObject(node: Node): any { const serializer = new XMLSerializer(); export function stringifyXML(content: any, opts?: { rootName?: string }): string { - if (content == undefined) { - throw new Error("Cannot convert undefined or null to object"); - } - if (content == "") { - throw new Error("Missing element text"); - } const rootName = (opts && opts.rootName) || "root"; - const dom = buildNode(removeBOM(content), rootName)[0]; + const dom = buildNode(content, rootName)[0]; return ( '' + serializer.serializeToString(dom) ); diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index 3bdd42bca0d5..eda4d5a9db1d 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -3,8 +3,6 @@ import * as xml2js from "xml2js"; -import { removeBOM } from "./utils"; - // Note: The reason we re-define all of the xml2js default settings (version 2.0) here is because the default settings object exposed // by the xm2js library is mutable. See https://github.com/Leonidas-from-XIV/node-xml2js/issues/536 // By creating a new copy of the settings each time we instantiate the parser, @@ -71,7 +69,7 @@ xml2jsBuilderSettings.renderOpts = { export function stringifyXML(obj: any, opts?: { rootName?: string }) { xml2jsBuilderSettings.rootName = (opts || {}).rootName; const builder = new xml2js.Builder(xml2jsBuilderSettings); - return builder.buildObject(removeBOM(obj)); + return builder.buildObject(obj); } /** diff --git a/sdk/core/core-http/test/xmlTests.ts b/sdk/core/core-http/test/xmlTests.ts index 05ddab716dec..be2e5296aa30 100644 --- a/sdk/core/core-http/test/xmlTests.ts +++ b/sdk/core/core-http/test/xmlTests.ts @@ -113,63 +113,9 @@ describe("XML serializer", function() { } }); }); - - it("with unwanted BOM characters", async function() { - const xml: any = await parseXML("\uFEFFapple"); - assert.deepStrictEqual(xml, { fruit: "apple" }); - }); }); describe("parseXML(string) with root", function() { - it("with undefined", async function() { - try { - await parseXML(undefined as any, { includeRoot: true }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Document is empty"), - -1, - `error.message ("${err.message}") should have contained "Document is empty"` - ); - } - }); - - it("with null", async function() { - try { - // tslint:disable-next-line:no-null-keyword - await parseXML(null as any, { includeRoot: true }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Document is empty"), - -1, - `error.message ("${err.message}") should have contained "Document is empty"` - ); - } - }); - - it("with empty", async function() { - try { - await parseXML("", { includeRoot: true }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Document is empty"), - -1, - `error.message ("${err.message}") should have contained "Document is empty"` - ); - } - }); - - it("with text", async function() { - try { - await parseXML("Hello World!", { includeRoot: true }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Non-whitespace before first tag"), - -1, - `error.message ("${err.message}") should have contained "Non-whitespace before first tag"` - ); - } - }); - it("with empty element", async function() { const json: any = await parseXML("", { includeRoot: true }); assert.deepStrictEqual(json, { fruit: `` }); @@ -288,85 +234,6 @@ describe("XML serializer", function() { }); describe("stringifyXML(JSON) with root", function() { - it("with undefined", async function() { - try { - await stringifyXML(undefined as any); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Cannot convert undefined or null to object"), - -1, - `error.message ("${err.message}") should have contained "Cannot convert undefined or null to object"` - ); - } - }); - - it("with null", async function() { - try { - // tslint:disable-next-line:no-null-keyword - await stringifyXML(null as any); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Cannot convert undefined or null to object"), - -1, - `error.message ("${err.message}") should have contained "Cannot convert undefined or null to object"` - ); - } - }); - - it("with empty", async function() { - try { - await stringifyXML("", { rootName: "fruits" }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Missing element text"), - -1, - `error.message ("${err.message}") should have contained "Missing element text"` - ); - } - }); - - it("with text", async function() { - try { - await stringifyXML("Hello World!", { rootName: "fruits" }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Document is empty"), - -1, - `error.message ("${err.message}") should have contained "Document is empty"` - ); - } - }); - - it("with empty element", async function() { - try { - await stringifyXML({}, { rootName: "fruits" }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Missing element text"), - -1, - `error.message ("${err.message}") should have contained "Missing element text"` - ); - } - }); - - it("with no root element name", async function() { - try { - await stringifyXML({ - fruit: { - $: { - healthy: "true" - } - } - }); - } catch (err) { - assert.notStrictEqual( - err.message.indexOf("Root element needs a name"), - -1, - `error.message ("${err.message}") should have contained "Root element needs a name"` - ); - } - }); - it("with empty element with attribute", async function() { const xml: any = await stringifyXML( { @@ -400,28 +267,38 @@ describe("XML serializer", function() { ); }); - it("with unwanted BOM characters", async function() { - const xml: any = await stringifyXML(`\uFEFFtext`, { rootName: "fruits" }); - assert.equal( + it("with element with attribute", async function() { + const xml: any = await stringifyXML( + { + fruit: { + $: { + healthy: "true" + } + } + }, + { rootName: "fruits" } + ); + assert.deepStrictEqual( xml, - `text` + `` ); }); - it("with element with attribute", async function() { + it("with element with attribute and value", async function() { const xml: any = await stringifyXML( { fruit: { $: { healthy: "true" - } + }, + _: "yum" } }, { rootName: "fruits" } ); assert.deepStrictEqual( xml, - `` + `yum` ); }); @@ -443,11 +320,11 @@ describe("XML serializer", function() { ); }); - it("with element with child empty element", async function() { + it.only("with element with child undefined element", async function() { const xml: any = await stringifyXML( { fruit: { - apples: `` + apples: undefined } }, { rootName: "fruits" } From a426163dc324abad344d9145391eaf5e24502f3e Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 16 Oct 2019 10:05:20 -0700 Subject: [PATCH 71/72] Fix typo and tag --- sdk/core/core-http/lib/util/xml.ts | 2 +- sdk/core/core-http/test/xmlTests.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index eda4d5a9db1d..c6eb87cb0f4a 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -74,7 +74,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { /** * Converts given XML string into JSON - * @param str String containg the XML content to be parsed into JSON + * @param str String containing the XML content to be parsed into JSON * @param opts Options that govern the parsing of given xml string. * `includeRoot` indicates whether the root element is to be included or not in the output */ diff --git a/sdk/core/core-http/test/xmlTests.ts b/sdk/core/core-http/test/xmlTests.ts index be2e5296aa30..fd9f0d1fb831 100644 --- a/sdk/core/core-http/test/xmlTests.ts +++ b/sdk/core/core-http/test/xmlTests.ts @@ -320,7 +320,7 @@ describe("XML serializer", function() { ); }); - it.only("with element with child undefined element", async function() { + it("with element with child undefined element", async function() { const xml: any = await stringifyXML( { fruit: { From 4e2054edc50c2c72f992b18dec902722c894d407 Mon Sep 17 00:00:00 2001 From: Ramya Raja Date: Wed, 16 Oct 2019 10:59:24 -0700 Subject: [PATCH 72/72] Dummy commit --- sdk/core/core-http/lib/util/xml.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/core-http/lib/util/xml.ts b/sdk/core/core-http/lib/util/xml.ts index c6eb87cb0f4a..afff409a256a 100644 --- a/sdk/core/core-http/lib/util/xml.ts +++ b/sdk/core/core-http/lib/util/xml.ts @@ -63,7 +63,7 @@ xml2jsBuilderSettings.renderOpts = { /** * Converts given JSON object to XML string * @param obj JSON object to be converted into XML string - * @param opts Options that govern the parsing of given JSON object. + * @param opts Options that govern the parsing of given JSON object * `rootName` indicates the name of the root element in the resulting XML */ export function stringifyXML(obj: any, opts?: { rootName?: string }) { @@ -75,7 +75,7 @@ export function stringifyXML(obj: any, opts?: { rootName?: string }) { /** * Converts given XML string into JSON * @param str String containing the XML content to be parsed into JSON - * @param opts Options that govern the parsing of given xml string. + * @param opts Options that govern the parsing of given xml string * `includeRoot` indicates whether the root element is to be included or not in the output */ export function parseXML(str: string, opts?: { includeRoot?: boolean }): Promise {