From 8e7f72fa7058810157084bb9c7005cc4f5ce5706 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Tue, 17 Dec 2024 19:19:37 +0530 Subject: [PATCH 1/9] Add sovereign cloud endpoints for PPAPI service --- l10n/bundle.l10n.json | 1 + .../vscode-powerplatform.xlf | 3 ++ package.json | 1 + src/client/extension.ts | 6 ++-- .../runtime-site-preview/PreviewSite.ts | 7 ++++- src/common/services/AuthenticationProvider.ts | 29 +++++++++++++++++-- src/common/services/Constants.ts | 3 ++ src/common/services/PPAPIService.ts | 10 +++++-- 8 files changed, 52 insertions(+), 8 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 02f57d61..1da2a9f9 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -98,6 +98,7 @@ "Cancel": "Cancel", "Site runtime preview feature is not enabled.": "Site runtime preview feature is not enabled.", "No workspace folder opened. Please open a site folder to preview.": "No workspace folder opened. Please open a site folder to preview.", + "Initializing site preview. Please try again after few seconds.": "Initializing site preview. Please try again after few seconds.", "Website URL not found.": "Website URL not found.", "Opening site preview...": "Opening site preview...", "File might be referenced by name {0} here./{0} represents the name of the file": { diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index ca709b39..b599371f 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -214,6 +214,9 @@ Return to this chat and @powerpages can help you write and edit your website cod In your own words, describe what you need. You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages. + + Initializing site preview. Please try again after few seconds. + Insert code into editor diff --git a/package.json b/package.json index 85b0b689..ee051b59 100644 --- a/package.json +++ b/package.json @@ -372,6 +372,7 @@ }, { "command": "microsoft.powerplatform.pages.preview-site", + "category": "Powerpages", "title": "%powerplatform.pages.previewSite.title%" } ], diff --git a/src/client/extension.ts b/src/client/extension.ts index e58bcf24..b0763d24 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -196,7 +196,7 @@ export async function activate( ) || []; - let websiteURL: string | undefined = ""; + let websiteURL: string | undefined = undefined; const isSiteRuntimePreviewEnabled = PreviewSite.isSiteRuntimePreviewEnabled(); vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.siteRuntimePreviewEnabled", isSiteRuntimePreviewEnabled); @@ -282,11 +282,11 @@ export async function activate( _telemetry.sendTelemetryEvent("EnableSiteRuntimePreview", { isEnabled: isSiteRuntimePreviewEnabled.toString(), - websiteURL: websiteURL + websiteURL: websiteURL || "undefined" }); oneDSLoggerWrapper.getLogger().traceInfo("EnableSiteRuntimePreview", { isEnabled: isSiteRuntimePreviewEnabled.toString(), - websiteURL: websiteURL + websiteURL: websiteURL || "undefined" }); _context.subscriptions.push( diff --git a/src/client/runtime-site-preview/PreviewSite.ts b/src/client/runtime-site-preview/PreviewSite.ts index 66dc3d1b..6adfbbaa 100644 --- a/src/client/runtime-site-preview/PreviewSite.ts +++ b/src/client/runtime-site-preview/PreviewSite.ts @@ -89,7 +89,12 @@ export class PreviewSite { return; } - if (!websiteURL || websiteURL === "") { + if (websiteURL === undefined) { + await vscode.window.showWarningMessage(vscode.l10n.t("Initializing site preview. Please try again after few seconds.")); + return; + } + + if (websiteURL === "") { await vscode.window.showErrorMessage(vscode.l10n.t("Website URL not found.")); return; } diff --git a/src/common/services/AuthenticationProvider.ts b/src/common/services/AuthenticationProvider.ts index 34c3bdb6..4d2f284d 100644 --- a/src/common/services/AuthenticationProvider.ts +++ b/src/common/services/AuthenticationProvider.ts @@ -23,10 +23,35 @@ import { VSCODE_EXTENSION_PPAPI_WEBSITES_AUTHENTICATION_FAILED } from "./TelemetryConstants"; import { ERROR_CONSTANTS } from "../ErrorConstants"; -import { BAP_SERVICE_SCOPE_DEFAULT, INTELLIGENCE_SCOPE_DEFAULT, PPAPI_PREPROD_WEBSITES_SERVICE_SCOPE_DEFAULT, PPAPI_WEBSITES_SERVICE_SCOPE_DEFAULT, PROVIDER_ID, SCOPE_OPTION_CONTACTS_READ, SCOPE_OPTION_DEFAULT, SCOPE_OPTION_OFFLINE_ACCESS, SCOPE_OPTION_USERS_READ_BASIC_ALL, ServiceEndpointCategory } from "./Constants"; +import { + BAP_SERVICE_SCOPE_DEFAULT, + INTELLIGENCE_SCOPE_DEFAULT, + PPAPI_GCC_HIGH_DOD_WEBSITES_SERVICE_SCOPE_DEFAULT, + PPAPI_MOONCAKE_WEBSITES_SERVICE_SCOPE_DEFAULT, + PPAPI_PREPROD_WEBSITES_SERVICE_SCOPE_DEFAULT, + PPAPI_TEST_WEBSITES_SERVICE_SCOPE_DEFAULT, + PPAPI_WEBSITES_SERVICE_SCOPE_DEFAULT, + PROVIDER_ID, + SCOPE_OPTION_CONTACTS_READ, + SCOPE_OPTION_DEFAULT, + SCOPE_OPTION_OFFLINE_ACCESS, + SCOPE_OPTION_USERS_READ_BASIC_ALL, + ServiceEndpointCategory +} from "./Constants"; import jwt_decode from 'jwt-decode'; import { showErrorDialog } from "../utilities/errorHandlerUtil"; +const serviceScopeMapping: { [key in ServiceEndpointCategory]: string } = { + [ServiceEndpointCategory.NONE]: "", + [ServiceEndpointCategory.PROD]: PPAPI_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.PREPROD]: PPAPI_PREPROD_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.TEST]: PPAPI_TEST_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.MOONCAKE]: PPAPI_MOONCAKE_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.GCC]: PPAPI_GCC_HIGH_DOD_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.DOD]: PPAPI_GCC_HIGH_DOD_WEBSITES_SERVICE_SCOPE_DEFAULT, + [ServiceEndpointCategory.HIGH]: PPAPI_GCC_HIGH_DOD_WEBSITES_SERVICE_SCOPE_DEFAULT, +}; + export function getCommonHeadersForDataverse( accessToken: string, useOctetStreamContentType?: boolean @@ -300,7 +325,7 @@ export async function powerPlatformAPIAuthentication( firstTimeAuth = false ): Promise { let accessToken = ""; - const PPAPI_WEBSITES_ENDPOINT = [ServiceEndpointCategory.TEST, ServiceEndpointCategory.PREPROD].includes(serviceEndpointStamp) ? PPAPI_PREPROD_WEBSITES_SERVICE_SCOPE_DEFAULT : PPAPI_WEBSITES_SERVICE_SCOPE_DEFAULT; + const PPAPI_WEBSITES_ENDPOINT = serviceScopeMapping[serviceEndpointStamp]; try { let session = await vscode.authentication.getSession( PROVIDER_ID, diff --git a/src/common/services/Constants.ts b/src/common/services/Constants.ts index a77791ab..91119527 100644 --- a/src/common/services/Constants.ts +++ b/src/common/services/Constants.ts @@ -23,6 +23,9 @@ export const BAP_ENVIRONMENT_LIST_URL = `scopes/admin/environments?api-version={ export const PPAPI_WEBSITES_API_VERSION = '2022-03-01-preview'; export const PPAPI_WEBSITES_SERVICE_SCOPE_DEFAULT = "https://api.powerplatform.com/.default"; export const PPAPI_PREPROD_WEBSITES_SERVICE_SCOPE_DEFAULT = "https://api.preprod.powerplatform.com/.default"; +export const PPAPI_TEST_WEBSITES_SERVICE_SCOPE_DEFAULT = "https://api.test.powerplatform.com/.default"; +export const PPAPI_MOONCAKE_WEBSITES_SERVICE_SCOPE_DEFAULT = "https://api.powerplatform.cn/.default"; +export const PPAPI_GCC_HIGH_DOD_WEBSITES_SERVICE_SCOPE_DEFAULT = "https://api.powerplatform.us/.default"; export const PPAPI_WEBSITES_ENDPOINT = `{rootURL}/powerpages/environments/{environmentId}/websites`; export enum ServiceEndpointCategory { diff --git a/src/common/services/PPAPIService.ts b/src/common/services/PPAPIService.ts index 438d3e27..79217703 100644 --- a/src/common/services/PPAPIService.ts +++ b/src/common/services/PPAPIService.ts @@ -93,11 +93,17 @@ export class PPAPIService { case ServiceEndpointCategory.PROD: ppapiEndpoint = "https://api.powerplatform.com"; break; - // All below endpoints are not supported yet case ServiceEndpointCategory.DOD: + ppapiEndpoint = "https://api.powerplatform.us"; + break; case ServiceEndpointCategory.GCC: - case ServiceEndpointCategory.HIGH: + ppapiEndpoint = "https://api.powerplatform.us"; + break; case ServiceEndpointCategory.MOONCAKE: + ppapiEndpoint = "https://api.powerplatform.cn"; + break; + // Below endpoints are not supported yet + case ServiceEndpointCategory.HIGH: default: sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_GET_PPAPI_WEBSITES_ENDPOINT_UNSUPPORTED_REGION, data: serviceEndpointStamp }); break; From 64c0c11c664a3095aa2c62f2087f104cd13922b3 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Wed, 8 Jan 2025 12:29:23 +0530 Subject: [PATCH 2/9] Fixes --- package.json | 2 +- .../runtime-site-preview/PreviewSite.ts | 35 ++++++++++++------- .../controls/ShowProgressNotification.ts | 19 ---------- src/common/services/PPAPIService.ts | 9 +---- 4 files changed, 25 insertions(+), 40 deletions(-) delete mode 100644 src/common/controls/ShowProgressNotification.ts diff --git a/package.json b/package.json index ee051b59..5fd05b8a 100644 --- a/package.json +++ b/package.json @@ -819,7 +819,7 @@ }, { "command": "microsoft.powerplatform.pages.preview-site", - "when": "microsoft.powerplatform.pages.siteRuntimePreviewEnabled" + "when": "microsoft.powerplatform.pages.siteRuntimePreviewEnabled && workspaceFolderCount == 1 && !isWeb" } ], "view/title": [ diff --git a/src/client/runtime-site-preview/PreviewSite.ts b/src/client/runtime-site-preview/PreviewSite.ts index 6adfbbaa..034eb68b 100644 --- a/src/client/runtime-site-preview/PreviewSite.ts +++ b/src/client/runtime-site-preview/PreviewSite.ts @@ -9,12 +9,12 @@ import { EnableSiteRuntimePreview } from '../../common/ecs-features/ecsFeatureGa import { ITelemetry } from '../../common/OneDSLoggerTelemetry/telemetry/ITelemetry'; import { WorkspaceFolder } from 'vscode-languageclient/node'; import { getWebsiteRecordId } from '../../common/utilities/WorkspaceInfoFinderUtil'; -import { ServiceEndpointCategory } from '../../common/services/Constants'; +import { PROVIDER_ID, ServiceEndpointCategory } from '../../common/services/Constants'; import { PPAPIService } from '../../common/services/PPAPIService'; import { VSCODE_EXTENSION_GET_WEBSITE_RECORD_ID_EMPTY } from '../../common/services/TelemetryConstants'; import { EDGE_TOOLS_EXTENSION_ID } from '../../common/constants'; import { oneDSLoggerWrapper } from "../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper"; -import { showProgressNotification } from '../../common/controls/ShowProgressNotification'; +import { showProgressWithNotification } from '../../common/utilities/Utils'; export const SITE_PREVIEW_COMMAND_ID = "microsoft.powerplatform.pages.preview-site"; @@ -64,11 +64,16 @@ export class PreviewSite { return; } - const settings = vscode.workspace.getConfiguration('vscode-edge-devtools'); - const currentDefaultUrl = await settings.get('defaultUrl'); - await settings.update('defaultUrl', webSitePreviewURL); - await vscode.commands.executeCommand('vscode-edge-devtools-view.launch'); - await settings.update('defaultUrl', currentDefaultUrl); + await showProgressWithNotification( + vscode.l10n.t('Opening site preview...'), + async () => { + const settings = vscode.workspace.getConfiguration('vscode-edge-devtools'); + const currentDefaultUrl = await settings.get('defaultUrl'); + await settings.update('defaultUrl', webSitePreviewURL); + await vscode.commands.executeCommand('vscode-edge-devtools-view.launch'); + await settings.update('defaultUrl', currentDefaultUrl); + } + ); } static async handlePreviewRequest(isSiteRuntimePreviewEnabled: boolean, websiteURL: string | undefined, telemetry: ITelemetry) { @@ -95,13 +100,19 @@ export class PreviewSite { } if (websiteURL === "") { - await vscode.window.showErrorMessage(vscode.l10n.t("Website URL not found.")); + const shouldInitiateLogin = await vscode.window.showErrorMessage( + vscode.l10n.t( + `Website not found in the environment. Please check the credentials and login with correct account.` + ), + vscode.l10n.t('Login') + ); + + if (shouldInitiateLogin === vscode.l10n.t('Login')) { + await vscode.authentication.getSession(PROVIDER_ID, [], { }) + } return; } - await showProgressNotification( - vscode.l10n.t('Opening site preview...'), - async () => await PreviewSite.launchBrowserAndDevToolsWithinVsCode(websiteURL) - ); + await PreviewSite.launchBrowserAndDevToolsWithinVsCode(websiteURL); } } diff --git a/src/common/controls/ShowProgressNotification.ts b/src/common/controls/ShowProgressNotification.ts deleted file mode 100644 index 5a7c606f..00000000 --- a/src/common/controls/ShowProgressNotification.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - */ - -import * as vscode from 'vscode'; -import { Progress } from 'vscode'; -import { CancellationToken } from 'vscode-languageserver'; - -export async function showProgressNotification(title: string, task: (progress: Progress<{ - message: string; - increment?: number; -}>, token: CancellationToken) => Thenable) { - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title, - cancellable: false - }, async (progress, token) => await task(progress, token)); -} diff --git a/src/common/services/PPAPIService.ts b/src/common/services/PPAPIService.ts index 79217703..ec74215d 100644 --- a/src/common/services/PPAPIService.ts +++ b/src/common/services/PPAPIService.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import * as vscode from 'vscode'; import { ITelemetry } from "../OneDSLoggerTelemetry/telemetry/ITelemetry"; import { getCommonHeaders, powerPlatformAPIAuthentication } from "./AuthenticationProvider"; import { VSCODE_EXTENSION_SERVICE_STAMP_NOT_FOUND, VSCODE_EXTENSION_GET_CROSS_GEO_DATA_MOVEMENT_ENABLED_FLAG_FAILED, VSCODE_EXTENSION_GET_PPAPI_WEBSITES_ENDPOINT_UNSUPPORTED_REGION, @@ -49,14 +48,8 @@ export class PPAPIService { if (websiteDetails) { sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_PPAPI_GET_WEBSITE_BY_RECORD_ID_COMPLETED, orgUrl: websiteDetails.dataverseInstanceUrl }); return websiteDetails; - } else { - // Showing a warning message when the website is not found in the environment - vscode.window.showWarningMessage( - vscode.l10n.t( - `Website not found in the environment. Please check the credentials and root folder path.` - ) - ); } + return null; } From 1e2f890bef1de0ed7a6cccb566c1c1194dc70583 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Thu, 9 Jan 2025 16:48:52 +0530 Subject: [PATCH 3/9] Fix bugs --- src/client/extension.ts | 17 ++-- .../runtime-site-preview/PreviewSite.ts | 99 ++++++++++++++++--- src/common/utilities/Utils.ts | 17 +++- 3 files changed, 103 insertions(+), 30 deletions(-) diff --git a/src/client/extension.ts b/src/client/extension.ts index b0763d24..5cda823c 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -44,7 +44,7 @@ import { EXTENSION_ID, SUCCESS } from "../common/constants"; import { AadIdKey, EnvIdKey, TenantIdKey } from "../common/OneDSLoggerTelemetry/telemetryConstants"; import { PowerPagesAppName, PowerPagesClientName } from "../common/ecs-features/constants"; import { ECSFeaturesClient } from "../common/ecs-features/ecsFeatureClient"; -import { getECSOrgLocationValue } from "../common/utilities/Utils"; +import { getECSOrgLocationValue, getWorkspaceFolders } from "../common/utilities/Utils"; import { CliAcquisitionContext } from "./lib/CliAcquisitionContext"; import { PreviewSite, SITE_PREVIEW_COMMAND_ID } from "./runtime-site-preview/PreviewSite"; @@ -190,13 +190,8 @@ export async function activate( let copilotNotificationShown = false; - const workspaceFolders = - vscode.workspace.workspaceFolders?.map( - (fl) => ({ ...fl, uri: fl.uri.fsPath } as WorkspaceFolder) - ) || []; - + const workspaceFolders = getWorkspaceFolders(); - let websiteURL: string | undefined = undefined; const isSiteRuntimePreviewEnabled = PreviewSite.isSiteRuntimePreviewEnabled(); vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.siteRuntimePreviewEnabled", isSiteRuntimePreviewEnabled); @@ -257,7 +252,7 @@ export async function activate( } if (artemisResponse !== null && isSiteRuntimePreviewEnabled) { - websiteURL = await PreviewSite.getWebSiteURL(workspaceFolders, artemisResponse?.stamp, orgDetails.EnvironmentId, _telemetry); + await PreviewSite.loadSiteUrl(workspaceFolders, artemisResponse?.stamp, orgDetails.EnvironmentId, _telemetry); } }) @@ -282,17 +277,17 @@ export async function activate( _telemetry.sendTelemetryEvent("EnableSiteRuntimePreview", { isEnabled: isSiteRuntimePreviewEnabled.toString(), - websiteURL: websiteURL || "undefined" + websiteURL: PreviewSite.getSiteUrl() || "undefined" }); oneDSLoggerWrapper.getLogger().traceInfo("EnableSiteRuntimePreview", { isEnabled: isSiteRuntimePreviewEnabled.toString(), - websiteURL: websiteURL || "undefined" + websiteURL: PreviewSite.getSiteUrl() || "undefined" }); _context.subscriptions.push( vscode.commands.registerCommand( SITE_PREVIEW_COMMAND_ID, - async () => await PreviewSite.handlePreviewRequest(isSiteRuntimePreviewEnabled, websiteURL, _telemetry) + async () => await PreviewSite.handlePreviewRequest(isSiteRuntimePreviewEnabled, _telemetry, pacTerminal) ) ); diff --git a/src/client/runtime-site-preview/PreviewSite.ts b/src/client/runtime-site-preview/PreviewSite.ts index 034eb68b..b94fa815 100644 --- a/src/client/runtime-site-preview/PreviewSite.ts +++ b/src/client/runtime-site-preview/PreviewSite.ts @@ -14,11 +14,16 @@ import { PPAPIService } from '../../common/services/PPAPIService'; import { VSCODE_EXTENSION_GET_WEBSITE_RECORD_ID_EMPTY } from '../../common/services/TelemetryConstants'; import { EDGE_TOOLS_EXTENSION_ID } from '../../common/constants'; import { oneDSLoggerWrapper } from "../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper"; -import { showProgressWithNotification } from '../../common/utilities/Utils'; +import { getWorkspaceFolders, showProgressWithNotification } from '../../common/utilities/Utils'; +import { PacTerminal } from '../lib/PacTerminal'; +import { initializeOrgDetails } from '../../common/utilities/OrgHandlerUtils'; +import { ArtemisService } from '../../common/services/ArtemisService'; export const SITE_PREVIEW_COMMAND_ID = "microsoft.powerplatform.pages.preview-site"; export class PreviewSite { + private static _websiteUrl: string | undefined = undefined; + static isSiteRuntimePreviewEnabled(): boolean { const enableSiteRuntimePreview = ECSFeaturesClient.getConfig(EnableSiteRuntimePreview).enableSiteRuntimePreview @@ -26,10 +31,25 @@ export class PreviewSite { return false; } - return enableSiteRuntimePreview; + return true; + } + + static async loadSiteUrl( + workspaceFolders: WorkspaceFolder[], + stamp: ServiceEndpointCategory, + envId: string, + telemetry: ITelemetry) + : Promise { + const websiteUrl = await PreviewSite.getWebSiteUrl(workspaceFolders, stamp, envId, telemetry); + + this._websiteUrl = websiteUrl; } - static async getWebSiteURL(workspaceFolders: WorkspaceFolder[], stamp: ServiceEndpointCategory, envId: string, telemetry: ITelemetry): Promise { + static getSiteUrl(): string | undefined { + return this._websiteUrl; + } + + private static async getWebSiteUrl(workspaceFolders: WorkspaceFolder[], stamp: ServiceEndpointCategory, envId: string, telemetry: ITelemetry): Promise { const websiteRecordId = getWebsiteRecordId(workspaceFolders, telemetry); if (!websiteRecordId) { telemetry.sendTelemetryEvent(VSCODE_EXTENSION_GET_WEBSITE_RECORD_ID_EMPTY, { @@ -74,9 +94,15 @@ export class PreviewSite { await settings.update('defaultUrl', currentDefaultUrl); } ); + + await vscode.window.showInformationMessage(vscode.l10n.t('The preview shown is for published changes.')); } - static async handlePreviewRequest(isSiteRuntimePreviewEnabled: boolean, websiteURL: string | undefined, telemetry: ITelemetry) { + static async handlePreviewRequest( + isSiteRuntimePreviewEnabled: boolean, + telemetry: ITelemetry, + pacTerminal: PacTerminal) { + telemetry.sendTelemetryEvent("StartCommand", { commandId: SITE_PREVIEW_COMMAND_ID, }); @@ -94,25 +120,66 @@ export class PreviewSite { return; } - if (websiteURL === undefined) { + if (this._websiteUrl === undefined) { await vscode.window.showWarningMessage(vscode.l10n.t("Initializing site preview. Please try again after few seconds.")); return; } - if (websiteURL === "") { - const shouldInitiateLogin = await vscode.window.showErrorMessage( - vscode.l10n.t( - `Website not found in the environment. Please check the credentials and login with correct account.` - ), - vscode.l10n.t('Login') - ); + if (this._websiteUrl === "") { + let shouldRepeatLoginFlow = true; - if (shouldInitiateLogin === vscode.l10n.t('Login')) { - await vscode.authentication.getSession(PROVIDER_ID, [], { }) + while (shouldRepeatLoginFlow) { + shouldRepeatLoginFlow = await PreviewSite.handleEmptyWebsiteUrl(pacTerminal, telemetry); } - return; } - await PreviewSite.launchBrowserAndDevToolsWithinVsCode(websiteURL); + await PreviewSite.launchBrowserAndDevToolsWithinVsCode(this._websiteUrl); + } + + private static async handleEmptyWebsiteUrl(pacTerminal: PacTerminal, telemetry: ITelemetry): Promise { + const shouldInitiateLogin = await vscode.window.showErrorMessage( + vscode.l10n.t( + `Website not found in the environment. Please check the credentials and login with correct account.` + ), + vscode.l10n.t('Login'), + vscode.l10n.t('Cancel') + ); + + let shouldRepeatLoginFlow = false; + + if (shouldInitiateLogin === vscode.l10n.t('Login')) { + await vscode.authentication.getSession(PROVIDER_ID, [], { forceNewSession: true, clearSessionPreference: true }); + + await showProgressWithNotification( + vscode.l10n.t('Initializing site preview'), + async (progress) => { + progress.report({ message: vscode.l10n.t('Getting org details...') }); + + const orgDetails = await initializeOrgDetails(false, pacTerminal.getWrapper()); + + progress.report({ message: vscode.l10n.t('Getting region information...') }); + + const artemisResponse = await ArtemisService.getArtemisResponse(orgDetails.orgID, telemetry, ""); + + if (artemisResponse === null || artemisResponse.response === null) { + vscode.window.showErrorMessage(vscode.l10n.t("Failed to get website endpoint. Please try again later")); + return; + } + + progress.report({ message: vscode.l10n.t('Getting website endpoint...') }); + + const websiteUrl = await PreviewSite.getWebSiteUrl(getWorkspaceFolders(), artemisResponse?.stamp, orgDetails.environmentID, telemetry); + + if (websiteUrl === "") { + shouldRepeatLoginFlow = true; + } + else { + this._websiteUrl = websiteUrl; + } + } + ); + } + + return shouldRepeatLoginFlow; } } diff --git a/src/common/utilities/Utils.ts b/src/common/utilities/Utils.ts index c53080eb..810d8a15 100644 --- a/src/common/utilities/Utils.ts +++ b/src/common/utilities/Utils.ts @@ -17,6 +17,8 @@ import { oneDSLoggerWrapper } from "../OneDSLoggerTelemetry/oneDSLoggerWrapper"; import { bapServiceAuthentication } from "../services/AuthenticationProvider"; import { BAP_API_VERSION, BAP_ENVIRONMENT_LIST_URL, BAP_SERVICE_ENDPOINT, ServiceEndpointCategory } from "../services/Constants"; import { VSCODE_EXTENSION_GET_ENV_LIST_SUCCESS, VSCODE_EXTENSION_GET_ENV_LIST_FAILED, VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION } from "../services/TelemetryConstants"; +import { WorkspaceFolder } from "vscode-languageserver"; +import { Progress } from "vscode"; export function getSelectedCode(editor: vscode.TextEditor): string { if (!editor) { @@ -104,13 +106,16 @@ export async function showInputBoxAndGetOrgUrl() { }); } -export async function showProgressWithNotification(title: string, task: () => Promise): Promise { +export async function showProgressWithNotification(title: string, task: (progress: Progress<{ + message?: string; + increment?: number; +}>) => Promise): Promise { return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: title, cancellable: false - }, async () => { - return await task(); + }, async (progress) => { + return await task(progress); }); } @@ -397,3 +402,9 @@ export function getBAPEndpoint(serviceEndpointStamp: ServiceEndpointCategory, te return BAP_SERVICE_ENDPOINT.replace('{rootURL}', bapEndpoint) } + +export function getWorkspaceFolders(): WorkspaceFolder[] { + return vscode.workspace.workspaceFolders?.map( + (fl) => ({ ...fl, uri: fl.uri.fsPath } as WorkspaceFolder) + ) || []; +} From 9c86515f484c31103979a072b251f5a66b1dc177 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Thu, 9 Jan 2025 17:01:29 +0530 Subject: [PATCH 4/9] Update translations --- l10n/bundle.l10n.json | 11 +++++--- .../vscode-powerplatform.xlf | 25 +++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 1da2a9f9..0e749849 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -33,7 +33,6 @@ }, "Enter the environment URL": "Enter the environment URL", "Active auth profile is not found or has expired. To create a new auth profile, enter the environment URL.": "Active auth profile is not found or has expired. To create a new auth profile, enter the environment URL.", - "Website not found in the environment. Please check the credentials and root folder path.": "Website not found in the environment. Please check the credentials and root folder path.", "Selection is empty.": "Selection is empty.", "PREVIEW": "PREVIEW", "Explain the following code snippet:": "Explain the following code snippet:", @@ -96,11 +95,17 @@ "The extension Microsoft Edge Tools is required to run this command. Do you want to install it now?": "The extension Microsoft Edge Tools is required to run this command. Do you want to install it now?", "Install": "Install", "Cancel": "Cancel", + "Opening site preview...": "Opening site preview...", + "The preview shown is for published changes.": "The preview shown is for published changes.", "Site runtime preview feature is not enabled.": "Site runtime preview feature is not enabled.", "No workspace folder opened. Please open a site folder to preview.": "No workspace folder opened. Please open a site folder to preview.", "Initializing site preview. Please try again after few seconds.": "Initializing site preview. Please try again after few seconds.", - "Website URL not found.": "Website URL not found.", - "Opening site preview...": "Opening site preview...", + "Website not found in the environment. Please check the credentials and login with correct account.": "Website not found in the environment. Please check the credentials and login with correct account.", + "Initializing site preview": "Initializing site preview", + "Getting org details...": "Getting org details...", + "Getting region information...": "Getting region information...", + "Failed to get website endpoint. Please try again later": "Failed to get website endpoint. Please try again later", + "Getting website endpoint...": "Getting website endpoint...", "File might be referenced by name {0} here./{0} represents the name of the file": { "message": "File might be referenced by name {0} here.", "comment": [ diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index b599371f..81d5e203 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -162,6 +162,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Failed to get file ready for edit: {0} + + Failed to get website endpoint. Please try again later + Feature is not enabled for this geo. @@ -190,6 +193,15 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Get GitHub Copilot to try @powerpages + + Getting org details... + + + Getting region information... + + + Getting website endpoint... + Here are a few suggestions to get you started @@ -214,6 +226,9 @@ Return to this chat and @powerpages can help you write and edit your website cod In your own words, describe what you need. You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages. + + Initializing site preview + Initializing site preview. Please try again after few seconds. @@ -415,6 +430,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) The pac CLI is ready for use in your VS Code terminal! + + The preview shown is for published changes. + There was a permissions problem with the server @@ -467,11 +485,8 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Webpage names should contain only letters, numbers, hyphens, or underscores. - - Website URL not found. - - - Website not found in the environment. Please check the credentials and root folder path. + + Website not found in the environment. Please check the credentials and login with correct account. What do you need help with? From d49cac39fd1b8775523c1d4d63274900234b7019 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Thu, 9 Jan 2025 18:53:30 +0530 Subject: [PATCH 5/9] Update command name --- src/client/runtime-site-preview/PreviewSite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/runtime-site-preview/PreviewSite.ts b/src/client/runtime-site-preview/PreviewSite.ts index b94fa815..d36396ea 100644 --- a/src/client/runtime-site-preview/PreviewSite.ts +++ b/src/client/runtime-site-preview/PreviewSite.ts @@ -90,7 +90,7 @@ export class PreviewSite { const settings = vscode.workspace.getConfiguration('vscode-edge-devtools'); const currentDefaultUrl = await settings.get('defaultUrl'); await settings.update('defaultUrl', webSitePreviewURL); - await vscode.commands.executeCommand('vscode-edge-devtools-view.launch'); + await vscode.commands.executeCommand('vscode-edge-devtools.launch'); await settings.update('defaultUrl', currentDefaultUrl); } ); From 69fda095ee637d936933e39b97ce930dd8db6b63 Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Wed, 15 Jan 2025 18:21:14 +0530 Subject: [PATCH 6/9] Rename folder --- src/client/extension.ts | 2 +- .../{runtime-site-preview => preview-site}/PreviewSite.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/client/{runtime-site-preview => preview-site}/PreviewSite.ts (100%) diff --git a/src/client/extension.ts b/src/client/extension.ts index 5cda823c..970ea135 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -46,7 +46,7 @@ import { PowerPagesAppName, PowerPagesClientName } from "../common/ecs-features/ import { ECSFeaturesClient } from "../common/ecs-features/ecsFeatureClient"; import { getECSOrgLocationValue, getWorkspaceFolders } from "../common/utilities/Utils"; import { CliAcquisitionContext } from "./lib/CliAcquisitionContext"; -import { PreviewSite, SITE_PREVIEW_COMMAND_ID } from "./runtime-site-preview/PreviewSite"; +import { PreviewSite, SITE_PREVIEW_COMMAND_ID } from "./preview-site/PreviewSite"; let client: LanguageClient; let _context: vscode.ExtensionContext; diff --git a/src/client/runtime-site-preview/PreviewSite.ts b/src/client/preview-site/PreviewSite.ts similarity index 100% rename from src/client/runtime-site-preview/PreviewSite.ts rename to src/client/preview-site/PreviewSite.ts From dd665263bbee518e009297d32b8a0bbfeb61e98e Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Wed, 15 Jan 2025 19:25:14 +0530 Subject: [PATCH 7/9] Move messages to constants --- l10n/bundle.l10n.json | 11 +++-- .../vscode-powerplatform.xlf | 9 ++-- src/client/preview-site/Constants.ts | 24 +++++++++++ src/client/preview-site/PreviewSite.ts | 41 +++++++++---------- 4 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 src/client/preview-site/Constants.ts diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 0e749849..e914c279 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -92,9 +92,14 @@ "Do not translate 'PCF' as it is a product name." ] }, - "The extension Microsoft Edge Tools is required to run this command. Do you want to install it now?": "The extension Microsoft Edge Tools is required to run this command. Do you want to install it now?", - "Install": "Install", "Cancel": "Cancel", + "Install": "Install", + "The extension 'Microsoft Edge Tools' is required to run this command. Do you want to install it now?/Do not translate 'Microsoft Edge Tools' ": { + "message": "The extension 'Microsoft Edge Tools' is required to run this command. Do you want to install it now?", + "comment": [ + "Do not translate 'Microsoft Edge Tools' " + ] + }, "Opening site preview...": "Opening site preview...", "The preview shown is for published changes.": "The preview shown is for published changes.", "Site runtime preview feature is not enabled.": "Site runtime preview feature is not enabled.", @@ -102,7 +107,7 @@ "Initializing site preview. Please try again after few seconds.": "Initializing site preview. Please try again after few seconds.", "Website not found in the environment. Please check the credentials and login with correct account.": "Website not found in the environment. Please check the credentials and login with correct account.", "Initializing site preview": "Initializing site preview", - "Getting org details...": "Getting org details...", + "Getting organization details...": "Getting organization details...", "Getting region information...": "Getting region information...", "Failed to get website endpoint. Please try again later": "Failed to get website endpoint. Please try again later", "Getting website endpoint...": "Getting website endpoint...", diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index 81d5e203..dce0833e 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -193,8 +193,8 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Get GitHub Copilot to try @powerpages - - Getting org details... + + Getting organization details... Getting region information... @@ -421,8 +421,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) The Power Pages generator is ready for use in your VS Code extension! - - The extension Microsoft Edge Tools is required to run this command. Do you want to install it now? + + The extension 'Microsoft Edge Tools' is required to run this command. Do you want to install it now? + Do not translate 'Microsoft Edge Tools' The name you want to give to this authentication profile diff --git a/src/client/preview-site/Constants.ts b/src/client/preview-site/Constants.ts new file mode 100644 index 00000000..10a2d914 --- /dev/null +++ b/src/client/preview-site/Constants.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import * as vscode from 'vscode'; + +export const Messages = { + LOGIN: vscode.l10n.t("Login"), + CANCEL: vscode.l10n.t("Cancel"), + INSTALL: vscode.l10n.t("Install"), + EDGE_DEV_TOOLS_NOT_INSTALLED_MESSAGE: vscode.l10n.t({ message: "The extension 'Microsoft Edge Tools' is required to run this command. Do you want to install it now?", comment:["Do not translate 'Microsoft Edge Tools' "] }), + OPENING_SITE_PREVIEW: vscode.l10n.t("Opening site preview..."), + PREVIEW_SHOWN_FOR_PUBLISHED_CHANGES: vscode.l10n.t("The preview shown is for published changes."), + SITE_PREVIEW_FEATURE_NOT_ENABLED: vscode.l10n.t("Site runtime preview feature is not enabled."), + NO_FOLDER_OPENED: vscode.l10n.t("No workspace folder opened. Please open a site folder to preview."), + INITIALIZING_PREVIEW_TRY_AGAIN: vscode.l10n.t("Initializing site preview. Please try again after few seconds."), + WEBSITE_NOT_FOUND_IN_ENVIRONMENT: vscode.l10n.t("Website not found in the environment. Please check the credentials and login with correct account."), + INITIALIZING_PREVIEW: vscode.l10n.t("Initializing site preview"), + GETTING_ORG_DETAILS: vscode.l10n.t("Getting organization details..."), + GETTING_REGION_INFORMATION: vscode.l10n.t("Getting region information..."), + FAILED_TO_GET_ENDPOINT: vscode.l10n.t("Failed to get website endpoint. Please try again later"), + GETTING_WEBSITE_ENDPOINT: vscode.l10n.t("Getting website endpoint...") +}; diff --git a/src/client/preview-site/PreviewSite.ts b/src/client/preview-site/PreviewSite.ts index d36396ea..d8f5d851 100644 --- a/src/client/preview-site/PreviewSite.ts +++ b/src/client/preview-site/PreviewSite.ts @@ -18,6 +18,7 @@ import { getWorkspaceFolders, showProgressWithNotification } from '../../common/ import { PacTerminal } from '../lib/PacTerminal'; import { initializeOrgDetails } from '../../common/utilities/OrgHandlerUtils'; import { ArtemisService } from '../../common/services/ArtemisService'; +import { Messages } from './Constants'; export const SITE_PREVIEW_COMMAND_ID = "microsoft.powerplatform.pages.preview-site"; @@ -70,14 +71,12 @@ export class PreviewSite { if (!edgeToolsExtension) { const install = await vscode.window.showWarningMessage( - vscode.l10n.t( - `The extension Microsoft Edge Tools is required to run this command. Do you want to install it now?` - ), - vscode.l10n.t('Install'), - vscode.l10n.t('Cancel') + Messages.EDGE_DEV_TOOLS_NOT_INSTALLED_MESSAGE, + Messages.INSTALL, + Messages.CANCEL ); - if (install === vscode.l10n.t('Install')) { + if (install === Messages.INSTALL) { await vscode.commands.executeCommand('workbench.extensions.search', EDGE_TOOLS_EXTENSION_ID); } @@ -85,7 +84,7 @@ export class PreviewSite { } await showProgressWithNotification( - vscode.l10n.t('Opening site preview...'), + Messages.OPENING_SITE_PREVIEW, async () => { const settings = vscode.workspace.getConfiguration('vscode-edge-devtools'); const currentDefaultUrl = await settings.get('defaultUrl'); @@ -95,7 +94,7 @@ export class PreviewSite { } ); - await vscode.window.showInformationMessage(vscode.l10n.t('The preview shown is for published changes.')); + await vscode.window.showInformationMessage(Messages.PREVIEW_SHOWN_FOR_PUBLISHED_CHANGES); } static async handlePreviewRequest( @@ -111,17 +110,17 @@ export class PreviewSite { }); if (!isSiteRuntimePreviewEnabled) { - await vscode.window.showInformationMessage(vscode.l10n.t("Site runtime preview feature is not enabled.")); + await vscode.window.showInformationMessage(Messages.SITE_PREVIEW_FEATURE_NOT_ENABLED); return; } if (!vscode.workspace.workspaceFolders) { - await vscode.window.showErrorMessage(vscode.l10n.t("No workspace folder opened. Please open a site folder to preview.")); + await vscode.window.showErrorMessage(Messages.NO_FOLDER_OPENED); return; } if (this._websiteUrl === undefined) { - await vscode.window.showWarningMessage(vscode.l10n.t("Initializing site preview. Please try again after few seconds.")); + await vscode.window.showWarningMessage(Messages.INITIALIZING_PREVIEW_TRY_AGAIN); return; } @@ -138,35 +137,33 @@ export class PreviewSite { private static async handleEmptyWebsiteUrl(pacTerminal: PacTerminal, telemetry: ITelemetry): Promise { const shouldInitiateLogin = await vscode.window.showErrorMessage( - vscode.l10n.t( - `Website not found in the environment. Please check the credentials and login with correct account.` - ), - vscode.l10n.t('Login'), - vscode.l10n.t('Cancel') + Messages.WEBSITE_NOT_FOUND_IN_ENVIRONMENT, + Messages.LOGIN, + Messages.CANCEL ); let shouldRepeatLoginFlow = false; - if (shouldInitiateLogin === vscode.l10n.t('Login')) { + if (shouldInitiateLogin === Messages.LOGIN) { await vscode.authentication.getSession(PROVIDER_ID, [], { forceNewSession: true, clearSessionPreference: true }); await showProgressWithNotification( - vscode.l10n.t('Initializing site preview'), + Messages.INITIALIZING_PREVIEW, async (progress) => { - progress.report({ message: vscode.l10n.t('Getting org details...') }); + progress.report({ message: Messages.GETTING_ORG_DETAILS }); const orgDetails = await initializeOrgDetails(false, pacTerminal.getWrapper()); - progress.report({ message: vscode.l10n.t('Getting region information...') }); + progress.report({ message: Messages.GETTING_REGION_INFORMATION }); const artemisResponse = await ArtemisService.getArtemisResponse(orgDetails.orgID, telemetry, ""); if (artemisResponse === null || artemisResponse.response === null) { - vscode.window.showErrorMessage(vscode.l10n.t("Failed to get website endpoint. Please try again later")); + vscode.window.showErrorMessage(Messages.FAILED_TO_GET_ENDPOINT); return; } - progress.report({ message: vscode.l10n.t('Getting website endpoint...') }); + progress.report({ message: Messages.GETTING_WEBSITE_ENDPOINT }); const websiteUrl = await PreviewSite.getWebSiteUrl(getWorkspaceFolders(), artemisResponse?.stamp, orgDetails.environmentID, telemetry); From f1233e989747c1b4b622d08f72b14ad8ddabf66c Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Wed, 15 Jan 2025 19:27:45 +0530 Subject: [PATCH 8/9] Refactor --- src/client/preview-site/PreviewSite.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/client/preview-site/PreviewSite.ts b/src/client/preview-site/PreviewSite.ts index d8f5d851..6510dd49 100644 --- a/src/client/preview-site/PreviewSite.ts +++ b/src/client/preview-site/PreviewSite.ts @@ -62,7 +62,18 @@ export class PreviewSite { return websiteDetails?.websiteUrl || ""; } - static async launchBrowserAndDevToolsWithinVsCode(webSitePreviewURL: string | undefined): Promise { + private static async promptInstallEdgeTools(): Promise { + const install = await vscode.window.showWarningMessage( + Messages.EDGE_DEV_TOOLS_NOT_INSTALLED_MESSAGE, + Messages.INSTALL, + Messages.CANCEL + ); + if (install === Messages.INSTALL) { + await vscode.commands.executeCommand('workbench.extensions.search', EDGE_TOOLS_EXTENSION_ID); + } + } + + private static async launchBrowserAndDevToolsWithinVsCode(webSitePreviewURL: string | undefined): Promise { if (!webSitePreviewURL || webSitePreviewURL === "") { return; } @@ -70,16 +81,7 @@ export class PreviewSite { const edgeToolsExtension = vscode.extensions.getExtension(EDGE_TOOLS_EXTENSION_ID); if (!edgeToolsExtension) { - const install = await vscode.window.showWarningMessage( - Messages.EDGE_DEV_TOOLS_NOT_INSTALLED_MESSAGE, - Messages.INSTALL, - Messages.CANCEL - ); - - if (install === Messages.INSTALL) { - await vscode.commands.executeCommand('workbench.extensions.search', EDGE_TOOLS_EXTENSION_ID); - } - + await this.promptInstallEdgeTools(); return; } From fbe33a2b15931d042fbc20009f7f12ee4bd7febd Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Thu, 16 Jan 2025 11:42:15 +0530 Subject: [PATCH 9/9] Update PPAPI endpoint for HIGH --- src/common/services/PPAPIService.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/common/services/PPAPIService.ts b/src/common/services/PPAPIService.ts index ec74215d..7cc7ae13 100644 --- a/src/common/services/PPAPIService.ts +++ b/src/common/services/PPAPIService.ts @@ -74,35 +74,32 @@ export class PPAPIService { static async getPPAPIServiceEndpoint(serviceEndpointStamp: ServiceEndpointCategory, telemetry: ITelemetry, environmentId: string, websitePreviewId?: string): Promise { - let ppapiEndpoint = ""; + let ppApiEndpoint = ""; switch (serviceEndpointStamp) { case ServiceEndpointCategory.TEST: - ppapiEndpoint = "https://api.test.powerplatform.com"; + ppApiEndpoint = "https://api.test.powerplatform.com"; break; case ServiceEndpointCategory.PREPROD: - ppapiEndpoint = "https://api.preprod.powerplatform.com"; + ppApiEndpoint = "https://api.preprod.powerplatform.com"; break; case ServiceEndpointCategory.PROD: - ppapiEndpoint = "https://api.powerplatform.com"; + ppApiEndpoint = "https://api.powerplatform.com"; break; case ServiceEndpointCategory.DOD: - ppapiEndpoint = "https://api.powerplatform.us"; - break; case ServiceEndpointCategory.GCC: - ppapiEndpoint = "https://api.powerplatform.us"; + case ServiceEndpointCategory.HIGH: + ppApiEndpoint = "https://api.powerplatform.us"; break; case ServiceEndpointCategory.MOONCAKE: - ppapiEndpoint = "https://api.powerplatform.cn"; + ppApiEndpoint = "https://api.powerplatform.cn"; break; - // Below endpoints are not supported yet - case ServiceEndpointCategory.HIGH: default: sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_GET_PPAPI_WEBSITES_ENDPOINT_UNSUPPORTED_REGION, data: serviceEndpointStamp }); break; } - return PPAPI_WEBSITES_ENDPOINT.replace("{rootURL}", ppapiEndpoint) + return PPAPI_WEBSITES_ENDPOINT.replace("{rootURL}", ppApiEndpoint) .replace("{environmentId}", environmentId) + (websitePreviewId ? `/${websitePreviewId}` : '') + `?api-version=${PPAPI_WEBSITES_API_VERSION}`;