Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@devcycle/nodejs-server-sdk

Package Overview
Dependencies
Maintainers
5
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@devcycle/nodejs-server-sdk - npm Package Compare versions

Comparing version 1.0.1 to 1.0.3

620

dist/main.js

@@ -5,3 +5,3 @@ /******/ (() => { // webpackBootstrap

/***/ "../../lib/shared/bucketing/src/bucketing.ts":
/***/ "./lib/shared/bucketing/src/bucketing.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -25,3 +25,3 @@

/* harmony import */ var murmurhash__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(murmurhash__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _segmentation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../lib/shared/bucketing/src/segmentation.ts");
/* harmony import */ var _segmentation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./lib/shared/bucketing/src/segmentation.ts");

@@ -175,3 +175,3 @@

/***/ "../../lib/shared/bucketing/src/index.ts":
/***/ "./lib/shared/bucketing/src/index.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -203,4 +203,4 @@

/* harmony export */ });
/* harmony import */ var _bucketing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("../../lib/shared/bucketing/src/bucketing.ts");
/* harmony import */ var _segmentation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../lib/shared/bucketing/src/segmentation.ts");
/* harmony import */ var _bucketing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./lib/shared/bucketing/src/bucketing.ts");
/* harmony import */ var _segmentation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./lib/shared/bucketing/src/segmentation.ts");

@@ -212,3 +212,3 @@

/***/ "../../lib/shared/bucketing/src/segmentation.ts":
/***/ "./lib/shared/bucketing/src/segmentation.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -233,3 +233,3 @@

/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _versionCompare__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../lib/shared/bucketing/src/versionCompare.js");
/* harmony import */ var _versionCompare__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./lib/shared/bucketing/src/versionCompare.js");
/* harmony import */ var ua_parser_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("ua-parser-js");

@@ -543,3 +543,3 @@ /* harmony import */ var ua_parser_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ua_parser_js__WEBPACK_IMPORTED_MODULE_2__);

/***/ "../../lib/shared/bucketing/src/versionCompare.js":
/***/ "./lib/shared/bucketing/src/versionCompare.js":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -593,3 +593,3 @@

/***/ "./src/client.ts":
/***/ "./sdk/nodejs-server-sdk/src/client.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -601,8 +601,9 @@

/* harmony export */ });
/* harmony import */ var _utils_configPollingHelper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/utils/configPollingHelper.ts");
/* harmony import */ var _utils_userBucketingHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/utils/userBucketingHelper.ts");
/* harmony import */ var _variable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/variable.ts");
/* harmony import */ var _request__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/request.ts");
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/utils/paramUtils.ts");
/* harmony import */ var _requestEvent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/requestEvent.ts");
/* harmony import */ var _environmentConfigManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./sdk/nodejs-server-sdk/src/environmentConfigManager.ts");
/* harmony import */ var _utils_userBucketingHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/userBucketingHelper.ts");
/* harmony import */ var _models_variable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./sdk/nodejs-server-sdk/src/models/variable.ts");
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/paramUtils.ts");
/* harmony import */ var _models_requestEvent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./sdk/nodejs-server-sdk/src/models/requestEvent.ts");
/* harmony import */ var _eventQueue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./sdk/nodejs-server-sdk/src/eventQueue.ts");
/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/logger.ts");

@@ -614,2 +615,3 @@

