From d828a1f042585feb0b8eb3c74cd17f0315d7a3b2 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Tue, 26 Jan 2021 12:00:05 -0800 Subject: [PATCH] Fix stringify error from resource deployment extension (#14059) * Fix stringify error from resource deployment extension * add comment --- .../resource-deployment/src/common/utils.ts | 19 +++++++++++++++++++ .../src/services/resourceTypeService.ts | 7 ++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/extensions/resource-deployment/src/common/utils.ts b/extensions/resource-deployment/src/common/utils.ts index 1be1206843..2dd8a56385 100644 --- a/extensions/resource-deployment/src/common/utils.ts +++ b/extensions/resource-deployment/src/common/utils.ts @@ -71,3 +71,22 @@ export async function tryExecuteAction(action: () => T | PromiseLike): Pro } return { result, error }; } + +export function deepClone(obj: T): T { + if (!obj || typeof obj !== 'object') { + return obj; + } + if (obj instanceof RegExp) { + // See https://github.com/Microsoft/TypeScript/issues/10990 + return obj as any; + } + const result: any = Array.isArray(obj) ? [] : {}; + Object.keys(obj).forEach((key: string) => { + if ((obj)[key] && typeof (obj)[key] === 'object') { + result[key] = deepClone((obj)[key]); + } else { + result[key] = (obj)[key]; + } + }); + return result; +} diff --git a/extensions/resource-deployment/src/services/resourceTypeService.ts b/extensions/resource-deployment/src/services/resourceTypeService.ts index dcc2a584fe..4e7b32bc34 100644 --- a/extensions/resource-deployment/src/services/resourceTypeService.ts +++ b/extensions/resource-deployment/src/services/resourceTypeService.ts @@ -17,6 +17,7 @@ import { IPlatformService } from './platformService'; import { IToolsService } from './toolsService'; import * as loc from './../localizedConstants'; import { ResourceTypeWizard } from '../ui/resourceTypeWizard'; +import { deepClone } from '../common/utils'; const localize = nls.loadMessageBundle(); @@ -40,7 +41,11 @@ export class ResourceTypeService implements IResourceTypeService { vscode.extensions.all.forEach((extension) => { const extensionResourceTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.resourceDeploymentTypes as ResourceType[]; if (extensionResourceTypes) { - extensionResourceTypes.forEach((resourceType: ResourceType) => { + extensionResourceTypes.forEach((extensionResourceType: ResourceType) => { + // Clone the object - we modify it by adding complex types and so if we modify the original contribution then + // we can break VS Code functionality since it will sometimes pass this object over the RPC layer which requires + // stringifying it - which can break with some of the complex types we add. + const resourceType = deepClone(extensionResourceType); this.updatePathProperties(resourceType, extension.extensionPath); resourceType.getProvider = (selectedOptions) => { return this.getProvider(resourceType, selectedOptions); }; resourceType.getOkButtonText = (selectedOptions) => { return this.getOkButtonText(resourceType, selectedOptions); };