strata-storage 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/Readme.md +113 -0
- package/android/src/main/java/com/strata/storage/EncryptedStorage.java +65 -0
- package/android/src/main/java/com/strata/storage/SQLiteStorage.java +147 -0
- package/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +74 -0
- package/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +256 -0
- package/dist/adapters/capacitor/FilesystemAdapter.d.ts +46 -0
- package/dist/adapters/capacitor/FilesystemAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/FilesystemAdapter.js +162 -0
- package/dist/adapters/capacitor/PreferencesAdapter.d.ts +46 -0
- package/dist/adapters/capacitor/PreferencesAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/PreferencesAdapter.js +162 -0
- package/dist/adapters/capacitor/SecureAdapter.d.ts +69 -0
- package/dist/adapters/capacitor/SecureAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/SecureAdapter.js +214 -0
- package/dist/adapters/capacitor/SqliteAdapter.d.ts +68 -0
- package/dist/adapters/capacitor/SqliteAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/SqliteAdapter.js +277 -0
- package/dist/adapters/capacitor/index.d.ts +9 -0
- package/dist/adapters/capacitor/index.d.ts.map +1 -0
- package/dist/adapters/capacitor/index.js +8 -0
- package/dist/adapters/web/CacheAdapter.d.ts +91 -0
- package/dist/adapters/web/CacheAdapter.d.ts.map +1 -0
- package/dist/adapters/web/CacheAdapter.js +291 -0
- package/dist/adapters/web/CookieAdapter.d.ts +77 -0
- package/dist/adapters/web/CookieAdapter.d.ts.map +1 -0
- package/dist/adapters/web/CookieAdapter.js +260 -0
- package/dist/adapters/web/IndexedDBAdapter.d.ts +78 -0
- package/dist/adapters/web/IndexedDBAdapter.d.ts.map +1 -0
- package/dist/adapters/web/IndexedDBAdapter.js +371 -0
- package/dist/adapters/web/LocalStorageAdapter.d.ts +63 -0
- package/dist/adapters/web/LocalStorageAdapter.d.ts.map +1 -0
- package/dist/adapters/web/LocalStorageAdapter.js +238 -0
- package/dist/adapters/web/MemoryAdapter.d.ts +69 -0
- package/dist/adapters/web/MemoryAdapter.d.ts.map +1 -0
- package/dist/adapters/web/MemoryAdapter.js +165 -0
- package/dist/adapters/web/SessionStorageAdapter.d.ts +53 -0
- package/dist/adapters/web/SessionStorageAdapter.d.ts.map +1 -0
- package/dist/adapters/web/SessionStorageAdapter.js +180 -0
- package/dist/adapters/web/index.d.ts +10 -0
- package/dist/adapters/web/index.d.ts.map +1 -0
- package/dist/adapters/web/index.js +9 -0
- package/dist/core/AdapterRegistry.d.ts +52 -0
- package/dist/core/AdapterRegistry.d.ts.map +1 -0
- package/dist/core/AdapterRegistry.js +102 -0
- package/dist/core/BaseAdapter.d.ts +79 -0
- package/dist/core/BaseAdapter.d.ts.map +1 -0
- package/dist/core/BaseAdapter.js +197 -0
- package/dist/core/StorageStrategy.d.ts +55 -0
- package/dist/core/StorageStrategy.d.ts.map +1 -0
- package/dist/core/StorageStrategy.js +199 -0
- package/dist/core/Strata.d.ts +122 -0
- package/dist/core/Strata.d.ts.map +1 -0
- package/dist/core/Strata.js +568 -0
- package/dist/features/compression.d.ts +65 -0
- package/dist/features/compression.d.ts.map +1 -0
- package/dist/features/compression.js +205 -0
- package/dist/features/encryption.d.ts +68 -0
- package/dist/features/encryption.d.ts.map +1 -0
- package/dist/features/encryption.js +172 -0
- package/dist/features/migration.d.ts +17 -0
- package/dist/features/migration.d.ts.map +1 -0
- package/dist/features/migration.js +43 -0
- package/dist/features/query.d.ts +75 -0
- package/dist/features/query.d.ts.map +1 -0
- package/dist/features/query.js +305 -0
- package/dist/features/sync.d.ts +87 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +233 -0
- package/dist/features/ttl.d.ts +124 -0
- package/dist/features/ttl.d.ts.map +1 -0
- package/dist/features/ttl.js +236 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/package.json +60 -0
- package/dist/plugin/definitions.d.ts +219 -0
- package/dist/plugin/definitions.d.ts.map +1 -0
- package/dist/plugin/definitions.js +5 -0
- package/dist/plugin/index.d.ts +8 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +27 -0
- package/dist/plugin/web.d.ts +24 -0
- package/dist/plugin/web.d.ts.map +1 -0
- package/dist/plugin/web.js +35 -0
- package/dist/types/index.d.ts +558 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/utils/errors.d.ts +92 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +153 -0
- package/dist/utils/index.d.ts +105 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +329 -0
- package/ios/Plugin/KeychainStorage.swift +87 -0
- package/ios/Plugin/SQLiteStorage.swift +167 -0
- package/ios/Plugin/StrataStoragePlugin.swift +204 -0
- package/ios/Plugin/UserDefaultsStorage.swift +44 -0
- package/package.json +126 -0
- package/scripts/build.js +52 -0
- package/scripts/cli.js +60 -0
- package/scripts/configure.js +444 -0
- package/scripts/postinstall.js +33 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem Adapter - Native file system storage
|
|
3
|
+
* Direct file access on iOS and Android
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import { StrataStorage } from '@/plugin';
|
|
7
|
+
import { StorageError } from '@/utils/errors';
|
|
8
|
+
import { isCapacitor } from '@/utils';
|
|
9
|
+
/**
|
|
10
|
+
* Native filesystem adapter using Capacitor plugin
|
|
11
|
+
*/
|
|
12
|
+
export class FilesystemAdapter extends BaseAdapter {
|
|
13
|
+
name = 'filesystem';
|
|
14
|
+
capabilities = {
|
|
15
|
+
persistent: true,
|
|
16
|
+
synchronous: false,
|
|
17
|
+
observable: false,
|
|
18
|
+
transactional: false,
|
|
19
|
+
queryable: true,
|
|
20
|
+
maxSize: -1, // Limited by device storage
|
|
21
|
+
binary: true, // Supports binary files
|
|
22
|
+
encrypted: false,
|
|
23
|
+
crossTab: true,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Check if filesystem is available
|
|
27
|
+
*/
|
|
28
|
+
async isAvailable() {
|
|
29
|
+
if (!isCapacitor())
|
|
30
|
+
return false;
|
|
31
|
+
try {
|
|
32
|
+
const result = await StrataStorage.isAvailable({ storage: 'filesystem' });
|
|
33
|
+
return result.available;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the adapter
|
|
41
|
+
*/
|
|
42
|
+
async initialize() {
|
|
43
|
+
this.startTTLCleanup();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a value from filesystem
|
|
47
|
+
*/
|
|
48
|
+
async get(key) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await StrataStorage.get({
|
|
51
|
+
key,
|
|
52
|
+
storage: 'filesystem',
|
|
53
|
+
});
|
|
54
|
+
if (!result.value)
|
|
55
|
+
return null;
|
|
56
|
+
const value = result.value;
|
|
57
|
+
// Check TTL
|
|
58
|
+
if (this.isExpired(value)) {
|
|
59
|
+
await this.remove(key);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error(`Failed to get key ${key} from filesystem:`, error);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set a value in filesystem
|
|
71
|
+
*/
|
|
72
|
+
async set(key, value) {
|
|
73
|
+
const oldValue = await this.get(key);
|
|
74
|
+
try {
|
|
75
|
+
await StrataStorage.set({
|
|
76
|
+
key,
|
|
77
|
+
value,
|
|
78
|
+
storage: 'filesystem',
|
|
79
|
+
});
|
|
80
|
+
this.emitChange(key, oldValue?.value, value.value, 'local');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new StorageError(`Failed to set key ${key} in filesystem: ${error}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Remove a value from filesystem
|
|
88
|
+
*/
|
|
89
|
+
async remove(key) {
|
|
90
|
+
const oldValue = await this.get(key);
|
|
91
|
+
try {
|
|
92
|
+
await StrataStorage.remove({
|
|
93
|
+
key,
|
|
94
|
+
storage: 'filesystem',
|
|
95
|
+
});
|
|
96
|
+
if (oldValue) {
|
|
97
|
+
this.emitChange(key, oldValue.value, undefined, 'local');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new StorageError(`Failed to remove key ${key} from filesystem: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Clear filesystem storage
|
|
106
|
+
*/
|
|
107
|
+
async clear(options) {
|
|
108
|
+
if (!options || (!options.pattern && !options.tags && !options.expiredOnly)) {
|
|
109
|
+
try {
|
|
110
|
+
await StrataStorage.clear({
|
|
111
|
+
storage: 'filesystem',
|
|
112
|
+
});
|
|
113
|
+
this.emitChange('*', undefined, undefined, 'local');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throw new StorageError(`Failed to clear filesystem: ${error}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Use base implementation for filtered clear
|
|
121
|
+
await super.clear(options);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all keys
|
|
125
|
+
*/
|
|
126
|
+
async keys(pattern) {
|
|
127
|
+
try {
|
|
128
|
+
const result = await StrataStorage.keys({
|
|
129
|
+
storage: 'filesystem',
|
|
130
|
+
pattern: pattern instanceof RegExp ? pattern.source : pattern,
|
|
131
|
+
});
|
|
132
|
+
const keys = result.keys;
|
|
133
|
+
// Check for expired keys
|
|
134
|
+
const validKeys = [];
|
|
135
|
+
for (const key of keys) {
|
|
136
|
+
const value = await this.get(key);
|
|
137
|
+
if (value) {
|
|
138
|
+
validKeys.push(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return this.filterKeys(validKeys, pattern);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new StorageError(`Failed to get keys from filesystem: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get storage size
|
|
149
|
+
*/
|
|
150
|
+
async size(detailed) {
|
|
151
|
+
try {
|
|
152
|
+
const result = await StrataStorage.size({
|
|
153
|
+
storage: 'filesystem',
|
|
154
|
+
detailed,
|
|
155
|
+
});
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new StorageError(`Failed to get size of filesystem: ${error}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preferences Adapter - Native preferences storage
|
|
3
|
+
* iOS: UserDefaults, Android: SharedPreferences
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import type { StorageType, StorageCapabilities, StorageValue, ClearOptions, SizeInfo } from '@/types';
|
|
7
|
+
/**
|
|
8
|
+
* Native preferences adapter using Capacitor plugin
|
|
9
|
+
*/
|
|
10
|
+
export declare class PreferencesAdapter extends BaseAdapter {
|
|
11
|
+
readonly name: StorageType;
|
|
12
|
+
readonly capabilities: StorageCapabilities;
|
|
13
|
+
/**
|
|
14
|
+
* Check if preferences are available
|
|
15
|
+
*/
|
|
16
|
+
isAvailable(): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the adapter
|
|
19
|
+
*/
|
|
20
|
+
initialize(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get a value from preferences
|
|
23
|
+
*/
|
|
24
|
+
get<T = unknown>(key: string): Promise<StorageValue<T> | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Set a value in preferences
|
|
27
|
+
*/
|
|
28
|
+
set<T = unknown>(key: string, value: StorageValue<T>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove a value from preferences
|
|
31
|
+
*/
|
|
32
|
+
remove(key: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear preferences
|
|
35
|
+
*/
|
|
36
|
+
clear(options?: ClearOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get all keys
|
|
39
|
+
*/
|
|
40
|
+
keys(pattern?: string | RegExp): Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Get storage size
|
|
43
|
+
*/
|
|
44
|
+
size(detailed?: boolean): Promise<SizeInfo>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=PreferencesAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreferencesAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/capacitor/PreferencesAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAKjB;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAiB;IAC3C,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAUxC;IAEF;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAWrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAwBpE;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1E;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxC;;OAEG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD;;OAEG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBxD;;OAEG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAYlD"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preferences Adapter - Native preferences storage
|
|
3
|
+
* iOS: UserDefaults, Android: SharedPreferences
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import { StrataStorage } from '@/plugin';
|
|
7
|
+
import { StorageError } from '@/utils/errors';
|
|
8
|
+
import { isCapacitor } from '@/utils';
|
|
9
|
+
/**
|
|
10
|
+
* Native preferences adapter using Capacitor plugin
|
|
11
|
+
*/
|
|
12
|
+
export class PreferencesAdapter extends BaseAdapter {
|
|
13
|
+
name = 'preferences';
|
|
14
|
+
capabilities = {
|
|
15
|
+
persistent: true,
|
|
16
|
+
synchronous: false,
|
|
17
|
+
observable: false, // No native change events
|
|
18
|
+
transactional: false,
|
|
19
|
+
queryable: true,
|
|
20
|
+
maxSize: -1, // Platform dependent
|
|
21
|
+
binary: false, // Only JSON-serializable data
|
|
22
|
+
encrypted: false,
|
|
23
|
+
crossTab: true, // Shared across app
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Check if preferences are available
|
|
27
|
+
*/
|
|
28
|
+
async isAvailable() {
|
|
29
|
+
if (!isCapacitor())
|
|
30
|
+
return false;
|
|
31
|
+
try {
|
|
32
|
+
const result = await StrataStorage.isAvailable({ storage: 'preferences' });
|
|
33
|
+
return result.available;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the adapter
|
|
41
|
+
*/
|
|
42
|
+
async initialize() {
|
|
43
|
+
this.startTTLCleanup();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a value from preferences
|
|
47
|
+
*/
|
|
48
|
+
async get(key) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await StrataStorage.get({
|
|
51
|
+
key,
|
|
52
|
+
storage: 'preferences',
|
|
53
|
+
});
|
|
54
|
+
if (!result.value)
|
|
55
|
+
return null;
|
|
56
|
+
const value = result.value;
|
|
57
|
+
// Check TTL
|
|
58
|
+
if (this.isExpired(value)) {
|
|
59
|
+
await this.remove(key);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error(`Failed to get key ${key} from preferences:`, error);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set a value in preferences
|
|
71
|
+
*/
|
|
72
|
+
async set(key, value) {
|
|
73
|
+
const oldValue = await this.get(key);
|
|
74
|
+
try {
|
|
75
|
+
await StrataStorage.set({
|
|
76
|
+
key,
|
|
77
|
+
value,
|
|
78
|
+
storage: 'preferences',
|
|
79
|
+
});
|
|
80
|
+
this.emitChange(key, oldValue?.value, value.value, 'local');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new StorageError(`Failed to set key ${key} in preferences: ${error}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Remove a value from preferences
|
|
88
|
+
*/
|
|
89
|
+
async remove(key) {
|
|
90
|
+
const oldValue = await this.get(key);
|
|
91
|
+
try {
|
|
92
|
+
await StrataStorage.remove({
|
|
93
|
+
key,
|
|
94
|
+
storage: 'preferences',
|
|
95
|
+
});
|
|
96
|
+
if (oldValue) {
|
|
97
|
+
this.emitChange(key, oldValue.value, undefined, 'local');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new StorageError(`Failed to remove key ${key} from preferences: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Clear preferences
|
|
106
|
+
*/
|
|
107
|
+
async clear(options) {
|
|
108
|
+
if (!options || (!options.pattern && !options.tags && !options.expiredOnly)) {
|
|
109
|
+
try {
|
|
110
|
+
await StrataStorage.clear({
|
|
111
|
+
storage: 'preferences',
|
|
112
|
+
});
|
|
113
|
+
this.emitChange('*', undefined, undefined, 'local');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throw new StorageError(`Failed to clear preferences: ${error}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Use base implementation for filtered clear
|
|
121
|
+
await super.clear(options);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all keys
|
|
125
|
+
*/
|
|
126
|
+
async keys(pattern) {
|
|
127
|
+
try {
|
|
128
|
+
const result = await StrataStorage.keys({
|
|
129
|
+
storage: 'preferences',
|
|
130
|
+
pattern: pattern instanceof RegExp ? pattern.source : pattern,
|
|
131
|
+
});
|
|
132
|
+
const keys = result.keys;
|
|
133
|
+
// Check for expired keys
|
|
134
|
+
const validKeys = [];
|
|
135
|
+
for (const key of keys) {
|
|
136
|
+
const value = await this.get(key);
|
|
137
|
+
if (value) {
|
|
138
|
+
validKeys.push(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return this.filterKeys(validKeys, pattern);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new StorageError(`Failed to get keys from preferences: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get storage size
|
|
149
|
+
*/
|
|
150
|
+
async size(detailed) {
|
|
151
|
+
try {
|
|
152
|
+
const result = await StrataStorage.size({
|
|
153
|
+
storage: 'preferences',
|
|
154
|
+
detailed,
|
|
155
|
+
});
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new StorageError(`Failed to get size of preferences: ${error}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Adapter - Native secure storage
|
|
3
|
+
* iOS: Keychain, Android: EncryptedSharedPreferences
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import type { StorageType, StorageCapabilities, StorageValue, ClearOptions, SizeInfo } from '@/types';
|
|
7
|
+
/**
|
|
8
|
+
* Native secure storage adapter using Capacitor plugin
|
|
9
|
+
*/
|
|
10
|
+
export declare class SecureAdapter extends BaseAdapter {
|
|
11
|
+
readonly name: StorageType;
|
|
12
|
+
readonly capabilities: StorageCapabilities;
|
|
13
|
+
/**
|
|
14
|
+
* Check if secure storage is available
|
|
15
|
+
*/
|
|
16
|
+
isAvailable(): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the adapter
|
|
19
|
+
*/
|
|
20
|
+
initialize(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get a value from secure storage
|
|
23
|
+
*/
|
|
24
|
+
get<T = unknown>(key: string): Promise<StorageValue<T> | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Set a value in secure storage
|
|
27
|
+
*/
|
|
28
|
+
set<T = unknown>(key: string, value: StorageValue<T>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove a value from secure storage
|
|
31
|
+
*/
|
|
32
|
+
remove(key: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear secure storage
|
|
35
|
+
*/
|
|
36
|
+
clear(options?: ClearOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get all keys
|
|
39
|
+
*/
|
|
40
|
+
keys(pattern?: string | RegExp): Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Get storage size
|
|
43
|
+
*/
|
|
44
|
+
size(detailed?: boolean): Promise<SizeInfo>;
|
|
45
|
+
/**
|
|
46
|
+
* iOS-specific: Store in Keychain with options
|
|
47
|
+
*/
|
|
48
|
+
setKeychainItem(key: string, value: string, options?: {
|
|
49
|
+
service?: string;
|
|
50
|
+
accessGroup?: string;
|
|
51
|
+
accessible?: import('@/plugin/definitions').KeychainAccessible;
|
|
52
|
+
}): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* iOS-specific: Get from Keychain
|
|
55
|
+
*/
|
|
56
|
+
getKeychainItem(key: string, options?: {
|
|
57
|
+
service?: string;
|
|
58
|
+
accessGroup?: string;
|
|
59
|
+
}): Promise<string | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Android-specific: Store encrypted preference
|
|
62
|
+
*/
|
|
63
|
+
setEncryptedPreference(key: string, value: unknown, fileName?: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Android-specific: Get encrypted preference
|
|
66
|
+
*/
|
|
67
|
+
getEncryptedPreference(key: string, fileName?: string): Promise<unknown>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=SecureAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecureAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/capacitor/SecureAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAKjB;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAY;IACtC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAUxC;IAEF;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAWrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAwBpE;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1E;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxC;;OAEG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD;;OAEG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBxD;;OAEG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAajD;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,sBAAsB,EAAE,kBAAkB,CAAC;KAChE,GACA,OAAO,CAAC,IAAI,CAAC;IAYhB;;OAEG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAazB;;OAEG;IACG,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3F;;OAEG;IACG,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAY/E"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Adapter - Native secure storage
|
|
3
|
+
* iOS: Keychain, Android: EncryptedSharedPreferences
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import { StrataStorage } from '@/plugin';
|
|
7
|
+
import { StorageError } from '@/utils/errors';
|
|
8
|
+
import { isCapacitor } from '@/utils';
|
|
9
|
+
/**
|
|
10
|
+
* Native secure storage adapter using Capacitor plugin
|
|
11
|
+
*/
|
|
12
|
+
export class SecureAdapter extends BaseAdapter {
|
|
13
|
+
name = 'secure';
|
|
14
|
+
capabilities = {
|
|
15
|
+
persistent: true,
|
|
16
|
+
synchronous: false,
|
|
17
|
+
observable: false,
|
|
18
|
+
transactional: false,
|
|
19
|
+
queryable: true,
|
|
20
|
+
maxSize: -1, // Platform dependent
|
|
21
|
+
binary: false, // String data only
|
|
22
|
+
encrypted: true, // Native encryption
|
|
23
|
+
crossTab: true,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Check if secure storage is available
|
|
27
|
+
*/
|
|
28
|
+
async isAvailable() {
|
|
29
|
+
if (!isCapacitor())
|
|
30
|
+
return false;
|
|
31
|
+
try {
|
|
32
|
+
const result = await StrataStorage.isAvailable({ storage: 'secure' });
|
|
33
|
+
return result.available;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the adapter
|
|
41
|
+
*/
|
|
42
|
+
async initialize() {
|
|
43
|
+
this.startTTLCleanup();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a value from secure storage
|
|
47
|
+
*/
|
|
48
|
+
async get(key) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await StrataStorage.get({
|
|
51
|
+
key,
|
|
52
|
+
storage: 'secure',
|
|
53
|
+
});
|
|
54
|
+
if (!result.value)
|
|
55
|
+
return null;
|
|
56
|
+
const value = result.value;
|
|
57
|
+
// Check TTL
|
|
58
|
+
if (this.isExpired(value)) {
|
|
59
|
+
await this.remove(key);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error(`Failed to get key ${key} from secure storage:`, error);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set a value in secure storage
|
|
71
|
+
*/
|
|
72
|
+
async set(key, value) {
|
|
73
|
+
const oldValue = await this.get(key);
|
|
74
|
+
try {
|
|
75
|
+
await StrataStorage.set({
|
|
76
|
+
key,
|
|
77
|
+
value,
|
|
78
|
+
storage: 'secure',
|
|
79
|
+
});
|
|
80
|
+
this.emitChange(key, oldValue?.value, value.value, 'local');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new StorageError(`Failed to set key ${key} in secure storage: ${error}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Remove a value from secure storage
|
|
88
|
+
*/
|
|
89
|
+
async remove(key) {
|
|
90
|
+
const oldValue = await this.get(key);
|
|
91
|
+
try {
|
|
92
|
+
await StrataStorage.remove({
|
|
93
|
+
key,
|
|
94
|
+
storage: 'secure',
|
|
95
|
+
});
|
|
96
|
+
if (oldValue) {
|
|
97
|
+
this.emitChange(key, oldValue.value, undefined, 'local');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new StorageError(`Failed to remove key ${key} from secure storage: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Clear secure storage
|
|
106
|
+
*/
|
|
107
|
+
async clear(options) {
|
|
108
|
+
if (!options || (!options.pattern && !options.tags && !options.expiredOnly)) {
|
|
109
|
+
try {
|
|
110
|
+
await StrataStorage.clear({
|
|
111
|
+
storage: 'secure',
|
|
112
|
+
});
|
|
113
|
+
this.emitChange('*', undefined, undefined, 'local');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throw new StorageError(`Failed to clear secure storage: ${error}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Use base implementation for filtered clear
|
|
121
|
+
await super.clear(options);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all keys
|
|
125
|
+
*/
|
|
126
|
+
async keys(pattern) {
|
|
127
|
+
try {
|
|
128
|
+
const result = await StrataStorage.keys({
|
|
129
|
+
storage: 'secure',
|
|
130
|
+
pattern: pattern instanceof RegExp ? pattern.source : pattern,
|
|
131
|
+
});
|
|
132
|
+
const keys = result.keys;
|
|
133
|
+
// Check for expired keys
|
|
134
|
+
const validKeys = [];
|
|
135
|
+
for (const key of keys) {
|
|
136
|
+
const value = await this.get(key);
|
|
137
|
+
if (value) {
|
|
138
|
+
validKeys.push(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return this.filterKeys(validKeys, pattern);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new StorageError(`Failed to get keys from secure storage: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get storage size
|
|
149
|
+
*/
|
|
150
|
+
async size(detailed) {
|
|
151
|
+
try {
|
|
152
|
+
const result = await StrataStorage.size({
|
|
153
|
+
storage: 'secure',
|
|
154
|
+
detailed,
|
|
155
|
+
});
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new StorageError(`Failed to get size of secure storage: ${error}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* iOS-specific: Store in Keychain with options
|
|
164
|
+
*/
|
|
165
|
+
async setKeychainItem(key, value, options) {
|
|
166
|
+
if (!StrataStorage.setKeychain) {
|
|
167
|
+
throw new StorageError('Keychain not available on this platform');
|
|
168
|
+
}
|
|
169
|
+
await StrataStorage.setKeychain({
|
|
170
|
+
key,
|
|
171
|
+
value,
|
|
172
|
+
...options,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* iOS-specific: Get from Keychain
|
|
177
|
+
*/
|
|
178
|
+
async getKeychainItem(key, options) {
|
|
179
|
+
if (!StrataStorage.getKeychain) {
|
|
180
|
+
throw new StorageError('Keychain not available on this platform');
|
|
181
|
+
}
|
|
182
|
+
const result = await StrataStorage.getKeychain({
|
|
183
|
+
key,
|
|
184
|
+
...options,
|
|
185
|
+
});
|
|
186
|
+
return result.value;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Android-specific: Store encrypted preference
|
|
190
|
+
*/
|
|
191
|
+
async setEncryptedPreference(key, value, fileName) {
|
|
192
|
+
if (!StrataStorage.setEncryptedPreference) {
|
|
193
|
+
throw new StorageError('Encrypted preferences not available on this platform');
|
|
194
|
+
}
|
|
195
|
+
await StrataStorage.setEncryptedPreference({
|
|
196
|
+
key,
|
|
197
|
+
value,
|
|
198
|
+
fileName,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Android-specific: Get encrypted preference
|
|
203
|
+
*/
|
|
204
|
+
async getEncryptedPreference(key, fileName) {
|
|
205
|
+
if (!StrataStorage.getEncryptedPreference) {
|
|
206
|
+
throw new StorageError('Encrypted preferences not available on this platform');
|
|
207
|
+
}
|
|
208
|
+
const result = await StrataStorage.getEncryptedPreference({
|
|
209
|
+
key,
|
|
210
|
+
fileName,
|
|
211
|
+
});
|
|
212
|
+
return result.value;
|
|
213
|
+
}
|
|
214
|
+
}
|