class DVCClient {

@@ -619,10 +621,12 @@ constructor(environmentKey, options) {

this.options = options;
this.configHelper = new _utils_configPollingHelper__WEBPACK_IMPORTED_MODULE_0__.ConfigPollingHelper(environmentKey, options || {});
this.logger = (options === null || options === void 0 ? void 0 : options.logger) || (0,_utils_logger__WEBPACK_IMPORTED_MODULE_6__.defaultLogger)();
this.configHelper = new _environmentConfigManager__WEBPACK_IMPORTED_MODULE_0__.EnvironmentConfigManager(this.logger, environmentKey, options || {});
this.eventQueue = new _eventQueue__WEBPACK_IMPORTED_MODULE_5__.EventQueue(this.logger, environmentKey, options === null || options === void 0 ? void 0 : options.flushEventsMS);
this.onInitialized = this.configHelper.fetchConfigPromise
.then(() => {
console.log('DevCycle initialized');
this.logger.info('DevCycle initialized');
return this;
})
.catch((err) => {
console.error(`Error initializing DevCycle: ${err}`);
this.logger.error(`Error initializing DevCycle: ${err}`);
return this;

@@ -645,10 +649,11 @@ });

const bucketedConfig = (0,_utils_userBucketingHelper__WEBPACK_IMPORTED_MODULE_1__.bucketUserForConfig)(user, (_a = this.configHelper) === null || _a === void 0 ? void 0 : _a.config);
const variable = new _variable__WEBPACK_IMPORTED_MODULE_2__.DVCVariable(Object.assign(Object.assign({}, (_b = bucketedConfig === null || bucketedConfig === void 0 ? void 0 : bucketedConfig.variables) === null || _b === void 0 ? void 0 : _b[key]), { key,
const variable = new _models_variable__WEBPACK_IMPORTED_MODULE_2__.DVCVariable(Object.assign(Object.assign({}, (_b = bucketedConfig === null || bucketedConfig === void 0 ? void 0 : bucketedConfig.variables) === null || _b === void 0 ? void 0 : _b[key]), { key,
defaultValue }));
(0,_request__WEBPACK_IMPORTED_MODULE_3__.publishEvents)(this.environmentKey, user, [{
type: variable.value === variable.defaultValue
? _requestEvent__WEBPACK_IMPORTED_MODULE_5__.EventTypes.variableDefaulted
: _requestEvent__WEBPACK_IMPORTED_MODULE_5__.EventTypes.variableEvaluated,
target: variable.key
}], bucketedConfig);
const variableEvent = {
type: variable.value === variable.defaultValue
? _models_requestEvent__WEBPACK_IMPORTED_MODULE_4__.EventTypes.variableDefaulted
: _models_requestEvent__WEBPACK_IMPORTED_MODULE_4__.EventTypes.variableEvaluated,
target: variable.key
};
this.eventQueue.queueAggregateEvent(user, variableEvent, bucketedConfig);
return variable;

@@ -668,9 +673,8 @@ }

var _a;
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_4__.checkParamDefined)('type', event.type);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_3__.checkParamDefined)('type', event.type);
const bucketedConfig = (0,_utils_userBucketingHelper__WEBPACK_IMPORTED_MODULE_1__.bucketUserForConfig)(user, (_a = this.configHelper) === null || _a === void 0 ? void 0 : _a.config);
(0,_request__WEBPACK_IMPORTED_MODULE_3__.publishEvents)(this.environmentKey, user, [event], bucketedConfig);
this.eventQueue.queueEvent(user, event, bucketedConfig);
}
flushEvents(callback) {
// TODO: implement when we implement /event-batch endpoint
throw new Error('Not Implemented');
return this.eventQueue.flushEvents().then(callback);
}

@@ -682,3 +686,3 @@ }

