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

prepare 5.0.0 release #87

Merged
merged 41 commits into from
Aug 20, 2021
Merged
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
67fb5ce
Removed the guides link
bwoskow-ld Feb 3, 2021
b6a113c
V4.0 (#68)
torchhound Apr 1, 2021
a193441
merge from public after release
LaunchDarklyCI Apr 1, 2021
510e581
Update iOS SDK dependency to fix Throttler behavior (#69)
torchhound Apr 7, 2021
0afc773
merge from public after release
LaunchDarklyCI Apr 7, 2021
9df202f
V4.1.0 (#72)
torchhound Apr 14, 2021
17e2d75
merge from public after release
LaunchDarklyCI Apr 14, 2021
35b61e1
Fixed jsonVariationDetail parsing on Android and fixed a typo in json…
torchhound Apr 16, 2021
fceade3
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 23, 2021
82ba5fe
Releasing version 4.0.2
bwoskow-ld Apr 23, 2021
5489162
Merge branch 'v4.0.x-squashed' of github.com:launchdarkly/react-nativ…
bwoskow-ld Apr 23, 2021
ccc28c3
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 24, 2021
c4a2891
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 24, 2021
cae667b
Removes Typescript enums and replaces them with types that extend str…
torchhound Apr 28, 2021
f975de3
Releasing version 4.0.3
bwoskow-ld Apr 28, 2021
881c2fb
Merge branch 'v4.0.x-squashed'
bwoskow-ld Apr 28, 2021
b23e1c0
Merge branch 'master' of github.com:launchdarkly/react-native-client-…
bwoskow-ld Apr 28, 2021
c261c78
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 28, 2021
5ad0499
Multi Environment (#65)
torchhound May 11, 2021
4ca1a1f
Add secondary user attribute (#76)
torchhound May 11, 2021
4a9530e
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld May 11, 2021
81ae48d
Fix multi environment on restwrapper (#77)
torchhound May 19, 2021
0029ba5
merge from public after release
LaunchDarklyCI May 19, 2021
83640b7
[ch109800] Await Android client initialization. (#78)
gwhelanLD May 28, 2021
2668c2a
Update iOS method signature to match implementation (#79)
bwoskow-ld Jun 1, 2021
9703765
Merge remote-tracking branch 'public/master'
gwhelanLD Jun 1, 2021
b1a94ca
merge from public after release
LaunchDarklyCI Jun 1, 2021
8399a02
Releasing version 4.0.4
bwoskow-ld Jun 2, 2021
14c3993
Merge tag '4.0.4'
bwoskow-ld Jun 2, 2021
4d003c0
[ch110474] Fixes for undeclared variables and other callback issues. …
gwhelanLD Jun 15, 2021
36516d0
Merge remote-tracking branch 'public/master'
gwhelanLD Jun 15, 2021
093d62d
Changes for Android 3. (#82)
gwhelanLD Jun 15, 2021
894de0f
Add unit tests for JS native bridge wrapper. (#83)
gwhelanLD Jun 16, 2021
3da41af
Docs improvements (#84)
gwhelanLD Jun 16, 2021
493d554
[ch94513] Add aliasing support (#85)
gwhelanLD Jun 16, 2021
a735bab
Requiring default values to be specified. Remove intVariation. (#86)
gwhelanLD Jun 29, 2021
0364d51
Safer and cleaner configuration on iOS (#87)
gwhelanLD Jul 1, 2021
eb1aecb
Cleanup Android variation implementation (#88)
gwhelanLD Jul 1, 2021
9f8dbc9
Merge remote-tracking branch 'public/master'
gwhelanLD Aug 19, 2021
cbad402
Use latest iOS and Android SDKs (#89)
gwhelanLD Aug 19, 2021
f0ade3f
Fix issue with numeric variation calls. (#90)
gwhelanLD Aug 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup Android variation implementation (#88)
gwhelanLD authored Jul 1, 2021
commit eb1aecbd3ba2921620889c7442c661f33c840d06
5 changes: 4 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

buildscript {
ext {
buildToolsVersion = "28.0.2"
@@ -32,6 +31,10 @@ android {
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

allprojects {
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@
import android.app.Application;
import android.net.Uri;

import androidx.arch.core.util.Function;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.Promise;
@@ -306,210 +308,149 @@ private LDUser.Builder userBuild(ReadableMap options) {

@ReactMethod
public void boolVariation(String flagKey, boolean defaultValue, String environment, Promise promise) {
try {
promise.resolve(LDClient.getForMobileKey(environment).boolVariation(flagKey, defaultValue));
} catch (Exception e) {
promise.resolve(defaultValue);
}
variation(LDClient::boolVariation, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void floatVariation(String flagKey, double defaultValue, String environment, Promise promise) {
try {
promise.resolve(LDClient.getForMobileKey(environment).doubleVariation(flagKey, defaultValue));
} catch (Exception e) {
promise.resolve(defaultValue);
}
public void numberVariation(String flagKey, double defaultValue, String environment, Promise promise) {
variation(LDClient::doubleVariation, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void stringVariation(String flagKey, String defaultValue, String environment, Promise promise) {
try {
promise.resolve(LDClient.getForMobileKey(environment).stringVariation(flagKey, defaultValue));
} catch (Exception e) {
promise.resolve(defaultValue);
}
variation(LDClient::stringVariation, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void jsonVariationNone(String flagKey, String environment, Promise promise) {
jsonVariationBase(flagKey, LDValue.ofNull(), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, LDValue.ofNull(), environment, promise);
}

@ReactMethod
public void jsonVariationNumber(String flagKey, double defaultValue, String environment, Promise promise) {
jsonVariationBase(flagKey, LDValue.of(defaultValue), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationBool(String flagKey, boolean defaultValue, String environment, Promise promise) {
jsonVariationBase(flagKey, LDValue.of(defaultValue), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationString(String flagKey, String defaultValue, String environment, Promise promise) {
jsonVariationBase(flagKey, LDValue.of(defaultValue), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationArray(String flagKey, ReadableArray defaultValue, String environment, Promise promise) {
jsonVariationBase(flagKey, toLDValue(defaultValue), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, toLDValue(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationObject(String flagKey, ReadableMap defaultValue, String environment, Promise promise) {
jsonVariationBase(flagKey, toLDValue(defaultValue), environment, promise);
variation(LDClient::jsonValueVariation, id -> id, flagKey, toLDValue(defaultValue), environment, promise);
}

@ReactMethod
public void boolVariationDetail(String flagKey, boolean defaultValue, String environment, Promise promise) {
EvaluationDetail<Boolean> detailResult;
interface EvalCall<T> {
T call(LDClient client, String flagKey, T defaultValue);
}

private <T> void variation(EvalCall<T> eval, Function<T, LDValue> transform,
String flagKey, T defaultValue, String environment, Promise promise) {
try {
detailResult = LDClient.getForMobileKey(environment).boolVariationDetail(flagKey, defaultValue);
promise.resolve(ldValueToBridge(transform.apply(eval.call(LDClient.getForMobileKey(environment), flagKey, defaultValue))));
} catch (Exception e) {
Timber.w(e);
detailResult = EvaluationDetail.fromValue(defaultValue, EvaluationDetail.NO_VARIATION, EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION));
promise.resolve(ldValueToBridge(transform.apply(defaultValue)));
}
WritableMap result = detailToMap(detailResult);
if (detailResult.getValue() == null) {
result.putNull("value");
} else {
result.putBoolean("value", detailResult.getValue());
}
promise.resolve(result);
}

@ReactMethod
public void boolVariationDetail(String flagKey, boolean defaultValue, String environment, Promise promise) {
detailVariation(LDClient::boolVariationDetail, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void numberVariationDetail(String flagKey, double defaultValue, String environment, Promise promise) {
EvaluationDetail<Double> detailResult;
try {
detailResult = LDClient.getForMobileKey(environment).doubleVariationDetail(flagKey, defaultValue);
} catch (Exception e) {
Timber.w(e);
detailResult = EvaluationDetail.fromValue(defaultValue, EvaluationDetail.NO_VARIATION, EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION));
}
WritableMap result = detailToMap(detailResult);
if (detailResult.getValue() == null) {
result.putNull("value");
} else {
result.putDouble("value", detailResult.getValue());
}
promise.resolve(result);
detailVariation(LDClient::doubleVariationDetail, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void stringVariationDetail(String flagKey, String defaultValue, String environment, Promise promise) {
EvaluationDetail<String> detailResult;
try {
detailResult = LDClient.getForMobileKey(environment).stringVariationDetail(flagKey, defaultValue);
} catch (Exception e) {
Timber.w(e);
detailResult = EvaluationDetail.fromValue(defaultValue, EvaluationDetail.NO_VARIATION, EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION));
}
WritableMap result = detailToMap(detailResult);
if (detailResult.getValue() == null) {
result.putNull("value");
} else {
result.putString("value", detailResult.getValue());
}
promise.resolve(result);
detailVariation(LDClient::stringVariationDetail, LDValue::of, flagKey, defaultValue, environment, promise);
}

@ReactMethod
public void jsonVariationDetailNone(String flagKey, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, LDValue.ofNull(), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, LDValue.ofNull(), environment, promise);
}

@ReactMethod
public void jsonVariationDetailNumber(String flagKey, double defaultValue, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, LDValue.of(defaultValue), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationDetailBool(String flagKey, boolean defaultValue, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, LDValue.of(defaultValue), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationDetailString(String flagKey, String defaultValue, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, LDValue.of(defaultValue), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, LDValue.of(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationDetailArray(String flagKey, ReadableArray defaultValue, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, toLDValue(defaultValue), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, toLDValue(defaultValue), environment, promise);
}

@ReactMethod
public void jsonVariationDetailObject(String flagKey, ReadableMap defaultValue, String environment, Promise promise) {
jsonVariationDetailBase(flagKey, toLDValue(defaultValue), environment, promise);
detailVariation(LDClient::jsonValueVariationDetail, id -> id, flagKey, toLDValue(defaultValue), environment, promise);
}

private void jsonVariationBase(String flagKey, LDValue defaultValue, String environment, Promise promise) {
try {
LDValue value = LDClient.getForMobileKey(environment).jsonValueVariation(flagKey, defaultValue);
resolveValue(promise, value);
} catch (Exception e) {
resolveValue(promise, defaultValue);
}
interface EvalDetailCall<T> {
EvaluationDetail<T> call(LDClient client, String flagKey, T defaultValue);
}

private void jsonVariationDetailBase(String flagKey, LDValue defaultValue, String environment, Promise promise) {
EvaluationDetail<LDValue> detailResult;
private <T> void detailVariation(EvalDetailCall<T> eval, Function<T, LDValue> transform,
String flagKey, T defaultValue, String environment, Promise promise) {
try {
detailResult = LDClient.getForMobileKey(environment).jsonValueVariationDetail(flagKey, defaultValue);
LDClient client = LDClient.getForMobileKey(environment);
EvaluationDetail<T> detail = eval.call(client, flagKey, defaultValue);
ObjectBuilder resultBuilder = objectBuilderFromDetail(detail);
resultBuilder.put("value", transform.apply(detail.getValue()));
promise.resolve(ldValueToBridge(resultBuilder.build()));
} catch (Exception e) {
Timber.w(e);
detailResult = EvaluationDetail.fromValue(defaultValue, EvaluationDetail.NO_VARIATION, EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION));
ObjectBuilder resultBuilder = LDValue.buildObject();
resultBuilder.put("kind", EvaluationReason.Kind.ERROR.name());
resultBuilder.put("errorKind", EvaluationReason.ErrorKind.EXCEPTION.name());
resultBuilder.put("value", transform.apply(defaultValue));
promise.resolve(ldValueToBridge(resultBuilder.build()));
}
resolveEvaluationDetailValue(promise, detailResult);
}

private void resolveValue(Promise promise, LDValue value) {
switch (value.getType()) {
case NULL: promise.resolve(null); break;
case BOOLEAN: promise.resolve(value.booleanValue()); break;
case NUMBER: promise.resolve(value.doubleValue()); break;
case STRING: promise.resolve(value.stringValue()); break;
case ARRAY: promise.resolve(ldValueToArray(value)); break;
case OBJECT: promise.resolve(ldValueToMap(value)); break;
}
}

private void resolveEvaluationDetailValue(Promise promise, EvaluationDetail<LDValue> detailValue) {
WritableMap result = detailToMap(detailValue);
switch (detailValue.getValue().getType()) {
case NULL: result.putNull("value"); break;
case BOOLEAN: result.putBoolean("value", detailValue.getValue().booleanValue()); break;
case NUMBER: result.putDouble("value", detailValue.getValue().doubleValue()); break;
case STRING: result.putString("value", detailValue.getValue().stringValue()); break;
case ARRAY: result.putArray("value", ldValueToArray(detailValue.getValue())); break;
case OBJECT: result.putMap("value", ldValueToMap(detailValue.getValue())); break;
}
promise.resolve(result);
}

private WritableMap detailToMap(EvaluationDetail<?> detail) {
EvaluationReason reason = detail.getReason();
WritableMap result = new WritableNativeMap();
private ObjectBuilder objectBuilderFromDetail(EvaluationDetail<?> detail) {
ObjectBuilder resultMap = LDValue.buildObject();
if (!detail.isDefaultValue()) {
result.putInt("variationIndex", detail.getVariationIndex());
resultMap.put("variationIndex", detail.getVariationIndex());
}
WritableMap reasonMap = new WritableNativeMap();
reasonMap.putString("kind", detail.getReason().getKind().name());
EvaluationReason reason = detail.getReason();
ObjectBuilder reasonMap = LDValue.buildObject();
reasonMap.put("kind", reason.getKind().name());
switch (reason.getKind()) {
case RULE_MATCH:
reasonMap.putInt("ruleIndex", reason.getRuleIndex());
reasonMap.put("ruleIndex", reason.getRuleIndex());
if (reason.getRuleId() != null) {
reasonMap.putString("ruleId", reason.getRuleId());
reasonMap.put("ruleId", reason.getRuleId());
}
break;
case PREREQUISITE_FAILED: reasonMap.putString("prerequisiteKey", reason.getPrerequisiteKey()); break;
case ERROR: reasonMap.putString("errorKind", reason.getErrorKind().name()); break;
case PREREQUISITE_FAILED: reasonMap.put("prerequisiteKey", reason.getPrerequisiteKey()); break;
case ERROR: reasonMap.put("errorKind", reason.getErrorKind().name()); break;
default: break;
}
result.putMap("reason", reasonMap);
return result;
resultMap.put("reason", reasonMap.build());
return resultMap;
}

@ReactMethod
@@ -522,20 +463,11 @@ public void allFlags(String environment, Promise promise) {
}

try {
Map<String, LDValue> flags = LDClient.getForMobileKey(environment).allFlags();

WritableMap response = new WritableNativeMap();
for (Map.Entry<String, LDValue> entry : flags.entrySet()) {
switch (entry.getValue().getType()) {
case NULL: response.putNull(entry.getKey()); break;
case BOOLEAN: response.putBoolean(entry.getKey(), entry.getValue().booleanValue()); break;
case NUMBER: response.putDouble(entry.getKey(), entry.getValue().doubleValue()); break;
case STRING: response.putString(entry.getKey(), entry.getValue().stringValue()); break;
case ARRAY: response.putArray(entry.getKey(), ldValueToArray(entry.getValue())); break;
case OBJECT: response.putMap(entry.getKey(), ldValueToMap(entry.getValue())); break;
}
ObjectBuilder resultBuilder = LDValue.buildObject();
for (Map.Entry<String, LDValue> entry : LDClient.getForMobileKey(environment).allFlags().entrySet()) {
resultBuilder.put(entry.getKey(), entry.getValue());
}
promise.resolve(response);
promise.resolve(ldValueToBridge(resultBuilder.build()));
} catch (LaunchDarklyException e) {
// Since we confirmed the SDK has been configured, this exception should only be thrown if the env doesn't exist
promise.reject(ERROR_UNKNOWN, "SDK not configured with requested environment");
@@ -887,45 +819,35 @@ private static LDValue toLDValue(Dynamic data) {
}
}


private static LDValue toLDValue(ReadableArray readableArray) {
if (readableArray == null) {
return LDValue.ofNull();
}
ArrayBuilder array = LDValue.buildArray();
for (int i = 0; i < readableArray.size(); i++) {
switch (readableArray.getType(i)) {
case Null: array.add(LDValue.ofNull()); break;
case Boolean: array.add(readableArray.getBoolean(i)); break;
case Number: array.add(readableArray.getDouble(i)); break;
case String: array.add(readableArray.getString(i)); break;
case Array: array.add(toLDValue(readableArray.getArray(i))); break;
case Map: array.add(toLDValue(readableArray.getMap(i))); break;
}
array.add(toLDValue(readableArray.getDynamic(i)));
}
return array.build();
}

private static LDValue toLDValue(ReadableMap readableMap) {
if (readableMap == null) {
return LDValue.ofNull();
}
ObjectBuilder object = LDValue.buildObject();
ReadableMapKeySetIterator iter = readableMap.keySetIterator();
while (iter.hasNextKey()) {
String key = iter.nextKey();
switch (readableMap.getType(key)) {
case Null: object.put(key, LDValue.ofNull()); break;
case Boolean: object.put(key, readableMap.getBoolean(key)); break;
case Number: object.put(key, readableMap.getDouble(key)); break;
case String: object.put(key, readableMap.getString(key)); break;
case Array: object.put(key, toLDValue(readableMap.getArray(key))); break;
case Map: object.put(key, toLDValue(readableMap.getMap(key))); break;
}
object.put(key, toLDValue(readableMap.getDynamic(key)));
}
return object.build();
}

private static Object ldValueToBridge(LDValue value) {
switch (value.getType()) {
case BOOLEAN: return value.booleanValue();
case NUMBER: return value.doubleValue();
case STRING: return value.stringValue();
case ARRAY: return ldValueToArray(value);
case OBJECT: return ldValueToMap(value);
default: return null;
}
}

private static WritableArray ldValueToArray(LDValue value) {
WritableArray result = new WritableNativeArray();
for (LDValue val : value.values()) {
4 changes: 0 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -50,10 +50,6 @@ export default class LDClient {
return Promise.resolve();
}

_validateInt(val) {
return !isNaN(val) && val > -0x80000001 && val < 0x80000000;
}

_normalizeEnv(environment) {
if (typeof environment !== 'string') {
return 'default';