diff --git a/.ldrelease/config.yml b/.ldrelease/config.yml index 3813052b..e1f82cf0 100644 --- a/.ldrelease/config.yml +++ b/.ldrelease/config.yml @@ -4,6 +4,11 @@ repo: public: js-client-sdk private: js-client-sdk-private +branches: +- name: main + description: 3.x +- name: 2.x + publications: - url: https://www.npmjs.com/package/launchdarkly-js-client-sdk description: npm diff --git a/example/example.js b/example/example.js index d181cab8..6c68552d 100644 --- a/example/example.js +++ b/example/example.js @@ -139,13 +139,13 @@ $(function() { // client.variation() to get individual values by flag key, but here we are iterating through them all. function showAllFlags(changes) { - var userJson = JSON.stringify(client.getUser(), null, ' '); + var contextJson = JSON.stringify(client.getContext(), null, ' '); var allFlags = client.allFlags(); var keys = Object.keys(allFlags).sort(); $content = $('
'); $content.append('These are the feature flag values from the current environment for the user:'); - $content.append($('').text(' ' + userJson)).append('

'); + $content.append($('').text(' ' + contextJson)).append('

'); var $table = $('
').addClass('table').addClass('table-sm'); var $thead = $(''); diff --git a/jest.config.js b/jest.config.js index 05de06a1..5de87dea 100644 --- a/jest.config.js +++ b/jest.config.js @@ -9,6 +9,9 @@ module.exports = { transform: { '^.+\\.js$': ['babel-jest', { rootMode: 'upward' }], }, + transformIgnorePatterns: [ + "node_modules/(?!uuid)" + ], globals: { window: true, VERSION: version, diff --git a/package.json b/package.json index d5c02f8b..055e4ed6 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ }, "dependencies": { "escape-string-regexp": "^4.0.0", - "launchdarkly-js-sdk-common": "3.8.2" + "launchdarkly-js-sdk-common": "5.0.0" }, "repository": { "type": "git", diff --git a/src/GoalManager.js b/src/GoalManager.js index 87b57d04..6d742a65 100644 --- a/src/GoalManager.js +++ b/src/GoalManager.js @@ -23,20 +23,16 @@ export default function GoalManager(clientVars, readyCallback) { } function sendGoalEvent(kind, goal) { - const user = clientVars.ident.getUser(); + const context = clientVars.ident.getContext(); const event = { kind: kind, key: goal.key, data: null, url: window.location.href, - user: user, creationDate: new Date().getTime(), + contextKeys: common.getContextKeys(context), }; - if (user && user.anonymous) { - event.contextKind = 'anonymousUser'; - } - if (kind === 'click') { event.selector = goal.selector; } diff --git a/src/__tests__/LDClient-events-test.js b/src/__tests__/LDClient-events-test.js index 919fd0d6..1115266e 100644 --- a/src/__tests__/LDClient-events-test.js +++ b/src/__tests__/LDClient-events-test.js @@ -40,7 +40,7 @@ describe('LDClient', () => { const trackEvent = ep.events[1]; expect(trackEvent.kind).toEqual('custom'); expect(trackEvent.key).toEqual('eventkey'); - expect(trackEvent.user).toEqual(user); + expect(trackEvent.context).toEqual(user); expect(trackEvent.data).toEqual(data); expect(trackEvent.url).toEqual(urlShouldBe); }); @@ -74,7 +74,7 @@ describe('LDClient', () => { const trackEvent = ep.events[1]; expect(trackEvent.kind).toEqual('custom'); expect(trackEvent.key).toEqual('eventkey'); - expect(trackEvent.user).toEqual(user); + expect(trackEvent.context).toEqual(user); expect(trackEvent.url).toEqual(urlShouldBe); }); }); diff --git a/src/browserPlatform.js b/src/browserPlatform.js index f2da795e..fb2dc42f 100644 --- a/src/browserPlatform.js +++ b/src/browserPlatform.js @@ -1,7 +1,9 @@ import newHttpRequest from './httpRequest'; export default function makeBrowserPlatform(options) { - const ret = {}; + const ret = { + userAgentHeaderName: 'X-LaunchDarkly-User-Agent', + }; ret.synchronousFlush = false; // this will be set to true by index.js if the page is closing diff --git a/test-types.ts b/test-types.ts index e4c5203d..0dbc3f0e 100644 --- a/test-types.ts +++ b/test-types.ts @@ -4,11 +4,13 @@ import * as ld from 'launchdarkly-js-client-sdk'; -var ver: string = ld.version; +import LaunchDarkly from 'launchdarkly-js-client-sdk'; -var emptyOptions: ld.LDOptions = {}; -var logger: ld.LDLogger = ld.basicLogger({ level: 'info' }); -var allOptions: ld.LDOptions = { +const ver: string = LaunchDarkly.version; + +const emptyOptions: ld.LDOptions = {}; +const logger: ld.LDLogger = ld.basicLogger({ level: 'info' }); +const allOptions: ld.LDOptions = { bootstrap: { }, hash: '', baseUrl: '', @@ -21,21 +23,17 @@ var allOptions: ld.LDOptions = { fetchGoals: true, sendEvents: true, allAttributesPrivate: true, - privateAttributeNames: [ 'x' ], - inlineUsersInEvents: true, - allowFrequentDuplicateEvents: true, + privateAttributes: [ 'x' ], sendEventsOnlyForVariation: true, flushInterval: 1, - samplingInterval: 1, streamReconnectDelay: 1, eventUrlTransformer: url => url + 'x', disableSyncEventPost: true, logger: logger, - autoAliasingOptOut: true }; -var userWithKeyOnly: ld.LDUser = { key: 'user' }; -var anonymousUser: ld.LDUser = { key: 'anon-user', anonymous: true }; -var user: ld.LDUser = { +const userWithKeyOnly: ld.LDUser = { key: 'user' }; +const anonymousUser: ld.LDUser = { key: 'anon-user', anonymous: true }; +const user: ld.LDUser = { key: 'user', name: 'name', firstName: 'first', @@ -55,7 +53,35 @@ var user: ld.LDUser = { }, privateAttributeNames: [ 'name', 'email' ] }; -var client: ld.LDClient = ld.initialize('env', user, allOptions); + +const singleKindContext: ld.LDContext = { + kind: 'user', + key: 'user', + aCustomValue: { + some: 'value' + }, + _meta: { + privateAttributes: ['aCustomValue'] + } +} + +const multiKindContext: ld.LDContext = { + kind: 'multi', + user: { + key: 'user', + aCustomValue: { + some: 'value' + }, + _meta: { + privateAttributes: ['aCustomValue'] + } + }, + device: { + key: 'device' + } +} + +const client: ld.LDClient = ld.initialize('env', user, allOptions); client.waitUntilReady().then(() => {}); client.waitForInitialization().then(() => {}); @@ -65,21 +91,27 @@ client.identify(user).then(() => {}); client.identify(user, undefined, () => {}); client.identify(user, 'hash').then(() => {}); -client.alias(user, anonymousUser); +client.identify(singleKindContext).then(() => {}); +client.identify(singleKindContext, undefined, () => {}); +client.identify(singleKindContext, 'hash').then(() => {}); + +client.identify(multiKindContext).then(() => {}); +client.identify(multiKindContext, undefined, () => {}); +client.identify(multiKindContext, 'hash').then(() => {}); -var user: ld.LDUser = client.getUser(); +const context: ld.LDContext = client.getContext(); client.flush(() => {}); client.flush().then(() => {}); -var boolFlagValue: ld.LDFlagValue = client.variation('key', false); -var numberFlagValue: ld.LDFlagValue = client.variation('key', 2); -var stringFlagValue: ld.LDFlagValue = client.variation('key', 'default'); +const boolFlagValue: ld.LDFlagValue = client.variation('key', false); +const numberFlagValue: ld.LDFlagValue = client.variation('key', 2); +const stringFlagValue: ld.LDFlagValue = client.variation('key', 'default'); -var detail: ld.LDEvaluationDetail = client.variationDetail('key', 'default'); -var detailValue: ld.LDFlagValue = detail.value; -var detailIndex: number | undefined = detail.variationIndex; -var detailReason: ld.LDEvaluationReason = detail.reason; +const detail: ld.LDEvaluationDetail = client.variationDetail('key', 'default'); +const detailValue: ld.LDFlagValue = detail.value; +const detailIndex: number | undefined = detail.variationIndex; +const detailReason: ld.LDEvaluationReason | undefined = detail.reason; client.setStreaming(true); client.setStreaming(); @@ -92,8 +124,8 @@ client.track('event'); client.track('event', { someData: 'x' }); client.track('event', null, 3.5); -var flagSet: ld.LDFlagSet = client.allFlags(); -var flagSetValue: ld.LDFlagValue = flagSet['key']; +const flagSet: ld.LDFlagSet = client.allFlags(); +const flagSetValue: ld.LDFlagValue = flagSet['key']; client.close(() => {}); client.close().then(() => {}); diff --git a/typings.d.ts b/typings.d.ts index 416c91d0..a59f7a4f 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -6,9 +6,9 @@ declare module 'launchdarkly-js-client-sdk' { import { BasicLoggerOptions, LDClientBase, + LDContext, LDLogger, LDOptionsBase, - LDUser } from 'launchdarkly-js-sdk-common'; //// DOCBUILD-END-REPLACE @@ -24,7 +24,7 @@ declare module 'launchdarkly-js-client-sdk' { * * // Preferred usage: * import { initialize } from 'launchdarkly-js-client-sdk'; - * const client = initialize(envKey, user, options); + * const client = initialize(envKey, context, options); * * // Deprecated usage: * import LaunchDarkly from 'launchdarkly-js-client-sdk'; @@ -32,20 +32,20 @@ declare module 'launchdarkly-js-client-sdk' { * * @param envKey * The environment ID. - * @param user - * The initial user properties. These can be changed later with [[LDClient.identify]]. + * @param context + * The initial context properties. These can be changed later with [[LDClient.identify]]. * @param options * Optional configuration settings. * @return * The new client instance. */ - export function initialize(envKey: string, user: LDUser, options?: LDOptions): LDClient; + export function initialize(envKey: string, context: LDContext, options?: LDOptions): LDClient; // This is @ignored because TypeDoc does not show default exports correctly. We'll just explain // the export situation in the comment for initialize(). /** @ignore */ const LaunchDarkly: { - initialize: (envKey: string, user: LDUser, options?: LDOptions) => LDClient; + initialize: (envKey: string, context: LDContext, options?: LDOptions) => LDClient; version: string; }; @@ -57,7 +57,7 @@ declare module 'launchdarkly-js-client-sdk' { */ export interface LDOptions extends LDOptionsBase { /** - * The signed user key for Secure Mode. + * The signed context key for Secure Mode. * * For more information, see the JavaScript SDK Reference Guide on * [Secure mode](https://docs.launchdarkly.com/sdk/features/secure-mode#configuring-secure-mode-in-the-javascript-client-side-sdk).