/***/ "./src/request.ts":
/***/ "./sdk/nodejs-server-sdk/src/environmentConfigManager.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -688,42 +692,267 @@

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "HOST": () => (/* binding */ HOST),
/* harmony export */ "EVENT_URL": () => (/* binding */ EVENT_URL),
/* harmony export */ "EVENTS_PATH": () => (/* binding */ EVENTS_PATH),
/* harmony export */ "publishEvents": () => (/* binding */ publishEvents)
/* harmony export */ "EnvironmentConfigManager": () => (/* binding */ EnvironmentConfigManager)
/* harmony export */ });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("tslib");
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tslib__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_eventUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/utils/eventUtils.ts");
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("axios");
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(axios__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./sdk/nodejs-server-sdk/src/request.ts");
class EnvironmentConfigManager {
constructor(logger, environmentKey, { configPollingIntervalMS = 10000, configPollingTimeoutMS = 5000, cdnURI = 'https://config-cdn.devcycle.com' }) {
this.logger = logger;
this.environmentKey = environmentKey;
this.pollingIntervalMS = configPollingIntervalMS >= 1000
? configPollingIntervalMS
: 1000;
this.requestTimeoutMS = configPollingTimeoutMS >= this.pollingIntervalMS
? this.pollingIntervalMS
: configPollingTimeoutMS;
this.cdnURI = cdnURI;
this.fetchConfigPromise = this._fetchConfig().then(() => {
this.logger.debug('DevCycle initial config loaded');
});
this.intervalTimeout = setInterval(() => this._fetchConfig(), this.pollingIntervalMS);
}
cleanup() {
clearInterval(this.intervalTimeout);
}
getConfigURL() {
return `${this.cdnURI}/config/v1/server/${this.environmentKey}.json`;
}
_fetchConfig() {
var _a, _b, _c;
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
const url = this.getConfigURL();
let res;
try {
this.logger.debug(`Requesting new config for ${url}, etag: ${this.configEtag}`);
res = yield (0,_request__WEBPACK_IMPORTED_MODULE_1__.getEnvironmentConfig)(url, this.requestTimeoutMS, this.configEtag);
this.logger.debug(`Downloaded config, status: ${res === null || res === void 0 ? void 0 : res.status}, etag: ${(_a = res === null || res === void 0 ? void 0 : res.headers) === null || _a === void 0 ? void 0 : _a.etag}`);
}
catch (ex) {
this.logger.error(`Request to get config failed for url: ${url}, ` +
`response message: ${ex.message}, response data ${(_b = ex === null || ex === void 0 ? void 0 : ex.response) === null || _b === void 0 ? void 0 : _b.data}`);
res = null;
}
if ((res === null || res === void 0 ? void 0 : res.status) === 304) {
this.logger.debug(`Config not modified, using cache, etag: ${this.configEtag}`);
}
else if ((res === null || res === void 0 ? void 0 : res.status) === 200) {
this.config = res === null || res === void 0 ? void 0 : res.data;
this.configEtag = (_c = res === null || res === void 0 ? void 0 : res.headers) === null || _c === void 0 ? void 0 : _c.etag;
}
else if (this.config) {
this.logger.error(`Failed to download config, using cached version. url: ${url}.`);
}
else {
throw new Error('Failed to download DevCycle config.');
}
});
}
}
const axiosClient = axios__WEBPACK_IMPORTED_MODULE_2___default().create({
validateStatus: (status) => status < 400 && status >= 200,
});
const HOST = '.devcycle.com';
const EVENT_URL = 'https://events';
const EVENTS_PATH = '/v1/events';
function publishEvents(envKey, user, events, config) {
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
if (!envKey || !config) {
throw new Error('DevCycle is not yet initialized to publish events.');
}
const payload = (0,_utils_eventUtils__WEBPACK_IMPORTED_MODULE_1__.generateEventPayload)(config, user, events);
console.log(`Submit Events Payload: ${JSON.stringify(payload)}`);
const res = yield axiosClient.request({
method: 'POST',
url: `${EVENT_URL}${HOST}${EVENTS_PATH}`,
headers: { 'Authorization': envKey },
data: payload
/***/ }),
/***/ "./sdk/nodejs-server-sdk/src/eventQueue.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "EventTypes": () => (/* binding */ EventTypes),
/* harmony export */ "EventQueue": () => (/* binding */ EventQueue)
/* harmony export */ });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("tslib");
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tslib__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./sdk/nodejs-server-sdk/src/request.ts");
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/paramUtils.ts");
/* harmony import */ var _models_requestEvent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./sdk/nodejs-server-sdk/src/models/requestEvent.ts");
/* harmony import */ var _models_requestUser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./sdk/nodejs-server-sdk/src/models/requestUser.ts");
const EventTypes = {
variableEvaluated: 'variableEvaluated',
variableDefaulted: 'variableDefaulted',
};
class EventQueue {
constructor(logger, environmentKey, flushEventsMS) {
this.logger = logger;
this.environmentKey = environmentKey;
this.userEventQueue = {};
this.aggregateUserEventMap = {};
this.flushEventsMS = flushEventsMS || 10 * 1000;
this.flushInterval = setInterval(this.flushEvents.bind(this), this.flushEventsMS);
}
cleanup() {
clearInterval(this.flushInterval);
}
/**
* Flush events in queue to DevCycle Events API. Requeue events if flush fails
*/
flushEvents() {
var _a;
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
const userEventBatch = this.combineUserEventsToFlush();
if (!userEventBatch.length) {
return;
}
const reducer = (val, batch) => val + batch.events.length;
const eventCount = userEventBatch.reduce(reducer, 0);
this.logger.debug(`DVC Flush ${eventCount} Events, for ${userEventBatch.length} Users`);
const savingUserEventQueue = this.userEventQueue;
this.userEventQueue = {};
const savingAggregateUserEventMap = this.aggregateUserEventMap;
this.aggregateUserEventMap = {};
try {
const res = yield (0,_request__WEBPACK_IMPORTED_MODULE_1__.publishEvents)(this.logger, this.environmentKey, userEventBatch);
if (res.status !== 201) {
throw new Error(`Error publishing events, status: ${res.status}, body: ${res.data}`);
}
else {
this.logger.debug(`DVC Flushed ${eventCount} Events, for ${userEventBatch.length} Users`);
}
}
catch (ex) {
this.logger.error(`DVC Error Flushing Events response message: ${ex.message}, ` +
`response data: ${(_a = ex === null || ex === void 0 ? void 0 : ex.response) === null || _a === void 0 ? void 0 : _a.data}`);
this.requeueUserEvents(savingUserEventQueue);
this.requeueAggUserEventMap(savingAggregateUserEventMap);
}
});
if (res.status !== 201) {
console.error(`Error posting events, status: ${res.status}, body: ${res.data}`);
}
/**
* Requeue user events after failed request to DevCycle Events API.
*/
requeueUserEvents(userEventQueueToMerge) {
for (const user_id in userEventQueueToMerge) {
const mergeRecord = userEventQueueToMerge[user_id];
const userRecord = this.userEventQueue[user_id];
if (!userRecord) {
this.userEventQueue[user_id] = Object.assign({}, mergeRecord);
}
else {
userRecord.events.push(...mergeRecord.events);
}
}
}
/**
* Queue DVCAPIEvent for publishing to DevCycle Events API.
*/
queueEvent(user, event, bucketedConfig) {
let userEvents = this.userEventQueue[user.user_id];
if (!userEvents) {
userEvents = this.userEventQueue[user.user_id] = {
user: new _models_requestUser__WEBPACK_IMPORTED_MODULE_4__.DVCRequestUser(user),
events: []
};
}
else {
console.log(`Posted Events, status: ${res.status}, body: ${res.data}`);
// Save updated User every time.
userEvents.user = new _models_requestUser__WEBPACK_IMPORTED_MODULE_4__.DVCRequestUser(user);
}
return res;
});
userEvents.events.push(new _models_requestEvent__WEBPACK_IMPORTED_MODULE_3__.DVCRequestEvent(event, user.user_id, bucketedConfig === null || bucketedConfig === void 0 ? void 0 : bucketedConfig.featureVariationMap));
}
/**
* Requeue aggregated user event map after failed request to DevCycle Events API.
*/
requeueAggUserEventMap(aggUserEventMapToMerge) {
for (const user_id in aggUserEventMapToMerge) {
const mergeEventMap = aggUserEventMapToMerge[user_id];
let userEventMap = this.aggregateUserEventMap[user_id];
if (!userEventMap) {
userEventMap = this.aggregateUserEventMap[user_id] = {
user: mergeEventMap.user,
events: {}
};
}
const aggEvents = this.eventsFromAggregateEventMap(mergeEventMap.events);
for (const event of aggEvents) {
this.saveAggUserEvent(userEventMap, event);
}
}
}
/**
* Save aggregated user event (i.e. variableEvaluated / variableDefaulted) to userEventMap.
*/
saveAggUserEvent(userEventMap, event) {
const { target } = event;
if (!target)
return;
const aggEventType = userEventMap.events[event.type];
const aggEvent = aggEventType === null || aggEventType === void 0 ? void 0 : aggEventType[target];
if (!aggEventType) {
userEventMap.events[event.type] = { [target]: event };
}
else if (aggEvent && aggEvent.value) {
aggEvent.value += event.value || 1;
}
else {
aggEventType[target] = event;
}
}
/**
* Queue DVCEvent that can be aggregated together, where multiple calls are aggregated
* by incrementing the 'value' field.
*/
queueAggregateEvent(user, event, bucketedConfig) {
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_2__.checkParamDefined)('user_id', user === null || user === void 0 ? void 0 : user.user_id);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_2__.checkParamDefined)('type', event.type);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_2__.checkParamDefined)('target', event.target);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_2__.checkParamString)('target', event.target);
const eventCopy = Object.assign({}, event);
eventCopy.date = Date.now();
eventCopy.value = 1;
let userEventMap = this.aggregateUserEventMap[user.user_id];
if (!userEventMap) {
userEventMap = this.aggregateUserEventMap[user.user_id] = {
user: new _models_requestUser__WEBPACK_IMPORTED_MODULE_4__.DVCRequestUser(user),
events: {}
};
}
else {
// Always keep the latest user object
userEventMap.user = new _models_requestUser__WEBPACK_IMPORTED_MODULE_4__.DVCRequestUser(user);
}
const requestEvent = new _models_requestEvent__WEBPACK_IMPORTED_MODULE_3__.DVCRequestEvent(eventCopy, user.user_id, bucketedConfig === null || bucketedConfig === void 0 ? void 0 : bucketedConfig.featureVariationMap);
this.saveAggUserEvent(userEventMap, requestEvent);
}
/**
* Turn the Aggregate Event Map into an UserEventsBatchRequestPayload for publishing.
*/
combineUserEventsToFlush() {
const userRequestEventsToFlush = {};
for (const user_id in this.userEventQueue) {
const userEventsRecord = this.userEventQueue[user_id];
const existingUserRequestEvents = userRequestEventsToFlush[user_id];
if (existingUserRequestEvents) {
existingUserRequestEvents.events.push(...userEventsRecord.events);
}
else {
userRequestEventsToFlush[user_id] = userEventsRecord;
}
}
for (const user_id in this.aggregateUserEventMap) {
const aggUserEventsRecord = this.aggregateUserEventMap[user_id];
const existingUserRequestEvents = userRequestEventsToFlush[user_id];
if (existingUserRequestEvents) {
existingUserRequestEvents.events.push(...this.eventsFromAggregateEventMap(aggUserEventsRecord.events));
}
else {
userRequestEventsToFlush[user_id] = {
user: aggUserEventsRecord.user,
events: this.eventsFromAggregateEventMap(aggUserEventsRecord.events)
};
}
}
return Object.values(userRequestEventsToFlush);
}
/**
* Convert aggregated events map into array of individual events for publishing
*/
eventsFromAggregateEventMap(eventsMap) {
return Object.values(eventsMap).map((typeMap) => Object.values(typeMap)).flat();
}
}

