@ojolowoblue/lamba 1.0.5 → 1.0.6
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 +58 -4
- package/dist/index.d.mts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +114 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -17
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/react.js +108 -17
- package/dist/integrations/react.js.map +1 -1
- package/dist/integrations/react.mjs +108 -17
- package/dist/integrations/react.mjs.map +1 -1
- package/dist/integrations/vue.js +108 -17
- package/dist/integrations/vue.js.map +1 -1
- package/dist/integrations/vue.mjs +108 -17
- package/dist/integrations/vue.mjs.map +1 -1
- package/dist/lamba.min.js +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ const isNewHeader = useLambaEnv<boolean>('VITE_NEW_HEADER', false);
|
|
|
167
167
|
|
|
168
168
|
### `lamba.init(options?: LambaOptions): LambaManager`
|
|
169
169
|
|
|
170
|
-
Initializes the lamba manager, hydrates saved overrides from
|
|
170
|
+
Initializes the lamba manager, hydrates saved overrides from the configured storage backend, enables network interceptors, and mounts the floating Shadow DOM UI.
|
|
171
171
|
|
|
172
172
|
| Option | Type | Default | Description |
|
|
173
173
|
| :--- | :--- | :--- | :--- |
|
|
@@ -178,6 +178,8 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
|
|
|
178
178
|
| `autoFetchEnvFile` | `boolean` | `false` | Whether to attempt fetching root `/.env` file during local development. |
|
|
179
179
|
| `interceptNetworkRequests` | `boolean` | `true` | Whether to implicitly intercept `fetch` & `XHR` calls matching original base URLs. |
|
|
180
180
|
| `allowedPrefixes` | `string \| string[] \| RegExp \| null` | `null` | Optional prefix filter (e.g. `['VITE_', 'NEXT_PUBLIC_']`). Omitting allows ALL keys regardless of prefix. |
|
|
181
|
+
| `storageStrategy` | `'local' \| 'session' \| 'memory'` | `'local'` | Where overrides and presets are persisted. See [Storage Strategies](#-storage-strategies) below. |
|
|
182
|
+
| `storage` | `LambaStorageAdapter` | `undefined` | Provide a fully custom storage adapter. Takes precedence over `storageStrategy`. |
|
|
181
183
|
|
|
182
184
|
---
|
|
183
185
|
|
|
@@ -187,7 +189,7 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
|
|
|
187
189
|
Returns the active value for the specified environment key (returns active override if present, otherwise default value or fallback). Preserves numbers, booleans, and objects.
|
|
188
190
|
|
|
189
191
|
#### `lamba.set(key: string, value: any): void`
|
|
190
|
-
Programmatically overrides an environment variable live at runtime with any data type. The change is persisted in
|
|
192
|
+
Programmatically overrides an environment variable live at runtime with any data type. The change is persisted in the configured storage backend and triggers UI and listener updates.
|
|
191
193
|
|
|
192
194
|
#### `lamba.remove(key: string): void`
|
|
193
195
|
Removes an override for a specific environment variable key, reverting it to its default value.
|
|
@@ -212,6 +214,57 @@ Programmatically controls the visibility of the lamba modal panel.
|
|
|
212
214
|
|
|
213
215
|
---
|
|
214
216
|
|
|
217
|
+
## 🔐 Storage Strategies
|
|
218
|
+
|
|
219
|
+
Control where lamba persists overrides and presets via the `storageStrategy` option:
|
|
220
|
+
|
|
221
|
+
| Strategy | Visibility in DevTools | Survives Tab Close? | XSS Storage Scraping Risk |
|
|
222
|
+
| :--- | :--- | :--- | :--- |
|
|
223
|
+
| `'local'` *(default)* | ⚠️ Visible (plain-text) | ✅ Yes (Indefinitely) | ⚠️ Yes |
|
|
224
|
+
| `'session'` | ⚠️ Visible (plain-text) | ❌ No (Cleared on close) | ⚠️ Yes |
|
|
225
|
+
| `'memory'` | ✅ **Not visible (0 bytes stored)** | ❌ No (GC'd on close) | ✅ **No** |
|
|
226
|
+
|
|
227
|
+
### In-Memory (Most Secure)
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
lamba.init({
|
|
231
|
+
storageStrategy: 'memory', // Nothing written to DevTools Storage
|
|
232
|
+
env: { VITE_API_URL: import.meta.env.VITE_API_URL },
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Session (Tab-Ephemeral)
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
lamba.init({
|
|
240
|
+
storageStrategy: 'session', // Cleared automatically when tab closes
|
|
241
|
+
env: { VITE_API_URL: import.meta.env.VITE_API_URL },
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Custom Adapter
|
|
246
|
+
|
|
247
|
+
Implement the `LambaStorageAdapter` interface to plug in any storage backend (encrypted storage, Electron keytar, IndexedDB, etc.):
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import lamba, { type LambaStorageAdapter } from '@ojolowoblue/lamba';
|
|
251
|
+
|
|
252
|
+
// Example: an encrypted wrapper around sessionStorage
|
|
253
|
+
const encryptedAdapter: LambaStorageAdapter = {
|
|
254
|
+
getItem: (key) => decrypt(sessionStorage.getItem(key)),
|
|
255
|
+
setItem: (key, value) => sessionStorage.setItem(key, encrypt(value)),
|
|
256
|
+
removeItem: (key) => sessionStorage.removeItem(key),
|
|
257
|
+
clear: () => sessionStorage.clear(),
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
lamba.init({
|
|
261
|
+
storage: encryptedAdapter,
|
|
262
|
+
env: { VITE_API_URL: import.meta.env.VITE_API_URL },
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
215
268
|
## 🔒 Production Security Best Practice
|
|
216
269
|
|
|
217
270
|
To prevent end-users from overriding environment variables in production, conditionally initialize `lamba` only in non-production environments:
|
|
@@ -221,6 +274,7 @@ import lamba from '@ojolowoblue/lamba';
|
|
|
221
274
|
|
|
222
275
|
lamba.init({
|
|
223
276
|
enabled: process.env.NODE_ENV !== 'production',
|
|
277
|
+
storageStrategy: 'memory', // Use memory storage so nothing lingers in DevTools
|
|
224
278
|
env: {
|
|
225
279
|
VITE_API_URL: import.meta.env.VITE_API_URL,
|
|
226
280
|
},
|
|
@@ -233,12 +287,12 @@ lamba.init({
|
|
|
233
287
|
|
|
234
288
|
<details>
|
|
235
289
|
<summary><b>Does lamba modify my local <code>.env</code> files on disk?</b></summary>
|
|
236
|
-
<p>No. <code>lamba</code> operates entirely in browser memory and persists overrides in
|
|
290
|
+
<p>No. <code>lamba</code> operates entirely in browser memory and optionally persists overrides in storage. It does not write to disk, so your git status remains clean.</p>
|
|
237
291
|
</details>
|
|
238
292
|
|
|
239
293
|
<details>
|
|
240
294
|
<summary><b>Do overrides persist when I refresh the page?</b></summary>
|
|
241
|
-
<p>
|
|
295
|
+
<p>It depends on the <code>storageStrategy</code>. With <code>'local'</code> (default), overrides persist indefinitely. With <code>'session'</code>, they survive reloads but clear when the tab is closed. With <code>'memory'</code>, overrides are lost on any page reload.</p>
|
|
242
296
|
</details>
|
|
243
297
|
|
|
244
298
|
<details>
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract interface for pluggable storage backends used by lamba to persist
|
|
3
|
+
* overrides and presets. All methods are synchronous for simplicity (async
|
|
4
|
+
* adapters can wrap with Promises if needed in custom implementations).
|
|
5
|
+
*/
|
|
6
|
+
interface LambaStorageAdapter {
|
|
7
|
+
getItem(key: string): string | null;
|
|
8
|
+
setItem(key: string, value: string): void;
|
|
9
|
+
removeItem(key: string): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* LocalStorage-backed adapter (default).
|
|
14
|
+
* Overrides persist indefinitely across tabs and page reloads.
|
|
15
|
+
* Visible in DevTools → Application → Local Storage.
|
|
16
|
+
*/
|
|
17
|
+
declare class LocalStorageAdapter implements LambaStorageAdapter {
|
|
18
|
+
getItem(key: string): string | null;
|
|
19
|
+
setItem(key: string, value: string): void;
|
|
20
|
+
removeItem(key: string): void;
|
|
21
|
+
clear(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* SessionStorage-backed adapter.
|
|
25
|
+
* Overrides survive page reloads within the same tab, but are automatically
|
|
26
|
+
* destroyed when the tab is closed. Still visible in DevTools Storage panel.
|
|
27
|
+
*/
|
|
28
|
+
declare class SessionStorageAdapter implements LambaStorageAdapter {
|
|
29
|
+
getItem(key: string): string | null;
|
|
30
|
+
setItem(key: string, value: string): void;
|
|
31
|
+
removeItem(key: string): void;
|
|
32
|
+
clear(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* In-memory adapter.
|
|
36
|
+
* The most secure option: zero bytes written to any browser storage mechanism.
|
|
37
|
+
* Overrides exist only in JavaScript heap memory and are destroyed when the
|
|
38
|
+
* tab/page is closed or navigated away. Nothing appears in DevTools Storage.
|
|
39
|
+
*/
|
|
40
|
+
declare class MemoryStorageAdapter implements LambaStorageAdapter {
|
|
41
|
+
private store;
|
|
42
|
+
getItem(key: string): string | null;
|
|
43
|
+
setItem(key: string, value: string): void;
|
|
44
|
+
removeItem(key: string): void;
|
|
45
|
+
clear(): void;
|
|
46
|
+
}
|
|
47
|
+
|
|
1
48
|
interface EnvVariable {
|
|
2
49
|
key: string;
|
|
3
50
|
value: any;
|
|
@@ -46,6 +93,22 @@ interface LambaOptions {
|
|
|
46
93
|
* If omitted, null, or empty, ALL environment variable keys are allowed and supported regardless of prefix.
|
|
47
94
|
*/
|
|
48
95
|
allowedPrefixes?: string | string[] | RegExp | null;
|
|
96
|
+
/**
|
|
97
|
+
* Storage strategy for persisting overrides and presets across page reloads:
|
|
98
|
+
* - `'local'` — (default) Standard `localStorage`. Persists indefinitely across tabs & reloads.
|
|
99
|
+
* Visible in DevTools → Application → Local Storage.
|
|
100
|
+
* - `'session'` — `sessionStorage`. Survives page reloads within the same tab, but cleared
|
|
101
|
+
* when the tab is closed. Visible in DevTools → Application → Session Storage.
|
|
102
|
+
* - `'memory'` — In-memory only. Most secure option — zero bytes written to any browser storage.
|
|
103
|
+
* Overrides are destroyed when the tab closes or navigates away.
|
|
104
|
+
* Nothing appears in DevTools Storage.
|
|
105
|
+
*/
|
|
106
|
+
storageStrategy?: 'local' | 'session' | 'memory';
|
|
107
|
+
/**
|
|
108
|
+
* Provide a fully custom storage adapter that conforms to the `LambaStorageAdapter` interface.
|
|
109
|
+
* When provided, this takes precedence over `storageStrategy`.
|
|
110
|
+
*/
|
|
111
|
+
storage?: LambaStorageAdapter;
|
|
49
112
|
}
|
|
50
113
|
type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
|
|
51
114
|
type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
|
|
@@ -116,4 +179,4 @@ declare class LambaManager {
|
|
|
116
179
|
}
|
|
117
180
|
declare const lamba: LambaManager;
|
|
118
181
|
|
|
119
|
-
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
|
182
|
+
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type LambaStorageAdapter, LocalStorageAdapter, MemoryStorageAdapter, type PresetProfile, SessionStorageAdapter, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract interface for pluggable storage backends used by lamba to persist
|
|
3
|
+
* overrides and presets. All methods are synchronous for simplicity (async
|
|
4
|
+
* adapters can wrap with Promises if needed in custom implementations).
|
|
5
|
+
*/
|
|
6
|
+
interface LambaStorageAdapter {
|
|
7
|
+
getItem(key: string): string | null;
|
|
8
|
+
setItem(key: string, value: string): void;
|
|
9
|
+
removeItem(key: string): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* LocalStorage-backed adapter (default).
|
|
14
|
+
* Overrides persist indefinitely across tabs and page reloads.
|
|
15
|
+
* Visible in DevTools → Application → Local Storage.
|
|
16
|
+
*/
|
|
17
|
+
declare class LocalStorageAdapter implements LambaStorageAdapter {
|
|
18
|
+
getItem(key: string): string | null;
|
|
19
|
+
setItem(key: string, value: string): void;
|
|
20
|
+
removeItem(key: string): void;
|
|
21
|
+
clear(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* SessionStorage-backed adapter.
|
|
25
|
+
* Overrides survive page reloads within the same tab, but are automatically
|
|
26
|
+
* destroyed when the tab is closed. Still visible in DevTools Storage panel.
|
|
27
|
+
*/
|
|
28
|
+
declare class SessionStorageAdapter implements LambaStorageAdapter {
|
|
29
|
+
getItem(key: string): string | null;
|
|
30
|
+
setItem(key: string, value: string): void;
|
|
31
|
+
removeItem(key: string): void;
|
|
32
|
+
clear(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* In-memory adapter.
|
|
36
|
+
* The most secure option: zero bytes written to any browser storage mechanism.
|
|
37
|
+
* Overrides exist only in JavaScript heap memory and are destroyed when the
|
|
38
|
+
* tab/page is closed or navigated away. Nothing appears in DevTools Storage.
|
|
39
|
+
*/
|
|
40
|
+
declare class MemoryStorageAdapter implements LambaStorageAdapter {
|
|
41
|
+
private store;
|
|
42
|
+
getItem(key: string): string | null;
|
|
43
|
+
setItem(key: string, value: string): void;
|
|
44
|
+
removeItem(key: string): void;
|
|
45
|
+
clear(): void;
|
|
46
|
+
}
|
|
47
|
+
|
|
1
48
|
interface EnvVariable {
|
|
2
49
|
key: string;
|
|
3
50
|
value: any;
|
|
@@ -46,6 +93,22 @@ interface LambaOptions {
|
|
|
46
93
|
* If omitted, null, or empty, ALL environment variable keys are allowed and supported regardless of prefix.
|
|
47
94
|
*/
|
|
48
95
|
allowedPrefixes?: string | string[] | RegExp | null;
|
|
96
|
+
/**
|
|
97
|
+
* Storage strategy for persisting overrides and presets across page reloads:
|
|
98
|
+
* - `'local'` — (default) Standard `localStorage`. Persists indefinitely across tabs & reloads.
|
|
99
|
+
* Visible in DevTools → Application → Local Storage.
|
|
100
|
+
* - `'session'` — `sessionStorage`. Survives page reloads within the same tab, but cleared
|
|
101
|
+
* when the tab is closed. Visible in DevTools → Application → Session Storage.
|
|
102
|
+
* - `'memory'` — In-memory only. Most secure option — zero bytes written to any browser storage.
|
|
103
|
+
* Overrides are destroyed when the tab closes or navigates away.
|
|
104
|
+
* Nothing appears in DevTools Storage.
|
|
105
|
+
*/
|
|
106
|
+
storageStrategy?: 'local' | 'session' | 'memory';
|
|
107
|
+
/**
|
|
108
|
+
* Provide a fully custom storage adapter that conforms to the `LambaStorageAdapter` interface.
|
|
109
|
+
* When provided, this takes precedence over `storageStrategy`.
|
|
110
|
+
*/
|
|
111
|
+
storage?: LambaStorageAdapter;
|
|
49
112
|
}
|
|
50
113
|
type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
|
|
51
114
|
type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
|
|
@@ -116,4 +179,4 @@ declare class LambaManager {
|
|
|
116
179
|
}
|
|
117
180
|
declare const lamba: LambaManager;
|
|
118
181
|
|
|
119
|
-
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
|
182
|
+
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type LambaStorageAdapter, LocalStorageAdapter, MemoryStorageAdapter, type PresetProfile, SessionStorageAdapter, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
LambaManager: () => LambaManager,
|
|
24
|
+
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
25
|
+
MemoryStorageAdapter: () => MemoryStorageAdapter,
|
|
26
|
+
SessionStorageAdapter: () => SessionStorageAdapter,
|
|
24
27
|
default: () => index_default,
|
|
25
28
|
lamba: () => lamba,
|
|
26
29
|
parseEnvString: () => parseEnvString,
|
|
@@ -32,34 +35,33 @@ module.exports = __toCommonJS(index_exports);
|
|
|
32
35
|
var STORAGE_PRESETS_KEY = "__lamba_presets__";
|
|
33
36
|
var STORAGE_ACTIVE_PRESET_KEY = "__lamba_active_preset__";
|
|
34
37
|
var PresetManager = class {
|
|
35
|
-
constructor() {
|
|
38
|
+
constructor(storage) {
|
|
36
39
|
this.presets = [];
|
|
37
40
|
this.activePresetId = null;
|
|
41
|
+
this.storage = storage;
|
|
38
42
|
this.loadFromStorage();
|
|
39
43
|
}
|
|
40
44
|
loadFromStorage() {
|
|
41
|
-
if (typeof localStorage === "undefined") return;
|
|
42
45
|
try {
|
|
43
|
-
const rawPresets =
|
|
46
|
+
const rawPresets = this.storage.getItem(STORAGE_PRESETS_KEY);
|
|
44
47
|
if (rawPresets) {
|
|
45
48
|
this.presets = JSON.parse(rawPresets);
|
|
46
49
|
}
|
|
47
|
-
this.activePresetId =
|
|
50
|
+
this.activePresetId = this.storage.getItem(STORAGE_ACTIVE_PRESET_KEY);
|
|
48
51
|
} catch (e) {
|
|
49
|
-
console.warn("[lamba] Failed to parse presets from
|
|
52
|
+
console.warn("[lamba] Failed to parse presets from storage", e);
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
saveToStorage() {
|
|
53
|
-
if (typeof localStorage === "undefined") return;
|
|
54
56
|
try {
|
|
55
|
-
|
|
57
|
+
this.storage.setItem(STORAGE_PRESETS_KEY, JSON.stringify(this.presets));
|
|
56
58
|
if (this.activePresetId) {
|
|
57
|
-
|
|
59
|
+
this.storage.setItem(STORAGE_ACTIVE_PRESET_KEY, this.activePresetId);
|
|
58
60
|
} else {
|
|
59
|
-
|
|
61
|
+
this.storage.removeItem(STORAGE_ACTIVE_PRESET_KEY);
|
|
60
62
|
}
|
|
61
63
|
} catch (e) {
|
|
62
|
-
console.warn("[lamba] Failed to save presets to
|
|
64
|
+
console.warn("[lamba] Failed to save presets to storage", e);
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
getPresets() {
|
|
@@ -211,6 +213,99 @@ async function tryFetchRootEnvFile() {
|
|
|
211
213
|
return {};
|
|
212
214
|
}
|
|
213
215
|
|
|
216
|
+
// src/core/storage.ts
|
|
217
|
+
var LocalStorageAdapter = class {
|
|
218
|
+
getItem(key) {
|
|
219
|
+
try {
|
|
220
|
+
return typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
|
|
221
|
+
} catch {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
setItem(key, value) {
|
|
226
|
+
try {
|
|
227
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(key, value);
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
removeItem(key) {
|
|
232
|
+
try {
|
|
233
|
+
if (typeof localStorage !== "undefined") localStorage.removeItem(key);
|
|
234
|
+
} catch {
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
clear() {
|
|
238
|
+
try {
|
|
239
|
+
if (typeof localStorage !== "undefined") {
|
|
240
|
+
localStorage.removeItem("__lamba_overrides__");
|
|
241
|
+
localStorage.removeItem("__lamba_presets__");
|
|
242
|
+
localStorage.removeItem("__lamba_active_preset__");
|
|
243
|
+
}
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var SessionStorageAdapter = class {
|
|
249
|
+
getItem(key) {
|
|
250
|
+
try {
|
|
251
|
+
return typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null;
|
|
252
|
+
} catch {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
setItem(key, value) {
|
|
257
|
+
try {
|
|
258
|
+
if (typeof sessionStorage !== "undefined") sessionStorage.setItem(key, value);
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
removeItem(key) {
|
|
263
|
+
try {
|
|
264
|
+
if (typeof sessionStorage !== "undefined") sessionStorage.removeItem(key);
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
clear() {
|
|
269
|
+
try {
|
|
270
|
+
if (typeof sessionStorage !== "undefined") {
|
|
271
|
+
sessionStorage.removeItem("__lamba_overrides__");
|
|
272
|
+
sessionStorage.removeItem("__lamba_presets__");
|
|
273
|
+
sessionStorage.removeItem("__lamba_active_preset__");
|
|
274
|
+
}
|
|
275
|
+
} catch {
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
var MemoryStorageAdapter = class {
|
|
280
|
+
constructor() {
|
|
281
|
+
this.store = /* @__PURE__ */ new Map();
|
|
282
|
+
}
|
|
283
|
+
getItem(key) {
|
|
284
|
+
return this.store.get(key) ?? null;
|
|
285
|
+
}
|
|
286
|
+
setItem(key, value) {
|
|
287
|
+
this.store.set(key, value);
|
|
288
|
+
}
|
|
289
|
+
removeItem(key) {
|
|
290
|
+
this.store.delete(key);
|
|
291
|
+
}
|
|
292
|
+
clear() {
|
|
293
|
+
this.store.clear();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
function createStorageAdapter(strategy = "local", custom) {
|
|
297
|
+
if (custom) return custom;
|
|
298
|
+
switch (strategy) {
|
|
299
|
+
case "session":
|
|
300
|
+
return new SessionStorageAdapter();
|
|
301
|
+
case "memory":
|
|
302
|
+
return new MemoryStorageAdapter();
|
|
303
|
+
case "local":
|
|
304
|
+
default:
|
|
305
|
+
return new LocalStorageAdapter();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
214
309
|
// src/core/store.ts
|
|
215
310
|
var STORAGE_OVERRIDES_KEY = "__lamba_overrides__";
|
|
216
311
|
var DEFAULT_SECRET_PATTERN = /(KEY|SECRET|TOKEN|PASSWORD|AUTH|PRIVATE|CREDENTIAL|SIGNATURE)/i;
|
|
@@ -222,7 +317,8 @@ var EnvStore = class {
|
|
|
222
317
|
this.storeChangeListeners = /* @__PURE__ */ new Set();
|
|
223
318
|
this.secretPattern = options.secretKeysPattern || DEFAULT_SECRET_PATTERN;
|
|
224
319
|
this.allowedPrefixes = options.allowedPrefixes;
|
|
225
|
-
this.
|
|
320
|
+
this.storage = createStorageAdapter(options.storageStrategy ?? "local", options.storage);
|
|
321
|
+
this.presetManager = new PresetManager(this.storage);
|
|
226
322
|
this.loadOverridesFromStorage();
|
|
227
323
|
if (options.env) {
|
|
228
324
|
this.mergeDefaults(options.env);
|
|
@@ -239,22 +335,20 @@ var EnvStore = class {
|
|
|
239
335
|
this.patchProcessEnv();
|
|
240
336
|
}
|
|
241
337
|
loadOverridesFromStorage() {
|
|
242
|
-
if (typeof localStorage === "undefined") return;
|
|
243
338
|
try {
|
|
244
|
-
const stored =
|
|
339
|
+
const stored = this.storage.getItem(STORAGE_OVERRIDES_KEY);
|
|
245
340
|
if (stored) {
|
|
246
341
|
this.overrides = JSON.parse(stored);
|
|
247
342
|
}
|
|
248
343
|
} catch (e) {
|
|
249
|
-
console.warn("[lamba] Failed to parse overrides from
|
|
344
|
+
console.warn("[lamba] Failed to parse overrides from storage", e);
|
|
250
345
|
}
|
|
251
346
|
}
|
|
252
347
|
saveOverridesToStorage() {
|
|
253
|
-
if (typeof localStorage === "undefined") return;
|
|
254
348
|
try {
|
|
255
|
-
|
|
349
|
+
this.storage.setItem(STORAGE_OVERRIDES_KEY, JSON.stringify(this.overrides));
|
|
256
350
|
} catch (e) {
|
|
257
|
-
console.warn("[lamba] Failed to save overrides to
|
|
351
|
+
console.warn("[lamba] Failed to save overrides to storage", e);
|
|
258
352
|
}
|
|
259
353
|
}
|
|
260
354
|
/**
|
|
@@ -1571,6 +1665,9 @@ var index_default = lamba;
|
|
|
1571
1665
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1572
1666
|
0 && (module.exports = {
|
|
1573
1667
|
LambaManager,
|
|
1668
|
+
LocalStorageAdapter,
|
|
1669
|
+
MemoryStorageAdapter,
|
|
1670
|
+
SessionStorageAdapter,
|
|
1574
1671
|
lamba,
|
|
1575
1672
|
parseEnvString,
|
|
1576
1673
|
stringifyEnv
|