@sap-devx/feature-toggle-node
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -5,18 +5,27 @@ "use strict"; | ||
const contextManager = require("./context_manager"); | ||
const logger_1 = require("./logger"); | ||
async function isFeatureEnabled(extensionName, featureToggleName) { | ||
if (!extensionName) { | ||
throw new Error("Feature toggle extension name can not be empty, null or undefined"); | ||
const ftName = `${extensionName}.${featureToggleName}`; | ||
try { | ||
if (!extensionName) { | ||
throw new Error("Feature toggle extension name can not be empty, null or undefined"); | ||
} | ||
if (!featureToggleName) { | ||
throw new Error("Feature toggle name can not be empty, null or undefined"); | ||
} | ||
//get unleash client | ||
const client = await clientManager.getUnleashClient(extensionName); | ||
// get the context | ||
const context = contextManager.getContext(extensionName); | ||
//check if the feature is enabled | ||
//fallback value is false (3rd parameter) | ||
return client.isEnabled(ftName, context, false); | ||
} | ||
if (!featureToggleName) { | ||
throw new Error("Feature toggle name can not be empty, null or undefined"); | ||
catch (err) { | ||
const logErr = `[ERROR] Failed to determine if feature toggle ${ftName} is enabled. Returning feature DISABLED. Error message: ${err}`; | ||
logger_1.log(logErr); | ||
return false; // error creating an Unleash client -> return feature is disabled | ||
} | ||
//get unleash client | ||
const client = await clientManager.getUnleashClient(extensionName); | ||
// get the context | ||
const context = contextManager.getContext(extensionName); | ||
//check if the feature is enabled | ||
//fallback value is false (3rd parameter) | ||
return client.isEnabled(`${extensionName}.${featureToggleName}`, context, false); | ||
} | ||
exports.isFeatureEnabled = isFeatureEnabled; | ||
//# sourceMappingURL=api.js.map |
@@ -33,3 +33,3 @@ "use strict"; | ||
currentUser: userName, | ||
currentWs: "" | ||
currentWs: "", | ||
}; | ||
@@ -36,0 +36,0 @@ // get the WS and region from the env |
@@ -8,4 +8,3 @@ "use strict"; | ||
const contextMap = new Map(); | ||
function createNewContext(extensionName) { | ||
// TODO: collect the data | ||
function createNewContext(extensionName, contextMap) { | ||
const context = appstudio_context_1.createContextObject(); | ||
@@ -23,3 +22,3 @@ //add the context to the map | ||
// The context does NOT exist in the map -> create a new context | ||
return createNewContext(extensionName); | ||
return createNewContext(extensionName, contextMap); | ||
} | ||
@@ -26,0 +25,0 @@ exports.getContextFromMap = getContextFromMap; |
@@ -7,3 +7,3 @@ "use strict"; | ||
function delay(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} | ||
@@ -10,0 +10,0 @@ (async () => { |
@@ -6,3 +6,3 @@ "use strict"; | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const parse = require("parse-duration"); | ||
const parseDuration = require("parse-duration"); | ||
exports.ENV_FT_SERVER_ENDPOINT_NAME = "FT_SERVER_ENDPOINT"; | ||
@@ -19,9 +19,11 @@ exports.ENV_REFRESH_INTERVAL_NAME = "FT_CLIENT_REFRESH_INTERVAL"; | ||
let interval = process.env[exports.ENV_REFRESH_INTERVAL_NAME]; | ||
// do not parse undefined, empty... | ||
if (interval) { | ||
interval = parseDuration(interval); | ||
} | ||
// parse parseDuration result | ||
if (!interval) { | ||
interval = parse(DEFAULT_REFRESH_INTERVAL); | ||
logger_1.log(`client refresh interval not set, using the default interval: ${DEFAULT_REFRESH_INTERVAL}`); | ||
interval = parseDuration(DEFAULT_REFRESH_INTERVAL); | ||
logger_1.log(`[INFO] client refresh interval not set or in incorrect pattern, using the default interval: ${DEFAULT_REFRESH_INTERVAL}`); | ||
} | ||
else { | ||
interval = parse(interval); | ||
} | ||
logger_1.log(`client refresh interval is: ${interval}`); | ||
@@ -28,0 +30,0 @@ return { ftServerEndPoint: endpoint, ftServerInterval: Number(interval) }; |
import { Unleash } from "unleash-client"; | ||
export declare function getUnleashClientFromMap(extensionName: string, unleashClientMap: Map<string, Unleash>): Promise<Unleash>; | ||
export declare function getUnleashClient(extensionName: string): Promise<Unleash>; |
@@ -10,3 +10,3 @@ "use strict"; | ||
const unleashClientMap = new Map(); | ||
async function createNewUnleashClient(extensionName) { | ||
async function createNewUnleashClient(extensionName, unleashClientMap) { | ||
//get server env arguments | ||
@@ -20,3 +20,3 @@ const serverArgs = ServerArgs.getServerArgs(); | ||
} | ||
async function getUnleashClient(extensionName) { | ||
async function getUnleashClientFromMap(extensionName, unleashClientMap) { | ||
// If the client exist in the map return it | ||
@@ -28,5 +28,9 @@ const unleashClient = unleashClientMap.get(extensionName); | ||
// The client does NOT exist in the map -> create a new client | ||
return createNewUnleashClient(extensionName); | ||
return createNewUnleashClient(extensionName, unleashClientMap); | ||
} | ||
exports.getUnleashClientFromMap = getUnleashClientFromMap; | ||
async function getUnleashClient(extensionName) { | ||
return getUnleashClientFromMap(extensionName, unleashClientMap); | ||
} | ||
exports.getUnleashClient = getUnleashClient; | ||
//# sourceMappingURL=unleash_client_manager.js.map |
import { Unleash, Strategy } from "unleash-client"; | ||
import { ServerArgs } from "./server_arguments"; | ||
export declare function initializeUnleashClient(extensionName: string, serverArgs: ServerArgs, featureStrategies: Strategy[]): Promise<Unleash>; | ||
export declare function initializeUnleashClient(extensionName: string, serverArgs: ServerArgs, customStrategies: Strategy[]): Promise<Unleash>; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const logger_1 = require("./logger"); | ||
const await_to_js_1 = require("await-to-js"); | ||
async function getUnleashClientReadyPromise(extensionName, client, serverArgs) { | ||
@@ -10,6 +11,6 @@ return new Promise((resolve, reject) => { | ||
client.once("error", (err) => { | ||
logger_1.log(`FT is initialization failed for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
logger_1.log(`[ERROR] FT is initialization failed for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
reject(err); | ||
}); | ||
client.once("ready", () => { | ||
client.once("registered", () => { | ||
logger_1.log(`FT is initialized to server for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
@@ -20,3 +21,3 @@ resolve(); | ||
} | ||
async function initializeUnleashClient(extensionName, serverArgs, featureStrategies) { | ||
async function initializeUnleashClient(extensionName, serverArgs, customStrategies) { | ||
//create a new unleash client | ||
@@ -27,5 +28,9 @@ const unleashClient = unleash_client_1.initialize({ | ||
url: serverArgs.ftServerEndPoint, | ||
strategies: featureStrategies | ||
strategies: customStrategies, | ||
}); | ||
await getUnleashClientReadyPromise(extensionName, unleashClient, serverArgs); | ||
const unleashClientReadyPromise = getUnleashClientReadyPromise(extensionName, unleashClient, serverArgs); | ||
const [err] = await await_to_js_1.default(unleashClientReadyPromise); | ||
if (err) { | ||
throw new Error(`Failed to create Unleash client for extension ${extensionName}. Error message: ${err}`); | ||
} | ||
return unleashClient; | ||
@@ -32,0 +37,0 @@ } |
@@ -8,3 +8,3 @@ "use strict"; | ||
if (!envValue) { | ||
throw new Error(errorMessage); | ||
throw new Error(`[ERROR] ${errorMessage}`); | ||
} | ||
@@ -11,0 +11,0 @@ envValue = envValue.trim().toLowerCase(); |
{ | ||
"name": "@sap-devx/feature-toggle-node", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "", | ||
@@ -19,8 +19,7 @@ "main": "lib/api.js", | ||
"test": "mocha", | ||
"lint": "eslint . --ext .ts", | ||
"lint": "eslint . --max-warnings 0 --ext .ts", | ||
"coverage": "nyc mocha", | ||
"clean": "rimraf ./lib", | ||
"watch": "tsc -p . --watch", | ||
"preversion": "npm run ci", | ||
"postversion": "git push --tags" | ||
"preversion": "npm run ci" | ||
}, | ||
@@ -37,19 +36,19 @@ "repository": { | ||
"@types/mocha": "^7.0.1", | ||
"@types/rimraf": "2.0.3", | ||
"@types/sinon": "^7.5.1", | ||
"@typescript-eslint/eslint-plugin": "2.19.0", | ||
"@typescript-eslint/parser": "2.19.0", | ||
"@types/rimraf": "3.0.0", | ||
"@types/sinon": "^9.0.0", | ||
"@typescript-eslint/eslint-plugin": "2.30.0", | ||
"@typescript-eslint/parser": "2.30.0", | ||
"chai": "^4.2.0", | ||
"eslint": "6.8.0", | ||
"eslint-config-prettier": "6.10.0", | ||
"eslint-plugin-prettier": "3.1.2", | ||
"eslint-config-prettier": "6.11.0", | ||
"eslint-plugin-prettier": "3.1.3", | ||
"mocha": "^7.0.1", | ||
"npm-run-all": "4.1.5", | ||
"nyc": "15.0.0", | ||
"prettier": "1.19.1", | ||
"rimraf": "3.0.1", | ||
"sinon": "^8.1.1", | ||
"source-map-support": "0.5.16", | ||
"ts-node": "8.6.2", | ||
"typescript": "3.7.5" | ||
"nyc": "15.0.1", | ||
"prettier": "2.0.5", | ||
"rimraf": "3.0.2", | ||
"sinon": "^9.0.2", | ||
"source-map-support": "0.5.19", | ||
"ts-node": "8.9.1", | ||
"typescript": "3.8.3" | ||
}, | ||
@@ -79,11 +78,12 @@ "mocha": { | ||
"all": true, | ||
"branches": 90, | ||
"lines": 90, | ||
"functions": 90, | ||
"statements": 90 | ||
"branches": 100, | ||
"lines": 100, | ||
"functions": 100, | ||
"statements": 100 | ||
}, | ||
"dependencies": { | ||
"parse-duration": "^0.1.2", | ||
"await-to-js": "^2.1.1", | ||
"parse-duration": "^0.3.0", | ||
"unleash-client": "^3.3.3" | ||
} | ||
} |
@@ -1,2 +0,6 @@ | ||
# feature-toggle-node [![CircleCI](https://circleci.com/gh/SAP/feature-toggle-node.svg?style=svg)](https://circleci.com/gh/SAP/feature-toggle-node) | ||
[![CircleCI](https://circleci.com/gh/SAP/feature-toggle-node.svg?style=svg)](https://circleci.com/gh/SAP/feature-toggle-node) | ||
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) | ||
[![Commitizen friendly](https://api.dependabot.com/badges/status?host=github&repo=SAP/feature-toggle-node)](https://dependabot.com/) | ||
# feature-toggle-node | ||
A Node.js module for enabling or disabling Node.js-based SAP Business Application Studio features. | ||
@@ -3,0 +7,0 @@ |
@@ -1,24 +0,32 @@ | ||
import { Unleash } from "unleash-client"; | ||
import { Context } from "unleash-client/lib/context"; | ||
import * as clientManager from "./unleash_client_manager"; | ||
import * as contextManager from "./context_manager"; | ||
import { log } from "./logger"; | ||
import { Unleash } from "unleash-client"; | ||
export async function isFeatureEnabled(extensionName: string, featureToggleName: string): Promise<boolean> { | ||
if (!extensionName) { | ||
throw new Error("Feature toggle extension name can not be empty, null or undefined"); | ||
} | ||
const ftName = `${extensionName}.${featureToggleName}`; | ||
try { | ||
if (!extensionName) { | ||
throw new Error("Feature toggle extension name can not be empty, null or undefined"); | ||
} | ||
if (!featureToggleName) { | ||
throw new Error("Feature toggle name can not be empty, null or undefined"); | ||
} | ||
if (!featureToggleName) { | ||
throw new Error("Feature toggle name can not be empty, null or undefined"); | ||
} | ||
//get unleash client | ||
const client: Unleash = await clientManager.getUnleashClient(extensionName); | ||
//get unleash client | ||
const client: Unleash = await clientManager.getUnleashClient(extensionName); | ||
// get the context | ||
const context: Context = contextManager.getContext(extensionName); | ||
// get the context | ||
const context: Context = contextManager.getContext(extensionName); | ||
//check if the feature is enabled | ||
//fallback value is false (3rd parameter) | ||
return client.isEnabled(`${extensionName}.${featureToggleName}`, context, false); | ||
//check if the feature is enabled | ||
//fallback value is false (3rd parameter) | ||
return client.isEnabled(ftName, context, false); | ||
} catch (err) { | ||
const logErr = `[ERROR] Failed to determine if feature toggle ${ftName} is enabled. Returning feature DISABLED. Error message: ${err}`; | ||
log(logErr); | ||
return false; // error creating an Unleash client -> return feature is disabled | ||
} | ||
} |
@@ -50,3 +50,3 @@ import { Context as appstudioContext } from "unleash-client/lib/context"; | ||
currentUser: userName, | ||
currentWs: "" | ||
currentWs: "", | ||
}; | ||
@@ -53,0 +53,0 @@ |
@@ -8,4 +8,3 @@ import { AppStudioMultiContext, createContextObject } from "./appstudio_context"; | ||
function createNewContext(extensionName: string): AppStudioMultiContext { | ||
// TODO: collect the data | ||
function createNewContext(extensionName: string, contextMap: Map<string, AppStudioMultiContext>): AppStudioMultiContext { | ||
const context: AppStudioMultiContext = createContextObject(); | ||
@@ -27,3 +26,3 @@ | ||
// The context does NOT exist in the map -> create a new context | ||
return createNewContext(extensionName); | ||
return createNewContext(extensionName, contextMap); | ||
} | ||
@@ -30,0 +29,0 @@ |
@@ -7,3 +7,3 @@ import { isFeatureEnabled } from "../api"; | ||
function delay(ms: number): Promise<void> { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} | ||
@@ -10,0 +10,0 @@ |
import { log } from "./logger"; | ||
import { getEnv } from "./utils"; | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const parse = require("parse-duration"); | ||
const parseDuration = require("parse-duration"); | ||
@@ -24,7 +24,10 @@ export const ENV_FT_SERVER_ENDPOINT_NAME = "FT_SERVER_ENDPOINT"; | ||
let interval = process.env[ENV_REFRESH_INTERVAL_NAME]; | ||
// do not parse undefined, empty... | ||
if (interval) { | ||
interval = parseDuration(interval); | ||
} | ||
// parse parseDuration result | ||
if (!interval) { | ||
interval = parse(DEFAULT_REFRESH_INTERVAL); | ||
log(`client refresh interval not set, using the default interval: ${DEFAULT_REFRESH_INTERVAL}`); | ||
} else { | ||
interval = parse(interval); | ||
interval = parseDuration(DEFAULT_REFRESH_INTERVAL); | ||
log(`[INFO] client refresh interval not set or in incorrect pattern, using the default interval: ${DEFAULT_REFRESH_INTERVAL}`); | ||
} | ||
@@ -31,0 +34,0 @@ log(`client refresh interval is: ${interval}`); |
@@ -11,3 +11,3 @@ import { Unleash } from "unleash-client"; | ||
async function createNewUnleashClient(extensionName: string): Promise<Unleash> { | ||
async function createNewUnleashClient(extensionName: string, unleashClientMap: Map<string, Unleash>): Promise<Unleash> { | ||
//get server env arguments | ||
@@ -25,3 +25,3 @@ const serverArgs = ServerArgs.getServerArgs(); | ||
export async function getUnleashClient(extensionName: string): Promise<Unleash> { | ||
export async function getUnleashClientFromMap(extensionName: string, unleashClientMap: Map<string, Unleash>): Promise<Unleash> { | ||
// If the client exist in the map return it | ||
@@ -34,3 +34,7 @@ const unleashClient = unleashClientMap.get(extensionName); | ||
// The client does NOT exist in the map -> create a new client | ||
return createNewUnleashClient(extensionName); | ||
return createNewUnleashClient(extensionName, unleashClientMap); | ||
} | ||
export async function getUnleashClient(extensionName: string): Promise<Unleash> { | ||
return getUnleashClientFromMap(extensionName, unleashClientMap); | ||
} |
import { initialize, Unleash, Strategy } from "unleash-client"; | ||
import { log } from "./logger"; | ||
import { ServerArgs } from "./server_arguments"; | ||
import to from "await-to-js"; | ||
@@ -9,6 +10,6 @@ async function getUnleashClientReadyPromise(extensionName: string, client: Unleash, serverArgs: ServerArgs): Promise<void> { | ||
client.once("error", (err: Error) => { | ||
log(`FT is initialization failed for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
log(`[ERROR] FT is initialization failed for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
reject(err); | ||
}); | ||
client.once("ready", () => { | ||
client.once("registered", () => { | ||
log(`FT is initialized to server for extension ${extensionName}. EndPoint: ${serverArgs.ftServerEndPoint}`); | ||
@@ -20,3 +21,3 @@ resolve(); | ||
export async function initializeUnleashClient(extensionName: string, serverArgs: ServerArgs, featureStrategies: Strategy[]): Promise<Unleash> { | ||
export async function initializeUnleashClient(extensionName: string, serverArgs: ServerArgs, customStrategies: Strategy[]): Promise<Unleash> { | ||
//create a new unleash client | ||
@@ -27,7 +28,11 @@ const unleashClient = initialize({ | ||
url: serverArgs.ftServerEndPoint, | ||
strategies: featureStrategies | ||
strategies: customStrategies, | ||
}); | ||
await getUnleashClientReadyPromise(extensionName, unleashClient, serverArgs); | ||
const unleashClientReadyPromise = getUnleashClientReadyPromise(extensionName, unleashClient, serverArgs); | ||
const [err] = await to(unleashClientReadyPromise); | ||
if (err) { | ||
throw new Error(`Failed to create Unleash client for extension ${extensionName}. Error message: ${err}`); | ||
} | ||
return unleashClient; | ||
} |
@@ -7,3 +7,3 @@ import { log } from "./logger"; | ||
if (!envValue) { | ||
throw new Error(errorMessage); | ||
throw new Error(`[ERROR] ${errorMessage}`); | ||
} | ||
@@ -10,0 +10,0 @@ envValue = envValue.trim().toLowerCase(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
54218
49
630
77
3
+ Addedawait-to-js@^2.1.1
+ Addedawait-to-js@2.1.1(transitive)
+ Addedparse-duration@0.3.3(transitive)
- Removedparse-duration@0.1.3(transitive)
Updatedparse-duration@^0.3.0