@devcycle/nodejs-server-sdk
Advanced tools
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
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
153536
1488
191
6
10