@@ -734,3 +963,3 @@

/***/ "./src/requestEvent.ts":
/***/ "./sdk/nodejs-server-sdk/src/models/requestEvent.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -743,3 +972,3 @@

/* harmony export */ });
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/utils/paramUtils.ts");
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/paramUtils.ts");

@@ -751,11 +980,17 @@ const EventTypes = {

class DVCRequestEvent {
constructor(event) {
constructor(event, user_id, featureVars) {
const { type, target, date, value, metaData } = event;
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('type', type);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamString)('type', type);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('user_id', user_id);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamString)('user_id', user_id);
const isCustomEvent = !EventTypes[type];
this.type = isCustomEvent ? 'customEvent' : type;
this.target = target;
this.customType = isCustomEvent ? type : undefined;
this.target = target;
this.user_id = user_id;
this.date = Date.now();
this.clientDate = date || Date.now();
this.value = value;
this.featureVars = featureVars;
this.metaData = metaData;

@@ -768,3 +1003,3 @@ }

/***/ "./src/requestUser.ts":
/***/ "./sdk/nodejs-server-sdk/src/models/requestUser.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -776,9 +1011,12 @@

/* harmony export */ });
/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./package.json");
/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./sdk/nodejs-server-sdk/package.json");
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/paramUtils.ts");
class DVCRequestUser {
constructor(user) {
if (!user.user_id) {
throw new Error('Must have a user_id, or have "isAnonymous" set on the user');
throw new Error('Must have a user_id set on the user');
}
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_1__.checkParamType)('user_id', user.user_id, _utils_paramUtils__WEBPACK_IMPORTED_MODULE_1__.typeEnum.string);
this.user_id = user.user_id;

@@ -808,3 +1046,3 @@ this.email = user.email;

/***/ "./src/utils/configPollingHelper.ts":
/***/ "./sdk/nodejs-server-sdk/src/models/variable.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -814,4 +1052,38 @@

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ConfigPollingHelper": () => (/* binding */ ConfigPollingHelper)
/* harmony export */ "DVCVariable": () => (/* binding */ DVCVariable)
/* harmony export */ });
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/paramUtils.ts");
class DVCVariable {
constructor(variable) {
const { key, defaultValue, value, evalReason } = variable;
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('key', key);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('defaultValue', defaultValue);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamType)('key', key, _utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.typeEnum.string);
this.key = key;
this.isDefaulted = (value === undefined || value === null);
this.value = (value === undefined || value === null)
? defaultValue
: value;
this.defaultValue = defaultValue;
this.evalReason = evalReason;
}
}
/***/ }),
/***/ "./sdk/nodejs-server-sdk/src/request.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "HOST": () => (/* binding */ HOST),
/* harmony export */ "EVENT_URL": () => (/* binding */ EVENT_URL),
/* harmony export */ "EVENTS_PATH": () => (/* binding */ EVENTS_PATH),
/* harmony export */ "publishEvents": () => (/* binding */ publishEvents),
/* harmony export */ "getEnvironmentConfig": () => (/* binding */ getEnvironmentConfig),
/* harmony export */ "post": () => (/* binding */ post),
/* harmony export */ "get": () => (/* binding */ get)
/* harmony export */ });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("tslib");

