molex-env 0.2.6 → 0.3.1

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 CHANGED
@@ -126,8 +126,8 @@ OPTIONAL_KEY=
126
126
 
127
127
  Files are loaded and merged in this order (later files override earlier ones):
128
128
 
129
- 1. `.menv` - Base configuration (committed to git)
130
- 2. `.menv.local` - Local overrides (ignored by git)
129
+ 1. `.menv` - Base configuration
130
+ 2. `.menv.local` - Local overrides
131
131
  3. `.menv.{profile}` - Profile-specific config (e.g., `.menv.prod`)
132
132
  4. `.menv.{profile}.local` - Profile + local overrides (e.g., `.menv.prod.local`)
133
133
 
@@ -277,23 +277,62 @@ Watch .menv files and reload automatically when they change. Perfect for develop
277
277
 
278
278
  **Arguments:**
279
279
 
280
- - `options` - Same options as `load()`
280
+ - `options` - Same options as `load()`, including `debug` for automatic change logging
281
281
  - `onChange(error, result)` - Callback fired on file changes
282
282
 
283
- **Example:**
283
+ **Automatic Change Detection:**
284
+
285
+ When `debug: true` is enabled, watch mode automatically logs what values changed on each reload:
284
286
 
285
287
  ```javascript
286
288
  const { watch } = require('molex-env');
287
289
 
288
- // Watch with callback
289
- watch({ profile: 'dev', strict: true }, (err, result) => {
290
+ watch({
291
+ profile: 'dev',
292
+ debug: true, // Automatically logs changes
293
+ schema: {
294
+ PORT: 'number',
295
+ DEBUG: 'boolean',
296
+ SERVICE_URL: 'string'
297
+ }
298
+ }, (err, result) => {
299
+ if (err) {
300
+ console.error('Config reload failed:', err.message);
301
+ return;
302
+ }
303
+ console.log('✅ Config successfully reloaded');
304
+ });
305
+
306
+ // When you edit .menv files, automatic output:
307
+ // [molex-env] Config reloaded - changes detected:
308
+ // PORT: 3000 → 8080
309
+ // SERVICE_URL: https://api.example.com → https://api.production.com
310
+ // ✅ Config successfully reloaded
311
+ ```
312
+
313
+ **Manual Change Detection:**
314
+
315
+ Without `debug: true`, you can manually detect changes in your callback:
316
+
317
+ ```javascript
318
+ let currentConfig;
319
+
320
+ watch({ profile: 'dev' }, (err, result) => {
290
321
  if (err) {
291
322
  console.error('Config reload failed:', err.message);
292
323
  return;
293
324
  }
294
325
 
295
- console.log('Config reloaded!');
296
- console.log('New PORT:', result.parsed.PORT);
326
+ if (!currentConfig) {
327
+ console.log('Initial config loaded');
328
+ } else {
329
+ // Manually check what changed
330
+ if (currentConfig.PORT !== result.parsed.PORT) {
331
+ console.log(`PORT changed: ${currentConfig.PORT} → ${result.parsed.PORT}`);
332
+ }
333
+ }
334
+
335
+ currentConfig = result.parsed;
297
336
 
298
337
  // Restart your server or update app state here
299
338
  if (global.server) {
@@ -325,10 +364,17 @@ function startServer(config) {
325
364
  const initial = require('molex-env').load({ profile: 'dev' });
326
365
  server = startServer(initial.parsed);
327
366
 
328
- // Watch for changes
329
- watch({ profile: 'dev' }, (err, result) => {
367
+ // Watch for changes with automatic change logging
368
+ watch({
369
+ profile: 'dev',
370
+ debug: true,
371
+ schema: {
372
+ PORT: 'number',
373
+ DEBUG: 'boolean'
374
+ }
375
+ }, (err, result) => {
330
376
  if (!err && result.parsed.PORT !== initial.parsed.PORT) {
331
- console.log('Port changed, restarting...');
377
+ console.log('Port changed, restarting server...');
332
378
  server.close(() => {
333
379
  server = startServer(result.parsed);
334
380
  });
@@ -657,10 +703,9 @@ console.log(`PORT: ${process.menv.PORT}`);
657
703
  ```javascript
658
704
  const { watch } = require('molex-env');
659
705
 
