scenv 0.8.0 → 1.0.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
@@ -42,13 +42,13 @@ await apiUrl.save(); // write current value to a context file
42
42
 
43
43
  Any string value matching **`@<context>:<key>`** (e.g. `@prod:core_server_url`) is resolved from that context file first—in set, env, context, default, and prompts.
44
44
 
45
- Prompting (when to ask the user) is controlled by config `prompt`: `always` | `never` | `fallback` | `no-env`.
45
+ Prompting is off by default (`prompt: "never"`). To enable it, set config `prompt` to `always`, `fallback`, or `no-env` (via config file, `SCENV_PROMPT`, or `configure()`).
46
46
 
47
47
  ## Optional integrations
48
48
 
49
49
  | Package | Purpose |
50
50
  | -------------------------------------------------------------- | ------------------------------------------------------------- |
51
- | [scenv-zod](https://www.npmjs.com/package/scenv-zod) | `validator(zodSchema)` for type-safe validation and coercion. |
51
+ | [scenv-zod](https://www.npmjs.com/package/scenv-zod) | `parser(zodSchema)` for type-safe parsing and coercion. |
52
52
  | [scenv-inquirer](https://www.npmjs.com/package/scenv-inquirer) | `prompt()` and callbacks for interactive prompts. |
53
53
 
54
54
  ## Documentation
package/dist/index.cjs CHANGED
@@ -477,7 +477,7 @@ function defaultKeyFromName(name) {
477
477
  function defaultEnvFromKey(key) {
478
478
  return key.toUpperCase().replace(/-/g, "_");
479
479
  }
480
- function normalizeValidatorResult(result) {
480
+ function normalizeParserResult(result) {
481
481
  if (typeof result === "boolean") {
482
482
  return result ? { success: true } : { success: false };
483
483
  }
@@ -487,7 +487,7 @@ function normalizeValidatorResult(result) {
487
487
  function scenv(name, options = {}) {
488
488
  const key = options.key ?? defaultKeyFromName(name);
489
489
  const envKey = options.env ?? defaultEnvFromKey(key);
490
- const validator = options.validator;
490
+ const parserFn = options.parser;
491
491
  const promptFn = options.prompt;
492
492
  const defaultValue = options.default;
493
493
  async function resolveRaw() {
@@ -526,7 +526,7 @@ function scenv(name, options = {}) {
526
526
  return { raw: void 0, source: void 0 };
527
527
  }
528
528
  function shouldPrompt(config, hadValue, hadEnv) {
529
- const mode = config.prompt ?? "fallback";
529
+ const mode = config.prompt ?? "never";
530
530
  if (mode === "never") return false;
531
531
  if (mode === "always") return true;
532
532
  if (mode === "fallback") return !hadValue;
@@ -542,7 +542,7 @@ function scenv(name, options = {}) {
542
542
  const doPrompt = shouldPrompt(config, hadValue, hadEnv);
543
543
  log(
544
544
  "debug",
545
- `prompt decision key=${key} prompt=${config.prompt ?? "fallback"} hadValue=${hadValue} hadEnv=${hadEnv} -> ${doPrompt ? "prompt" : "no prompt"}`
545
+ `prompt decision key=${key} prompt=${config.prompt ?? "never"} hadValue=${hadValue} hadEnv=${hadEnv} -> ${doPrompt ? "prompt" : "no prompt"}`
546
546
  );
547
547
  const effectiveDefault = overrides?.default !== void 0 ? overrides.default : defaultValue;
548
548
  const resolvedDefault = effectiveDefault === void 0 ? void 0 : typeof effectiveDefault === "string" ? resolveContextReference(effectiveDefault, key) : effectiveDefault;
@@ -574,10 +574,10 @@ function scenv(name, options = {}) {
574
574
  log("info", `variable "${name}" (key=${key}) resolved from ${resolvedFrom}`);
575
575
  return { value, raw, hadEnv, wasPrompted };
576
576
  }
577
- function validate(value) {
578
- if (!validator) return { success: true, data: value };
579
- const result = validator(value);
580
- const normalized = normalizeValidatorResult(result);
577
+ function parse(value) {
578
+ if (!parserFn) return { success: true, data: value };
579
+ const result = parserFn(value);
580
+ const normalized = normalizeParserResult(result);
581
581
  if (normalized.success) {
582
582
  const data = "data" in normalized && normalized.data !== void 0 ? normalized.data : value;
583
583
  return { success: true, data };
@@ -589,13 +589,13 @@ function scenv(name, options = {}) {
589
589
  }
590
590
  async function get(options2) {
591
591
  const { value, wasPrompted } = await getResolvedValue(options2);
592
- const validated = validate(value);
593
- if (!validated.success) {
594
- const errMsg = `Validation failed for "${name}": ${validated.error ?? "unknown"}`;
592
+ const parsed = parse(value);
593
+ if (!parsed.success) {
594
+ const errMsg = `Parsing failed for "${name}": ${parsed.error ?? "unknown"}`;
595
595
  log("error", errMsg);
596
596
  throw new Error(errMsg);
597
597
  }
598
- const final = validated.data;
598
+ const final = parsed.data;
599
599
  const config = loadConfig();
600
600
  if (wasPrompted) setInMemoryContext(key, String(final));
601
601
  if (config.saveContextTo) {
@@ -617,16 +617,16 @@ function scenv(name, options = {}) {
617
617
  }
618
618
  async function save(value) {
619
619
  const toSave = value ?? (await getResolvedValue()).value;
620
- const validated = validate(toSave);
621
- if (!validated.success) {
622
- const errMsg = `Validation failed for "${name}": ${validated.error ?? "unknown"}`;
620
+ const parsed = parse(toSave);
621
+ if (!parsed.success) {
622
+ const errMsg = `Parsing failed for "${name}": ${parsed.error ?? "unknown"}`;
623
623
  log("error", errMsg);
624
624
  throw new Error(errMsg);
625
625
  }
626
626
  const config = loadConfig();
627
- setInMemoryContext(key, String(validated.data));
627
+ setInMemoryContext(key, String(parsed.data));
628
628
  if (config.saveContextTo) {
629
- writeToContext(config.saveContextTo, key, String(validated.data));
629
+ writeToContext(config.saveContextTo, key, String(parsed.data));
630
630
  log("info", `Saved key=${key} to saveContextTo ${config.saveContextTo}`);
631
631
  }
632
632
  }
package/dist/index.d.cts CHANGED
@@ -29,7 +29,7 @@ interface ScenvConfig {
29
29
  context?: string[];
30
30
  /** Merge these context names with existing (CLI: `--add-context a,b,c`). Ignored if `context` is set in the same layer. */
31
31
  addContext?: string[];
32
- /** When to prompt for a variable value. See {@link PromptMode}. Default is `"fallback"`. */
32
+ /** When to prompt for a variable value. See {@link PromptMode}. Default is `"never"`; set to `always`, `fallback`, or `no-env` to enable prompting (via config file, SCENV_PROMPT, or configure()). */
33
33
  prompt?: PromptMode;
34
34
  /** If true, environment variables are not used during resolution. */
35
35
  ignoreEnv?: boolean;
@@ -154,18 +154,35 @@ declare function getMergedContextValues(): Record<string, string>;
154
154
  declare function getContextWritePath(contextName: string): string;
155
155
 
156
156
  /**
157
- * Return type for a variable's optional `validator` function. Use a boolean for simple
158
- * pass/fail, or an object to pass a transformed value or a custom error.
159
- * - `true` or `{ success: true, data?: T }` – validation passed; optional `data` replaces the value.
160
- * - `false` or `{ success: false, error?: unknown }` – validation failed; `.get()` throws with the error.
157
+ * Return type for a variable's optional `parser` function. Input is always the raw string
158
+ * (from set/env/context) or the default. Use a boolean for simple pass/fail, or an object
159
+ * to pass a parsed/transformed value or a custom error.
160
+ * - `true` or `{ success: true, data?: T }` – parsing passed; optional `data` is the output value (type T).
161
+ * - `false` or `{ success: false, error?: unknown }` – parsing failed; `.get()` throws with the error.
161
162
  */
162
- type ValidatorResult<T> = boolean | {
163
+ type ParserResult<T> = boolean | {
163
164
  success: true;
164
165
  data?: T;
165
166
  } | {
166
167
  success: false;
167
168
  error?: unknown;
168
169
  };
170
+ /**
171
+ * Infers the variable's value type (output type) from options: when a parser returns
172
+ * `{ success: true, data: D }`, that D is used; otherwise the type comes from `default` or defaults to string.
173
+ */
174
+ type InferVariableType<O> = O extends {
175
+ parser: (v: unknown) => infer R;
176
+ } ? R extends {
177
+ success: true;
178
+ data: infer D;
179
+ } ? D extends undefined ? O extends {
180
+ default: infer Def;
181
+ } ? Def : string : D : O extends {
182
+ default: infer Def;
183
+ } ? Def : string : O extends {
184
+ default: infer Def;
185
+ } ? Def : string;
169
186
  /**
170
187
  * Prompt function signature. Called when config requests prompting for this variable.
171
188
  * Receives the variable's display name and the current default (from set/env/context or option default).
@@ -175,17 +192,18 @@ type PromptFn<T> = (name: string, defaultValue: T) => T | Promise<T>;
175
192
  /**
176
193
  * Options when creating a variable with {@link scenv}. All properties are optional.
177
194
  * If you omit `key` and `env`, they are derived from `name`: e.g. "API URL" → key `api_url`, env `API_URL`.
195
+ * Input from set/env/context is always string; `default` and the variable's value type are the output type T.
178
196
  */
179
- interface ScenvVariableOptions<T> {
197
+ interface ScenvVariableOptions<T = string> {
180
198
  /** Internal key for --set, context files, and env. Default: name lowercased, spaces → underscores, non-alphanumeric stripped (e.g. "API URL" → "api_url"). */
181
199
  key?: string;
182
200
  /** Environment variable name (e.g. API_URL). Default: key uppercased, hyphens → underscores. */
183
201
  env?: string;
184
- /** Fallback when nothing is provided via --set, env, or context (and we're not prompting). */
202
+ /** Fallback when nothing is provided via --set, env, or context (and we're not prompting). Same type T as the variable's output (not parsed). */
185
203
  default?: T;
186
- /** Optional. Run after value is resolved or prompted. Return true / { success: true } to accept, false / { success: false, error } to reject (get() throws). Use to coerce types or enforce rules. */
187
- validator?: (val: T) => ValidatorResult<T>;
188
- /** Optional. Called when config says to prompt (e.g. prompt: "fallback" and no value found). Overrides callbacks.defaultPrompt for this variable. */
204
+ /** Optional. Parses the raw string (or default) into output type T. Receives raw value (typically string). Return { success: true, data } with the parsed value; variable type is inferred from data. */
205
+ parser?: (val: unknown) => ParserResult<T>;
206
+ /** Optional. Called when config has enabled prompting (e.g. prompt: "fallback" and no value found). Overrides callbacks.defaultPrompt for this variable. */
189
207
  prompt?: PromptFn<T>;
190
208
  }
191
209
  /**
@@ -204,8 +222,8 @@ interface GetOptions<T> {
204
222
  */
205
223
  interface ScenvVariable<T> {
206
224
  /**
207
- * Resolve and return the value. Uses resolution order (set > env > context > default) and any prompt/validator.
208
- * @throws If no value is found and no default/prompt, or if validation fails.
225
+ * Resolve and return the value. Uses resolution order (set > env > context > default) and any prompt/parser.
226
+ * @throws If no value is found and no default/prompt, or if parsing fails.
209
227
  */
210
228
  get(options?: GetOptions<T>): Promise<T>;
211
229
  /**
@@ -236,16 +254,15 @@ interface ScenvVariable<T> {
236
254
  * - Environment variable (e.g. API_URL for key "api_url")
237
255
  * - Context files (merged key-value from the context list in config, e.g. dev.context.json)
238
256
  *
239
- * If config says to prompt (see prompt mode in config: "always", "fallback", "no-env"), the prompt callback
257
+ * If prompting is enabled in config (prompt: "always", "fallback", or "no-env"), the prompt callback
240
258
  * may run. When it runs, it receives the variable name and a suggested value (the raw value if any, otherwise
241
259
  * the default option). The callback's return value is used as the value. When we don't prompt, we use the
242
260
  * raw value if present, otherwise the default option, otherwise get() throws (no value).
243
261
  *
244
- * ## Validator
262
+ * ## Parser
245
263
  *
246
- * If you pass a validator option, it is called with the resolved or prompted value. It can return true or
247
- * { success: true } to accept, or false or { success: false, error } to reject; on reject, get() throws.
248
- * Use it to coerce types (e.g. string to number) or enforce rules.
264
+ * If you pass a parser option, it is called with the raw value (typically string from set/env/context) or the default.
265
+ * Return { success: true, data } with the parsed output; the variable's type is inferred from data. On { success: false }, get() throws.
249
266
  *
250
267
  * ## save()
251
268
  *
@@ -254,16 +271,20 @@ interface ScenvVariable<T> {
254
271
  * When the user is prompted during get(), the value is always saved (to saveContextTo file if set, and always to in-memory)
255
272
  * so a second get() on the same variable does not prompt again.
256
273
  *
257
- * @typeParam T - Value type (default string). Use a validator to coerce to number, boolean, etc.
274
+ * @typeParam T - Output (value) type of the variable, e.g. string, number, URL. Defaults to string.
258
275
  * @param name - Display name used in prompts and errors. If you omit key/env, key is derived from name (e.g. "API URL" → "api_url") and env from key (e.g. "API_URL").
259
- * @param options - Optional. key, env, default, validator, prompt. See {@link ScenvVariableOptions}.
260
- * @returns A {@link ScenvVariable} with get(), safeGet(), and save().
276
+ * @param options - Optional. key, env, default, parser, prompt. See {@link ScenvVariableOptions}.
277
+ * @returns A {@link ScenvVariable<T>} with get(), safeGet(), and save().
261
278
  *
262
279
  * @example
263
280
  * const apiUrl = scenv("API URL", { default: "http://localhost:4000" });
264
281
  * const url = await apiUrl.get();
282
+ *
283
+ * @example
284
+ * const port = scenv<number>("Port", { parser: parser(z.coerce.number()), default: 3000 });
285
+ * const n = await port.get(); // number
265
286
  */
266
- declare function scenv<T>(name: string, options?: ScenvVariableOptions<T>): ScenvVariable<T>;
287
+ declare function scenv<T = string>(name: string, options?: ScenvVariableOptions<T>): ScenvVariable<T>;
267
288
 
268
289
  /**
269
290
  * Parses command-line arguments into a partial {@link ScenvConfig} suitable for {@link configure}.
@@ -286,4 +307,4 @@ declare function scenv<T>(name: string, options?: ScenvVariableOptions<T>): Scen
286
307
  */
287
308
  declare function parseScenvArgs(argv: string[]): Partial<ScenvConfig>;
288
309
 
289
- export { type DefaultPromptFn, type GetOptions, LOG_LEVELS, type LogLevel, type PromptMode, type SaveMode, type ScenvCallbacks, type ScenvConfig, type ScenvVariable, configure, discoverContextPaths, getCallbacks, getContext, getContextWritePath, getInMemoryContext, getMergedContextValues, loadConfig, parseScenvArgs, resetConfig, resetInMemoryContext, resetLogState, scenv, setInMemoryContext };
310
+ export { type DefaultPromptFn, type GetOptions, type InferVariableType, LOG_LEVELS, type LogLevel, type ParserResult, type PromptMode, type SaveMode, type ScenvCallbacks, type ScenvConfig, type ScenvVariable, type ScenvVariableOptions, configure, discoverContextPaths, getCallbacks, getContext, getContextWritePath, getInMemoryContext, getMergedContextValues, loadConfig, parseScenvArgs, resetConfig, resetInMemoryContext, resetLogState, scenv, setInMemoryContext };
package/dist/index.d.ts CHANGED
@@ -29,7 +29,7 @@ interface ScenvConfig {
29
29
  context?: string[];
30
30
  /** Merge these context names with existing (CLI: `--add-context a,b,c`). Ignored if `context` is set in the same layer. */
31
31
  addContext?: string[];
32
- /** When to prompt for a variable value. See {@link PromptMode}. Default is `"fallback"`. */
32
+ /** When to prompt for a variable value. See {@link PromptMode}. Default is `"never"`; set to `always`, `fallback`, or `no-env` to enable prompting (via config file, SCENV_PROMPT, or configure()). */
33
33
  prompt?: PromptMode;
34
34
  /** If true, environment variables are not used during resolution. */
35
35
  ignoreEnv?: boolean;
@@ -154,18 +154,35 @@ declare function getMergedContextValues(): Record<string, string>;
154
154
  declare function getContextWritePath(contextName: string): string;
155
155
 
156
156
  /**
157
- * Return type for a variable's optional `validator` function. Use a boolean for simple
158
- * pass/fail, or an object to pass a transformed value or a custom error.
159
- * - `true` or `{ success: true, data?: T }` – validation passed; optional `data` replaces the value.
160
- * - `false` or `{ success: false, error?: unknown }` – validation failed; `.get()` throws with the error.
157
+ * Return type for a variable's optional `parser` function. Input is always the raw string
158
+ * (from set/env/context) or the default. Use a boolean for simple pass/fail, or an object
159
+ * to pass a parsed/transformed value or a custom error.
160
+ * - `true` or `{ success: true, data?: T }` – parsing passed; optional `data` is the output value (type T).
161
+ * - `false` or `{ success: false, error?: unknown }` – parsing failed; `.get()` throws with the error.
161
162
  */
162
- type ValidatorResult<T> = boolean | {
163
+ type ParserResult<T> = boolean | {
163
164
  success: true;
164
165
  data?: T;
165
166
  } | {
166
167
  success: false;
167
168
  error?: unknown;
168
169
  };
170
+ /**
171
+ * Infers the variable's value type (output type) from options: when a parser returns
172
+ * `{ success: true, data: D }`, that D is used; otherwise the type comes from `default` or defaults to string.
173
+ */
174
+ type InferVariableType<O> = O extends {
175
+ parser: (v: unknown) => infer R;
176
+ } ? R extends {
177
+ success: true;
178
+ data: infer D;
179
+ } ? D extends undefined ? O extends {
180
+ default: infer Def;
181
+ } ? Def : string : D : O extends {
182
+ default: infer Def;
183
+ } ? Def : string : O extends {
184
+ default: infer Def;
185
+ } ? Def : string;
169
186
  /**
170
187
  * Prompt function signature. Called when config requests prompting for this variable.
171
188
  * Receives the variable's display name and the current default (from set/env/context or option default).
@@ -175,17 +192,18 @@ type PromptFn<T> = (name: string, defaultValue: T) => T | Promise<T>;
175
192
  /**
176
193
  * Options when creating a variable with {@link scenv}. All properties are optional.
177
194
  * If you omit `key` and `env`, they are derived from `name`: e.g. "API URL" → key `api_url`, env `API_URL`.
195
+ * Input from set/env/context is always string; `default` and the variable's value type are the output type T.
178
196
  */
179
- interface ScenvVariableOptions<T> {
197
+ interface ScenvVariableOptions<T = string> {
180
198
  /** Internal key for --set, context files, and env. Default: name lowercased, spaces → underscores, non-alphanumeric stripped (e.g. "API URL" → "api_url"). */
181
199
  key?: string;
182
200
  /** Environment variable name (e.g. API_URL). Default: key uppercased, hyphens → underscores. */
183
201
  env?: string;
184
- /** Fallback when nothing is provided via --set, env, or context (and we're not prompting). */
202
+ /** Fallback when nothing is provided via --set, env, or context (and we're not prompting). Same type T as the variable's output (not parsed). */
185
203
  default?: T;
186
- /** Optional. Run after value is resolved or prompted. Return true / { success: true } to accept, false / { success: false, error } to reject (get() throws). Use to coerce types or enforce rules. */
187
- validator?: (val: T) => ValidatorResult<T>;
188
- /** Optional. Called when config says to prompt (e.g. prompt: "fallback" and no value found). Overrides callbacks.defaultPrompt for this variable. */
204
+ /** Optional. Parses the raw string (or default) into output type T. Receives raw value (typically string). Return { success: true, data } with the parsed value; variable type is inferred from data. */
205
+ parser?: (val: unknown) => ParserResult<T>;
206
+ /** Optional. Called when config has enabled prompting (e.g. prompt: "fallback" and no value found). Overrides callbacks.defaultPrompt for this variable. */
189
207
  prompt?: PromptFn<T>;
190
208
  }
191
209
  /**
@@ -204,8 +222,8 @@ interface GetOptions<T> {
204
222
  */
205
223
  interface ScenvVariable<T> {
206
224
  /**
207
- * Resolve and return the value. Uses resolution order (set > env > context > default) and any prompt/validator.
208
- * @throws If no value is found and no default/prompt, or if validation fails.
225
+ * Resolve and return the value. Uses resolution order (set > env > context > default) and any prompt/parser.
226
+ * @throws If no value is found and no default/prompt, or if parsing fails.
209
227
  */
210
228
  get(options?: GetOptions<T>): Promise<T>;
211
229
  /**
@@ -236,16 +254,15 @@ interface ScenvVariable<T> {
236
254
  * - Environment variable (e.g. API_URL for key "api_url")
237
255
  * - Context files (merged key-value from the context list in config, e.g. dev.context.json)
238
256
  *
239
- * If config says to prompt (see prompt mode in config: "always", "fallback", "no-env"), the prompt callback
257
+ * If prompting is enabled in config (prompt: "always", "fallback", or "no-env"), the prompt callback
240
258
  * may run. When it runs, it receives the variable name and a suggested value (the raw value if any, otherwise
241
259
  * the default option). The callback's return value is used as the value. When we don't prompt, we use the
242
260
  * raw value if present, otherwise the default option, otherwise get() throws (no value).
243
261
  *
244
- * ## Validator
262
+ * ## Parser
245
263
  *
246
- * If you pass a validator option, it is called with the resolved or prompted value. It can return true or
247
- * { success: true } to accept, or false or { success: false, error } to reject; on reject, get() throws.
248
- * Use it to coerce types (e.g. string to number) or enforce rules.
264
+ * If you pass a parser option, it is called with the raw value (typically string from set/env/context) or the default.
265
+ * Return { success: true, data } with the parsed output; the variable's type is inferred from data. On { success: false }, get() throws.
249
266
  *
250
267
  * ## save()
251
268
  *
@@ -254,16 +271,20 @@ interface ScenvVariable<T> {
254
271
  * When the user is prompted during get(), the value is always saved (to saveContextTo file if set, and always to in-memory)
255
272
  * so a second get() on the same variable does not prompt again.
256
273
  *
257
- * @typeParam T - Value type (default string). Use a validator to coerce to number, boolean, etc.
274
+ * @typeParam T - Output (value) type of the variable, e.g. string, number, URL. Defaults to string.
258
275
  * @param name - Display name used in prompts and errors. If you omit key/env, key is derived from name (e.g. "API URL" → "api_url") and env from key (e.g. "API_URL").
259
- * @param options - Optional. key, env, default, validator, prompt. See {@link ScenvVariableOptions}.
260
- * @returns A {@link ScenvVariable} with get(), safeGet(), and save().
276
+ * @param options - Optional. key, env, default, parser, prompt. See {@link ScenvVariableOptions}.
277
+ * @returns A {@link ScenvVariable<T>} with get(), safeGet(), and save().
261
278
  *
262
279
  * @example
263
280
  * const apiUrl = scenv("API URL", { default: "http://localhost:4000" });
264
281
  * const url = await apiUrl.get();
282
+ *
283
+ * @example
284
+ * const port = scenv<number>("Port", { parser: parser(z.coerce.number()), default: 3000 });
285
+ * const n = await port.get(); // number
265
286
  */
266
- declare function scenv<T>(name: string, options?: ScenvVariableOptions<T>): ScenvVariable<T>;
287
+ declare function scenv<T = string>(name: string, options?: ScenvVariableOptions<T>): ScenvVariable<T>;
267
288
 
268
289
  /**
269
290
  * Parses command-line arguments into a partial {@link ScenvConfig} suitable for {@link configure}.
@@ -286,4 +307,4 @@ declare function scenv<T>(name: string, options?: ScenvVariableOptions<T>): Scen
286
307
  */
287
308
  declare function parseScenvArgs(argv: string[]): Partial<ScenvConfig>;
288
309
 
289
- export { type DefaultPromptFn, type GetOptions, LOG_LEVELS, type LogLevel, type PromptMode, type SaveMode, type ScenvCallbacks, type ScenvConfig, type ScenvVariable, configure, discoverContextPaths, getCallbacks, getContext, getContextWritePath, getInMemoryContext, getMergedContextValues, loadConfig, parseScenvArgs, resetConfig, resetInMemoryContext, resetLogState, scenv, setInMemoryContext };
310
+ export { type DefaultPromptFn, type GetOptions, type InferVariableType, LOG_LEVELS, type LogLevel, type ParserResult, type PromptMode, type SaveMode, type ScenvCallbacks, type ScenvConfig, type ScenvVariable, type ScenvVariableOptions, configure, discoverContextPaths, getCallbacks, getContext, getContextWritePath, getInMemoryContext, getMergedContextValues, loadConfig, parseScenvArgs, resetConfig, resetInMemoryContext, resetLogState, scenv, setInMemoryContext };
package/dist/index.js CHANGED
@@ -444,7 +444,7 @@ function defaultKeyFromName(name) {
444
444
  function defaultEnvFromKey(key) {
445
445
  return key.toUpperCase().replace(/-/g, "_");
446
446
  }
447
- function normalizeValidatorResult(result) {
447
+ function normalizeParserResult(result) {
448
448
  if (typeof result === "boolean") {
449
449
  return result ? { success: true } : { success: false };
450
450
  }
@@ -454,7 +454,7 @@ function normalizeValidatorResult(result) {
454
454
  function scenv(name, options = {}) {
455
455
  const key = options.key ?? defaultKeyFromName(name);
456
456
  const envKey = options.env ?? defaultEnvFromKey(key);
457
- const validator = options.validator;
457
+ const parserFn = options.parser;
458
458
  const promptFn = options.prompt;
459
459
  const defaultValue = options.default;
460
460
  async function resolveRaw() {
@@ -493,7 +493,7 @@ function scenv(name, options = {}) {
493
493
  return { raw: void 0, source: void 0 };
494
494
  }
495
495
  function shouldPrompt(config, hadValue, hadEnv) {
496
- const mode = config.prompt ?? "fallback";
496
+ const mode = config.prompt ?? "never";
497
497
  if (mode === "never") return false;
498
498
  if (mode === "always") return true;
499
499
  if (mode === "fallback") return !hadValue;
@@ -509,7 +509,7 @@ function scenv(name, options = {}) {
509
509
  const doPrompt = shouldPrompt(config, hadValue, hadEnv);
510
510
  log(
511
511
  "debug",
512
- `prompt decision key=${key} prompt=${config.prompt ?? "fallback"} hadValue=${hadValue} hadEnv=${hadEnv} -> ${doPrompt ? "prompt" : "no prompt"}`
512
+ `prompt decision key=${key} prompt=${config.prompt ?? "never"} hadValue=${hadValue} hadEnv=${hadEnv} -> ${doPrompt ? "prompt" : "no prompt"}`
513
513
  );
514
514
  const effectiveDefault = overrides?.default !== void 0 ? overrides.default : defaultValue;
515
515
  const resolvedDefault = effectiveDefault === void 0 ? void 0 : typeof effectiveDefault === "string" ? resolveContextReference(effectiveDefault, key) : effectiveDefault;
@@ -541,10 +541,10 @@ function scenv(name, options = {}) {
541
541
  log("info", `variable "${name}" (key=${key}) resolved from ${resolvedFrom}`);
542
542
  return { value, raw, hadEnv, wasPrompted };
543
543
  }
544
- function validate(value) {
545
- if (!validator) return { success: true, data: value };
546
- const result = validator(value);
547
- const normalized = normalizeValidatorResult(result);
544
+ function parse(value) {
545
+ if (!parserFn) return { success: true, data: value };
546
+ const result = parserFn(value);
547
+ const normalized = normalizeParserResult(result);
548
548
  if (normalized.success) {
549
549
  const data = "data" in normalized && normalized.data !== void 0 ? normalized.data : value;
550
550
  return { success: true, data };
@@ -556,13 +556,13 @@ function scenv(name, options = {}) {
556
556
  }
557
557
  async function get(options2) {
558
558
  const { value, wasPrompted } = await getResolvedValue(options2);
559
- const validated = validate(value);
560
- if (!validated.success) {
561
- const errMsg = `Validation failed for "${name}": ${validated.error ?? "unknown"}`;
559
+ const parsed = parse(value);
560
+ if (!parsed.success) {
561
+ const errMsg = `Parsing failed for "${name}": ${parsed.error ?? "unknown"}`;
562
562
  log("error", errMsg);
563
563
  throw new Error(errMsg);
564
564
  }
565
- const final = validated.data;
565
+ const final = parsed.data;
566
566
  const config = loadConfig();
567
567
  if (wasPrompted) setInMemoryContext(key, String(final));
568
568
  if (config.saveContextTo) {
@@ -584,16 +584,16 @@ function scenv(name, options = {}) {
584
584
  }
585
585
  async function save(value) {
586
586
  const toSave = value ?? (await getResolvedValue()).value;
587
- const validated = validate(toSave);
588
- if (!validated.success) {
589
- const errMsg = `Validation failed for "${name}": ${validated.error ?? "unknown"}`;
587
+ const parsed = parse(toSave);
588
+ if (!parsed.success) {
589
+ const errMsg = `Parsing failed for "${name}": ${parsed.error ?? "unknown"}`;
590
590
  log("error", errMsg);
591
591
  throw new Error(errMsg);
592
592
  }
593
593
  const config = loadConfig();
594
- setInMemoryContext(key, String(validated.data));
594
+ setInMemoryContext(key, String(parsed.data));
595
595
  if (config.saveContextTo) {
596
- writeToContext(config.saveContextTo, key, String(validated.data));
596
+ writeToContext(config.saveContextTo, key, String(parsed.data));
597
597
  log("info", `Saved key=${key} to saveContextTo ${config.saveContextTo}`);
598
598
  }
599
599
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scenv",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "Environment and context variables with runtime-configurable resolution",
5
5
  "repository": {
6
6
  "type": "git",