@@ -823,60 +1095,51 @@ /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tslib__WEBPACK_IMPORTED_MODULE_0__);

class ConfigPollingHelper {
constructor(envKey, { configPollingIntervalMS = 10000, configPollingTimeoutMS = 5000, cdnURI = 'https://config-cdn.devcycle.com' }) {
this.envKey = envKey;
this.pollingIntervalMS = configPollingIntervalMS >= 1000
? configPollingIntervalMS
: 1000;
this.requestTimeoutMS = configPollingTimeoutMS >= this.pollingIntervalMS
? this.pollingIntervalMS
: configPollingTimeoutMS;
this.cdnURI = cdnURI;
this.fetchConfigPromise = this._fetchConfig().then(() => {
console.debug('DevCycle initial config loaded');
const axiosClient = axios__WEBPACK_IMPORTED_MODULE_1___default().create({
validateStatus: (status) => status < 400 && status >= 200,
});
const HOST = '.devcycle.com';
const EVENT_URL = 'https://events';
const EVENTS_PATH = '/v1/events/batch';
function publishEvents(logger, envKey, eventsBatch) {
var _a, _b;
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
if (!envKey) {
throw new Error('DevCycle is not yet initialized to publish events.');
}
const res = yield post({
url: `${EVENT_URL}${HOST}${EVENTS_PATH}`,
headers: { 'Authorization': envKey },
data: { batch: eventsBatch }
});
this.intervalTimeout = setInterval(() => this._fetchConfig(), this.pollingIntervalMS);
}
cleanup() {
clearInterval(this.intervalTimeout);
}
_fetchConfig() {
var _a, _b;
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
const url = `${this.cdnURI}/config/v1/server/${this.envKey}.json`;
const axiosOptions = {
method: 'GET',
url,
validateStatus: (status) => status < 400 && status >= 200,
timeout: this.requestTimeoutMS,
headers: {}
};
if (this.configEtag && axiosOptions.headers) {
axiosOptions.headers['If-None-Match'] = this.configEtag;
}
let res;
try {
console.debug(`Requesting new config for ${url}, etag: ${this.configEtag}`);
res = yield axios__WEBPACK_IMPORTED_MODULE_1___default().request(axiosOptions);
console.debug(`Downloaded config, status: ${res === null || res === void 0 ? void 0 : res.status}, etag: ${(_a = res === null || res === void 0 ? void 0 : res.headers) === null || _a === void 0 ? void 0 : _a.etag}`);
}
catch (ex) {
console.error(`Request to get config failed for ${url}`, ex);
res = null;
}
if ((res === null || res === void 0 ? void 0 : res.status) === 304) {
console.debug(`Config not modified, using cache, etag: ${this.configEtag}`);
}
else if ((res === null || res === void 0 ? void 0 : res.status) === 200) {
this.config = res === null || res === void 0 ? void 0 : res.data;
this.configEtag = (_b = res === null || res === void 0 ? void 0 : res.headers) === null || _b === void 0 ? void 0 : _b.etag;
}
else if (this.config) {
console.error(`Failed to download config, using cached version. url: ${url}.`);
}
else {
throw new Error('Failed to download DevCycle config.');
}
if (res.status !== 201) {
logger.error(`Error posting events, status: ${res.status}, body: ${(_a = res.data) === null || _a === void 0 ? void 0 : _a.message}`);
}
else {
logger.debug(`Posted Events, status: ${res.status}, body: ${(_b = res.data) === null || _b === void 0 ? void 0 : _b.message}`);
}
return res;
});
}
function getEnvironmentConfig(url, requestTimeout, etag) {
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
const headers = {};
if (etag) {
headers['If-None-Match'] = etag;
}
return yield get({
url,
timeout: requestTimeout,
headers: headers
});
}
});
}
function post(requestConfig) {
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
return yield axiosClient.request(Object.assign(Object.assign({}, requestConfig), { method: 'POST' }));
});
}
function get(requestConfig) {
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
return yield axiosClient.request(Object.assign(Object.assign({}, requestConfig), { method: 'GET' }));
});
}

