@ojolowoblue/lamba 1.0.3 → 1.0.5
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 +17 -17
- package/dist/index.d.mts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +39 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -13
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.d.ts +1 -1
- package/dist/integrations/react.js +40 -14
- package/dist/integrations/react.js.map +1 -1
- package/dist/integrations/react.mjs +40 -14
- package/dist/integrations/react.mjs.map +1 -1
- package/dist/integrations/vue.d.mts +1 -1
- package/dist/integrations/vue.d.ts +1 -1
- package/dist/integrations/vue.js +40 -14
- package/dist/integrations/vue.js.map +1 -1
- package/dist/integrations/vue.mjs +40 -14
- package/dist/integrations/vue.mjs.map +1 -1
- package/dist/lamba.min.js +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Deployed via CDN or installed via NPM, `lamba` injects a non-intrusive floating
|
|
|
27
27
|
Include the script tag in your `index.html` file before your application bundle:
|
|
28
28
|
|
|
29
29
|
```html
|
|
30
|
-
<script src="https://unpkg.com/@ojolowoblue/lamba"></script>
|
|
30
|
+
<script src="https://unpkg.com/@ojolowoblue/lamba" data-lamba-auto></script>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
That's it! A floating settings button (⚙️) will automatically appear in the bottom-right corner of your web page.
|
|
@@ -52,11 +52,11 @@ import lamba from '@ojolowoblue/lamba';
|
|
|
52
52
|
lamba.init({
|
|
53
53
|
position: 'bottom-right',
|
|
54
54
|
env: {
|
|
55
|
-
// Supports any
|
|
55
|
+
// Supports any data type (strings, numbers, booleans, objects) & any prefix:
|
|
56
56
|
NEXT_PUBLIC_API_URL: 'https://api.dev.example.com',
|
|
57
|
-
|
|
58
|
-
VITE_ENABLE_ANALYTICS:
|
|
59
|
-
|
|
57
|
+
PORT: 3000,
|
|
58
|
+
VITE_ENABLE_ANALYTICS: true,
|
|
59
|
+
FEATURE_FLAGS: { newCheckout: true },
|
|
60
60
|
},
|
|
61
61
|
});
|
|
62
62
|
```
|
|
@@ -88,7 +88,7 @@ Wrap your existing `import.meta.env` (Vite) or `process.env` (Webpack/Next.js) o
|
|
|
88
88
|
// src/config.ts
|
|
89
89
|
import lamba from '@ojolowoblue/lamba';
|
|
90
90
|
|
|
91
|
-
// Wrap your env object in a dynamic ES Proxy
|
|
91
|
+
// Wrap your env object in a dynamic ES Proxy (preserves primitive boolean & number types!)
|
|
92
92
|
export const env = lamba.wrap(import.meta.env);
|
|
93
93
|
|
|
94
94
|
// Access keys anywhere in your application:
|
|
@@ -121,15 +121,15 @@ import React from 'react';
|
|
|
121
121
|
import { useLambaEnv } from '@ojolowoblue/lamba/react';
|
|
122
122
|
|
|
123
123
|
export function UserDashboard() {
|
|
124
|
-
const apiBase = useLambaEnv('VITE_API_BASE_URL', 'https://api.dev.com');
|
|
125
|
-
const
|
|
124
|
+
const apiBase = useLambaEnv<string>('VITE_API_BASE_URL', 'https://api.dev.com');
|
|
125
|
+
const isBetaEnabled = useLambaEnv<boolean>('VITE_FEATURE_BETA_UI', false);
|
|
126
126
|
|
|
127
127
|
return (
|
|
128
128
|
<div style={{ padding: '24px' }}>
|
|
129
129
|
<h1>Dashboard</h1>
|
|
130
130
|
<p>Connected Environment: <code>{apiBase}</code></p>
|
|
131
131
|
|
|
132
|
-
{
|
|
132
|
+
{isBetaEnabled && (
|
|
133
133
|
<div className="beta-banner">
|
|
134
134
|
🚀 Beta UI Enabled Live via lamba!
|
|
135
135
|
</div>
|
|
@@ -147,14 +147,14 @@ Import `useLambaEnv` from `lamba/vue` as a reactive composition Vue Ref:
|
|
|
147
147
|
<script setup lang="ts">
|
|
148
148
|
import { useLambaEnv } from '@ojolowoblue/lamba/vue';
|
|
149
149
|
|
|
150
|
-
const apiBase = useLambaEnv('VITE_API_BASE_URL', 'https://api.dev.com');
|
|
151
|
-
const
|
|
150
|
+
const apiBase = useLambaEnv<string>('VITE_API_BASE_URL', 'https://api.dev.com');
|
|
151
|
+
const isNewHeader = useLambaEnv<boolean>('VITE_NEW_HEADER', false);
|
|
152
152
|
</script>
|
|
153
153
|
|
|
154
154
|
<template>
|
|
155
155
|
<div class="container">
|
|
156
156
|
<h2>Current Backend: {{ apiBase }}</h2>
|
|
157
|
-
<header v-if="
|
|
157
|
+
<header v-if="isNewHeader">
|
|
158
158
|
<h3>✨ New Header Component</h3>
|
|
159
159
|
</header>
|
|
160
160
|
</div>
|
|
@@ -171,7 +171,7 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
|
|
|
171
171
|
|
|
172
172
|
| Option | Type | Default | Description |
|
|
173
173
|
| :--- | :--- | :--- | :--- |
|
|
174
|
-
| `env` | `Record<string,
|
|
174
|
+
| `env` | `Record<string, any>` | `{}` | Initial default key-value pairs of environment variables (supports strings, numbers, booleans, objects). |
|
|
175
175
|
| `enabled` | `boolean` | `true` | Set to `false` to disable lamba (e.g. in production builds). |
|
|
176
176
|
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Screen position for the floating widget launcher button. |
|
|
177
177
|
| `secretKeysPattern` | `RegExp` | `/(KEY\|SECRET\|TOKEN\|PASSWORD\|AUTH\|PRIVATE)/i` | Regular expression to automatically obscure sensitive keys in the UI. |
|
|
@@ -183,11 +183,11 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
|
|
|
183
183
|
|
|
184
184
|
### Core Methods
|
|
185
185
|
|
|
186
|
-
#### `lamba.get(key: string, fallback?:
|
|
187
|
-
Returns the active value for the specified environment key (returns active override if present, otherwise default value or fallback).
|
|
186
|
+
#### `lamba.get<T = any>(key: string, fallback?: T): T`
|
|
187
|
+
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
188
|
|
|
189
|
-
#### `lamba.set(key: string, value:
|
|
190
|
-
Programmatically overrides an environment variable live at runtime. The change is persisted in `localStorage` and triggers UI and listener updates.
|
|
189
|
+
#### `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 `localStorage` and triggers UI and listener updates.
|
|
191
191
|
|
|
192
192
|
#### `lamba.remove(key: string): void`
|
|
193
193
|
Removes an override for a specific environment variable key, reverting it to its default value.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
interface EnvVariable {
|
|
2
2
|
key: string;
|
|
3
|
-
value:
|
|
4
|
-
defaultValue:
|
|
3
|
+
value: any;
|
|
4
|
+
defaultValue: any;
|
|
5
5
|
isOverridden: boolean;
|
|
6
6
|
isSecret?: boolean;
|
|
7
7
|
}
|
|
8
8
|
interface PresetProfile {
|
|
9
9
|
id: string;
|
|
10
10
|
name: string;
|
|
11
|
-
overrides: Record<string,
|
|
11
|
+
overrides: Record<string, any>;
|
|
12
12
|
createdAt: number;
|
|
13
13
|
}
|
|
14
14
|
interface LambaOptions {
|
|
15
15
|
/**
|
|
16
|
-
* Initial environment variable key-values to supply to lamba.
|
|
16
|
+
* Initial environment variable key-values to supply to lamba. Accepts strings, numbers, booleans, objects, etc.
|
|
17
17
|
*/
|
|
18
|
-
env?: Record<string,
|
|
18
|
+
env?: Record<string, any>;
|
|
19
19
|
/**
|
|
20
20
|
* Whether lamba floating UI is enabled. Defaults to true in non-production or when specified.
|
|
21
21
|
*/
|
|
@@ -47,7 +47,7 @@ interface LambaOptions {
|
|
|
47
47
|
*/
|
|
48
48
|
allowedPrefixes?: string | string[] | RegExp | null;
|
|
49
49
|
}
|
|
50
|
-
type EnvChangeListener = (key: string, value:
|
|
50
|
+
type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
|
|
51
51
|
type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -70,7 +70,7 @@ declare class LambaManager {
|
|
|
70
70
|
* Implicit ES Proxy object where properties like `lamba.env.VITE_API_BASE_URL`
|
|
71
71
|
* return the live active overridden value automatically.
|
|
72
72
|
*/
|
|
73
|
-
env: Record<string,
|
|
73
|
+
env: Record<string, any>;
|
|
74
74
|
constructor();
|
|
75
75
|
/**
|
|
76
76
|
* Wraps any environment object (such as `import.meta.env` or `process.env`)
|
|
@@ -84,11 +84,11 @@ declare class LambaManager {
|
|
|
84
84
|
/**
|
|
85
85
|
* Gets the active value of an environment variable (returns overridden value if active, otherwise default).
|
|
86
86
|
*/
|
|
87
|
-
get(key: string, fallback?:
|
|
87
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
88
88
|
/**
|
|
89
89
|
* Overrides an environment variable live at runtime.
|
|
90
90
|
*/
|
|
91
|
-
set(key: string, value:
|
|
91
|
+
set(key: string, value: any): void;
|
|
92
92
|
/**
|
|
93
93
|
* Removes an override for a specific environment variable key.
|
|
94
94
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
interface EnvVariable {
|
|
2
2
|
key: string;
|
|
3
|
-
value:
|
|
4
|
-
defaultValue:
|
|
3
|
+
value: any;
|
|
4
|
+
defaultValue: any;
|
|
5
5
|
isOverridden: boolean;
|
|
6
6
|
isSecret?: boolean;
|
|
7
7
|
}
|
|
8
8
|
interface PresetProfile {
|
|
9
9
|
id: string;
|
|
10
10
|
name: string;
|
|
11
|
-
overrides: Record<string,
|
|
11
|
+
overrides: Record<string, any>;
|
|
12
12
|
createdAt: number;
|
|
13
13
|
}
|
|
14
14
|
interface LambaOptions {
|
|
15
15
|
/**
|
|
16
|
-
* Initial environment variable key-values to supply to lamba.
|
|
16
|
+
* Initial environment variable key-values to supply to lamba. Accepts strings, numbers, booleans, objects, etc.
|
|
17
17
|
*/
|
|
18
|
-
env?: Record<string,
|
|
18
|
+
env?: Record<string, any>;
|
|
19
19
|
/**
|
|
20
20
|
* Whether lamba floating UI is enabled. Defaults to true in non-production or when specified.
|
|
21
21
|
*/
|
|
@@ -47,7 +47,7 @@ interface LambaOptions {
|
|
|
47
47
|
*/
|
|
48
48
|
allowedPrefixes?: string | string[] | RegExp | null;
|
|
49
49
|
}
|
|
50
|
-
type EnvChangeListener = (key: string, value:
|
|
50
|
+
type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
|
|
51
51
|
type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -70,7 +70,7 @@ declare class LambaManager {
|
|
|
70
70
|
* Implicit ES Proxy object where properties like `lamba.env.VITE_API_BASE_URL`
|
|
71
71
|
* return the live active overridden value automatically.
|
|
72
72
|
*/
|
|
73
|
-
env: Record<string,
|
|
73
|
+
env: Record<string, any>;
|
|
74
74
|
constructor();
|
|
75
75
|
/**
|
|
76
76
|
* Wraps any environment object (such as `import.meta.env` or `process.env`)
|
|
@@ -84,11 +84,11 @@ declare class LambaManager {
|
|
|
84
84
|
/**
|
|
85
85
|
* Gets the active value of an environment variable (returns overridden value if active, otherwise default).
|
|
86
86
|
*/
|
|
87
|
-
get(key: string, fallback?:
|
|
87
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
88
88
|
/**
|
|
89
89
|
* Overrides an environment variable live at runtime.
|
|
90
90
|
*/
|
|
91
|
-
set(key: string, value:
|
|
91
|
+
set(key: string, value: any): void;
|
|
92
92
|
/**
|
|
93
93
|
* Removes an override for a specific environment variable key.
|
|
94
94
|
*/
|
package/dist/index.js
CHANGED
|
@@ -305,8 +305,9 @@ var EnvStore = class {
|
|
|
305
305
|
}
|
|
306
306
|
mergeDefaults(env) {
|
|
307
307
|
let changed = false;
|
|
308
|
-
for (const [key,
|
|
308
|
+
for (const [key, rawDefault] of Object.entries(env)) {
|
|
309
309
|
if (!this.isAllowedKey(key)) continue;
|
|
310
|
+
const defaultValue = rawDefault;
|
|
310
311
|
const isOverridden = key in this.overrides;
|
|
311
312
|
const currentValue = isOverridden ? this.overrides[key] : defaultValue;
|
|
312
313
|
const isSecret = this.secretPattern.test(key);
|
|
@@ -493,9 +494,12 @@ var NetworkInterceptor = class {
|
|
|
493
494
|
const allVars = this.store.getAll();
|
|
494
495
|
let resultUrl = url;
|
|
495
496
|
for (const varObj of Object.values(allVars)) {
|
|
496
|
-
if (varObj.isOverridden && varObj.defaultValue && varObj.value) {
|
|
497
|
-
const
|
|
498
|
-
const
|
|
497
|
+
if (varObj.isOverridden && varObj.defaultValue !== void 0 && varObj.value !== void 0) {
|
|
498
|
+
const rawDefault = String(varObj.defaultValue ?? "");
|
|
499
|
+
const rawOverride = String(varObj.value ?? "");
|
|
500
|
+
if (!rawDefault || !rawOverride) continue;
|
|
501
|
+
const defaultBase = rawDefault.replace(/\/+$/, "");
|
|
502
|
+
const overrideBase = rawOverride.replace(/\/+$/, "");
|
|
499
503
|
if (defaultBase && resultUrl.includes(defaultBase)) {
|
|
500
504
|
resultUrl = resultUrl.replace(defaultBase, overrideBase);
|
|
501
505
|
}
|
|
@@ -1359,7 +1363,15 @@ var ModalUI = class {
|
|
|
1359
1363
|
`;
|
|
1360
1364
|
const inputEl = card.querySelector(".var-input");
|
|
1361
1365
|
inputEl.addEventListener("change", () => {
|
|
1362
|
-
|
|
1366
|
+
let val = inputEl.value;
|
|
1367
|
+
if (typeof varItem.defaultValue === "boolean") {
|
|
1368
|
+
if (val === "true") val = true;
|
|
1369
|
+
else if (val === "false") val = false;
|
|
1370
|
+
} else if (typeof varItem.defaultValue === "number") {
|
|
1371
|
+
const num = Number(val);
|
|
1372
|
+
if (!isNaN(num) && val.trim() !== "") val = num;
|
|
1373
|
+
}
|
|
1374
|
+
this.store.setOverride(varItem.key, val);
|
|
1363
1375
|
});
|
|
1364
1376
|
card.querySelector(".toggle-secret-btn")?.addEventListener("click", () => {
|
|
1365
1377
|
this.secretVisibilityMap.set(varItem.key, !isVisible);
|
|
@@ -1371,7 +1383,9 @@ var ModalUI = class {
|
|
|
1371
1383
|
return card;
|
|
1372
1384
|
}
|
|
1373
1385
|
escapeHtml(str) {
|
|
1374
|
-
|
|
1386
|
+
if (str === null || str === void 0) return "";
|
|
1387
|
+
const text = typeof str === "object" ? JSON.stringify(str) : String(str);
|
|
1388
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1375
1389
|
}
|
|
1376
1390
|
};
|
|
1377
1391
|
|
|
@@ -1394,7 +1408,7 @@ var LambaManager = class {
|
|
|
1394
1408
|
},
|
|
1395
1409
|
set(_target, prop, value) {
|
|
1396
1410
|
if (typeof prop === "string") {
|
|
1397
|
-
self.set(prop,
|
|
1411
|
+
self.set(prop, value);
|
|
1398
1412
|
return true;
|
|
1399
1413
|
}
|
|
1400
1414
|
return false;
|
|
@@ -1413,9 +1427,7 @@ var LambaManager = class {
|
|
|
1413
1427
|
try {
|
|
1414
1428
|
const defaultObj = {};
|
|
1415
1429
|
for (const [k, v] of Object.entries(targetEnv)) {
|
|
1416
|
-
|
|
1417
|
-
defaultObj[k] = String(v);
|
|
1418
|
-
}
|
|
1430
|
+
defaultObj[k] = v;
|
|
1419
1431
|
}
|
|
1420
1432
|
if (Object.keys(defaultObj).length > 0) {
|
|
1421
1433
|
this.store.mergeDefaults(defaultObj);
|
|
@@ -1429,10 +1441,24 @@ var LambaManager = class {
|
|
|
1429
1441
|
if (typeof prop === "string") {
|
|
1430
1442
|
const overrideVal = self.get(prop);
|
|
1431
1443
|
if (overrideVal !== void 0 && overrideVal !== "") {
|
|
1444
|
+
const targetVal = Reflect.get(target, prop);
|
|
1445
|
+
if (typeof targetVal === "boolean") {
|
|
1446
|
+
if (overrideVal === "true" || overrideVal === true) return true;
|
|
1447
|
+
if (overrideVal === "false" || overrideVal === false) return false;
|
|
1448
|
+
} else if (typeof targetVal === "number" && typeof overrideVal === "string") {
|
|
1449
|
+
const num = Number(overrideVal);
|
|
1450
|
+
if (!isNaN(num)) return num;
|
|
1451
|
+
}
|
|
1432
1452
|
return overrideVal;
|
|
1433
1453
|
}
|
|
1434
1454
|
}
|
|
1435
1455
|
return Reflect.get(target, prop);
|
|
1456
|
+
},
|
|
1457
|
+
set(target, prop, value) {
|
|
1458
|
+
if (typeof prop === "string") {
|
|
1459
|
+
self.set(prop, value);
|
|
1460
|
+
}
|
|
1461
|
+
return Reflect.set(target, prop, value);
|
|
1436
1462
|
}
|
|
1437
1463
|
});
|
|
1438
1464
|
}
|
|
@@ -1485,7 +1511,7 @@ var LambaManager = class {
|
|
|
1485
1511
|
if (!this.store) {
|
|
1486
1512
|
this.init();
|
|
1487
1513
|
}
|
|
1488
|
-
return this.store?.get(key, fallback) ?? fallback
|
|
1514
|
+
return this.store?.get(key, fallback) ?? fallback;
|
|
1489
1515
|
}
|
|
1490
1516
|
/**
|
|
1491
1517
|
* Overrides an environment variable live at runtime.
|
|
@@ -1536,8 +1562,8 @@ var LambaManager = class {
|
|
|
1536
1562
|
var lamba = new LambaManager();
|
|
1537
1563
|
if (typeof window !== "undefined") {
|
|
1538
1564
|
window.lamba = lamba;
|
|
1539
|
-
const
|
|
1540
|
-
if (
|
|
1565
|
+
const currentScript = document.currentScript;
|
|
1566
|
+
if (currentScript && (currentScript.hasAttribute("data-lamba-auto") || currentScript.hasAttribute("data-auto-init"))) {
|
|
1541
1567
|
lamba.init();
|
|
1542
1568
|
}
|
|
1543
1569
|
}
|