react-native-storage-inspector 1.0.0
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/LICENSE +21 -0
- package/README.md +105 -0
- package/dist/index.d.mts +111 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.js +1235 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1223 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +82 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 react-native-storage-inspector contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# react-native-storage-inspector
|
|
2
|
+
|
|
3
|
+
react-native-storage-inspector is a plug-and-play developer tool that empowers you to browse, search, and edit all your app’s persisted data.
|
|
4
|
+
|
|
5
|
+
## Supported libraries
|
|
6
|
+
|
|
7
|
+
Tabs appear only when the corresponding package is installed (optional peer dependencies).
|
|
8
|
+
|
|
9
|
+
| Library | Package | Storage |
|
|
10
|
+
| ---------------------------------------------------------------------------- | ------------------------------------------- | ------------ |
|
|
11
|
+
| [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) | `react-native-mmkv` | MMKV |
|
|
12
|
+
| [Async Storage](https://github.com/react-native-async-storage/async-storage) | `@react-native-async-storage/async-storage` | AsyncStorage |
|
|
13
|
+
| [react-native-keychain](https://github.com/oblador/react-native-keychain) | `react-native-keychain` | Keychain |
|
|
14
|
+
| [expo-secure-store](https://docs.expo.dev/versions/latest/sdk/securestore/) | `expo-secure-store` | Secure Store |
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install the inspector and at least one storage library you use:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install react-native-storage-inspector
|
|
22
|
+
# And one or more:
|
|
23
|
+
npm install react-native-mmkv
|
|
24
|
+
npm install @react-native-async-storage/async-storage
|
|
25
|
+
npm install react-native-keychain
|
|
26
|
+
npm install expo-secure-store
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Use `StorageInspector` as a **full-page component**. It renders only the content area, no header, back button, or status bar. The consumer screen must handle those.
|
|
32
|
+
|
|
33
|
+
Put it in a screen with `flex: 1`, and wrap with `SafeAreaView` (or your nav's safe area) so it respects status bar and notches.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { SafeAreaView } from 'react-native';
|
|
37
|
+
import { StorageInspector } from 'react-native-storage-inspector';
|
|
38
|
+
|
|
39
|
+
export function StorageInspectorScreen() {
|
|
40
|
+
return (
|
|
41
|
+
<SafeAreaView style={{ flex: 1 }}>
|
|
42
|
+
<StorageInspector />
|
|
43
|
+
</SafeAreaView>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The component fills its container. The consumer is responsible for header, back button, and status bar (via SafeAreaView or your navigation setup).
|
|
49
|
+
|
|
50
|
+
### Props
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Description |
|
|
53
|
+
| ----------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `mmkvInstances` | `MMKV[]` | **Required for MMKV.** Pass your MMKV instances to inspect. |
|
|
55
|
+
| `secureStoreKeys` | `string[]` | **Required for Secure Store.** Keys to list (no list API). |
|
|
56
|
+
| `keychainKeys` | `string[]` | Optional. Only for internet credentials (no list API). Generic passwords auto-discovered via `getAllGenericPasswordServices`. |
|
|
57
|
+
| `customAdapters` | `IStorageAdapter[]` | Optional. Custom adapters for other storages. |
|
|
58
|
+
|
|
59
|
+
## Expo
|
|
60
|
+
|
|
61
|
+
- **Expo Go**: Async Storage and Expo Secure Store work. MMKV and Keychain need native code and are not available in Expo Go.
|
|
62
|
+
- **Development build**: All four storages work with `expo-dev-client`.
|
|
63
|
+
|
|
64
|
+
## API (for custom adapters)
|
|
65
|
+
|
|
66
|
+
Implement `IStorageAdapter` and pass it via `customAdapters`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
interface IStorageAdapter {
|
|
70
|
+
type: string;
|
|
71
|
+
name: string;
|
|
72
|
+
getAllKeys(): Promise<string[]>;
|
|
73
|
+
getItem(key: string): Promise<string | null>;
|
|
74
|
+
setItem(key: string, value: string): Promise<void>;
|
|
75
|
+
removeItem(key: string): Promise<void>;
|
|
76
|
+
isAvailable(): boolean;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm run format # Format all files with Prettier
|
|
84
|
+
npm run format:check # Check formatting (fails if any file is unformatted)
|
|
85
|
+
npm run lint # Same as format:check
|
|
86
|
+
npm test # Run tests
|
|
87
|
+
npm run build # Build src/ to dist/
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- **Formatting:** No auto-format. Run `npm run format` to fix. **Pre-commit** runs `format:check`; **pre-push** runs `format:check`, `test`, and `build`.
|
|
91
|
+
- **Commits:** Use [Conventional Commits](https://www.conventionalcommits.org/) (enforced by `commit-msg` hook).
|
|
92
|
+
- **Before publish:** `prepublishOnly` runs `format:check`, `test`, and `build`.
|
|
93
|
+
|
|
94
|
+
### Publishing
|
|
95
|
+
|
|
96
|
+
1. Run `npm version patch` (or `minor`/`major`).
|
|
97
|
+
2. Run `npm publish` (prepublishOnly will run checks and build).
|
|
98
|
+
|
|
99
|
+
See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for full guidelines. [Code of Conduct](docs/CODE_OF_CONDUCT.md).
|
|
100
|
+
|
|
101
|
+
For AI assistants: see [ai/PRIMER.md](ai/PRIMER.md).
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type StorageType = 'mmkv' | 'async-storage' | 'keychain' | 'expo-secure-store';
|
|
4
|
+
|
|
5
|
+
interface StorageItem {
|
|
6
|
+
key: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
interface IStorageAdapter {
|
|
10
|
+
type: StorageType;
|
|
11
|
+
name: string;
|
|
12
|
+
getAllKeys(): Promise<string[]>;
|
|
13
|
+
getItem(key: string): Promise<string | null>;
|
|
14
|
+
setItem(key: string, value: string): Promise<void>;
|
|
15
|
+
removeItem(key: string): Promise<void>;
|
|
16
|
+
isAvailable(): boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface StorageInspectorProps {
|
|
20
|
+
mmkvInstances?: Array<{
|
|
21
|
+
getAllKeys(): string[];
|
|
22
|
+
getString(k: string): string | undefined;
|
|
23
|
+
set(k: string, v: string | number | boolean): void;
|
|
24
|
+
delete(k: string): void;
|
|
25
|
+
}>;
|
|
26
|
+
keychainKeys?: string[];
|
|
27
|
+
secureStoreKeys?: string[];
|
|
28
|
+
customAdapters?: IStorageAdapter[];
|
|
29
|
+
}
|
|
30
|
+
declare function StorageInspector({ mmkvInstances, keychainKeys: keychainKeysProp, secureStoreKeys: secureStoreKeysProp, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Centralized user-facing text for the storage inspector.
|
|
34
|
+
* Enables localization and consistent messaging.
|
|
35
|
+
*/
|
|
36
|
+
declare const strings: {
|
|
37
|
+
readonly noAdapterAvailable: "No storage adapter available. Install at least one of: react-native-mmkv, @react-native-async-storage/async-storage, react-native-keychain, expo-secure-store";
|
|
38
|
+
readonly keychainHint: "No generic password items yet. Add a key using + above, or pass keychainKeys for internet credentials.";
|
|
39
|
+
readonly secureStoreHint: "Secure Store has no list API. Pass secureStoreKeys prop with known keys, or add a key using + above.";
|
|
40
|
+
readonly loading: "Loading…";
|
|
41
|
+
readonly noItems: "No items";
|
|
42
|
+
readonly valueLabel: "Value";
|
|
43
|
+
readonly emptyValue: "(empty)";
|
|
44
|
+
readonly charCount: (n: number) => string;
|
|
45
|
+
readonly deleteItemTitle: (key: string) => string;
|
|
46
|
+
readonly deleteItemMessage: (key: string) => string;
|
|
47
|
+
readonly clearAllTitle: (name: string) => string;
|
|
48
|
+
readonly clearAllMessage: (count: number, name: string) => string;
|
|
49
|
+
readonly storageNotAvailable: "This storage is not available.";
|
|
50
|
+
readonly keychainHintShort: "No items yet. Add a key below, or pass keychainKeys for internet credentials.";
|
|
51
|
+
readonly edit: "Edit";
|
|
52
|
+
readonly delete: "Delete";
|
|
53
|
+
readonly addItem: "Add item";
|
|
54
|
+
readonly keyRequired: "Key is required";
|
|
55
|
+
readonly saveFailed: "Save failed";
|
|
56
|
+
readonly editItemTitle: (key: string) => string;
|
|
57
|
+
readonly addItemTitle: (storageName: string) => string;
|
|
58
|
+
readonly storageTypeLabel: (name: string) => string;
|
|
59
|
+
readonly keyLabel: "Key";
|
|
60
|
+
readonly enterKeyPlaceholder: "Enter key";
|
|
61
|
+
readonly enterValuePlaceholder: "Enter value";
|
|
62
|
+
readonly cancel: "Cancel";
|
|
63
|
+
readonly saving: "Saving…";
|
|
64
|
+
readonly save: "Save";
|
|
65
|
+
readonly add: "Add";
|
|
66
|
+
readonly confirmDelete: "Yes, delete";
|
|
67
|
+
readonly cancelKeep: "No, keep it";
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Theme: minimalistic black and white palette.
|
|
72
|
+
* All colors centralized here - no direct hex values in components.
|
|
73
|
+
*/
|
|
74
|
+
declare const theme: {
|
|
75
|
+
readonly colors: {
|
|
76
|
+
readonly background: "#ffffff";
|
|
77
|
+
readonly backgroundSecondary: "#f5f5f5";
|
|
78
|
+
readonly backgroundTertiary: "#eeeeee";
|
|
79
|
+
readonly border: "#e0e0e0";
|
|
80
|
+
readonly borderLight: "#ebebeb";
|
|
81
|
+
readonly text: "#000000";
|
|
82
|
+
readonly textSecondary: "#666666";
|
|
83
|
+
readonly textMuted: "#999999";
|
|
84
|
+
readonly inverted: "#ffffff";
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
type Theme = typeof theme;
|
|
88
|
+
|
|
89
|
+
type MMKVInstance = {
|
|
90
|
+
getAllKeys(): string[];
|
|
91
|
+
getString(key: string): string | undefined;
|
|
92
|
+
set(key: string, value: string | number | boolean): void;
|
|
93
|
+
delete(key: string): void;
|
|
94
|
+
};
|
|
95
|
+
declare function createMMKVAdapter(instance: MMKVInstance, name?: string): IStorageAdapter;
|
|
96
|
+
|
|
97
|
+
declare function createAsyncStorageAdapter(): IStorageAdapter;
|
|
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 };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type StorageType = 'mmkv' | 'async-storage' | 'keychain' | 'expo-secure-store';
|
|
4
|
+
|
|
5
|
+
interface StorageItem {
|
|
6
|
+
key: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
interface IStorageAdapter {
|
|
10
|
+
type: StorageType;
|
|
11
|
+
name: string;
|
|
12
|
+
getAllKeys(): Promise<string[]>;
|
|
13
|
+
getItem(key: string): Promise<string | null>;
|
|
14
|
+
setItem(key: string, value: string): Promise<void>;
|
|
15
|
+
removeItem(key: string): Promise<void>;
|
|
16
|
+
isAvailable(): boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface StorageInspectorProps {
|
|
20
|
+
mmkvInstances?: Array<{
|
|
21
|
+
getAllKeys(): string[];
|
|
22
|
+
getString(k: string): string | undefined;
|
|
23
|
+
set(k: string, v: string | number | boolean): void;
|
|
24
|
+
delete(k: string): void;
|
|
25
|
+
}>;
|
|
26
|
+
keychainKeys?: string[];
|
|
27
|
+
secureStoreKeys?: string[];
|
|
28
|
+
customAdapters?: IStorageAdapter[];
|
|
29
|
+
}
|
|
30
|
+
declare function StorageInspector({ mmkvInstances, keychainKeys: keychainKeysProp, secureStoreKeys: secureStoreKeysProp, customAdapters, }: StorageInspectorProps): React.JSX.Element;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Centralized user-facing text for the storage inspector.
|
|
34
|
+
* Enables localization and consistent messaging.
|
|
35
|
+
*/
|
|
36
|
+
declare const strings: {
|
|
37
|
+
readonly noAdapterAvailable: "No storage adapter available. Install at least one of: react-native-mmkv, @react-native-async-storage/async-storage, react-native-keychain, expo-secure-store";
|
|
38
|
+
readonly keychainHint: "No generic password items yet. Add a key using + above, or pass keychainKeys for internet credentials.";
|
|
39
|
+
readonly secureStoreHint: "Secure Store has no list API. Pass secureStoreKeys prop with known keys, or add a key using + above.";
|
|
40
|
+
readonly loading: "Loading…";
|
|
41
|
+
readonly noItems: "No items";
|
|
42
|
+
readonly valueLabel: "Value";
|
|
43
|
+
readonly emptyValue: "(empty)";
|
|
44
|
+
readonly charCount: (n: number) => string;
|
|
45
|
+
readonly deleteItemTitle: (key: string) => string;
|
|
46
|
+
readonly deleteItemMessage: (key: string) => string;
|
|
47
|
+
readonly clearAllTitle: (name: string) => string;
|
|
48
|
+
readonly clearAllMessage: (count: number, name: string) => string;
|
|
49
|
+
readonly storageNotAvailable: "This storage is not available.";
|
|
50
|
+
readonly keychainHintShort: "No items yet. Add a key below, or pass keychainKeys for internet credentials.";
|
|
51
|
+
readonly edit: "Edit";
|
|
52
|
+
readonly delete: "Delete";
|
|
53
|
+
readonly addItem: "Add item";
|
|
54
|
+
readonly keyRequired: "Key is required";
|
|
55
|
+
readonly saveFailed: "Save failed";
|
|
56
|
+
readonly editItemTitle: (key: string) => string;
|
|
57
|
+
readonly addItemTitle: (storageName: string) => string;
|
|
58
|
+
readonly storageTypeLabel: (name: string) => string;
|
|
59
|
+
readonly keyLabel: "Key";
|
|
60
|
+
readonly enterKeyPlaceholder: "Enter key";
|
|
61
|
+
readonly enterValuePlaceholder: "Enter value";
|
|
62
|
+
readonly cancel: "Cancel";
|
|
63
|
+
readonly saving: "Saving…";
|
|
64
|
+
readonly save: "Save";
|
|
65
|
+
readonly add: "Add";
|
|
66
|
+
readonly confirmDelete: "Yes, delete";
|
|
67
|
+
readonly cancelKeep: "No, keep it";
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Theme: minimalistic black and white palette.
|
|
72
|
+
* All colors centralized here - no direct hex values in components.
|
|
73
|
+
*/
|
|
74
|
+
declare const theme: {
|
|
75
|
+
readonly colors: {
|
|
76
|
+
readonly background: "#ffffff";
|
|
77
|
+
readonly backgroundSecondary: "#f5f5f5";
|
|
78
|
+
readonly backgroundTertiary: "#eeeeee";
|
|
79
|
+
readonly border: "#e0e0e0";
|
|
80
|
+
readonly borderLight: "#ebebeb";
|
|
81
|
+
readonly text: "#000000";
|
|
82
|
+
readonly textSecondary: "#666666";
|
|
83
|
+
readonly textMuted: "#999999";
|
|
84
|
+
readonly inverted: "#ffffff";
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
type Theme = typeof theme;
|
|
88
|
+
|
|
89
|
+
type MMKVInstance = {
|
|
90
|
+
getAllKeys(): string[];
|
|
91
|
+
getString(key: string): string | undefined;
|
|
92
|
+
set(key: string, value: string | number | boolean): void;
|
|
93
|
+
delete(key: string): void;
|
|
94
|
+
};
|
|
95
|
+
declare function createMMKVAdapter(instance: MMKVInstance, name?: string): IStorageAdapter;
|
|
96
|
+
|
|
97
|
+
declare function createAsyncStorageAdapter(): IStorageAdapter;
|
|
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 };
|