@@ -886,3 +1149,3 @@

/***/ "./src/utils/eventUtils.ts":
/***/ "./sdk/nodejs-server-sdk/src/utils/logger.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -892,14 +1155,29 @@

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "generateEventPayload": () => (/* binding */ generateEventPayload)
/* harmony export */ "DVCLogLevels": () => (/* binding */ DVCLogLevels),
/* harmony export */ "defaultLogger": () => (/* binding */ defaultLogger)
/* harmony export */ });
/* harmony import */ var _requestEvent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/requestEvent.ts");
/* harmony import */ var _requestUser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/requestUser.ts");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("lodash");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);
function generateEventPayload(config, user, events) {
const prefix = '[DevCycle]: ';
var DVCLogLevels;
(function (DVCLogLevels) {
DVCLogLevels[DVCLogLevels["debug"] = 0] = "debug";
DVCLogLevels[DVCLogLevels["info"] = 1] = "info";
DVCLogLevels[DVCLogLevels["warn"] = 2] = "warn";
DVCLogLevels[DVCLogLevels["error"] = 3] = "error";
})(DVCLogLevels || (DVCLogLevels = {}));
function defaultLogger(options) {
const minLevel = ((options === null || options === void 0 ? void 0 : options.level) && (0,lodash__WEBPACK_IMPORTED_MODULE_0__.isNumber)(DVCLogLevels[options === null || options === void 0 ? void 0 : options.level]))
? DVCLogLevels[options === null || options === void 0 ? void 0 : options.level]
: DVCLogLevels.info;
const logWriter = (options === null || options === void 0 ? void 0 : options.logWriter) || console.error;
const writeLog = (message) => logWriter(prefix + message);
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noOpLog = (message) => { };
return {
events: events.map((event) => {
return Object.assign(Object.assign({}, (new _requestEvent__WEBPACK_IMPORTED_MODULE_0__.DVCRequestEvent(event))), { user_id: user.user_id, date: Date.now(), featureVars: config.featureVariationMap });
}),
user: new _requestUser__WEBPACK_IMPORTED_MODULE_1__.DVCRequestUser(user)
error: DVCLogLevels.error >= minLevel ? writeLog : noOpLog,
warn: DVCLogLevels.warn >= minLevel ? writeLog : noOpLog,
info: DVCLogLevels.info >= minLevel ? writeLog : noOpLog,
debug: DVCLogLevels.debug >= minLevel ? writeLog : noOpLog,
};

@@ -911,3 +1189,3 @@ }

/***/ "./src/utils/paramUtils.ts":
/***/ "./sdk/nodejs-server-sdk/src/utils/paramUtils.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -918,3 +1196,5 @@

/* harmony export */ "checkParamDefined": () => (/* binding */ checkParamDefined),
/* harmony export */ "checkParamType": () => (/* binding */ checkParamType)
/* harmony export */ "typeEnum": () => (/* binding */ typeEnum),
/* harmony export */ "checkParamType": () => (/* binding */ checkParamType),
/* harmony export */ "checkParamString": () => (/* binding */ checkParamString)
/* harmony export */ });

