molex-env 0.1.0 → 0.2.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 CHANGED
@@ -1,24 +1,35 @@
1
- molex-env
1
+ # molex-env
2
2
 
3
- Native .menv loader with profiles, typing, origin tracking, and optional reload.
3
+ [![npm](https://img.shields.io/npm/v/molex-env)](https://www.npmjs.com/package/molex-env)
4
+ [![downloads](https://img.shields.io/npm/dm/molex-env)](https://www.npmjs.com/package/molex-env)
5
+ [![license](https://img.shields.io/npm/l/molex-env)](LICENSE)
6
+ [![deps](https://img.shields.io/badge/deps-0-brightgreen)](package.json)
4
7
 
5
- Highlights
6
- - Deterministic profile merging
7
- - Typed parsing (boolean, number, json, date)
8
- - Strict mode for unknown or duplicate keys
9
- - Origin tracking (file + line)
10
- - Immutable config objects
11
- - Optional file watching for reload
8
+ > Native .menv loader with profiles, typing, origin tracking, and optional reload.
12
9
 
13
- Install
14
- - npm install molex-env
10
+ ## Features
11
+ - Deterministic profile merging - Predictable resolution across base and profile files
12
+ - Typed parsing - Booleans, numbers, JSON, and dates with optional casting control
13
+ - Strict mode - Reject unknown keys, duplicates, and invalid lines
14
+ - Origin tracking - See the file and line for every value
15
+ - Immutable config - Optional deep-freeze for safety
16
+ - Live reload - Watch files and reload on change
15
17
 
16
- Basic usage
18
+ ## Install
19
+ ```bash
20
+ npm install molex-env
21
+ ```
22
+
23
+ ## Quick start
24
+ ```js
25
+ // simplest usage
26
+ require('molex-env').load();
27
+
28
+ // more detailed usage
17
29
  const { load } = require('molex-env');
18
30
 
19
31
  const result = load({
20
32
  profile: 'prod',
21
- export: true,
22
33
  strict: true,
23
34
  schema: {
24
35
  PORT: 'number',
@@ -29,47 +40,144 @@ const result = load({
29
40
 
30
41
  console.log(result.parsed.PORT);
31
42
  console.log(result.origins.SERVICE_URL);
43
+ console.log(process.menv.PORT);
44
+ ```
45
+
46
+ ## Setup
47
+ 1) Add one or more .menv files in your project root.
48
+ 2) Call `load()` during startup.
49
+ 3) Optionally enable profile-specific files (e.g. `prod`).
32
50
 
33
- File precedence
51
+ ## File format
52
+ ```env
53
+ # Comments start with #
54
+ PORT=3000
55
+ DEBUG=true
56
+ SERVICE_URL="https://api.example.com"
57
+ METADATA={"region":"us-east-1"}
58
+ START_DATE=2026-02-02
59
+ ```
60
+
61
+ ## File precedence
34
62
  1) .menv
35
63
  2) .menv.local
36
64
  3) .menv.{profile}
37
65
  4) .menv.{profile}.local
38
66
 
39
- API
40
- load(options)
67
+ ## API
68
+
69
+ ## load(options)
70
+ Load, merge, parse, and validate .menv files.
71
+
72
+ ## Options
41
73
  - cwd: base directory (default: process.cwd())
42
74
  - profile: profile name for .menv.{profile}
43
75
  - files: custom file list (absolute or relative to cwd)
44
76
  - schema: allowed keys, types, defaults, required
45
77
  - strict: reject unknown keys, duplicates, and invalid lines
46
78
  - cast: true | false | { boolean, number, json, date }
47
- - export: write values to process.env
79
+ - exportEnv: write values to process.env
48
80
  - override: override existing process.env values
81
+ - attach: attach parsed values to process.menv (default true)
49
82
  - freeze: deep-freeze parsed config (default true)
50
83
  - onWarning: function(info) for non-strict duplicates
51
84
 
52
- parse(text, options)
53
- - Parse a string of .menv content using the same typing rules
85
+ ## Returns
86
+ ```js
87
+ {
88
+ parsed, // typed values
89
+ raw, // raw strings
90
+ origins, // { KEY: { file, line } }
91
+ files // list of resolved files
92
+ }
93
+ ```
94
+
95
+ ## parse(text, options)
96
+ Parse a string of .menv content using the same typing rules as `load()`.
97
+
98
+ ## Options
99
+ - schema
100
+ - strict
101
+ - cast
102
+ - freeze
103
+
104
+ ## watch(options, onChange)
105
+ Watch resolved files and reload on change.
106
+
107
+ ## Arguments
108
+ - options: same as `load()`
109
+ - onChange: function(err, result)
54
110
 
55
- watch(options, onChange)
56
- - Watch resolved files and reload on change
57
- - onChange(err, result)
111
+ ## Schema
112
+ You can define simple types or richer objects per key.
58
113
 
59
- Schema example
114
+ ```js
60
115
  const schema = {
61
116
  PORT: { type: 'number', default: 3000 },
62
117
  DEBUG: { type: 'boolean', default: false },
63
118
  METADATA: { type: 'json' },
64
- START_DATE: { type: 'date' }
119
+ START_DATE: { type: 'date' },
120
+ SERVICE_URL: { type: 'string', required: true }
65
121
  };
122
+ ```
123
+
124
+ ## Schema options per key
125
+ - type: string | boolean | number | json | date
126
+ - default: value used when key is missing
127
+ - required: true | false
128
+
129
+ ## Typing rules
130
+ - boolean: true/false (case-insensitive)
131
+ - number: integer or float
132
+ - json: JSON.parse on the value
133
+ - date: Date.parse on the value
134
+
135
+ ## Strict mode
136
+ When `strict` is true, the loader rejects:
137
+ - unknown keys not in `schema`
138
+ - duplicate keys across files
139
+ - invalid lines or parse errors
140
+
141
+ ## Non-strict mode
142
+ Duplicates are allowed and `onWarning(info)` is called with:
143
+ ```js
144
+ {
145
+ key,
146
+ previous: { file, line },
147
+ next: { file, line }
148
+ }
149
+ ```
150
+
151
+ ## Examples
152
+
153
+ ## Custom files
154
+ ```js
155
+ load({
156
+ files: ['config/.menv', 'config/.menv.local'],
157
+ schema: { PORT: 'number' }
158
+ });
159
+ ```
160
+
161
+ ## Disable casting
162
+ ```js
163
+ load({ cast: false });
164
+ ```
165
+
166
+ ## Freeze control
167
+ ```js
168
+ load({ freeze: false });
169
+ ```
66
170
 
67
- Notes
171
+ ## Notes
68
172
  - Use .menv.local for machine-specific values
69
173
  - Use strict mode to detect surprises early
174
+ - Parsed values are attached to process.menv by default (disable with attach: false)
70
175
 
71
- Example project
176
+ ## Example project
72
177
  An example app is included in examples/basic.
73
178
  Run it with:
74
- - npm install (from examples/basic)
75
- - npm start
179
+ ```bash
180
+ cd examples/basic
181
+ npm install
182
+ npm start
183
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "molex-env",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Native .menv loader with profiles, typing, and origin tracking.",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -28,5 +28,8 @@
28
28
  "bugs": {
29
29
  "url": "https://github.com/tonywied17/molex-env/issues"
30
30
  },
31
- "homepage": "https://github.com/tonywied17/molex-env#readme"
31
+ "homepage": "https://github.com/tonywied17/molex-env#readme",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
32
35
  }
package/src/index.js CHANGED
@@ -3,17 +3,24 @@
3
3
  const { load, parse } = require('./lib/core');
4
4
  const { watch } = require('./lib/watch');
5
5
 
6
- module.exports = {
7
- load,
6
+ function loadEntry(options)
7
+ {
8
+ return load(options);
9
+ }
10
+
11
+ /**
12
+ * Watch resolved .menv files and reload on change.
13
+ * @param {object} options
14
+ * @param {(err: Error|null, result?: {parsed: object, origins: object, files: string[]}) => void} onChange
15
+ * @returns {{close: () => void}}
16
+ */
17
+ function watchEntry(options, onChange)
18
+ {
19
+ return watch(options, onChange, loadEntry);
20
+ }
21
+
22
+ module.exports = Object.assign(loadEntry, {
23
+ load: loadEntry,
8
24
  parse,
9
- /**
10
- * Watch resolved .menv files and reload on change.
11
- * @param {object} options
12
- * @param {(err: Error|null, result?: {parsed: object, origins: object, files: string[]}) => void} onChange
13
- * @returns {{close: () => void}}
14
- */
15
- watch(options, onChange)
16
- {
17
- return watch(options, onChange, load);
18
- }
19
- };
25
+ watch: watchEntry
26
+ });
package/src/lib/core.js CHANGED
@@ -30,7 +30,7 @@ function buildState()
30
30
  */
31
31
  function exportToEnv(values, options)
32
32
  {
33
- if (!options.export) return;
33
+ if (!options.exportEnv) return;
34
34
  for (const [key, value] of Object.entries(values))
35
35
  {
36
36
  if (!options.override && Object.prototype.hasOwnProperty.call(process.env, key))
@@ -41,6 +41,18 @@ function exportToEnv(values, options)
41
41
  }
42
42
  }
43
43
 
44
+ /**
45
+ * Attach parsed values to process.menv unless disabled.
46
+ * @param {object} values
47
+ * @param {object} options
48
+ * @returns {void}
49
+ */
50
+ function attachToProcess(values, options)
51
+ {
52
+ if (options.attach === false) return;
53
+ process.menv = values;
54
+ }
55
+
44
56
  /**
45
57
  * Load .menv files and return parsed values with origins.
46
58
  * @param {object} options
@@ -81,6 +93,8 @@ function load(options = {})
81
93
  deepFreeze(state.values);
82
94
  }
83
95
 
96
+ attachToProcess(state.values, options);
97
+
84
98
  return {
85
99
  parsed: state.values,
86
100
  origins: state.origins,