-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
226 additions
and
2 deletions.
There are no files selected for viewing
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,24 @@ | ||
/** | ||
* Copyright (c) 2022 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License-AGPL.txt in the project root for license information. | ||
*/ | ||
import { Attributes, Client } from "./client"; | ||
|
||
// AlwaysReturningDefaultValueClient is an implemention of an experiments.Client which performs no lookup/network operation | ||
// and always returns the default value for a given experimentName. | ||
// This client is used for non-SaaS version of Gitpod, in particular for self-hosted installations where external | ||
// network connections are not desirable or even possible. | ||
class AlwaysReturningDefaultValueClient implements Client { | ||
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T> { | ||
return Promise.resolve(defaultValue); | ||
} | ||
|
||
dispose(): void { | ||
// there is nothing to dispose, no-op. | ||
} | ||
} | ||
|
||
export function newAlwaysReturningDefaultValueClient(): Client { | ||
return new AlwaysReturningDefaultValueClient(); | ||
} |
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,55 @@ | ||
/** | ||
* Copyright (c) 2022 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License-AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
// Attributes define attributes which can be used to segment audiences. | ||
// Set the attributes which you want to use to group audiences into. | ||
import { newNonProductionConfigCatClient, newProductionConfigCatClient } from "./configcat"; | ||
import { newAlwaysReturningDefaultValueClient } from "./always-default"; | ||
|
||
export interface Attributes { | ||
userID?: string; | ||
email?: string; | ||
|
||
// Gitpod Project ID | ||
projectID?: string; | ||
|
||
// Gitpod Team ID | ||
teamID?: string; | ||
// Gitpod Team Name | ||
teamName?: string; | ||
} | ||
|
||
export interface Client { | ||
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T>; | ||
|
||
// dispose will dispose of the client, no longer retrieving flags | ||
dispose(): void; | ||
} | ||
|
||
let client: Client | undefined; | ||
|
||
export function getExperimentsClient(): Client { | ||
// We have already instantiated a client, we can just re-use it. | ||
if (client !== undefined) { | ||
return client; | ||
} | ||
|
||
const host = window.location.hostname; | ||
if (host === "gitpod.io") { | ||
client = newProductionConfigCatClient(); | ||
} else if (host === "gitpod-staging.com" || host.endsWith("gitpod-dev.com") || host.endsWith("gitpod-io-dev.com")) { | ||
client = newNonProductionConfigCatClient(); | ||
} else { | ||
// We're gonna use a client which always returns the default value. | ||
client = newAlwaysReturningDefaultValueClient(); | ||
} | ||
|
||
return client; | ||
} | ||
|
||
export const PROJECT_ID_ATTRIBUTE = "project_id"; | ||
export const TEAM_ID_ATTRIBUTE = "team_id"; | ||
export const TEAM_NAME_ATTRIBUTE = "team_name"; |
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,69 @@ | ||
/** | ||
* Copyright (c) 2022 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License-AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import * as configcat from "configcat-js"; | ||
import { IConfigCatClient } from "configcat-common/lib/ConfigCatClient"; | ||
import { User } from "configcat-common/lib/RolloutEvaluator"; | ||
import { Attributes, Client, PROJECT_ID_ATTRIBUTE, TEAM_ID_ATTRIBUTE, TEAM_NAME_ATTRIBUTE } from "./client"; | ||
|
||
// newProductionConfigCatClient constructs a new ConfigCat client with production configuration. | ||
// DO NOT USE DIRECTLY! Use getExperimentsClient() instead. | ||
export function newProductionConfigCatClient(): Client { | ||
// clientKey is an identifier of our ConfigCat application. It is not a secret. | ||
const clientKey = "WBLaCPtkjkqKHlHedziE9g/TwAe6YyftEGPnGxVRXd0Ig"; | ||
const client = configcat.createClient(clientKey, { | ||
logger: configcat.createConsoleLogger(2), | ||
}); | ||
|
||
return new ConfigCatClient(client); | ||
} | ||
|
||
// newNonProductionConfigCatClient constructs a new ConfigCat client with non-production configuration. | ||
// DO NOT USE DIRECTLY! Use getExperimentsClient() instead. | ||
export function newNonProductionConfigCatClient(): Client { | ||
// clientKey is an identifier of our ConfigCat application. It is not a secret. | ||
const clientKey = "WBLaCPtkjkqKHlHedziE9g/LEAOCNkbuUKiqUZAcVg7dw"; | ||
const client = configcat.createClient(clientKey, { | ||
pollIntervalSeconds: 60 * 3, // 3 minutes | ||
logger: configcat.createConsoleLogger(3), | ||
}); | ||
|
||
return new ConfigCatClient(client); | ||
} | ||
|
||
class ConfigCatClient implements Client { | ||
private client: IConfigCatClient; | ||
|
||
constructor(cc: IConfigCatClient) { | ||
this.client = cc; | ||
} | ||
|
||
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T> { | ||
return this.client.getValueAsync(experimentName, defaultValue, attributesToUser(attributes)); | ||
} | ||
|
||
dispose(): void { | ||
return this.client.dispose(); | ||
} | ||
} | ||
|
||
function attributesToUser(attributes: Attributes): User { | ||
const userID = attributes.userID || ""; | ||
const email = attributes.email || ""; | ||
|
||
const custom: { [key: string]: string } = {}; | ||
if (attributes.projectID) { | ||
custom[PROJECT_ID_ATTRIBUTE] = attributes.projectID; | ||
} | ||
if (attributes.teamID) { | ||
custom[TEAM_ID_ATTRIBUTE] = attributes.teamID; | ||
} | ||
if (attributes.teamName) { | ||
custom[TEAM_NAME_ATTRIBUTE] = attributes.teamName; | ||
} | ||
|
||
return new User(userID, email, "", custom); | ||
} |
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,22 @@ | ||
/** | ||
* Copyright (c) 2022 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License-AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import * as configcat from "configcat-node"; | ||
import { IConfigCatClient } from "configcat-common/lib/ConfigCatClient"; | ||
|
||
let logger = configcat.createConsoleLogger(3); // Setting log level to 3 (Info) | ||
let client: IConfigCatClient | undefined; | ||
|
||
export function getExperimentsClient(): IConfigCatClient { | ||
if (client === undefined) { | ||
client = configcat.createClient("WBLaCPtkjkqKHlHedziE9g/LEAOCNkbuUKiqUZAcVg7dw", { | ||
// <-- This is the actual SDK Key for your Test environment | ||
logger: logger, | ||
}); | ||
} | ||
|
||
return client; | ||
} |
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 |
---|---|---|
|
@@ -5813,6 +5813,27 @@ concurrently@^6.2.1: | |
tree-kill "^1.2.2" | ||
yargs "^16.2.0" | ||
|
||
configcat-common@^4.6.1, configcat-common@^4.6.2: | ||
version "4.6.2" | ||
resolved "https://registry.yarnpkg.com/configcat-common/-/configcat-common-4.6.2.tgz#ef37114cf77c10378e686078bc45903508e0ed49" | ||
integrity sha512-o7qp5xb3K9w3tL0dK0g2/IwzOym4SOcdl+Hgh7d1125fKamDk8Jg6nBb+jEkA0qs0msYI+kpcL7pEsihYUhEDg== | ||
|
||
configcat-js@^5.7.2: | ||
version "5.7.2" | ||
resolved "https://registry.yarnpkg.com/configcat-js/-/configcat-js-5.7.2.tgz#2466269f941c8564c0d2670ffbc74dc0657f1450" | ||
integrity sha512-Pvryi3y1z1ZyhId5fGv6Weel6YU6EuTHHYdfY1SOaVSvNeXNU9HwLpzMUCwdINtSXyxtHd0xUMumRUje2h7/Ng== | ||
dependencies: | ||
configcat-common "^4.6.2" | ||
|
||
configcat-node@^6.7.1: | ||
version "6.7.1" | ||
resolved "https://registry.yarnpkg.com/configcat-node/-/configcat-node-6.7.1.tgz#87c6be569d646575c969d00966a97416a4b6a4fa" | ||
integrity sha512-+tdKZkrWo3JdRezU90daly9LmL2efCDTnjHlKMUpwtVjrNjPVXggrydrgB5QUKmJUspWUd9bFSXS3jQgoGpB4g== | ||
dependencies: | ||
configcat-common "^4.6.1" | ||
got "^9.6.0" | ||
tunnel "0.0.6" | ||
|
||
configstore@^5.0.0, configstore@^5.0.1: | ||
version "5.0.1" | ||
resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" | ||
|
@@ -17078,6 +17099,11 @@ tunnel-agent@^0.6.0: | |
dependencies: | ||
safe-buffer "^5.0.1" | ||
|
||
[email protected]: | ||
version "0.0.6" | ||
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" | ||
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== | ||
|
||
tweetnacl@^0.14.3, tweetnacl@~0.14.0: | ||
version "0.14.5" | ||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" | ||
|