react-native-storage-inspector 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.d.mts +83 -16
- package/dist/index.d.ts +83 -16
- package/dist/index.js +64 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -61,6 +61,18 @@ The component fills its container. The consumer is responsible for header, back
|
|
|
61
61
|
- **Expo Go**: Async Storage and Expo Secure Store work. MMKV and Keychain need native code and are not available in Expo Go.
|
|
62
62
|
- **Development build**: All four storages work with `expo-dev-client`.
|
|
63
63
|
|
|
64
|
+
## Troubleshooting
|
|
65
|
+
|
|
66
|
+
If you see **"Requiring unknown module"** for optional storage packages (AsyncStorage, Keychain, Secure Store), add to your `metro.config.js`:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
70
|
+
const config = getDefaultConfig(__dirname);
|
|
71
|
+
config.transformer ??= {};
|
|
72
|
+
config.transformer.allowOptionalDependencies = true;
|
|
73
|
+
module.exports = config;
|
|
74
|
+
```
|
|
75
|
+
|
|
64
76
|
## API (for custom adapters)
|
|
65
77
|
|
|
66
78
|
Implement `IStorageAdapter` and pass it via `customAdapters`:
|
package/dist/index.d.mts
CHANGED
|
@@ -16,6 +16,81 @@ interface IStorageAdapter {
|
|
|
16
16
|
isAvailable(): boolean;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* AsyncStorage-compatible module interface.
|
|
21
|
+
* Pass your AsyncStorage instance to avoid Metro "unknown module" errors in Expo:
|
|
22
|
+
* @example
|
|
23
|
+
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
24
|
+
* createAsyncStorageAdapter(AsyncStorage)
|
|
25
|
+
*/
|
|
26
|
+
type AsyncStorageModule = {
|
|
27
|
+
getAllKeys(): Promise<string[]>;
|
|
28
|
+
getItem(key: string): Promise<string | null>;
|
|
29
|
+
setItem(key: string, value: string): Promise<void>;
|
|
30
|
+
removeItem(key: string): Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Creates an AsyncStorage adapter. Pass the AsyncStorage instance for reliable
|
|
34
|
+
* bundling in Expo/Metro (avoids "unknown module" errors):
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
38
|
+
* createAsyncStorageAdapter(AsyncStorage)
|
|
39
|
+
*/
|
|
40
|
+
declare function createAsyncStorageAdapter(instance?: AsyncStorageModule | null): IStorageAdapter;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Keychain-compatible module. Pass your keychain instance to avoid Metro
|
|
44
|
+
* "unknown module" errors in Expo.
|
|
45
|
+
*/
|
|
46
|
+
type KeychainModule = {
|
|
47
|
+
getAllGenericPasswordServices?(options?: object): Promise<string[]>;
|
|
48
|
+
getGenericPassword?(options?: {
|
|
49
|
+
service?: string;
|
|
50
|
+
}): Promise<{
|
|
51
|
+
password: string;
|
|
52
|
+
} | false>;
|
|
53
|
+
setGenericPassword?(username: string, password: string, options?: {
|
|
54
|
+
service?: string;
|
|
55
|
+
}): Promise<{
|
|
56
|
+
storage: string;
|
|
57
|
+
} | false>;
|
|
58
|
+
resetGenericPassword?(options?: {
|
|
59
|
+
service?: string;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
setInternetCredentials(server: string, username: string, password: string): Promise<{
|
|
62
|
+
storage: string;
|
|
63
|
+
} | false>;
|
|
64
|
+
getInternetCredentials(server: string): Promise<{
|
|
65
|
+
username: string;
|
|
66
|
+
password: string;
|
|
67
|
+
} | null>;
|
|
68
|
+
resetInternetCredentials(server: string): Promise<void>;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Keychain adapter. Pass the keychain instance for reliable bundling in Expo:
|
|
72
|
+
* @example import * as Keychain from 'react-native-keychain';
|
|
73
|
+
* createKeychainAdapter([], Keychain)
|
|
74
|
+
*/
|
|
75
|
+
declare function createKeychainAdapter(knownKeys?: string[], instance?: KeychainModule | null): IStorageAdapter;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* expo-secure-store compatible module. Pass the module to avoid Metro
|
|
79
|
+
* "unknown module" errors in Expo.
|
|
80
|
+
*/
|
|
81
|
+
type SecureStoreModule = {
|
|
82
|
+
getItemAsync(key: string): Promise<string | null>;
|
|
83
|
+
setItemAsync(key: string, value: string): Promise<void>;
|
|
84
|
+
deleteItemAsync(key: string): Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* expo-secure-store has no API to list all keys. Pass knownKeys to inspect
|
|
88
|
+
* those entries. Pass the module for reliable bundling in Expo:
|
|
89
|
+
* @example import * as SecureStore from 'expo-secure-store';
|
|
90
|
+
* createSecureStoreAdapter([], SecureStore)
|
|
91
|
+
*/
|
|
92
|
+
declare function createSecureStoreAdapter(knownKeys?: string[], instance?: SecureStoreModule | null): IStorageAdapter;
|
|
93
|
+
|
|
19
94
|
interface StorageInspectorProps {
|
|
20
95
|
mmkvInstances?: Array<{
|
|
21
96
|
getAllKeys(): string[];
|
|
@@ -23,11 +98,17 @@ interface StorageInspectorProps {
|
|
|
23
98
|
set(k: string, v: string | number | boolean): void;
|
|
24
99
|
delete(k: string): void;
|
|
25
100
|
}>;
|
|
101
|
+
/** Pass AsyncStorage to avoid Metro "unknown module" in Expo. */
|
|
102
|
+
asyncStorageInstance?: AsyncStorageModule | null;
|
|
26
103
|
keychainKeys?: string[];
|
|
104
|
+
/** Pass Keychain module to avoid Metro "unknown module" in Expo. */
|
|
105
|
+
keychainInstance?: KeychainModule | null;
|
|
27
106
|
secureStoreKeys?: string[];
|
|
107
|
+
/** Pass SecureStore module to avoid Metro "unknown module" in Expo. */
|
|
108
|
+
secureStoreInstance?: SecureStoreModule | null;
|
|
28
109
|
customAdapters?: IStorageAdapter[];
|
|
29
110
|
}
|
|
30
|
-
declare function StorageInspector({ mmkvInstances, keychainKeys: keychainKeysProp, secureStoreKeys: secureStoreKeysProp, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
111
|
+
declare function StorageInspector({ mmkvInstances, asyncStorageInstance, keychainKeys: keychainKeysProp, keychainInstance, secureStoreKeys: secureStoreKeysProp, secureStoreInstance, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
31
112
|
|
|
32
113
|
/**
|
|
33
114
|
* Centralized user-facing text for the storage inspector.
|
|
@@ -94,18 +175,4 @@ type MMKVInstance = {
|
|
|
94
175
|
};
|
|
95
176
|
declare function createMMKVAdapter(instance: MMKVInstance, name?: string): IStorageAdapter;
|
|
96
177
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Keychain adapter. Auto-discovers keys via getAllGenericPasswordServices() (generic passwords).
|
|
101
|
-
* Pass knownKeys only if you also store data with setInternetCredentials – those cannot be listed.
|
|
102
|
-
*/
|
|
103
|
-
declare function createKeychainAdapter(knownKeys?: string[]): IStorageAdapter;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* expo-secure-store has no API to list all keys. Pass knownKeys to inspect
|
|
107
|
-
* those entries, or keys will appear after the user adds them via the inspector.
|
|
108
|
-
*/
|
|
109
|
-
declare function createSecureStoreAdapter(knownKeys?: string[]): IStorageAdapter;
|
|
110
|
-
|
|
111
|
-
export { type IStorageAdapter, StorageInspector, type StorageInspectorProps, type StorageItem, type Theme, createAsyncStorageAdapter, createKeychainAdapter, createMMKVAdapter, createSecureStoreAdapter, strings, theme };
|
|
178
|
+
export { type AsyncStorageModule, type IStorageAdapter, type KeychainModule, type SecureStoreModule, StorageInspector, type StorageInspectorProps, type StorageItem, type Theme, createAsyncStorageAdapter, createKeychainAdapter, createMMKVAdapter, createSecureStoreAdapter, strings, theme };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,81 @@ interface IStorageAdapter {
|
|
|
16
16
|
isAvailable(): boolean;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* AsyncStorage-compatible module interface.
|
|
21
|
+
* Pass your AsyncStorage instance to avoid Metro "unknown module" errors in Expo:
|
|
22
|
+
* @example
|
|
23
|
+
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
24
|
+
* createAsyncStorageAdapter(AsyncStorage)
|
|
25
|
+
*/
|
|
26
|
+
type AsyncStorageModule = {
|
|
27
|
+
getAllKeys(): Promise<string[]>;
|
|
28
|
+
getItem(key: string): Promise<string | null>;
|
|
29
|
+
setItem(key: string, value: string): Promise<void>;
|
|
30
|
+
removeItem(key: string): Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Creates an AsyncStorage adapter. Pass the AsyncStorage instance for reliable
|
|
34
|
+
* bundling in Expo/Metro (avoids "unknown module" errors):
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
38
|
+
* createAsyncStorageAdapter(AsyncStorage)
|
|
39
|
+
*/
|
|
40
|
+
declare function createAsyncStorageAdapter(instance?: AsyncStorageModule | null): IStorageAdapter;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Keychain-compatible module. Pass your keychain instance to avoid Metro
|
|
44
|
+
* "unknown module" errors in Expo.
|
|
45
|
+
*/
|
|
46
|
+
type KeychainModule = {
|
|
47
|
+
getAllGenericPasswordServices?(options?: object): Promise<string[]>;
|
|
48
|
+
getGenericPassword?(options?: {
|
|
49
|
+
service?: string;
|
|
50
|
+
}): Promise<{
|
|
51
|
+
password: string;
|
|
52
|
+
} | false>;
|
|
53
|
+
setGenericPassword?(username: string, password: string, options?: {
|
|
54
|
+
service?: string;
|
|
55
|
+
}): Promise<{
|
|
56
|
+
storage: string;
|
|
57
|
+
} | false>;
|
|
58
|
+
resetGenericPassword?(options?: {
|
|
59
|
+
service?: string;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
setInternetCredentials(server: string, username: string, password: string): Promise<{
|
|
62
|
+
storage: string;
|
|
63
|
+
} | false>;
|
|
64
|
+
getInternetCredentials(server: string): Promise<{
|
|
65
|
+
username: string;
|
|
66
|
+
password: string;
|
|
67
|
+
} | null>;
|
|
68
|
+
resetInternetCredentials(server: string): Promise<void>;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Keychain adapter. Pass the keychain instance for reliable bundling in Expo:
|
|
72
|
+
* @example import * as Keychain from 'react-native-keychain';
|
|
73
|
+
* createKeychainAdapter([], Keychain)
|
|
74
|
+
*/
|
|
75
|
+
declare function createKeychainAdapter(knownKeys?: string[], instance?: KeychainModule | null): IStorageAdapter;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* expo-secure-store compatible module. Pass the module to avoid Metro
|
|
79
|
+
* "unknown module" errors in Expo.
|
|
80
|
+
*/
|
|
81
|
+
type SecureStoreModule = {
|
|
82
|
+
getItemAsync(key: string): Promise<string | null>;
|
|
83
|
+
setItemAsync(key: string, value: string): Promise<void>;
|
|
84
|
+
deleteItemAsync(key: string): Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* expo-secure-store has no API to list all keys. Pass knownKeys to inspect
|
|
88
|
+
* those entries. Pass the module for reliable bundling in Expo:
|
|
89
|
+
* @example import * as SecureStore from 'expo-secure-store';
|
|
90
|
+
* createSecureStoreAdapter([], SecureStore)
|
|
91
|
+
*/
|
|
92
|
+
declare function createSecureStoreAdapter(knownKeys?: string[], instance?: SecureStoreModule | null): IStorageAdapter;
|
|
93
|
+
|
|
19
94
|
interface StorageInspectorProps {
|
|
20
95
|
mmkvInstances?: Array<{
|
|
21
96
|
getAllKeys(): string[];
|
|
@@ -23,11 +98,17 @@ interface StorageInspectorProps {
|
|
|
23
98
|
set(k: string, v: string | number | boolean): void;
|
|
24
99
|
delete(k: string): void;
|
|
25
100
|
}>;
|
|
101
|
+
/** Pass AsyncStorage to avoid Metro "unknown module" in Expo. */
|
|
102
|
+
asyncStorageInstance?: AsyncStorageModule | null;
|
|
26
103
|
keychainKeys?: string[];
|
|
104
|
+
/** Pass Keychain module to avoid Metro "unknown module" in Expo. */
|
|
105
|
+
keychainInstance?: KeychainModule | null;
|
|
27
106
|
secureStoreKeys?: string[];
|
|
107
|
+
/** Pass SecureStore module to avoid Metro "unknown module" in Expo. */
|
|
108
|
+
secureStoreInstance?: SecureStoreModule | null;
|
|
28
109
|
customAdapters?: IStorageAdapter[];
|
|
29
110
|
}
|
|
30
|
-
declare function StorageInspector({ mmkvInstances, keychainKeys: keychainKeysProp, secureStoreKeys: secureStoreKeysProp, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
111
|
+
declare function StorageInspector({ mmkvInstances, asyncStorageInstance, keychainKeys: keychainKeysProp, keychainInstance, secureStoreKeys: secureStoreKeysProp, secureStoreInstance, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
31
112
|
|
|
32
113
|
/**
|
|
33
114
|
* Centralized user-facing text for the storage inspector.
|
|
@@ -94,18 +175,4 @@ type MMKVInstance = {
|
|
|
94
175
|
};
|
|
95
176
|
declare function createMMKVAdapter(instance: MMKVInstance, name?: string): IStorageAdapter;
|
|
96
177
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Keychain adapter. Auto-discovers keys via getAllGenericPasswordServices() (generic passwords).
|
|
101
|
-
* Pass knownKeys only if you also store data with setInternetCredentials – those cannot be listed.
|
|
102
|
-
*/
|
|
103
|
-
declare function createKeychainAdapter(knownKeys?: string[]): IStorageAdapter;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* expo-secure-store has no API to list all keys. Pass knownKeys to inspect
|
|
107
|
-
* those entries, or keys will appear after the user adds them via the inspector.
|
|
108
|
-
*/
|
|
109
|
-
declare function createSecureStoreAdapter(knownKeys?: string[]): IStorageAdapter;
|
|
110
|
-
|
|
111
|
-
export { type IStorageAdapter, StorageInspector, type StorageInspectorProps, type StorageItem, type Theme, createAsyncStorageAdapter, createKeychainAdapter, createMMKVAdapter, createSecureStoreAdapter, strings, theme };
|
|
178
|
+
export { type AsyncStorageModule, type IStorageAdapter, type KeychainModule, type SecureStoreModule, StorageInspector, type StorageInspectorProps, type StorageItem, type Theme, createAsyncStorageAdapter, createKeychainAdapter, createMMKVAdapter, createSecureStoreAdapter, strings, theme };
|
package/dist/index.js
CHANGED
|
@@ -42,62 +42,61 @@ function createMMKVAdapter(instance, name) {
|
|
|
42
42
|
|
|
43
43
|
// src/adapters/async-storage.ts
|
|
44
44
|
var asyncStorage = null;
|
|
45
|
-
function
|
|
46
|
-
if (asyncStorage) return asyncStorage;
|
|
45
|
+
function getAsyncStorageFromRequire() {
|
|
47
46
|
try {
|
|
48
|
-
|
|
49
|
-
return
|
|
47
|
+
const mod = require("@react-native-async-storage/async-storage");
|
|
48
|
+
return mod.default ?? mod;
|
|
50
49
|
} catch {
|
|
51
50
|
return null;
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
|
-
function createAsyncStorageAdapter() {
|
|
53
|
+
function createAsyncStorageAdapter(instance) {
|
|
54
|
+
const getStorage = () => instance ?? (asyncStorage ?? (asyncStorage = getAsyncStorageFromRequire()));
|
|
55
55
|
return {
|
|
56
56
|
type: "async-storage",
|
|
57
57
|
name: "Async Storage",
|
|
58
58
|
async getAllKeys() {
|
|
59
|
-
const storage =
|
|
59
|
+
const storage = getStorage();
|
|
60
60
|
if (!storage) return [];
|
|
61
61
|
return storage.getAllKeys();
|
|
62
62
|
},
|
|
63
63
|
async getItem(key) {
|
|
64
|
-
const storage =
|
|
64
|
+
const storage = getStorage();
|
|
65
65
|
if (!storage) return null;
|
|
66
66
|
return storage.getItem(key);
|
|
67
67
|
},
|
|
68
68
|
async setItem(key, value) {
|
|
69
|
-
const storage =
|
|
69
|
+
const storage = getStorage();
|
|
70
70
|
if (!storage) throw new Error("AsyncStorage is not available");
|
|
71
71
|
await storage.setItem(key, value);
|
|
72
72
|
},
|
|
73
73
|
async removeItem(key) {
|
|
74
|
-
const storage =
|
|
74
|
+
const storage = getStorage();
|
|
75
75
|
if (!storage) throw new Error("AsyncStorage is not available");
|
|
76
76
|
await storage.removeItem(key);
|
|
77
77
|
},
|
|
78
78
|
isAvailable() {
|
|
79
|
-
return
|
|
79
|
+
return getStorage() !== null;
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// src/adapters/keychain.ts
|
|
85
85
|
var keychain = null;
|
|
86
|
-
function
|
|
87
|
-
if (keychain) return keychain;
|
|
86
|
+
function getKeychainFromRequire() {
|
|
88
87
|
try {
|
|
89
|
-
|
|
90
|
-
return keychain;
|
|
88
|
+
return require("react-native-keychain");
|
|
91
89
|
} catch {
|
|
92
90
|
return null;
|
|
93
91
|
}
|
|
94
92
|
}
|
|
95
|
-
function createKeychainAdapter(knownKeys = []) {
|
|
93
|
+
function createKeychainAdapter(knownKeys = [], instance) {
|
|
94
|
+
const getKc = () => instance ?? (keychain ?? (keychain = getKeychainFromRequire()));
|
|
96
95
|
return {
|
|
97
96
|
type: "keychain",
|
|
98
97
|
name: "Keychain",
|
|
99
98
|
async getAllKeys() {
|
|
100
|
-
const kc =
|
|
99
|
+
const kc = getKc();
|
|
101
100
|
if (!kc) return [...knownKeys];
|
|
102
101
|
const genericServices = [];
|
|
103
102
|
if (typeof kc.getAllGenericPasswordServices === "function") {
|
|
@@ -111,7 +110,7 @@ function createKeychainAdapter(knownKeys = []) {
|
|
|
111
110
|
return Array.from(merged);
|
|
112
111
|
},
|
|
113
112
|
async getItem(key) {
|
|
114
|
-
const kc =
|
|
113
|
+
const kc = getKc();
|
|
115
114
|
if (!kc) return null;
|
|
116
115
|
if (typeof kc.getGenericPassword === "function") {
|
|
117
116
|
try {
|
|
@@ -126,7 +125,7 @@ function createKeychainAdapter(knownKeys = []) {
|
|
|
126
125
|
return creds?.password ?? null;
|
|
127
126
|
},
|
|
128
127
|
async setItem(key, value) {
|
|
129
|
-
const kc =
|
|
128
|
+
const kc = getKc();
|
|
130
129
|
if (!kc) throw new Error("react-native-keychain is not available");
|
|
131
130
|
if (typeof kc.setGenericPassword === "function") {
|
|
132
131
|
const result2 = await kc.setGenericPassword(key, value, { service: key });
|
|
@@ -137,7 +136,7 @@ function createKeychainAdapter(knownKeys = []) {
|
|
|
137
136
|
if (result === false) throw new Error("Keychain set failed");
|
|
138
137
|
},
|
|
139
138
|
async removeItem(key) {
|
|
140
|
-
const kc =
|
|
139
|
+
const kc = getKc();
|
|
141
140
|
if (!kc) throw new Error("react-native-keychain is not available");
|
|
142
141
|
if (typeof kc.resetGenericPassword === "function") {
|
|
143
142
|
await kc.resetGenericPassword({ service: key });
|
|
@@ -145,23 +144,22 @@ function createKeychainAdapter(knownKeys = []) {
|
|
|
145
144
|
await kc.resetInternetCredentials(key);
|
|
146
145
|
},
|
|
147
146
|
isAvailable() {
|
|
148
|
-
return
|
|
147
|
+
return getKc() !== null;
|
|
149
148
|
}
|
|
150
149
|
};
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
// src/adapters/secure-store.ts
|
|
154
153
|
var secureStore = null;
|
|
155
|
-
function
|
|
156
|
-
if (secureStore) return secureStore;
|
|
154
|
+
function getSecureStoreFromRequire() {
|
|
157
155
|
try {
|
|
158
|
-
|
|
159
|
-
return secureStore;
|
|
156
|
+
return require("expo-secure-store");
|
|
160
157
|
} catch {
|
|
161
158
|
return null;
|
|
162
159
|
}
|
|
163
160
|
}
|
|
164
|
-
function createSecureStoreAdapter(knownKeys = []) {
|
|
161
|
+
function createSecureStoreAdapter(knownKeys = [], instance) {
|
|
162
|
+
const getStore = () => instance ?? (secureStore ?? (secureStore = getSecureStoreFromRequire()));
|
|
165
163
|
return {
|
|
166
164
|
type: "expo-secure-store",
|
|
167
165
|
name: "Secure Store",
|
|
@@ -169,22 +167,22 @@ function createSecureStoreAdapter(knownKeys = []) {
|
|
|
169
167
|
return [...knownKeys];
|
|
170
168
|
},
|
|
171
169
|
async getItem(key) {
|
|
172
|
-
const store =
|
|
170
|
+
const store = getStore();
|
|
173
171
|
if (!store) return null;
|
|
174
172
|
return store.getItemAsync(key);
|
|
175
173
|
},
|
|
176
174
|
async setItem(key, value) {
|
|
177
|
-
const store =
|
|
175
|
+
const store = getStore();
|
|
178
176
|
if (!store) throw new Error("expo-secure-store is not available");
|
|
179
177
|
await store.setItemAsync(key, value);
|
|
180
178
|
},
|
|
181
179
|
async removeItem(key) {
|
|
182
|
-
const store =
|
|
180
|
+
const store = getStore();
|
|
183
181
|
if (!store) throw new Error("expo-secure-store is not available");
|
|
184
182
|
await store.deleteItemAsync(key);
|
|
185
183
|
},
|
|
186
184
|
isAvailable() {
|
|
187
|
-
return
|
|
185
|
+
return getStore() !== null;
|
|
188
186
|
}
|
|
189
187
|
};
|
|
190
188
|
}
|
|
@@ -1062,11 +1060,10 @@ function StorageSection({
|
|
|
1062
1060
|
return next;
|
|
1063
1061
|
});
|
|
1064
1062
|
};
|
|
1065
|
-
return /* @__PURE__ */ React6__default.default.createElement(
|
|
1063
|
+
return /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { key: item.key, style: styles2.itemRow }, /* @__PURE__ */ React6__default.default.createElement(
|
|
1066
1064
|
reactNative.TouchableOpacity,
|
|
1067
1065
|
{
|
|
1068
1066
|
key: item.key,
|
|
1069
|
-
style: styles2.itemRow,
|
|
1070
1067
|
onPress: toggleItemExpanded,
|
|
1071
1068
|
activeOpacity: 0.7
|
|
1072
1069
|
},
|
|
@@ -1087,17 +1084,24 @@ function StorageSection({
|
|
|
1087
1084
|
size: LAYOUT.chevronSize,
|
|
1088
1085
|
tintColor: theme.colors.text
|
|
1089
1086
|
}
|
|
1090
|
-
)))
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1087
|
+
)))
|
|
1088
|
+
), isItemExpanded && /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.itemRowExpanded }, /* @__PURE__ */ React6__default.default.createElement(
|
|
1089
|
+
reactNative.TouchableOpacity,
|
|
1090
|
+
{
|
|
1091
|
+
onPress: () => handleEdit(item),
|
|
1092
|
+
style: styles2.valueBox
|
|
1093
|
+
},
|
|
1094
|
+
/* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.valueBoxLabel }, strings.valueLabel),
|
|
1095
|
+
/* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.valueBoxText, selectable: true }, item.value || strings.emptyValue)
|
|
1096
|
+
), /* @__PURE__ */ React6__default.default.createElement(
|
|
1097
|
+
ItemRowActions,
|
|
1098
|
+
{
|
|
1099
|
+
item,
|
|
1100
|
+
onCopy: handleCopy,
|
|
1101
|
+
onEdit: handleEdit,
|
|
1102
|
+
onDelete: setDeleteItem
|
|
1103
|
+
}
|
|
1104
|
+
)));
|
|
1101
1105
|
}), !loading && items.length === 0 && !showKeychainHint && !showSecureStoreHint ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.empty }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.emptyText }, strings.noItems)) : null), /* @__PURE__ */ React6__default.default.createElement(
|
|
1102
1106
|
ItemForm,
|
|
1103
1107
|
{
|
|
@@ -1134,8 +1138,11 @@ function StorageSection({
|
|
|
1134
1138
|
// src/components/StorageInspector.tsx
|
|
1135
1139
|
function StorageInspector({
|
|
1136
1140
|
mmkvInstances = [],
|
|
1141
|
+
asyncStorageInstance,
|
|
1137
1142
|
keychainKeys: keychainKeysProp,
|
|
1143
|
+
keychainInstance,
|
|
1138
1144
|
secureStoreKeys: secureStoreKeysProp,
|
|
1145
|
+
secureStoreInstance,
|
|
1139
1146
|
customAdapters = []
|
|
1140
1147
|
}) {
|
|
1141
1148
|
const [keychainKeysAdded, setKeychainKeysAdded] = React6.useState([]);
|
|
@@ -1158,15 +1165,26 @@ function StorageInspector({
|
|
|
1158
1165
|
createMMKVAdapter(inst, mmkvInstances.length > 1 ? `MMKV ${i + 1}` : "MMKV")
|
|
1159
1166
|
);
|
|
1160
1167
|
});
|
|
1161
|
-
const asyncAdapter = createAsyncStorageAdapter();
|
|
1168
|
+
const asyncAdapter = createAsyncStorageAdapter(asyncStorageInstance);
|
|
1162
1169
|
if (asyncAdapter.isAvailable()) list.push(asyncAdapter);
|
|
1163
|
-
const keychainAdapter = createKeychainAdapter(keychainKeys);
|
|
1170
|
+
const keychainAdapter = createKeychainAdapter(keychainKeys, keychainInstance);
|
|
1164
1171
|
if (keychainAdapter.isAvailable()) list.push(keychainAdapter);
|
|
1165
|
-
const secureStoreAdapter = createSecureStoreAdapter(
|
|
1172
|
+
const secureStoreAdapter = createSecureStoreAdapter(
|
|
1173
|
+
secureStoreKeys,
|
|
1174
|
+
secureStoreInstance
|
|
1175
|
+
);
|
|
1166
1176
|
if (secureStoreAdapter.isAvailable()) list.push(secureStoreAdapter);
|
|
1167
1177
|
list.push(...customAdapters);
|
|
1168
1178
|
return list;
|
|
1169
|
-
}, [
|
|
1179
|
+
}, [
|
|
1180
|
+
mmkvInstances,
|
|
1181
|
+
asyncStorageInstance,
|
|
1182
|
+
keychainKeys,
|
|
1183
|
+
keychainInstance,
|
|
1184
|
+
secureStoreKeys,
|
|
1185
|
+
secureStoreInstance,
|
|
1186
|
+
customAdapters
|
|
1187
|
+
]);
|
|
1170
1188
|
const handleKeychainKeyAdded = (key) => {
|
|
1171
1189
|
setKeychainKeysAdded(
|
|
1172
1190
|
(prev) => prev.includes(key) ? prev : [...prev, key]
|