Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

Commit

Permalink
prepare 6.3.0 release (#236)
Browse files Browse the repository at this point in the history
* fix tests

* object shorthand

* add more end-to-end tests, improve HTTP test helpers, general cleanup

* rm nock

* Node 6 compatibility

* remove redundant helper, misc cleanup

* Node 6 compatibility

* fix comment

* change asyncify to promisifySingle

* misc fixes

* add Windows CircleCI job

* fix config

* syntax

* diagnostic events, part 2: initial event and stats, except for stream inits

* comments

* add test for stats event

* capture stream connection stats in diagnostic events

* fix test

* remove eventReportingDisabled from diagnostic event; only create diagnosticsManager if needed

* revise tests to use new helper package

* misc cleanup

* use launchdarkly-js-test-helpers 1.0.0

* fix package reference

* minor fixes to config validation messages + add comment

* diagnostic eventsInQueue counter should be # of events at last flush

* rename eventsInQueue to eventsInLastBatch

* don't let user fall outside of last bucket in rollout

* add unit tests for basic bucketing logic and edge case

* avoid redundant property lookups

* fix Redis client parameter to match TS declaration (but still support old incorrect parameter)

* add event payload ID

* remove mistakenly checked-in test code (note, this SDK key was only valid on staging)

* add mention of singleton usage

* update diagnostic event info for OS name, data store type, Node version

* standardize linting

* disallow window and document

* fix null/undef checks

* misc linting fixes

* inlineUsersInEvents is not an unknown option

* drop node-sha1 dependency

* don't omit streamInits.failed when it's false

* bump request dependency to get security patch; loosen some exact dependencies

* remove request package; improve polling cache logic + add test

* bump typescript version to fix build error in Node 6

* update @types/node to fix TypeScript check step

* lint

* make sure we keep polling regardless of whether we got new data

* use launchdarkly-eventsource, make stream retry behavior consistent

* stream retry delay option should be in seconds & should be included in diagnostics

* minor test fix

* fix: Throw an error on malformed user-supplied logger

* don't call unref() on Redis client; ensure that database integration tests close the store

* update Redis driver to major version 3

* add test case

* allow redisOpts parameter to be omitted

* add logger adapter shim + tests

* minor cleanup and comments for ch74741 fix (logger wrapper)

* fix proxy tunnel configuration and make sure it's used in streaming

* change some string concatenation expressions to use interpolation

* feat: upgrade winston (#189)

* fix merge

* remove support for indirect/patch and indirect/put (#182)

* reuse same Promise and same event listeners for all waitForInitialization calls

* better docs for waitForInitialization + misc doc cleanup (#184)

* update js-eventsource to 1.3.1 for stream parsing bugfix (#185)

* fix broken logger format (#186)

* retroactively update changelog for bugfix in 5.13.2 release

* allow get/getAll Redis queries to be queued if Redis client hasn't yet connected

* set stream read timeout

* adding the alias functionality (#190)

* Removed the guides link

* remove monkey-patching of setImmediate

* Persist contextKind property during feature and custom event transformations (#194)

* add inlineUsersInEvents option in TypeScript

* Add support for seed to bucketUser

* Add note for incorporating seed into evaluation

* Send events when the evaluation is from an experiment

* Use seed to evaluate.

* Clean up test descriptions

* Rename variable to be less confusing

* Use ternary to eliminate mutation

* Make return signature more consistent

* Un-prettier the tests

* redis lower bounds bump (#199)

* update launchdarkly-js-test-helpers to fix TLS tests (#200)

* update js-eventsource to remove vulnerability warning (#201)

* add CI jobs for all compatible Node versions

* CI fixes

* more CI fixes

* comment

* use default value to simplify config

* (6.0 - #1) stop saying we're compatible with Node <12 (#203)

* add CI jobs for all compatible Node versions (#202)

* (6.0 - #2) remove Redis integration (#204)

* allow feature store to be specified as a factory (so it can get our logger)

* (6.0 - #3) remove Winston (#205)

* remove deprecated things for 6.0 (#206)

* update node-cache to 5.x (drops old Node compat)

* update semver to 7.x (drops old Node compat)

* update uuid to 8.x (Node compat, perf improvements, bugfixes)

* update dev dependencies

* linter

* replace lrucache package with lru-cache (#209)

* make yaml dependency optional (#210)

* update release metadata to include maintenance branch

* remove package-lock.json (#211)

* rm prerelease changelog

* (big segments #1) add interfaces for big segments (#212)

* (big segments #2) add all components for big segments except evaluation (#213)

* (big segments #3) implement big segments in flag evaluation (#214)

* (big segments #4) add standard test suite for big segment store tests + refactor feature store tests (#215)

* move new interfaces to a module instead of a namespace (#216)

* fix TS export of CachingStoreWrapper

* use Releaser v2 config

* fix overly specific test expectation that breaks in Node 17

* Initial work on FlagBuilder (#219)

* Add TestData factory(with some dummy methods); Initial work on FlagBuilder

* fixed indentation and linter errors; fixed an error in update; fixed incorrect test label

* fixed typo in TestData store

* converted boolean variation constants to be file variables instead of class variables

Co-authored-by: charukiewicz <[email protected]>
Co-authored-by: belevy <[email protected]>

* implemented FlagRuleBuilder; added .build() methods to FlagBuilder/FlagRuleBuilder and changed tests to avoid using private interface

* converted _targets to be Map instead of object literal; changed variationForBoolean to be a module-scoped function instead class-scoped

* Implement stream processor(data source) interface for test data

* Add TestData to index.js and write out the types for TestData and friends

* added testdata documentation to index.d.ts; fix linter errors; changed flag default behavior to create boolean flag

* Fix the interface file: reindented to 2 spaces, corrected definition of functions from properties to functions in interfaces; corrected issues in JSDoc comments

* modify tests to fix capitalization and actually test the test datasource works as an LDClient updateProcessor.

* Fix linter error on defaulted callback

* explicitly enable JSDOM types in TypeScript build to avoid errors when jsdom is referenced for some reason

* capitalize Big Segments in docs & logs

* documentation comment fixes for TestData

* pin TypeScript to 4.4.x

* move TestData and FIleDataSource to integrations module

* lint

* rename types used by TestData for clarity (#229)

* use varargs semantics for TestFlagBuilder.variations() and add it to the TS interface (#230)

* don't ever use for...in (#232)

* don't ever use for...in

* add null guard

* bump launchdarkly-eventsource dependency for sc-136154 fix

* use TestData in our own tests (#231)

* use TestData in our own tests

* update TS interface

* lint

* typo

* fix allFlagsState behavior regarding experimentation

* lint

* allow "secondary" to be referenced in clauses

* don't throw an exception for non-string in semver comparison

* correctly handle "client not ready" condition in allFlagsState

* lint

Co-authored-by: Eli Bishop <[email protected]>
Co-authored-by: LaunchDarklyCI <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Maxwell Gerber <[email protected]>
Co-authored-by: Chris West <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Mike Zorn <[email protected]>
Co-authored-by: Robert J. Neal <[email protected]>
Co-authored-by: Ben Levy <[email protected]>
Co-authored-by: charukiewicz <[email protected]>
Co-authored-by: belevy <[email protected]>
Co-authored-by: charukiewicz <[email protected]>
Co-authored-by: LaunchDarklyReleaseBot <[email protected]>
  • Loading branch information
14 people authored Feb 19, 2022
1 parent 1268551 commit a38d913
Show file tree
Hide file tree
Showing 13 changed files with 1,186 additions and 211 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ env:
es6: true
node: true
parserOptions:
ecmaVersion: 2017 # allows us to use async/await, now that our Node version is always >= 8
ecmaVersion: 2018
plugins:
#- babel
- prettier
Expand Down
405 changes: 403 additions & 2 deletions index.d.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ const newClient = function (sdkKey, originalConfig) {
module.exports = {
init: newClient,
basicLogger: basicLogger,
FileDataSource: FileDataSource,
FileDataSource: FileDataSource, // deprecated entry point - should use integrations module now
errors: errors,
};

Expand Down
7 changes: 7 additions & 0 deletions integrations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const FileDataSource = require('./file_data_source');
const TestData = require('./test_data');

module.exports = {
FileDataSource,
TestData,
};
19 changes: 19 additions & 0 deletions test-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// developer can use all of the SDK features.

import * as ld from 'launchdarkly-node-server-sdk';
import * as integrations from 'launchdarkly-node-server-sdk/integrations';
import * as interfaces from 'launchdarkly-node-server-sdk/interfaces';

var logger: ld.LDLogger = {
Expand Down Expand Up @@ -96,6 +97,24 @@ var logger1: ld.LDLogger = ld.basicLogger();
var logger2: ld.LDLogger = ld.basicLogger({ level: 'info' });
var logger3: ld.LDLogger = ld.basicLogger({ destination: console.log });

// integrations module:

// FileDataSource
const fdsOptions: integrations.FileDataSourceOptions = {
paths: [ 'filepath' ],
autoUpdate: true,
logger: ld.basicLogger(),
};
const fds = integrations.FileDataSource(fdsOptions);

// TestData
const td: integrations.TestData = integrations.TestData();
const fb: integrations.TestDataFlagBuilder = td.flag('key');
td.update(fb);
fb.ifMatch('name', 'x').thenReturn(true);

// interfaces module:

// BigSegmentStoreStatusProvider
var bsssp: interfaces.BigSegmentStoreStatusProvider = client.bigSegmentStoreStatusProvider
var bssStatus: interfaces.BigSegmentStoreStatus | undefined = bsssp.getStatus();
Expand Down
17 changes: 7 additions & 10 deletions test/LDClient-big-segments-test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
const { hashForUserKey } = require('../big_segments');
const { makeBigSegmentRef } = require('../evaluator');
const InMemoryFeatureStore = require('../feature_store');
const dataKind = require('../versioned_data_kind');
const { TestData } = require('../integrations');
const stubs = require('./stubs');
const { makeSegmentMatchClause } = require('./evaluator_helpers');
const { promisifySingle, withCloseable } = require('launchdarkly-js-test-helpers');
const { withCloseable } = require('launchdarkly-js-test-helpers');

describe('LDClient - big segments', () => {

Expand All @@ -26,18 +25,16 @@ describe('LDClient - big segments', () => {
}

async function makeClient(bigSegmentsStore, config) {
const dataStore = InMemoryFeatureStore();
const initData = {
[dataKind.features.namespace]: { [flag.key]: flag },
[dataKind.segments.namespace]: { [bigSegment.key]: bigSegment },
};
await promisifySingle(dataStore.init)(initData);
const td = TestData();
td.usePreconfiguredFlag(flag);
td.usePreconfiguredSegment(bigSegment);

const bigSegmentsConfig = {
store: bigSegmentsStore && (() => bigSegmentsStore),
...(config && config.bigSegments),
};
return stubs.createClient({ ...config, featureStore: dataStore, bigSegments: bigSegmentsConfig });

return stubs.createClient({ ...config, updateProcessor: td, bigSegments: bigSegmentsConfig });
}

it('user not found in big segment store', async () => {
Expand Down
50 changes: 29 additions & 21 deletions test/LDClient-evaluation-all-flags-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { TestData } = require('../integrations');
const stubs = require('./stubs');

describe('LDClient.allFlagsState', () => {
Expand Down Expand Up @@ -31,8 +32,12 @@ describe('LDClient.allFlagsState', () => {
trackEvents: false,
trackEventsFallthrough: true
};
const td = TestData();
td.usePreconfiguredFlag(flag1);
td.usePreconfiguredFlag(flag2);
td.usePreconfiguredFlag(flag3);

const client = stubs.createClient({}, { [flag1.key]: flag1, [flag2.key]: flag2, [flag3.key]: flag3 });
const client = stubs.createClient({ updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser);
expect(state.valid).toEqual(true);
Expand Down Expand Up @@ -66,29 +71,29 @@ describe('LDClient.allFlagsState', () => {
});

it('can filter for only client-side flags', async () => {
const flag1 = { key: 'server-side-1', on: false, offVariation: 0, variations: ['a'], clientSide: false };
const flag2 = { key: 'server-side-2', on: false, offVariation: 0, variations: ['b'], clientSide: false };
const flag3 = { key: 'client-side-1', on: false, offVariation: 0, variations: ['value1'], clientSide: true };
const flag4 = { key: 'client-side-2', on: false, offVariation: 0, variations: ['value2'], clientSide: true };
const client = stubs.createClient({}, {
'server-side-1': flag1, 'server-side-2': flag2, 'client-side-1': flag3, 'client-side-2': flag4
});
const td = TestData();
td.usePreconfiguredFlag({ key: 'server-side-1', on: false, offVariation: 0, variations: ['a'], clientSide: false });
td.usePreconfiguredFlag({ key: 'server-side-2', on: false, offVariation: 0, variations: ['b'], clientSide: false });
td.usePreconfiguredFlag({ key: 'client-side-1', on: false, offVariation: 0, variations: ['value1'], clientSide: true });
td.usePreconfiguredFlag({ key: 'client-side-2', on: false, offVariation: 0, variations: ['value2'], clientSide: true });
const client = stubs.createClient({ updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser, { clientSideOnly: true });
expect(state.valid).toEqual(true);
expect(state.allValues()).toEqual({ 'client-side-1': 'value1', 'client-side-2': 'value2' });
});

it('can include reasons', async () => {
const flag = {
const td = TestData();
td.usePreconfiguredFlag({
key: 'feature',
version: 100,
offVariation: 1,
variations: ['a', 'b'],
trackEvents: true,
debugEventsUntilDate: 1000
};
const client = stubs.createClient({}, { feature: flag });
});
const client = stubs.createClient({ updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser, { withReasons: true });
expect(state.valid).toEqual(true);
Expand Down Expand Up @@ -130,9 +135,12 @@ describe('LDClient.allFlagsState', () => {
variations: ['value3'],
debugEventsUntilDate: 1000
};
const td = TestData();
td.usePreconfiguredFlag(flag1);
td.usePreconfiguredFlag(flag2);
td.usePreconfiguredFlag(flag3);

const client = stubs.createClient({}, { flag1: flag1, flag2: flag2, flag3: flag3 });
const user = { key: 'user' };
const client = stubs.createClient({ updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser, { withReasons: true, detailsOnlyForTrackedFlags: true });
expect(state.valid).toEqual(true);
Expand Down Expand Up @@ -169,8 +177,10 @@ describe('LDClient.allFlagsState', () => {
on: false,
offVariation: null
};
const td = TestData();
td.usePreconfiguredFlag(flag);
const logger = stubs.stubLogger();
const client = stubs.createClient({ offline: true, logger: logger }, { flagkey: flag });
const client = stubs.createClient({ offline: true, logger: logger, updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser);
expect(state.valid).toEqual(false);
Expand All @@ -180,17 +190,15 @@ describe('LDClient.allFlagsState', () => {

it('does not overflow the call stack when evaluating a huge number of flags', async () => {
const flagCount = 5000;
const flags = {};
const td = TestData();
for (let i = 0; i < flagCount; i++) {
const key = 'feature' + i;
const flag = {
key: key,
td.usePreconfiguredFlag({
key: 'feature' + i,
version: 1,
on: false
};
flags[key] = flag;
});
}
const client = stubs.createClient({}, flags);
const client = stubs.createClient({ updateProcessor: td });
await client.waitForInitialization();
const state = await client.allFlagsState(defaultUser);
expect(Object.keys(state.allValues()).length).toEqual(flagCount);
Expand Down
Loading

0 comments on commit a38d913

Please sign in to comment.