@launchdarkly/js-server-sdk-common
Advanced tools
Comparing version 1.4.0-alpha.3 to 1.4.0-alpha.4
@@ -75,3 +75,3 @@ import { LDMigrationOrigin } from '../LDMigration'; | ||
* The result of the flag evaluation. This will be either one of the flag's variations or | ||
* the default value that was passed to `LDClient.variationMigration`. | ||
* the default value that was passed to `LDClient.migrationVariation`. | ||
*/ | ||
@@ -78,0 +78,0 @@ value: LDMigrationStage; |
@@ -1,2 +0,2 @@ | ||
import { LDContext, LDEvaluationDetail, LDFlagValue } from '@launchdarkly/js-sdk-common'; | ||
import { LDContext, LDEvaluationDetail, LDEvaluationDetailTyped, LDFlagValue } from '@launchdarkly/js-sdk-common'; | ||
import { LDMigrationOpEvent, LDMigrationVariation } from './data'; | ||
@@ -124,4 +124,155 @@ import { LDFlagsState } from './data/LDFlagsState'; | ||
*/ | ||
variationMigration(key: string, context: LDContext, defaultValue: LDMigrationStage): Promise<LDMigrationVariation>; | ||
migrationVariation(key: string, context: LDContext, defaultValue: LDMigrationStage): Promise<LDMigrationVariation>; | ||
/** | ||
* Determines the boolean variation of a feature flag for a context. | ||
* | ||
* If the flag variation does not have a boolean value, defaultValue is returned. | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result value. | ||
*/ | ||
boolVariation(key: string, context: LDContext, defaultValue: boolean): Promise<boolean>; | ||
/** | ||
* Determines the numeric variation of a feature flag for a context. | ||
* | ||
* If the flag variation does not have a numeric value, defaultValue is returned. | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result value. | ||
*/ | ||
numberVariation(key: string, context: LDContext, defaultValue: number): Promise<number>; | ||
/** | ||
* Determines the string variation of a feature flag for a context. | ||
* | ||
* If the flag variation does not have a string value, defaultValue is returned. | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result value. | ||
*/ | ||
stringVariation(key: string, context: LDContext, defaultValue: string): Promise<string>; | ||
/** | ||
* Determines the variation of a feature flag for a context. | ||
* | ||
* This version may be favored in TypeScript versus `variation` because it returns | ||
* an `unknown` type instead of `any`. `unknown` will require a cast before usage. | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result value. | ||
*/ | ||
jsonVariation(key: string, context: LDContext, defaultValue: unknown): Promise<unknown>; | ||
/** | ||
* Determines the boolean variation of a feature flag for a context, along with information about | ||
* how it was calculated. | ||
* | ||
* The `reason` property of the result will also be included in analytics events, if you are | ||
* capturing detailed event data for this flag. | ||
* | ||
* If the flag variation does not have a boolean value, defaultValue is returned. The reason will | ||
* indicate an error of the type `WRONG_KIND` in this case. | ||
* | ||
* For more information, see the [SDK reference | ||
* guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side). | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result | ||
* (as an {@link LDEvaluationDetailTyped<boolean>}). | ||
*/ | ||
boolVariationDetail(key: string, context: LDContext, defaultValue: boolean): Promise<LDEvaluationDetailTyped<boolean>>; | ||
/** | ||
* Determines the numeric variation of a feature flag for a context, along with information about | ||
* how it was calculated. | ||
* | ||
* The `reason` property of the result will also be included in analytics events, if you are | ||
* capturing detailed event data for this flag. | ||
* | ||
* If the flag variation does not have a numeric value, defaultValue is returned. The reason will | ||
* indicate an error of the type `WRONG_KIND` in this case. | ||
* | ||
* For more information, see the [SDK reference | ||
* guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side). | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result | ||
* (as an {@link LDEvaluationDetailTyped<number>}). | ||
*/ | ||
numberVariationDetail(key: string, context: LDContext, defaultValue: number): Promise<LDEvaluationDetailTyped<number>>; | ||
/** | ||
* Determines the string variation of a feature flag for a context, along with information about | ||
* how it was calculated. | ||
* | ||
* The `reason` property of the result will also be included in analytics events, if you are | ||
* capturing detailed event data for this flag. | ||
* | ||
* If the flag variation does not have a string value, defaultValue is returned. The reason will | ||
* indicate an error of the type `WRONG_KIND` in this case. | ||
* | ||
* For more information, see the [SDK reference | ||
* guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side). | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @returns | ||
* A Promise which will be resolved with the result | ||
* (as an {@link LDEvaluationDetailTyped<string>}). | ||
*/ | ||
stringVariationDetail(key: string, context: LDContext, defaultValue: string): Promise<LDEvaluationDetailTyped<string>>; | ||
/** | ||
* Determines the variation of a feature flag for a context, along with information about how it | ||
* was calculated. | ||
* | ||
* The `reason` property of the result will also be included in analytics events, if you are | ||
* capturing detailed event data for this flag. | ||
* | ||
* This version may be favored in TypeScript versus `variation` because it returns | ||
* an `unknown` type instead of `any`. `unknown` will require a cast before usage. | ||
* | ||
* For more information, see the [SDK reference | ||
* guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side). | ||
* | ||
* @param key The unique key of the feature flag. | ||
* @param context The context requesting the flag. The client will generate an analytics event to | ||
* register this context with LaunchDarkly if the context does not already exist. | ||
* @param defaultValue The default value of the flag, to be used if the value is not available | ||
* from LaunchDarkly. | ||
* @param callback A Node-style callback to receive the result (as an {@link LDEvaluationDetail}). | ||
* If omitted, you will receive a Promise instead. | ||
* @returns | ||
* If you provided a callback, then nothing. Otherwise, a Promise which will be resolved with | ||
* the result (as an{@link LDEvaluationDetailTyped<unknown>}). | ||
*/ | ||
jsonVariationDetail(key: string, context: LDContext, defaultValue: unknown): Promise<LDEvaluationDetailTyped<unknown>>; | ||
/** | ||
* Builds an object that encapsulates the state of all feature flags for a given context. | ||
@@ -128,0 +279,0 @@ * This includes the flag values and also metadata that can be used on the front end. This |
@@ -14,2 +14,3 @@ "use strict"; | ||
ErrorKinds["ClientNotReady"] = "CLIENT_NOT_READY"; | ||
ErrorKinds["WrongType"] = "WRONG_TYPE"; | ||
})(ErrorKinds || (ErrorKinds = {})); | ||
@@ -16,0 +17,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import { LDContext, LDEvaluationDetail, Platform } from '@launchdarkly/js-sdk-common'; | ||
import { LDContext, LDEvaluationDetail, LDEvaluationDetailTyped, Platform } from '@launchdarkly/js-sdk-common'; | ||
import { LDClient, LDFlagsState, LDFlagsStateOptions, LDMigrationOpEvent, LDMigrationStage, LDMigrationVariation, LDOptions } from './api'; | ||
@@ -49,3 +49,12 @@ import BigSegmentStoreStatusProvider from './BigSegmentStatusProviderImpl'; | ||
variationDetail(key: string, context: LDContext, defaultValue: any, callback?: (err: any, res: LDEvaluationDetail) => void): Promise<LDEvaluationDetail>; | ||
variationMigration(key: string, context: LDContext, defaultValue: LDMigrationStage): Promise<LDMigrationVariation>; | ||
private typedEval; | ||
boolVariation(key: string, context: LDContext, defaultValue: boolean): Promise<boolean>; | ||
numberVariation(key: string, context: LDContext, defaultValue: number): Promise<number>; | ||
stringVariation(key: string, context: LDContext, defaultValue: string): Promise<string>; | ||
jsonVariation(key: string, context: LDContext, defaultValue: unknown): Promise<unknown>; | ||
boolVariationDetail(key: string, context: LDContext, defaultValue: boolean): Promise<LDEvaluationDetailTyped<boolean>>; | ||
numberVariationDetail(key: string, context: LDContext, defaultValue: number): Promise<LDEvaluationDetailTyped<number>>; | ||
stringVariationDetail(key: string, context: LDContext, defaultValue: string): Promise<LDEvaluationDetailTyped<string>>; | ||
jsonVariationDetail(key: string, context: LDContext, defaultValue: unknown): Promise<LDEvaluationDetailTyped<unknown>>; | ||
migrationVariation(key: string, context: LDContext, defaultValue: LDMigrationStage): Promise<LDMigrationVariation>; | ||
allFlagsState(context: LDContext, options?: LDFlagsStateOptions, callback?: (err: Error | null, res: LDFlagsState) => void): Promise<LDFlagsState>; | ||
@@ -60,4 +69,5 @@ secureModeHash(context: LDContext): string; | ||
private variationInternal; | ||
private sendEvalEvent; | ||
private evaluateIfPossible; | ||
} | ||
//# sourceMappingURL=LDClientImpl.d.ts.map |
@@ -170,3 +170,57 @@ "use strict"; | ||
} | ||
async variationMigration(key, context, defaultValue) { | ||
typedEval(key, context, defaultValue, eventFactory, typeChecker) { | ||
return new Promise((resolve) => { | ||
this.evaluateIfPossible(key, context, defaultValue, eventFactory, (res) => { | ||
const typedRes = { | ||
value: res.detail.value, | ||
reason: res.detail.reason, | ||
variationIndex: res.detail.variationIndex, | ||
}; | ||
resolve(typedRes); | ||
}, typeChecker); | ||
}); | ||
} | ||
async boolVariation(key, context, defaultValue) { | ||
return (await this.typedEval(key, context, defaultValue, this.eventFactoryDefault, (value) => [ | ||
js_sdk_common_1.TypeValidators.Boolean.is(value), | ||
js_sdk_common_1.TypeValidators.Boolean.getType(), | ||
])).value; | ||
} | ||
async numberVariation(key, context, defaultValue) { | ||
return (await this.typedEval(key, context, defaultValue, this.eventFactoryDefault, (value) => [ | ||
js_sdk_common_1.TypeValidators.Number.is(value), | ||
js_sdk_common_1.TypeValidators.Number.getType(), | ||
])).value; | ||
} | ||
async stringVariation(key, context, defaultValue) { | ||
return (await this.typedEval(key, context, defaultValue, this.eventFactoryDefault, (value) => [ | ||
js_sdk_common_1.TypeValidators.String.is(value), | ||
js_sdk_common_1.TypeValidators.String.getType(), | ||
])).value; | ||
} | ||
jsonVariation(key, context, defaultValue) { | ||
return this.variation(key, context, defaultValue); | ||
} | ||
boolVariationDetail(key, context, defaultValue) { | ||
return this.typedEval(key, context, defaultValue, this.eventFactoryWithReasons, (value) => [ | ||
js_sdk_common_1.TypeValidators.Boolean.is(value), | ||
js_sdk_common_1.TypeValidators.Boolean.getType(), | ||
]); | ||
} | ||
numberVariationDetail(key, context, defaultValue) { | ||
return this.typedEval(key, context, defaultValue, this.eventFactoryWithReasons, (value) => [ | ||
js_sdk_common_1.TypeValidators.Number.is(value), | ||
js_sdk_common_1.TypeValidators.Number.getType(), | ||
]); | ||
} | ||
stringVariationDetail(key, context, defaultValue) { | ||
return this.typedEval(key, context, defaultValue, this.eventFactoryWithReasons, (value) => [ | ||
js_sdk_common_1.TypeValidators.String.is(value), | ||
js_sdk_common_1.TypeValidators.String.getType(), | ||
]); | ||
} | ||
jsonVariationDetail(key, context, defaultValue) { | ||
return this.variationDetail(key, context, defaultValue); | ||
} | ||
async migrationVariation(key, context, defaultValue) { | ||
const convertedContext = js_sdk_common_1.Context.fromLDContext(context); | ||
@@ -318,3 +372,3 @@ return new Promise((resolve) => { | ||
} | ||
variationInternal(flagKey, context, defaultValue, eventFactory, cb) { | ||
variationInternal(flagKey, context, defaultValue, eventFactory, cb, typeChecker) { | ||
var _a, _b; | ||
@@ -352,12 +406,14 @@ if (this.config.offline) { | ||
} | ||
// Immediately invoked function expression to get the event out of the callback | ||
// path and allow access to async methods. | ||
(async () => { | ||
var _a; | ||
const indexSamplingRatio = await this.eventConfig.indexEventSamplingRatio(); | ||
(_a = evalRes.events) === null || _a === void 0 ? void 0 : _a.forEach((event) => { | ||
this.eventProcessor.sendEvent(Object.assign(Object.assign({}, event), { indexSamplingRatio })); | ||
}); | ||
this.eventProcessor.sendEvent(eventFactory.evalEvent(flag, evalContext, evalRes.detail, defaultValue, undefined, indexSamplingRatio)); | ||
})(); | ||
if (typeChecker) { | ||
const [matched, type] = typeChecker(evalRes.detail.value); | ||
if (!matched) { | ||
const errorRes = EvalResult_1.default.forError(ErrorKinds_1.default.WrongType, `Did not receive expected type (${type}) evaluating feature flag "${flagKey}"`, defaultValue); | ||
// Method intentionally not awaited, puts event processing outside hot path. | ||
this.sendEvalEvent(evalRes, eventFactory, flag, evalContext, defaultValue); | ||
cb(errorRes, flag); | ||
return; | ||
} | ||
} | ||
// Method intentionally not awaited, puts event processing outside hot path. | ||
this.sendEvalEvent(evalRes, eventFactory, flag, evalContext, defaultValue); | ||
cb(evalRes, flag); | ||
@@ -367,3 +423,11 @@ }, eventFactory); | ||
} | ||
evaluateIfPossible(flagKey, context, defaultValue, eventFactory, cb) { | ||
async sendEvalEvent(evalRes, eventFactory, flag, evalContext, defaultValue) { | ||
var _a; | ||
const indexSamplingRatio = await this.eventConfig.indexEventSamplingRatio(); | ||
(_a = evalRes.events) === null || _a === void 0 ? void 0 : _a.forEach((event) => { | ||
this.eventProcessor.sendEvent(Object.assign(Object.assign({}, event), { indexSamplingRatio })); | ||
}); | ||
this.eventProcessor.sendEvent(eventFactory.evalEvent(flag, evalContext, evalRes.detail, defaultValue, undefined, indexSamplingRatio)); | ||
} | ||
evaluateIfPossible(flagKey, context, defaultValue, eventFactory, cb, typeChecker) { | ||
if (!this.initialized()) { | ||
@@ -375,3 +439,3 @@ this.featureStore.initialized((storeInitialized) => { | ||
" (did you wait for the 'ready' event?) - using last known values from feature store"); | ||
this.variationInternal(flagKey, context, defaultValue, eventFactory, cb); | ||
this.variationInternal(flagKey, context, defaultValue, eventFactory, cb, typeChecker); | ||
return; | ||
@@ -385,3 +449,3 @@ } | ||
} | ||
this.variationInternal(flagKey, context, defaultValue, eventFactory, cb); | ||
this.variationInternal(flagKey, context, defaultValue, eventFactory, cb, typeChecker); | ||
} | ||
@@ -388,0 +452,0 @@ } |
@@ -159,3 +159,3 @@ "use strict"; | ||
async read(key, context, defaultStage, payload) { | ||
const stage = await this.client.variationMigration(key, context, defaultStage); | ||
const stage = await this.client.migrationVariation(key, context, defaultStage); | ||
const res = await this.readTable[stage.value]({ | ||
@@ -170,3 +170,3 @@ payload, | ||
async write(key, context, defaultStage, payload) { | ||
const stage = await this.client.variationMigration(key, context, defaultStage); | ||
const stage = await this.client.migrationVariation(key, context, defaultStage); | ||
const res = await this.writeTable[stage.value]({ | ||
@@ -173,0 +173,0 @@ payload, |
@@ -63,13 +63,17 @@ "use strict"; | ||
createEvent() { | ||
var _a, _b, _c, _d; | ||
var _a, _b, _c, _d, _e; | ||
if (!js_sdk_common_1.TypeValidators.String.is(this.flagKey) || this.flagKey === '') { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('The flag key for a migration operation must be a non-empty string.'); | ||
return undefined; | ||
} | ||
if (!this.operation) { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('The operation must be set using "op" before an event can be created.'); | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('The operation must be set using "op" before an event can be created.'); | ||
return undefined; | ||
} | ||
if (Object.keys(this.contextKeys).length === 0) { | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('The migration was not done against a valid context and cannot generate an event.'); | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.error('The migration was not done against a valid context and cannot generate an event.'); | ||
return undefined; | ||
} | ||
if (!this.wasInvoked.old && !this.wasInvoked.new) { | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.error('The migration invoked neither the "old" or "new" implementation and' + | ||
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.error('The migration invoked neither the "old" or "new" implementation and' + | ||
'an event cannot be generated'); | ||
@@ -100,3 +104,3 @@ return undefined; | ||
measurements, | ||
samplingRatio: (_d = this.samplingRatio) !== null && _d !== void 0 ? _d : 1, | ||
samplingRatio: (_e = this.samplingRatio) !== null && _e !== void 0 ? _e : 1, | ||
}; | ||
@@ -103,0 +107,0 @@ } |
{ | ||
"name": "@launchdarkly/js-server-sdk-common", | ||
"version": "1.4.0-alpha.3", | ||
"version": "1.4.0-alpha.4", | ||
"type": "commonjs", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
617390
8778