660
- let currentConfig;
661
-
662
706
  watch({
663
707
  profile: 'dev',
708
+ debug: true, // Automatic change detection
664
709
  schema: {
665
710
  PORT: 'number',
666
711
  DEBUG: 'boolean',
@@ -672,24 +717,15 @@ watch({
672
717
  return;
673
718
  }
674
719
 
675
- const changed = [];
676
- if (!currentConfig) {
677
- console.log('Initial config loaded');
678
- } else {
679
- // Detect what changed
680
- Object.keys(result.parsed).forEach(key => {
681
- if (currentConfig[key] !== result.parsed[key]) {
682
- changed.push(`${key}: ${currentConfig[key]} → ${result.parsed[key]}`);
683
- }
684
- });
685
-
686
- if (changed.length > 0) {
687
- console.log('Config updated:', changed.join(', '));
688
- }
689
- }
690
-
691
- currentConfig = result.parsed;
720
+ console.log('Config reloaded and ready to use');
721
+ // result.parsed has the new values
692
722
  });
723
+
724
+ console.log('Watching for changes...');
725
+ // Output on file change:
726
+ // [molex-env] Config reloaded - changes detected:
727
+ // DEBUG: false → true
728
+ // API_URL: https://api.example.com → https://api.dev.local
693
729
  ```
694
730
 
695
731
  ### Validation and Error Handling
@@ -730,35 +766,19 @@ try {
730
766
 
731
767
  ## Best Practices
732
768
 
733
- ### Git Configuration
734
-
735
- Add to `.gitignore`:
736
- ```gitignore
737
- # Keep base configs in git
738
- # .menv
739
- # .menv.dev
740
- # .menv.prod
741
-
742
- # Ignore local overrides (machine-specific, secrets)
743
- .menv.local
744
- .menv.*.local
745
- ```
746
-
747
769
  ### Environment Strategy
748
770
 
749
771
  ```
750
772
  Development: .menv + .menv.local
751
773
  Staging: .menv + .menv.staging
752
- Production: .menv + .menv.prod + .menv.prod.local (secrets)
774
+ Production: .menv + .menv.prod + .menv.prod.local
753
775
  ```
754
776
 
755
777
  ### Security Tips
756
778
 
757
- - ✅ **DO** use `.menv.local` for secrets and add to `.gitignore`
758
779
  - ✅ **DO** use `strict: true` in production to catch unknown keys and configuration errors
759
780
  - ✅ **DO** use `debug: true` during development to understand file precedence
760
781
  - ✅ **DO** validate sensitive values (URLs, ports, etc.) after loading
761
- - ❌ **DON'T** commit production secrets to git
762
782
  - ❌ **DON'T** use `exportEnv: true` if you need immutable config
763
783
 
764
784
  ### Performance
@@ -794,11 +814,25 @@ The example demonstrates:
794
814
 
795
815
  **Problem:** Getting errors about unknown keys when loading config.
796
816
 
797
- **Solution:** Add all keys to your schema or disable strict mode:
817
+ **Cause:** You have a key in your `.menv` file that isn't defined in your schema, and `strict: true` is enabled.
818
+
819
+ **Solution:** Either add the key to your schema or disable strict mode:
798
820
  ```javascript
799
- load({ strict: false }); // Allow unknown keys
821
+ // Option 1: Add missing key to schema
822
+ load({
823
+ strict: true,
824
+ schema: {
825
+ PORT: 'number',
826
+ YOUR_MISSING_KEY: 'string' // Add this
827
+ }
828
+ });
829
+
830
+ // Option 2: Disable strict mode to allow unknown keys
831
+ load({ strict: false });
800
832
  ```
801
833
 
834
+ > **Note:** This is different from "required" - unknown keys exist in your file but not in schema. Required keys exist in schema but not in your file.
835
+
802
836
  ### Values are strings instead of typed
803
837
 
804
838
  **Problem:** `PORT` is `"3000"` (string) instead of `3000` (number).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "molex-env",
3
- "version": "0.2.6",
3
+ "version": "0.3.1",
4
4
  "description": "Native .menv loader with profiles, typing, and origin tracking.",
5
5
  "main": "src/index.js",
6
6
  "files": [
package/src/lib/watch.js CHANGED
@@ -27,6 +27,7 @@ function watch(options, onChange, load)
27
27
  const basenames = new Set(files.map((file) => path.basename(file)));
28
28
  const watchers = [];
29
29
  let timer = null;
30
+ let previousConfig = null;
30
31
 
31
32
  const trigger = () =>
32
33
  {
@@ -35,7 +36,40 @@ function watch(options, onChange, load)
35
36
  {
36
37
  try
37
38
  {
38
- const result = load(options);
39
+ // Disable file precedence debug during reload to avoid conflicts with watch change detection
40
+ const reloadOptions = { ...options, debug: false };
41
+ const result = load(reloadOptions);
42
+
43
+ // Auto-detect changes if debug mode was enabled
44
+ if (options.debug && previousConfig)
45
+ {
46
+ const changes = [];
47
+ for (const key in result.parsed)
48
+ {
49
+ const oldValue = previousConfig[key];
50
+ const newValue = result.parsed[key];
51
+
52
+ // Compare values (handle dates and objects)
53
+ const oldStr = oldValue instanceof Date ? oldValue.toISOString() : JSON.stringify(oldValue);
54
+ const newStr = newValue instanceof Date ? newValue.toISOString() : JSON.stringify(newValue);
55
+
56
+ if (oldStr !== newStr)
57
+ {
58
+ changes.push({ key, old: oldValue, new: newValue });
59
+ }
60
+ }
61
+
62
+ if (changes.length > 0)
63
+ {
64
+ console.log('[molex-env] Config reloaded - changes detected:');
65
+ changes.forEach(({ key, old, new: newVal }) =>
66
+ {
67
+ console.log(` ${key}: ${old} → ${newVal}`);
68
+ });
69
+ }
70
+ }
71
+
72
+ previousConfig = { ...result.parsed };
39
73
  onChange(null, result);
40
74
  } catch (err)
41
75
  {