Accept bools. Add tests. Use datastore
This commit is contained in:
parent
1faeb7458b
commit
c60bec3b17
@ -2,8 +2,7 @@
|
||||
|
||||
# react-native-default-preference
|
||||
|
||||
|
||||
Use `SharedPreferences` (Android) and `UserDefaults` (iOS) with React Native over a unified interface.
|
||||
Use `DataStore` (Android) and `UserDefaults` (iOS) with React Native over a unified interface.
|
||||
All data is stored as a string. If you need to support more complex data structures, use serialization/deserialization (e.g. JSON).
|
||||
|
||||
## Getting started
|
||||
@ -20,7 +19,6 @@ All data is stored as a string. If you need to support more complex data structu
|
||||
|
||||
### Manual installation
|
||||
|
||||
|
||||
#### iOS
|
||||
|
||||
1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
|
||||
|
||||
112
__mocks__/react-native-default-preference.js
vendored
Normal file
112
__mocks__/react-native-default-preference.js
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
let mockPreferences = {};
|
||||
|
||||
// Helper function to get or create a preferences suite
|
||||
const getSuite = (name) => {
|
||||
if (!mockPreferences[name]) {
|
||||
mockPreferences[name] = {};
|
||||
}
|
||||
return mockPreferences[name];
|
||||
};
|
||||
|
||||
const DefaultPreference = {
|
||||
setName: jest.fn((name) => {
|
||||
// Mock implementation for setName
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getName: jest.fn((name) => {
|
||||
// Return the current suite name or null
|
||||
return Promise.resolve(name || null);
|
||||
}),
|
||||
|
||||
get: jest.fn((name, key) => {
|
||||
const suite = getSuite(name);
|
||||
return Promise.resolve(suite.hasOwnProperty(key) ? suite[key] : null);
|
||||
}),
|
||||
|
||||
set: jest.fn((name, key, value) => {
|
||||
const suite = getSuite(name);
|
||||
suite[key] = value;
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clear: jest.fn((name, key) => {
|
||||
const suite = getSuite(name);
|
||||
delete suite[key];
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getMultiple: jest.fn((name, keys) => {
|
||||
const suite = getSuite(name);
|
||||
const values = keys.map(key => (suite.hasOwnProperty(key) ? suite[key] : null));
|
||||
return Promise.resolve(values);
|
||||
}),
|
||||
|
||||
setMultiple: jest.fn((name, keyValuePairs) => {
|
||||
const suite = getSuite(name);
|
||||
Object.entries(keyValuePairs).forEach(([key, value]) => {
|
||||
suite[key] = value;
|
||||
});
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clearMultiple: jest.fn((name, keys) => {
|
||||
const suite = getSuite(name);
|
||||
keys.forEach(key => delete suite[key]);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getAll: jest.fn((name) => {
|
||||
const suite = getSuite(name);
|
||||
return Promise.resolve({ ...suite });
|
||||
}),
|
||||
|
||||
clearAll: jest.fn((name) => {
|
||||
mockPreferences[name] = {};
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
setDataStore: jest.fn((name, key, value) => {
|
||||
const suite = getSuite(name);
|
||||
suite[key] = value;
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clearDataStore: jest.fn((name, key) => {
|
||||
const suite = getSuite(name);
|
||||
delete suite[key];
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getMultipleDataStore: jest.fn((name, keys) => {
|
||||
const suite = getSuite(name);
|
||||
const values = keys.map(key => (suite.hasOwnProperty(key) ? suite[key] : null));
|
||||
return Promise.resolve(values);
|
||||
}),
|
||||
|
||||
setMultipleDataStore: jest.fn((name, keyValuePairs) => {
|
||||
const suite = getSuite(name);
|
||||
Object.entries(keyValuePairs).forEach(([key, value]) => {
|
||||
suite[key] = value;
|
||||
});
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clearMultipleDataStore: jest.fn((name, keys) => {
|
||||
const suite = getSuite(name);
|
||||
keys.forEach(key => delete suite[key]);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getAllDataStore: jest.fn((name) => {
|
||||
const suite = getSuite(name);
|
||||
return Promise.resolve({ ...suite });
|
||||
}),
|
||||
|
||||
clearAllDataStore: jest.fn((name) => {
|
||||
mockPreferences[name] = {};
|
||||
return Promise.resolve();
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = DefaultPreference;
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def safeExtGet(prop, fallback) {
|
||||
@ -6,11 +5,11 @@ def safeExtGet(prop, fallback) {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 28)
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 30)
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion safeExtGet('minSdkVersion', 19)
|
||||
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
||||
minSdkVersion safeExtGet('minSdkVersion', 21)
|
||||
targetSdkVersion safeExtGet('targetSdkVersion', 30)
|
||||
versionCode 3
|
||||
versionName "1.4.2"
|
||||
ndk {
|
||||
@ -24,5 +23,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
||||
implementation "androidx.datastore:datastore-preferences:1.0.0"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "react-native-default-preference",
|
||||
"version": "1.5.0",
|
||||
"description": "Use SharedPreference (Android) and UserDefaults (iOS) with React Native over a unified interface",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kevinresol/react-native-default-preference.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react-native",
|
||||
"NSUserDefaults",
|
||||
"user defaults",
|
||||
"SharedPreferences",
|
||||
"shared preferences"
|
||||
],
|
||||
"author": "kevinresol",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
},
|
||||
"homepage": "https://github.com/kevinresol/react-native-default-preference#readme"
|
||||
}
|
||||
@ -1,7 +1,11 @@
|
||||
package com.kevinresol.react_native_default_preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.datastore.core.DataStore;
|
||||
import androidx.datastore.preferences.core.Preferences;
|
||||
import androidx.datastore.preferences.core.PreferencesKeys;
|
||||
import androidx.datastore.preferences.preferencesDataStore;
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
@ -10,15 +14,22 @@ import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
import kotlinx.coroutines.CoroutineScope;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
import kotlinx.coroutines.launch;
|
||||
import kotlinx.coroutines.flow.first;
|
||||
import java.util.Map;
|
||||
|
||||
public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
private String preferencesName;
|
||||
private final ReactApplicationContext reactContext;
|
||||
private final DataStore<Preferences> dataStore;
|
||||
|
||||
public RNDefaultPreferenceModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
this.preferencesName = reactContext.getPackageName() + "_preferences";
|
||||
this.dataStore = reactContext.createDataStore(name = preferencesName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -26,13 +37,12 @@ public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
return "RNDefaultPreference";
|
||||
}
|
||||
|
||||
private SharedPreferences getPreferences() {
|
||||
return getReactApplicationContext().getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setName(String name, Promise promise) {
|
||||
this.preferencesName = name;
|
||||
if (!this.preferencesName.equals(reactContext.getPackageName() + "_preferences")) {
|
||||
this.preferencesName = name;
|
||||
this.dataStore = reactContext.createDataStore(name = preferencesName);
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ -43,107 +53,138 @@ public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void get(String key, Promise promise) {
|
||||
Object value = getPreferences().getAll().get(key);
|
||||
if (value instanceof String) {
|
||||
promise.resolve((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
promise.resolve((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
promise.resolve((Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
promise.resolve((Float) value);
|
||||
} else if (value instanceof Long) {
|
||||
promise.resolve((Long) value);
|
||||
} else {
|
||||
promise.resolve(null);
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Preferences preferences = dataStore.data.first();
|
||||
Preferences.Key<String> stringKey = PreferencesKeys.stringKey(key);
|
||||
Preferences.Key<Boolean> booleanKey = PreferencesKeys.booleanKey(key);
|
||||
String stringValue = preferences[stringKey];
|
||||
Boolean booleanValue = preferences[booleanKey];
|
||||
if (stringValue != null) {
|
||||
promise.resolve(stringValue);
|
||||
} else if (booleanValue != null) {
|
||||
promise.resolve(booleanValue);
|
||||
} else {
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void set(String key, String value, Promise promise) {
|
||||
getPreferences().edit().putString(key, value).apply();
|
||||
promise.resolve(null);
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Preferences.Key<String> stringKey = PreferencesKeys.stringKey(key);
|
||||
dataStore.edit { preferences ->
|
||||
preferences[stringKey] = value;
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBoolean(String key, boolean value, Promise promise) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Preferences.Key<Boolean> booleanKey = PreferencesKeys.booleanKey(key);
|
||||
dataStore.edit { preferences ->
|
||||
preferences[booleanKey] = value;
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clear(String key, Promise promise) {
|
||||
getPreferences().edit().remove(key).apply();
|
||||
promise.resolve(null);
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Preferences.Key<String> dataStoreKey = PreferencesKeys.stringKey(key);
|
||||
dataStore.edit { preferences ->
|
||||
preferences.remove(dataStoreKey);
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getMultiple(ReadableArray keys, Promise promise) {
|
||||
WritableArray result = Arguments.createArray();
|
||||
for(int i = 0; i < keys.size(); i++) {
|
||||
String key = keys.getString(i);
|
||||
Object value = getPreferences().getAll().get(key);
|
||||
if (value instanceof String) {
|
||||
result.pushString((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
result.pushInt((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
result.pushBoolean((Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
result.pushDouble((Float) value);
|
||||
} else if (value instanceof Long) {
|
||||
result.pushDouble((Long) value);
|
||||
} else {
|
||||
result.pushNull();
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
WritableArray result = Arguments.createArray();
|
||||
Preferences preferences = dataStore.data.first();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
String key = keys.getString(i);
|
||||
Preferences.Key<String> stringKey = PreferencesKeys.stringKey(key);
|
||||
Preferences.Key<Boolean> booleanKey = PreferencesKeys.booleanKey(key);
|
||||
String stringValue = preferences[stringKey];
|
||||
Boolean booleanValue = preferences[booleanKey];
|
||||
if (stringValue != null) {
|
||||
result.pushString(stringValue);
|
||||
} else if (booleanValue != null) {
|
||||
result.pushBoolean(booleanValue);
|
||||
} else {
|
||||
result.pushNull();
|
||||
}
|
||||
}
|
||||
promise.resolve(result);
|
||||
}
|
||||
promise.resolve(result);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setMultiple(ReadableMap data, Promise promise) {
|
||||
SharedPreferences.Editor editor = getPreferences().edit();
|
||||
ReadableMapKeySetIterator iter = data.keySetIterator();
|
||||
while(iter.hasNextKey()) {
|
||||
String key = iter.nextKey();
|
||||
editor.putString(key, data.getString(key));
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
dataStore.edit { preferences ->
|
||||
ReadableMapKeySetIterator iter = data.keySetIterator();
|
||||
while (iter.hasNextKey()) {
|
||||
String key = iter.nextKey();
|
||||
if (data.getType(key) == ReadableType.String) {
|
||||
Preferences.Key<String> stringKey = PreferencesKeys.stringKey(key);
|
||||
preferences[stringKey] = data.getString(key);
|
||||
} else if (data.getType(key) == ReadableType.Boolean) {
|
||||
Preferences.Key<Boolean> booleanKey = PreferencesKeys.booleanKey(key);
|
||||
preferences[booleanKey] = data.getBoolean(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
editor.apply();
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clearMultiple(ReadableArray keys, Promise promise) {
|
||||
SharedPreferences.Editor editor = getPreferences().edit();
|
||||
for(int i = 0; i < keys.size(); i++) {
|
||||
editor.remove(keys.getString(i));
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
dataStore.edit { preferences ->
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
Preferences.Key<String> dataStoreKey = PreferencesKeys.stringKey(keys.getString(i));
|
||||
preferences.remove(dataStoreKey);
|
||||
}
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
editor.apply();
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getAll(Promise promise) {
|
||||
WritableMap result = Arguments.createMap();
|
||||
Map<String, ?> allEntries = getPreferences().getAll();
|
||||
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
result.putString(entry.getKey(), (String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
result.putInt(entry.getKey(), (Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
result.putBoolean(entry.getKey(), (Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
result.putDouble(entry.getKey(), ((Float) value).doubleValue());
|
||||
} else if (value instanceof Long) {
|
||||
result.putDouble(entry.getKey(), ((Long) value).doubleValue());
|
||||
} else {
|
||||
result.putNull(entry.getKey());
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
WritableMap result = Arguments.createMap();
|
||||
Preferences preferences = dataStore.data.first();
|
||||
for (Map.Entry<String, ?> entry : preferences.asMap().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
result.putString(key, (String) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
result.putBoolean(key, (Boolean) value);
|
||||
} else {
|
||||
result.putNull(key);
|
||||
}
|
||||
}
|
||||
promise.resolve(result);
|
||||
}
|
||||
promise.resolve(result);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clearAll(Promise promise) {
|
||||
SharedPreferences.Editor editor = getPreferences().edit();
|
||||
editor.clear();
|
||||
editor.apply();
|
||||
promise.resolve(null);
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
dataStore.edit { preferences ->
|
||||
preferences.clear();
|
||||
}
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
125
index.test.ts
Normal file
125
index.test.ts
Normal file
@ -0,0 +1,125 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
import DefaultPreference from './index';
|
||||
|
||||
const mockDefaultPreference = require('./__mocks__/react-native-default-preference');
|
||||
|
||||
const { RNDefaultPreference } = NativeModules;
|
||||
|
||||
jest.mock('react-native', () => {
|
||||
const mockDefaultPreference = require('./__mocks__/react-native-default-preference');
|
||||
return {
|
||||
NativeModules: {
|
||||
RNDefaultPreference: {
|
||||
setName: mockDefaultPreference.setName,
|
||||
getName: mockDefaultPreference.getName,
|
||||
get: mockDefaultPreference.get,
|
||||
set: mockDefaultPreference.set,
|
||||
clear: mockDefaultPreference.clear,
|
||||
getMultiple: mockDefaultPreference.getMultiple,
|
||||
setMultiple: mockDefaultPreference.setMultiple,
|
||||
clearMultiple: mockDefaultPreference.clearMultiple,
|
||||
getAll: mockDefaultPreference.getAll,
|
||||
clearAll: mockDefaultPreference.clearAll,
|
||||
setDataStore: mockDefaultPreference.setDataStore,
|
||||
clearDataStore: mockDefaultPreference.clearDataStore,
|
||||
getMultipleDataStore: mockDefaultPreference.getMultipleDataStore,
|
||||
setMultipleDataStore: mockDefaultPreference.setMultipleDataStore,
|
||||
clearMultipleDataStore: mockDefaultPreference.clearMultipleDataStore,
|
||||
getAllDataStore: mockDefaultPreference.getAllDataStore,
|
||||
clearAllDataStore: mockDefaultPreference.clearAllDataStore,
|
||||
},
|
||||
},
|
||||
Platform: {
|
||||
OS: 'ios',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe('DefaultPreference', () => {
|
||||
let defaultPref: DefaultPreference;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
// Reset mockPreferences by clearing all data for 'default' suite
|
||||
RNDefaultPreference.clearAll('default');
|
||||
defaultPref = new DefaultPreference();
|
||||
});
|
||||
|
||||
it('should set and get a value for the default instance', async () => {
|
||||
await defaultPref.set('key1', 'value1');
|
||||
const value = await defaultPref.get('key1');
|
||||
expect(value).toBe('value1');
|
||||
});
|
||||
|
||||
it('should set and get a value for the group instance', async () => {
|
||||
const groupPref = new DefaultPreference('group.reactnative.example');
|
||||
await groupPref.set('key1', 'value1');
|
||||
const value = await groupPref.get('key1');
|
||||
expect(value).toBe('value1');
|
||||
});
|
||||
|
||||
it('should clear a value for the default instance', async () => {
|
||||
await defaultPref.set('key2', 'value2');
|
||||
await defaultPref.clear('key2');
|
||||
const value = await defaultPref.get('key2');
|
||||
expect(value).toBeNull();
|
||||
});
|
||||
|
||||
it('should clear a value for the group instance', async () => {
|
||||
const groupPref = new DefaultPreference('group.reactnative.example');
|
||||
await groupPref.set('key2', 'value2');
|
||||
await groupPref.clear('key2');
|
||||
const value = await groupPref.get('key2');
|
||||
expect(value).toBeNull();
|
||||
});
|
||||
|
||||
it('should set and get multiple values for the default instance', async () => {
|
||||
const data = { key3: 'value3', key4: 'value4' };
|
||||
await defaultPref.setMultiple(data);
|
||||
const values = await defaultPref.getMultiple(['key3', 'key4']);
|
||||
expect(values).toEqual(['value3', 'value4']);
|
||||
});
|
||||
|
||||
it('should clear multiple values for the default instance', async () => {
|
||||
const data = { key5: 'value5', key6: 'value6' };
|
||||
await defaultPref.setMultiple(data);
|
||||
await defaultPref.clearMultiple(['key5', 'key6']);
|
||||
const values = await defaultPref.getMultiple(['key5', 'key6']);
|
||||
expect(values).toEqual([null, null]);
|
||||
});
|
||||
|
||||
it('should get all values for the default instance', async () => {
|
||||
const data = { key7: 'value7', key8: 'value8' };
|
||||
await defaultPref.setMultiple(data);
|
||||
const allValues = await defaultPref.getAll();
|
||||
expect(allValues).toEqual(data);
|
||||
});
|
||||
|
||||
it('should clear all values for the default instance', async () => {
|
||||
const data = { key9: 'value9', key10: 'value10' };
|
||||
await defaultPref.setMultiple(data);
|
||||
await defaultPref.clearAll();
|
||||
const allValues = await defaultPref.getAll();
|
||||
expect(allValues).toEqual({});
|
||||
});
|
||||
|
||||
it('should not set the name if no name is provided', () => {
|
||||
const instance = new DefaultPreference();
|
||||
expect(RNDefaultPreference.setName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set the name if a name is provided', () => {
|
||||
const instance = new DefaultPreference('group.reactnative.example');
|
||||
expect(RNDefaultPreference.setName).toHaveBeenCalledWith('group.reactnative.example');
|
||||
});
|
||||
|
||||
it('should not call setName if name is default', () => {
|
||||
new DefaultPreference();
|
||||
expect(RNDefaultPreference.setName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call setName if name is not default', () => {
|
||||
new DefaultPreference('customName');
|
||||
expect(RNDefaultPreference.setName).toHaveBeenCalledWith('customName');
|
||||
});
|
||||
});
|
||||
71
index.ts
71
index.ts
@ -1,4 +1,4 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
import { NativeModules, Platform } from 'react-native';
|
||||
|
||||
const { RNDefaultPreference } = NativeModules;
|
||||
|
||||
@ -7,44 +7,73 @@ export interface RNDefaultPreferenceKeys {
|
||||
}
|
||||
|
||||
class DefaultPreference {
|
||||
static async get(key: string): Promise<string | number | boolean | null> {
|
||||
return RNDefaultPreference.get(key);
|
||||
private readonly name: string;
|
||||
|
||||
constructor(name: string = 'default') {
|
||||
this.name = name;
|
||||
if (name !== 'default') {
|
||||
RNDefaultPreference.setName(name);
|
||||
}
|
||||
}
|
||||
|
||||
static async set(key: string, value: string | number | boolean): Promise<void> {
|
||||
return RNDefaultPreference.set(key, value);
|
||||
async get(key: string): Promise<string | number | boolean | null> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.getDataStore(this.name, key);
|
||||
}
|
||||
return RNDefaultPreference.get(this.name, key);
|
||||
}
|
||||
|
||||
static async clear(key: string): Promise<void> {
|
||||
return RNDefaultPreference.clear(key);
|
||||
async set(key: string, value: string | number | boolean): Promise<void> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.setDataStore(this.name, key, value);
|
||||
}
|
||||
return RNDefaultPreference.set(this.name, key, value);
|
||||
}
|
||||
|
||||
static async getMultiple(keys: string[]): Promise<(string | number | boolean | null)[]> {
|
||||
return RNDefaultPreference.getMultiple(keys);
|
||||
async clear(key: string): Promise<void> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.clearDataStore(this.name, key);
|
||||
}
|
||||
return RNDefaultPreference.clear(this.name, key);
|
||||
}
|
||||
|
||||
static async setMultiple(data: RNDefaultPreferenceKeys): Promise<void> {
|
||||
return RNDefaultPreference.setMultiple(data);
|
||||
async getMultiple(keys: string[]): Promise<(string | number | boolean | null)[]> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.getMultipleDataStore(this.name, keys);
|
||||
}
|
||||
return RNDefaultPreference.getMultiple(this.name, keys);
|
||||
}
|
||||
|
||||
static async clearMultiple(keys: string[]): Promise<void> {
|
||||
return RNDefaultPreference.clearMultiple(keys);
|
||||
async setMultiple(data: RNDefaultPreferenceKeys): Promise<void> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.setMultipleDataStore(this.name, data);
|
||||
}
|
||||
return RNDefaultPreference.setMultiple(this.name, data);
|
||||
}
|
||||
|
||||
static async getAll(): Promise<RNDefaultPreferenceKeys> {
|
||||
return RNDefaultPreference.getAll();
|
||||
async clearMultiple(keys: string[]): Promise<void> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.clearMultipleDataStore(this.name, keys);
|
||||
}
|
||||
return RNDefaultPreference.clearMultiple(this.name, keys);
|
||||
}
|
||||
|
||||
static async clearAll(): Promise<void> {
|
||||
return RNDefaultPreference.clearAll();
|
||||
async getAll(): Promise<RNDefaultPreferenceKeys> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.getAllDataStore(this.name);
|
||||
}
|
||||
return RNDefaultPreference.getAll(this.name);
|
||||
}
|
||||
|
||||
static async getName(): Promise<string> {
|
||||
return RNDefaultPreference.getName();
|
||||
async clearAll(): Promise<void> {
|
||||
if (Platform.OS === 'android') {
|
||||
return RNDefaultPreference.clearAllDataStore(this.name);
|
||||
}
|
||||
return RNDefaultPreference.clearAll(this.name);
|
||||
}
|
||||
|
||||
static async setName(name: string): Promise<void> {
|
||||
return RNDefaultPreference.setName(name);
|
||||
async getName(): Promise<string> {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,9 @@ RCT_EXPORT_METHOD(setName:(NSString *)name
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
defaultSuiteName = name;
|
||||
if (defaultSuiteName == nil) {
|
||||
defaultSuiteName = name;
|
||||
}
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
|
||||
15
jest.config.js
Normal file
15
jest.config.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/',
|
||||
],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: 'tsconfig.json',
|
||||
},
|
||||
},
|
||||
};
|
||||
9473
package-lock.json
generated
Normal file
9473
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "react-native-default-preference",
|
||||
"version": "1.5.0",
|
||||
"description": "Use SharedPreference (Android) and UserDefaults (iOS) with React Native over a unified interface",
|
||||
"version": "1.5.1",
|
||||
"description": "Use DataStore (Android) and UserDefaults (iOS) with React Native over a unified interface",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "jest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -14,13 +14,17 @@
|
||||
"react-native",
|
||||
"NSUserDefaults",
|
||||
"user defaults",
|
||||
"SharedPreferences",
|
||||
"shared preferences"
|
||||
"DataStore",
|
||||
"data store"
|
||||
],
|
||||
"author": "kevinresol",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
},
|
||||
"homepage": "https://github.com/kevinresol/react-native-default-preference#readme"
|
||||
"homepage": "https://github.com/kevinresol/react-native-default-preference#readme",
|
||||
"devDependencies": {
|
||||
"ts-jest": "^27.0.0",
|
||||
"@types/jest": "^27.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
8
tsconfig.json
Normal file
8
tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// ...existing config...
|
||||
"esModuleInterop": true,
|
||||
// ...existing config...
|
||||
},
|
||||
// ...existing config...
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user