@@ -925,11 +1205,32 @@ const checkParamDefined = (name, param) => {

}
return param;
};
var typeEnum;
(function (typeEnum) {
typeEnum["string"] = "string";
typeEnum["number"] = "number";
typeEnum["boolean"] = "boolean";
})(typeEnum || (typeEnum = {}));
const typeEnumValues = Object.values(typeEnum);
const checkParamType = (name, param, type) => {
if (!param) {
if (param === undefined || param === null) {
throw new Error(`${name} is invalid!`);
}
if (!typeEnumValues.includes(type)) {
throw new Error(`unknown type to check: ${type}`);
}
if (typeof param !== type) {
throw new Error(`${name} is not of type ${type}`);
throw new Error(`${name} is not of type: ${type}`);
}
if (type === typeEnum.string && !param.length) {
throw new Error(`${name} is invalid string!`);
}
if (type === typeEnum.number && isNaN(param)) {
throw new Error(`${name} is invalid number!`);
}
};
function checkParamString(name, param) {
checkParamType(name, param, typeEnum.string);
return param;
}

@@ -939,3 +1240,3 @@

/***/ "./src/utils/userBucketingHelper.ts":
/***/ "./sdk/nodejs-server-sdk/src/utils/userBucketingHelper.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

@@ -947,3 +1248,3 @@

/* harmony export */ });
/* harmony import */ var _devcycle_shared_bucketing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("../../lib/shared/bucketing/src/index.ts");
/* harmony import */ var _devcycle_shared_bucketing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./lib/shared/bucketing/src/index.ts");
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries

@@ -953,3 +1254,3 @@

if (!config)
return null;
return;
return (0,_devcycle_shared_bucketing__WEBPACK_IMPORTED_MODULE_0__.generateBucketedConfig)({ config, user });

@@ -961,30 +1262,2 @@ }

/***/ "./src/variable.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DVCVariable": () => (/* binding */ DVCVariable)
/* harmony export */ });
/* harmony import */ var _utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/utils/paramUtils.ts");
class DVCVariable {
constructor(variable) {
const { key, defaultValue, value, evalReason } = variable;
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('key', key);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamDefined)('defaultValue', defaultValue);
(0,_utils_paramUtils__WEBPACK_IMPORTED_MODULE_0__.checkParamType)('key', key, 'string');
this.key = key;
this.isDefaulted = (value === undefined || value === null);
this.value = (value === undefined || value === null)
? defaultValue
: value;
this.defaultValue = defaultValue;
this.evalReason = evalReason;
}
}
/***/ }),
/***/ "axios":

