-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into users/amitjoshi/copilotPanelLocJson
- Loading branch information
Showing
18 changed files
with
645 additions
and
402 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
export const ECS_REQUEST_URL_TEMPLATE = "https://ecs.office.com/config/v1"; | ||
|
||
export const PowerPagesClientName = 'PortalsMakerExperiences'; // Project name in ECS Portal, Do not change this | ||
export type ProjectTeam = typeof PowerPagesClientName; | ||
export const PowerPagesAppName = 'powerpages-microsoft-com'; // Project name in ECS Portal, Do not change this | ||
export type ProjectName = typeof PowerPagesAppName; | ||
|
||
export const VisualStudioCodeDevInsidersUrl = 'https://insiders.vscode.dev/power/portal'; // VScode dev insiders/pre-prod env | ||
export const VisualStudioCodeDevUrl = 'https://vscode.dev/power/portal'; // VScode dev GA/prod env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
import TelemetryReporter from "@vscode/extension-telemetry"; | ||
import { ITelemetry } from "../../client/telemetry/ITelemetry"; | ||
import { createECSRequestURL } from "./ecsFeatureUtil"; | ||
import { ECSFeatureDefinition as ECSFeatureProperties } from "./ecsFeatureProperties"; | ||
import { ECSAPIFeatureFlagFilters } from "./ecsFeatureFlagFilters"; | ||
|
||
export abstract class ECSFeaturesClient { | ||
private static _ecsConfig: Record<string, string | boolean>; | ||
private static _featuresConfig = {}; | ||
|
||
// Initialize ECSFeatureClient - any client config can be fetched with utility function like below | ||
// EnableMultifileVscodeWeb.getConfig().enableMultifileVscodeWeb | ||
public static async init(telemetry: ITelemetry | TelemetryReporter, filters: ECSAPIFeatureFlagFilters, clientName: string) { | ||
if (this._ecsConfig) return; | ||
|
||
const requestURL = createECSRequestURL(filters, clientName); | ||
try { | ||
const response = await fetch(requestURL, { | ||
method: 'GET' | ||
}); | ||
if (!response.ok) { | ||
throw new Error('Request failed'); | ||
} | ||
const result = await response.json(); | ||
// Update telemetry in other PR | ||
// telemetry.sendTelemetryEvent('ECSConfig', {}); | ||
|
||
// Initialize ECS config | ||
this._ecsConfig = result[clientName]; | ||
} catch (error) { | ||
// Log error | ||
// telemetry.sendTelemetryEvent('ECSConfigError', {}); | ||
} | ||
} | ||
|
||
public static getConfig<TConfig extends Record<string, boolean | string>, TeamName extends string>( | ||
feature: ECSFeatureProperties<TConfig, TeamName> | ||
) { | ||
if (Object.keys(this._featuresConfig).length === 0) { | ||
this._featuresConfig = this._ecsConfig && feature.extractECSFeatureFlagConfig?.(this._ecsConfig as TConfig); | ||
} | ||
|
||
return Object.keys(this._featuresConfig).length === 0 ? feature.fallback : this._featuresConfig; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
export interface ECSAPIFeatureFlagFilters { | ||
/** | ||
* Application AppName | ||
* @example powerpages-microsoft-com | ||
*/ | ||
AppName: string; | ||
|
||
/** The AAD user object ID or MSA. */ | ||
UserID: string; | ||
|
||
/** The AAD tenant object ID. */ | ||
TenantID: string; | ||
|
||
/** Unique Dataverse Environment ID */ | ||
EnvID: string; | ||
|
||
/** | ||
* Deployment region | ||
* @example test, preview, prod | ||
*/ | ||
Region: string; | ||
|
||
// TBD - more API call filters to be added later | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
import { PowerPagesClientName } from './constants'; | ||
import { getFeatureConfigs } from './ecsFeatureUtil'; | ||
|
||
export const { | ||
feature: EnableMultifileVscodeWeb | ||
} = getFeatureConfigs({ | ||
teamName: PowerPagesClientName, | ||
description: 'Enable multiple file view in Visual Studio Code Web', | ||
fallback: { | ||
enableMultifileVscodeWeb: false, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
/** | ||
* Interface representing a Feature config in ECS. | ||
*/ | ||
export interface ECSFeatureDefinition<TConfig extends Record<string, string | boolean>, TeamName extends string> { | ||
/** | ||
* Name of the Team owning the feature. Must match the "clientTeam" name configured in ECS. | ||
*/ | ||
teamName: TeamName; | ||
|
||
/** | ||
* Fallback config to be used while loading or if configs are unavailable. | ||
*/ | ||
fallback: TConfig; | ||
|
||
/** | ||
* Brief description of the feature (used for tracking/cleanup purposes) | ||
*/ | ||
description?: string; | ||
|
||
/** | ||
* Callback to extract the Feature-specific config from the Team config. | ||
* @param config overall config for the Team. | ||
*/ | ||
extractECSFeatureFlagConfig<TTeamConfig extends TConfig>(config: TTeamConfig): Partial<TConfig>; | ||
} | ||
|
||
export type ECSFeatureInfo<TConfig extends Record<string, boolean | string>, TeamName extends string> = Omit< | ||
ECSFeatureDefinition<TConfig, TeamName>, | ||
'extractECSFeatureFlagConfig' | ||
>; | ||
|
||
/** | ||
* Creates a Feature object based on the feature definition that includes fallback flags and the team owning the feature. | ||
* @param featureInfo Feature definition specifying the fallback flags and the team owning the feature. | ||
*/ | ||
export function createECSFeatureDefinition<TConfig extends Record<string, boolean | string>, TeamName extends string>( | ||
featureInfo: ECSFeatureInfo<TConfig, TeamName> | ||
): ECSFeatureDefinition<TConfig, TeamName> { | ||
return { | ||
...featureInfo, | ||
extractECSFeatureFlagConfig: (config) => extractECSFeatureFlagConfig(config, Object.keys(featureInfo.fallback)), | ||
}; | ||
} | ||
|
||
/** | ||
* Extracts the feature-specific config, based on the provided keys, from the overall Project Team config | ||
* @param teamConfig the overall config object for the Project Team | ||
* @param keys property names to extract from the Project Team config | ||
*/ | ||
function extractECSFeatureFlagConfig<TConfig extends Record<string, boolean | string>, TeamConfig extends TConfig>( | ||
teamConfig: TeamConfig, | ||
keys: (keyof TConfig)[] | ||
): Partial<TConfig> { | ||
const config: Partial<TConfig> = {}; | ||
|
||
for (const key of keys) { | ||
if (typeof teamConfig[key] !== 'undefined') { | ||
config[key] = teamConfig[key]; | ||
} | ||
} | ||
|
||
return config; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*/ | ||
|
||
import { PowerPagesClientName, ECS_REQUEST_URL_TEMPLATE } from "./constants"; | ||
import { ECSFeaturesClient } from "./ecsFeatureClient"; | ||
import { ECSAPIFeatureFlagFilters } from "./ecsFeatureFlagFilters"; | ||
import { ECSFeatureDefinition, ECSFeatureInfo, createECSFeatureDefinition } from "./ecsFeatureProperties"; | ||
|
||
export function createECSRequestURL(filters: ECSAPIFeatureFlagFilters, clientName = PowerPagesClientName): string { | ||
const queryParams: { [key: string]: string } = { | ||
AppName: filters.AppName, | ||
EnvironmentID: filters.EnvID, | ||
UserID: filters.UserID, | ||
TenantID: filters.TenantID, | ||
region: filters.Region | ||
}; | ||
|
||
const queryString = Object.keys(queryParams) | ||
.map(key => `${key}=${encodeURIComponent(queryParams[key])}`) | ||
.join('&'); | ||
|
||
return `${ECS_REQUEST_URL_TEMPLATE}/${clientName}/1.0.0.0?${queryString}`; | ||
} | ||
|
||
export function getFeatureConfigs<TConfig extends Record<string, string | boolean>, TeamName extends string>(featureInfo: ECSFeatureInfo<TConfig, TeamName>) { | ||
type EnhancedFeature = ECSFeatureDefinition<TConfig, TeamName> & { | ||
getConfig: () => Partial<TConfig>; | ||
}; | ||
|
||
const feature = createECSFeatureDefinition(featureInfo) as EnhancedFeature; | ||
feature.getConfig = () => ECSFeaturesClient.getConfig(feature); | ||
|
||
return { | ||
feature: feature, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.