@ojolowoblue/lamba 1.0.5 → 1.0.7
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 +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +130 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +127 -18
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/react.js +124 -18
- package/dist/integrations/react.js.map +1 -1
- package/dist/integrations/react.mjs +124 -18
- package/dist/integrations/react.mjs.map +1 -1
- package/dist/integrations/vue.js +124 -18
- package/dist/integrations/vue.js.map +1 -1
- package/dist/integrations/vue.mjs +124 -18
- 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;
|
|
@@ -97,6 +160,15 @@ declare class LambaManager {
|
|
|
97
160
|
* Resets all environment variable overrides.
|
|
98
161
|
*/
|
|
99
162
|
reset(): void;
|
|
163
|
+
/**
|
|
164
|
+
* Removes ALL lamba data from storage (overrides, presets, active preset).
|
|
165
|
+
* Safe to call even when lamba has not been initialized.
|
|
166
|
+
* Useful when disabling lamba to ensure no stale data remains in the browser.
|
|
167
|
+
*
|
|
168
|
+
* @param options - Optionally pass storage options to target the correct adapter.
|
|
169
|
+
* Defaults to 'local' (localStorage) to cover the common case.
|
|
170
|
+
*/
|
|
171
|
+
purge(options?: Pick<LambaOptions, 'storageStrategy' | 'storage'>): void;
|
|
100
172
|
/**
|
|
101
173
|
* Subscribes to environment variable changes.
|
|
102
174
|
*/
|
|
@@ -116,4 +188,4 @@ declare class LambaManager {
|
|
|
116
188
|
}
|
|
117
189
|
declare const lamba: LambaManager;
|
|
118
190
|
|
|
119
|
-
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
|
191
|
+
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;
|
|
@@ -97,6 +160,15 @@ declare class LambaManager {
|
|
|
97
160
|
* Resets all environment variable overrides.
|
|
98
161
|
*/
|
|
99
162
|
reset(): void;
|
|
163
|
+
/**
|
|
164
|
+
* Removes ALL lamba data from storage (overrides, presets, active preset).
|
|
165
|
+
* Safe to call even when lamba has not been initialized.
|
|
166
|
+
* Useful when disabling lamba to ensure no stale data remains in the browser.
|
|
167
|
+
*
|
|
168
|
+
* @param options - Optionally pass storage options to target the correct adapter.
|
|
169
|
+
* Defaults to 'local' (localStorage) to cover the common case.
|
|
170
|
+
*/
|
|
171
|
+
purge(options?: Pick<LambaOptions, 'storageStrategy' | 'storage'>): void;
|
|
100
172
|
/**
|
|
101
173
|
* Subscribes to environment variable changes.
|
|
102
174
|
*/
|
|
@@ -116,4 +188,4 @@ declare class LambaManager {
|
|
|
116
188
|
}
|
|
117
189
|
declare const lamba: LambaManager;
|
|
118
190
|
|
|
119
|
-
export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
|
|
191
|
+
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
|
/**
|
|
@@ -1475,7 +1569,10 @@ var LambaManager = class {
|
|
|
1475
1569
|
interceptNetworkRequests: true,
|
|
1476
1570
|
...options
|
|
1477
1571
|
};
|
|
1478
|
-
if (this.options.enabled === false)
|
|
1572
|
+
if (this.options.enabled === false) {
|
|
1573
|
+
this.purge(options);
|
|
1574
|
+
return this;
|
|
1575
|
+
}
|
|
1479
1576
|
this.store = new EnvStore(this.options);
|
|
1480
1577
|
if (this.options.interceptNetworkRequests !== false) {
|
|
1481
1578
|
this.networkInterceptor = new NetworkInterceptor(this.store);
|
|
@@ -1532,6 +1629,18 @@ var LambaManager = class {
|
|
|
1532
1629
|
reset() {
|
|
1533
1630
|
this.store?.resetAllOverrides();
|
|
1534
1631
|
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Removes ALL lamba data from storage (overrides, presets, active preset).
|
|
1634
|
+
* Safe to call even when lamba has not been initialized.
|
|
1635
|
+
* Useful when disabling lamba to ensure no stale data remains in the browser.
|
|
1636
|
+
*
|
|
1637
|
+
* @param options - Optionally pass storage options to target the correct adapter.
|
|
1638
|
+
* Defaults to 'local' (localStorage) to cover the common case.
|
|
1639
|
+
*/
|
|
1640
|
+
purge(options) {
|
|
1641
|
+
const adapter = this.store?.storage ?? createStorageAdapter(options?.storageStrategy ?? "local", options?.storage);
|
|
1642
|
+
adapter.clear();
|
|
1643
|
+
}
|
|
1535
1644
|
/**
|
|
1536
1645
|
* Subscribes to environment variable changes.
|
|
1537
1646
|
*/
|
|
@@ -1571,6 +1680,9 @@ var index_default = lamba;
|
|
|
1571
1680
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1572
1681
|
0 && (module.exports = {
|
|
1573
1682
|
LambaManager,
|
|
1683
|
+
LocalStorageAdapter,
|
|
1684
|
+
MemoryStorageAdapter,
|
|
1685
|
+
SessionStorageAdapter,
|
|
1574
1686
|
lamba,
|
|
1575
1687
|
parseEnvString,
|
|
1576
1688
|
stringifyEnv
|