@@ -1025,6 +1298,6 @@ /***/ ((module) => {

/***/ "./package.json":
/***/ "./sdk/nodejs-server-sdk/package.json":
/***/ ((module) => {
module.exports = JSON.parse('{"name":"@devcycle/nodejs-server-sdk","version":"1.0.1","description":"The DevCycle NodeJS Server SDK used for feature management.","main":"dist/main.js","types":"types.d.ts","files":["dist","README.md","types.d.ts"],"scripts":{"clean":"rimraf dist","test":"jest --runInBand","tsc":"tsc","build":"yarn clean && webpack","lint":"eslint --ext .js,.ts"},"license":"MIT","devDependencies":{"@babel/plugin-transform-runtime":"^7.15.0","@babel/preset-env":"^7.15.6","@types/jest":"^27.0.2","@types/uuid":"^8.3.1","babel-jest":"^27.2.1","eslint":"^7.22.0","jest":"^27.2.1","rimraf":"^3.0.2","ts-jest":"^27.0.5","ts-loader":"^9.2.6","typescript":"^4.4.3","webpack":"^5.53.0","webpack-cli":"^4.8.0"},"dependencies":{"axios":"^0.24.0","lodash":"^4.17.21","md5":"^2.2.1","murmurhash":"^2.0.0","tslib":"^2.0.0","ua-parser-js":"^0.7.21","uuid":"^8.3.2"}}');
module.exports = JSON.parse('{"name":"@devcycle/nodejs-server-sdk","version":"1.0.3","description":"The DevCycle NodeJS Server SDK used for feature management.","main":"dist/main.js","types":"types.d.ts","files":["dist","README.md","types.d.ts"],"scripts":{"clean":"rimraf dist","test":"jest --runInBand","tsc":"tsc","build":"yarn clean && webpack","lint":"eslint --ext .js,.ts"},"license":"MIT","devDependencies":{"@babel/plugin-transform-runtime":"^7.15.0","@babel/preset-env":"^7.15.6","@types/jest":"^27.0.2","@types/uuid":"^8.3.1","babel-jest":"^27.2.1","eslint":"^7.22.0","jest":"^27.2.1","rimraf":"^3.0.2","ts-jest":"^27.0.5","ts-loader":"^9.2.6","typescript":"^4.4.3","webpack":"^5.53.0","webpack-cli":"^4.8.0"},"dependencies":{"axios":"^0.24.0","lodash":"^4.17.21","md5":"^2.2.1","murmurhash":"^2.0.0","tslib":"^2.0.0","ua-parser-js":"^0.7.21","uuid":"^8.3.2"}}');

@@ -1107,7 +1380,10 @@ /***/ })

/* harmony export */ "DVCClient": () => (/* reexport safe */ _client__WEBPACK_IMPORTED_MODULE_0__.DVCClient),
/* harmony export */ "defaultLogger": () => (/* reexport safe */ _utils_logger__WEBPACK_IMPORTED_MODULE_1__.defaultLogger),
/* harmony export */ "initialize": () => (/* binding */ initialize)
/* harmony export */ });
/* harmony import */ var _client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/client.ts");
/* harmony import */ var _client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./sdk/nodejs-server-sdk/src/client.ts");
/* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./sdk/nodejs-server-sdk/src/utils/logger.ts");
function initialize(environmentKey, options) {

@@ -1114,0 +1390,0 @@ if (!environmentKey) {

{
"name": "@devcycle/nodejs-server-sdk",
"version": "1.0.1",
"version": "1.0.3",
"description": "The DevCycle NodeJS Server SDK used for feature management.",

@@ -5,0 +5,0 @@ "main": "dist/main.js",

@@ -16,2 +16,7 @@ /**

/**
* Logger override to replace default logger
*/
logger?: DVCLogger
/**
* Controls the polling interval in milliseconds to fetch new environment config changes, defaults to 10 seconds.

@@ -259,1 +264,19 @@ * @min 1000

export type DVCFeatureSet = Record<string, DVCFeature>
export interface DVCLogger {
error(message: string): void
warn(message: string): void
info(message: string): void
debug(message: string): void
}
export type DVCDefaultLoggerOptions = {
level?: 'debug' | 'info' | 'warn' | 'error'
logWriter?: (message: string) => void
}
export function defaultLogger(options?: DVCDefaultLoggerOptions): DVCLogger

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc