@launchdarkly/js-server-sdk-common
Version:
LaunchDarkly Server SDK for JavaScript - common code
209 lines • 7.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const js_sdk_common_1 = require("@launchdarkly/js-sdk-common");
function isOperation(value) {
if (!js_sdk_common_1.TypeValidators.String.is(value)) {
return false;
}
return value === 'read' || value === 'write';
}
function isLatencyMeasurement(value) {
return value.key === 'latency_ms';
}
function isErrorMeasurement(value) {
return value.key === 'error';
}
function isInvokedMeasurement(value) {
return value.key === 'invoked';
}
function isConsistencyMeasurement(value) {
return value.key === 'consistent';
}
function areValidNumbers(values) {
const oldValue = values.old;
const newValue = values.new;
if (oldValue !== undefined && !js_sdk_common_1.TypeValidators.Number.is(oldValue)) {
return false;
}
if (newValue !== undefined && !js_sdk_common_1.TypeValidators.Number.is(newValue)) {
return false;
}
return true;
}
function areValidBooleans(values) {
const oldValue = values.old;
const newValue = values.new;
if (oldValue !== undefined && !js_sdk_common_1.TypeValidators.Boolean.is(oldValue)) {
return false;
}
if (newValue !== undefined && !js_sdk_common_1.TypeValidators.Boolean.is(newValue)) {
return false;
}
return true;
}
function validateMeasurement(measurement) {
// Here we are protecting ourselves from JS callers. TypeScript says that
// it cannot be an empty string, but those using JS can do what they want.
// @ts-ignore
if (!js_sdk_common_1.TypeValidators.String.is(measurement.key) || measurement.key === '') {
return undefined;
}
if (isLatencyMeasurement(measurement)) {
if (!js_sdk_common_1.TypeValidators.Object.is(measurement.values)) {
return undefined;
}
if (!areValidNumbers(measurement.values)) {
return undefined;
}
return {
key: measurement.key,
values: {
old: measurement.values.old,
new: measurement.values.new,
},
};
}
if (isErrorMeasurement(measurement)) {
if (!js_sdk_common_1.TypeValidators.Object.is(measurement.values)) {
return undefined;
}
if (!areValidBooleans(measurement.values)) {
return undefined;
}
return {
key: measurement.key,
values: {
old: measurement.values.old,
new: measurement.values.new,
},
};
}
if (isConsistencyMeasurement(measurement)) {
if (!js_sdk_common_1.TypeValidators.Boolean.is(measurement.value) ||
!js_sdk_common_1.TypeValidators.Number.is(measurement.samplingRatio)) {
return undefined;
}
return {
key: measurement.key,
value: measurement.value,
samplingRatio: measurement.samplingRatio,
};
}
if (isInvokedMeasurement(measurement)) {
if (!js_sdk_common_1.TypeValidators.Object.is(measurement.values)) {
return undefined;
}
if (!areValidBooleans(measurement.values)) {
return undefined;
}
return {
key: measurement.key,
values: {
old: measurement.values.old,
new: measurement.values.new,
},
};
}
// Not a supported measurement type.
return undefined;
}
function validateMeasurements(measurements) {
return measurements
.map(validateMeasurement)
.filter((value) => value !== undefined);
}
function validateEvaluation(evaluation) {
if (!js_sdk_common_1.TypeValidators.String.is(evaluation.key) || evaluation.key === '') {
return undefined;
}
if (!js_sdk_common_1.TypeValidators.Object.is(evaluation.reason)) {
return undefined;
}
if (!js_sdk_common_1.TypeValidators.String.is(evaluation.reason.kind) || evaluation.reason.kind === '') {
return undefined;
}
const validated = {
key: evaluation.key,
value: evaluation.value,
default: evaluation.default,
reason: {
kind: evaluation.reason.kind,
},
};
const inReason = evaluation.reason;
const outReason = validated.reason;
if (js_sdk_common_1.TypeValidators.String.is(inReason.errorKind)) {
outReason.errorKind = inReason.errorKind;
}
if (js_sdk_common_1.TypeValidators.String.is(inReason.ruleId)) {
outReason.ruleId = inReason.ruleId;
}
if (js_sdk_common_1.TypeValidators.String.is(inReason.prerequisiteKey)) {
outReason.prerequisiteKey = inReason.prerequisiteKey;
}
if (js_sdk_common_1.TypeValidators.Boolean.is(inReason.inExperiment)) {
outReason.inExperiment = inReason.inExperiment;
}
if (js_sdk_common_1.TypeValidators.Number.is(inReason.ruleIndex)) {
outReason.ruleIndex = inReason.ruleIndex;
}
if (js_sdk_common_1.TypeValidators.String.is(inReason.bigSegmentsStatus)) {
outReason.bigSegmentsStatus = inReason.bigSegmentsStatus;
}
if (evaluation.variation !== undefined && js_sdk_common_1.TypeValidators.Number.is(evaluation.variation)) {
validated.variation = evaluation.variation;
}
if (evaluation.version !== undefined && js_sdk_common_1.TypeValidators.Number.is(evaluation.version)) {
validated.version = evaluation.version;
}
return validated;
}
/**
* Migration events can be generated directly in user code and may not follow the shape
* expected by the TypeScript definitions. So we do some validation on these events, as well
* as copying the data out of them, to reduce the amount of invalid data we may send.
*
* @param inEvent The event to process.
* @returns An event, or undefined if it could not be converted.
*/
function MigrationOpEventToInputEvent(inEvent) {
var _a;
// The sampling ratio is omitted and needs populated by the track migration method.
if (inEvent.kind !== 'migration_op') {
return undefined;
}
if (!isOperation(inEvent.operation)) {
return undefined;
}
if (!js_sdk_common_1.TypeValidators.Number.is(inEvent.creationDate)) {
return undefined;
}
const contextKeysOrContext = {};
if (js_sdk_common_1.TypeValidators.Object.is(inEvent.context)) {
const context = js_sdk_common_1.Context.fromLDContext(inEvent.context);
if (context.valid) {
contextKeysOrContext.context = context;
}
}
else if (js_sdk_common_1.TypeValidators.Object.is(inEvent.contextKeys)) {
if (Object.keys(inEvent.contextKeys).every((key) => js_sdk_common_1.TypeValidators.Kind.is(key)) &&
Object.values(inEvent.contextKeys).every((value) => js_sdk_common_1.TypeValidators.String.is(value) && value !== '')) {
contextKeysOrContext.contextKeys = Object.assign({}, inEvent.contextKeys);
}
}
if (!contextKeysOrContext.context && !contextKeysOrContext.contextKeys) {
return undefined;
}
const samplingRatio = (_a = inEvent.samplingRatio) !== null && _a !== void 0 ? _a : 1;
if (!js_sdk_common_1.TypeValidators.Number.is(samplingRatio)) {
return undefined;
}
const evaluation = validateEvaluation(inEvent.evaluation);
if (!evaluation) {
return undefined;
}
return Object.assign(Object.assign({ kind: inEvent.kind, operation: inEvent.operation, creationDate: inEvent.creationDate }, contextKeysOrContext), { measurements: validateMeasurements(inEvent.measurements), evaluation,
samplingRatio });
}
exports.default = MigrationOpEventToInputEvent;
//# sourceMappingURL=MigrationOpEventConversion.js.map