@optique/env 1.0.0-dev.1758 → 1.0.0-dev.1766
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/dist/index.cjs +92 -13
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +93 -14
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -111,8 +111,12 @@ function createEnvContext(options = {}) {
|
|
|
111
111
|
* {@link ValueParser}.
|
|
112
112
|
* @throws {Error} If the inner parser throws while parsing or completing a
|
|
113
113
|
* value, if the environment source throws while reading a
|
|
114
|
-
* variable,
|
|
115
|
-
* parsing the environment variable value
|
|
114
|
+
* variable, if the environment value parser throws while
|
|
115
|
+
* parsing the environment variable value, or if the inner
|
|
116
|
+
* parser's {@link Parser.validateValue} hook throws while
|
|
117
|
+
* re-validating a fallback value (environment variable value
|
|
118
|
+
* or configured `default`) — the hook can run even when no
|
|
119
|
+
* CLI tokens are parsed (see issue #414).
|
|
116
120
|
* @since 1.0.0
|
|
117
121
|
*/
|
|
118
122
|
function bindEnv(parser, options) {
|
|
@@ -207,17 +211,22 @@ function bindEnv(parser, options) {
|
|
|
207
211
|
configurable: true,
|
|
208
212
|
enumerable: false
|
|
209
213
|
});
|
|
214
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(boundParser, "validateValue", {
|
|
215
|
+
value: parser.validateValue.bind(parser),
|
|
216
|
+
configurable: true,
|
|
217
|
+
enumerable: false
|
|
218
|
+
});
|
|
210
219
|
const dependencyMetadata = (0, __optique_core_parser.composeWrappedSourceMetadata)(parser.dependencyMetadata, (sourceMetadata) => ({
|
|
211
220
|
...sourceMetadata,
|
|
212
221
|
extractSourceValue: (state) => {
|
|
213
222
|
if (!isEnvBindState(state)) {
|
|
214
|
-
if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue);
|
|
223
|
+
if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue, parser);
|
|
215
224
|
return sourceMetadata.extractSourceValue(state);
|
|
216
225
|
}
|
|
217
226
|
if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
|
|
218
227
|
const innerState = state.cliState ?? state;
|
|
219
228
|
if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(innerState);
|
|
220
|
-
return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue);
|
|
229
|
+
return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue, parser);
|
|
221
230
|
}
|
|
222
231
|
}));
|
|
223
232
|
if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
|
|
@@ -227,11 +236,57 @@ function bindEnv(parser, options) {
|
|
|
227
236
|
});
|
|
228
237
|
return boundParser;
|
|
229
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Resolves a `bindEnv()` fallback value with env > default > inner
|
|
241
|
+
* `complete()` priority, running each candidate through the inner
|
|
242
|
+
* parser's `validateValue()` hook when available so the inner CLI
|
|
243
|
+
* parser's constraints are enforced on fallback values (see issue
|
|
244
|
+
* #414).
|
|
245
|
+
*
|
|
246
|
+
* @param state The wrapper state, which may carry env annotations.
|
|
247
|
+
* @param options The binding options with lookup and default settings.
|
|
248
|
+
* @param mode The parser mode (`"sync"` or `"async"`), used to
|
|
249
|
+
* dispatch env parsing and fallback validation.
|
|
250
|
+
* @param innerParser Optional wrapped parser. When present, its
|
|
251
|
+
* `validateValue()` hook is used to re-validate
|
|
252
|
+
* fallback values and its `complete()` is
|
|
253
|
+
* delegated to as the last fallback.
|
|
254
|
+
* @param innerState Optional unwrapped inner state to pass through to
|
|
255
|
+
* `innerParser.complete()`.
|
|
256
|
+
* @param exec Optional execution context forwarded to
|
|
257
|
+
* `innerParser.complete()`.
|
|
258
|
+
* @returns The resolved value as a mode-dependent result.
|
|
259
|
+
* @throws {Error} Propagates errors thrown by the env source callback
|
|
260
|
+
* (`sourceData.source(fullKey)`) while reading the
|
|
261
|
+
* environment variable.
|
|
262
|
+
* @throws {Error} Propagates errors thrown by
|
|
263
|
+
* `options.parser.parse(rawValue)` (sync or async)
|
|
264
|
+
* while parsing the raw env string into `TValue`.
|
|
265
|
+
* @throws {Error} Propagates errors thrown by
|
|
266
|
+
* `innerParser.validateValue()` while re-validating
|
|
267
|
+
* a successful env-sourced value or the configured
|
|
268
|
+
* `default` against the inner CLI parser's
|
|
269
|
+
* constraints.
|
|
270
|
+
* @throws {Error} Propagates errors thrown by `innerParser.complete()`
|
|
271
|
+
* when falling through to the inner parser (e.g.,
|
|
272
|
+
* `bindEnv(bindConfig(...))` with neither env nor
|
|
273
|
+
* default set).
|
|
274
|
+
*/
|
|
230
275
|
function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
231
276
|
const annotations = (0, __optique_core_annotations.getAnnotations)(state);
|
|
232
277
|
const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
|
|
233
278
|
const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
|
|
234
279
|
const rawValue = sourceData?.source(fullKey);
|
|
280
|
+
const validateSync = (parsed) => {
|
|
281
|
+
if (!parsed.success) return parsed;
|
|
282
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
283
|
+
return innerParser.validateValue(parsed.value);
|
|
284
|
+
};
|
|
285
|
+
const validateAsync = async (parsed) => {
|
|
286
|
+
if (!parsed.success) return parsed;
|
|
287
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
288
|
+
return await innerParser.validateValue(parsed.value);
|
|
289
|
+
};
|
|
235
290
|
if (rawValue !== void 0) {
|
|
236
291
|
if (typeof rawValue !== "string") {
|
|
237
292
|
const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
|
|
@@ -240,13 +295,21 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
|
240
295
|
error: __optique_core_message.message`Environment variable ${(0, __optique_core_message.envVar)(fullKey)} must be a string, but got: ${type}.`
|
|
241
296
|
});
|
|
242
297
|
}
|
|
243
|
-
|
|
244
|
-
|
|
298
|
+
return (0, __optique_core_mode_dispatch.dispatchByMode)(mode, () => {
|
|
299
|
+
const parsed = options.parser.parse(rawValue);
|
|
300
|
+
return validateSync(parsed);
|
|
301
|
+
}, async () => {
|
|
302
|
+
const parsed = await options.parser.parse(rawValue);
|
|
303
|
+
return await validateAsync(parsed);
|
|
304
|
+
});
|
|
245
305
|
}
|
|
246
|
-
if (options.default !== void 0) return (0, __optique_core_mode_dispatch.
|
|
306
|
+
if (options.default !== void 0) return (0, __optique_core_mode_dispatch.dispatchByMode)(mode, () => validateSync({
|
|
247
307
|
success: true,
|
|
248
308
|
value: options.default
|
|
249
|
-
})
|
|
309
|
+
}), () => validateAsync({
|
|
310
|
+
success: true,
|
|
311
|
+
value: options.default
|
|
312
|
+
}));
|
|
250
313
|
if (innerParser != null) {
|
|
251
314
|
const completeState = innerState ?? (annotations != null && innerParser.initialState == null && Reflect.get(innerParser, __optique_core_parser.inheritParentAnnotationsKey) === true ? (0, __optique_core_annotations.injectAnnotations)(innerParser.initialState, annotations) : innerParser.initialState);
|
|
252
315
|
return (0, __optique_core_mode_dispatch.wrapForMode)(mode, innerParser.complete(completeState, exec));
|
|
@@ -264,20 +327,37 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
|
264
327
|
* `options.default` and finally delegates to the wrapped parser's source
|
|
265
328
|
* extractor.
|
|
266
329
|
*
|
|
330
|
+
* When `innerParser` exposes a `validateValue` hook, env-sourced values
|
|
331
|
+
* and the configured default are re-validated against the inner parser's
|
|
332
|
+
* CLI constraints (see issue #414). This is only called from the
|
|
333
|
+
* `preservesSourceValue: true` branch in {@link bindEnv}, so the source
|
|
334
|
+
* value type is guaranteed to equal `TValue`.
|
|
335
|
+
*
|
|
267
336
|
* @param state The wrapper state, which may carry env annotations.
|
|
268
337
|
* @param options The binding options with lookup and default settings.
|
|
269
338
|
* @param innerState The unwrapped inner state for delegated extraction.
|
|
270
339
|
* @param extractInnerSourceValue The wrapped parser's source extractor.
|
|
340
|
+
* @param innerParser The wrapped parser, used to revalidate fallback values.
|
|
271
341
|
* @returns The resolved source value, an async source value, or `undefined`.
|
|
272
342
|
* @throws {Error} Propagates errors thrown by the env source callback
|
|
273
343
|
* (`sourceData.source(fullKey)`).
|
|
274
344
|
* @throws {Error} Propagates errors thrown by `options.parser.parse(rawValue)`.
|
|
345
|
+
* @throws {Error} Propagates errors thrown by
|
|
346
|
+
* `innerParser.validateValue()` while revalidating a
|
|
347
|
+
* successful env-sourced value or the configured
|
|
348
|
+
* `default` against the inner CLI parser's constraints
|
|
349
|
+
* (see issue #414).
|
|
275
350
|
*/
|
|
276
|
-
function getEnvSourceValue(state, options, innerState, extractInnerSourceValue) {
|
|
351
|
+
function getEnvSourceValue(state, options, innerState, extractInnerSourceValue, innerParser) {
|
|
277
352
|
const annotations = (0, __optique_core_annotations.getAnnotations)(state);
|
|
278
353
|
const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
|
|
279
354
|
const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
|
|
280
355
|
const rawValue = sourceData?.source(fullKey);
|
|
356
|
+
const validateFallback = (parsed) => {
|
|
357
|
+
if (!parsed.success) return parsed;
|
|
358
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
359
|
+
return innerParser.validateValue(parsed.value);
|
|
360
|
+
};
|
|
281
361
|
if (rawValue !== void 0) {
|
|
282
362
|
if (typeof rawValue !== "string") {
|
|
283
363
|
const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
|
|
@@ -286,13 +366,12 @@ function getEnvSourceValue(state, options, innerState, extractInnerSourceValue)
|
|
|
286
366
|
error: __optique_core_message.message`Environment variable ${(0, __optique_core_message.envVar)(fullKey)} must be a string, but got: ${type}.`
|
|
287
367
|
};
|
|
288
368
|
}
|
|
289
|
-
|
|
290
|
-
return parsed;
|
|
369
|
+
return (0, __optique_core_mode_dispatch.mapModeValue)(options.parser.$mode, options.parser.parse(rawValue), (p) => validateFallback(p));
|
|
291
370
|
}
|
|
292
|
-
if (options.default !== void 0) return {
|
|
371
|
+
if (options.default !== void 0) return validateFallback({
|
|
293
372
|
success: true,
|
|
294
373
|
value: options.default
|
|
295
|
-
};
|
|
374
|
+
});
|
|
296
375
|
return extractInnerSourceValue(innerState);
|
|
297
376
|
}
|
|
298
377
|
const TRUE_LITERALS = [
|
package/dist/index.d.cts
CHANGED
|
@@ -122,8 +122,12 @@ interface BindEnvOptions<M extends Mode, TValue> {
|
|
|
122
122
|
* {@link ValueParser}.
|
|
123
123
|
* @throws {Error} If the inner parser throws while parsing or completing a
|
|
124
124
|
* value, if the environment source throws while reading a
|
|
125
|
-
* variable,
|
|
126
|
-
* parsing the environment variable value
|
|
125
|
+
* variable, if the environment value parser throws while
|
|
126
|
+
* parsing the environment variable value, or if the inner
|
|
127
|
+
* parser's {@link Parser.validateValue} hook throws while
|
|
128
|
+
* re-validating a fallback value (environment variable value
|
|
129
|
+
* or configured `default`) — the hook can run even when no
|
|
130
|
+
* CLI tokens are parsed (see issue #414).
|
|
127
131
|
* @since 1.0.0
|
|
128
132
|
*/
|
|
129
133
|
declare function bindEnv<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options: BindEnvOptions<M, TValue>): Parser<M, TValue, TState>;
|
package/dist/index.d.ts
CHANGED
|
@@ -122,8 +122,12 @@ interface BindEnvOptions<M extends Mode, TValue> {
|
|
|
122
122
|
* {@link ValueParser}.
|
|
123
123
|
* @throws {Error} If the inner parser throws while parsing or completing a
|
|
124
124
|
* value, if the environment source throws while reading a
|
|
125
|
-
* variable,
|
|
126
|
-
* parsing the environment variable value
|
|
125
|
+
* variable, if the environment value parser throws while
|
|
126
|
+
* parsing the environment variable value, or if the inner
|
|
127
|
+
* parser's {@link Parser.validateValue} hook throws while
|
|
128
|
+
* re-validating a fallback value (environment variable value
|
|
129
|
+
* or configured `default`) — the hook can run even when no
|
|
130
|
+
* CLI tokens are parsed (see issue #414).
|
|
127
131
|
* @since 1.0.0
|
|
128
132
|
*/
|
|
129
133
|
declare function bindEnv<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options: BindEnvOptions<M, TValue>): Parser<M, TValue, TState>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { annotationKey, getAnnotations, injectAnnotations, isInjectedAnnotationWrapper } from "@optique/core/annotations";
|
|
2
2
|
import { envVar, message, valueSet } from "@optique/core/message";
|
|
3
|
-
import { mapModeValue, wrapForMode } from "@optique/core/mode-dispatch";
|
|
3
|
+
import { dispatchByMode, mapModeValue, wrapForMode } from "@optique/core/mode-dispatch";
|
|
4
4
|
import { composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "@optique/core/parser";
|
|
5
5
|
import { ensureNonEmptyString, isValueParser } from "@optique/core/valueparser";
|
|
6
6
|
|
|
@@ -88,8 +88,12 @@ function createEnvContext(options = {}) {
|
|
|
88
88
|
* {@link ValueParser}.
|
|
89
89
|
* @throws {Error} If the inner parser throws while parsing or completing a
|
|
90
90
|
* value, if the environment source throws while reading a
|
|
91
|
-
* variable,
|
|
92
|
-
* parsing the environment variable value
|
|
91
|
+
* variable, if the environment value parser throws while
|
|
92
|
+
* parsing the environment variable value, or if the inner
|
|
93
|
+
* parser's {@link Parser.validateValue} hook throws while
|
|
94
|
+
* re-validating a fallback value (environment variable value
|
|
95
|
+
* or configured `default`) — the hook can run even when no
|
|
96
|
+
* CLI tokens are parsed (see issue #414).
|
|
93
97
|
* @since 1.0.0
|
|
94
98
|
*/
|
|
95
99
|
function bindEnv(parser, options) {
|
|
@@ -184,17 +188,22 @@ function bindEnv(parser, options) {
|
|
|
184
188
|
configurable: true,
|
|
185
189
|
enumerable: false
|
|
186
190
|
});
|
|
191
|
+
if (typeof parser.validateValue === "function") Object.defineProperty(boundParser, "validateValue", {
|
|
192
|
+
value: parser.validateValue.bind(parser),
|
|
193
|
+
configurable: true,
|
|
194
|
+
enumerable: false
|
|
195
|
+
});
|
|
187
196
|
const dependencyMetadata = composeWrappedSourceMetadata(parser.dependencyMetadata, (sourceMetadata) => ({
|
|
188
197
|
...sourceMetadata,
|
|
189
198
|
extractSourceValue: (state) => {
|
|
190
199
|
if (!isEnvBindState(state)) {
|
|
191
|
-
if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue);
|
|
200
|
+
if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue, parser);
|
|
192
201
|
return sourceMetadata.extractSourceValue(state);
|
|
193
202
|
}
|
|
194
203
|
if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
|
|
195
204
|
const innerState = state.cliState ?? state;
|
|
196
205
|
if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(innerState);
|
|
197
|
-
return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue);
|
|
206
|
+
return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue, parser);
|
|
198
207
|
}
|
|
199
208
|
}));
|
|
200
209
|
if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
|
|
@@ -204,11 +213,57 @@ function bindEnv(parser, options) {
|
|
|
204
213
|
});
|
|
205
214
|
return boundParser;
|
|
206
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Resolves a `bindEnv()` fallback value with env > default > inner
|
|
218
|
+
* `complete()` priority, running each candidate through the inner
|
|
219
|
+
* parser's `validateValue()` hook when available so the inner CLI
|
|
220
|
+
* parser's constraints are enforced on fallback values (see issue
|
|
221
|
+
* #414).
|
|
222
|
+
*
|
|
223
|
+
* @param state The wrapper state, which may carry env annotations.
|
|
224
|
+
* @param options The binding options with lookup and default settings.
|
|
225
|
+
* @param mode The parser mode (`"sync"` or `"async"`), used to
|
|
226
|
+
* dispatch env parsing and fallback validation.
|
|
227
|
+
* @param innerParser Optional wrapped parser. When present, its
|
|
228
|
+
* `validateValue()` hook is used to re-validate
|
|
229
|
+
* fallback values and its `complete()` is
|
|
230
|
+
* delegated to as the last fallback.
|
|
231
|
+
* @param innerState Optional unwrapped inner state to pass through to
|
|
232
|
+
* `innerParser.complete()`.
|
|
233
|
+
* @param exec Optional execution context forwarded to
|
|
234
|
+
* `innerParser.complete()`.
|
|
235
|
+
* @returns The resolved value as a mode-dependent result.
|
|
236
|
+
* @throws {Error} Propagates errors thrown by the env source callback
|
|
237
|
+
* (`sourceData.source(fullKey)`) while reading the
|
|
238
|
+
* environment variable.
|
|
239
|
+
* @throws {Error} Propagates errors thrown by
|
|
240
|
+
* `options.parser.parse(rawValue)` (sync or async)
|
|
241
|
+
* while parsing the raw env string into `TValue`.
|
|
242
|
+
* @throws {Error} Propagates errors thrown by
|
|
243
|
+
* `innerParser.validateValue()` while re-validating
|
|
244
|
+
* a successful env-sourced value or the configured
|
|
245
|
+
* `default` against the inner CLI parser's
|
|
246
|
+
* constraints.
|
|
247
|
+
* @throws {Error} Propagates errors thrown by `innerParser.complete()`
|
|
248
|
+
* when falling through to the inner parser (e.g.,
|
|
249
|
+
* `bindEnv(bindConfig(...))` with neither env nor
|
|
250
|
+
* default set).
|
|
251
|
+
*/
|
|
207
252
|
function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
208
253
|
const annotations = getAnnotations(state);
|
|
209
254
|
const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
|
|
210
255
|
const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
|
|
211
256
|
const rawValue = sourceData?.source(fullKey);
|
|
257
|
+
const validateSync = (parsed) => {
|
|
258
|
+
if (!parsed.success) return parsed;
|
|
259
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
260
|
+
return innerParser.validateValue(parsed.value);
|
|
261
|
+
};
|
|
262
|
+
const validateAsync = async (parsed) => {
|
|
263
|
+
if (!parsed.success) return parsed;
|
|
264
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
265
|
+
return await innerParser.validateValue(parsed.value);
|
|
266
|
+
};
|
|
212
267
|
if (rawValue !== void 0) {
|
|
213
268
|
if (typeof rawValue !== "string") {
|
|
214
269
|
const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
|
|
@@ -217,13 +272,21 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
|
217
272
|
error: message`Environment variable ${envVar(fullKey)} must be a string, but got: ${type}.`
|
|
218
273
|
});
|
|
219
274
|
}
|
|
220
|
-
|
|
221
|
-
|
|
275
|
+
return dispatchByMode(mode, () => {
|
|
276
|
+
const parsed = options.parser.parse(rawValue);
|
|
277
|
+
return validateSync(parsed);
|
|
278
|
+
}, async () => {
|
|
279
|
+
const parsed = await options.parser.parse(rawValue);
|
|
280
|
+
return await validateAsync(parsed);
|
|
281
|
+
});
|
|
222
282
|
}
|
|
223
|
-
if (options.default !== void 0) return
|
|
283
|
+
if (options.default !== void 0) return dispatchByMode(mode, () => validateSync({
|
|
224
284
|
success: true,
|
|
225
285
|
value: options.default
|
|
226
|
-
})
|
|
286
|
+
}), () => validateAsync({
|
|
287
|
+
success: true,
|
|
288
|
+
value: options.default
|
|
289
|
+
}));
|
|
227
290
|
if (innerParser != null) {
|
|
228
291
|
const completeState = innerState ?? (annotations != null && innerParser.initialState == null && Reflect.get(innerParser, inheritParentAnnotationsKey) === true ? injectAnnotations(innerParser.initialState, annotations) : innerParser.initialState);
|
|
229
292
|
return wrapForMode(mode, innerParser.complete(completeState, exec));
|
|
@@ -241,20 +304,37 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
|
|
|
241
304
|
* `options.default` and finally delegates to the wrapped parser's source
|
|
242
305
|
* extractor.
|
|
243
306
|
*
|
|
307
|
+
* When `innerParser` exposes a `validateValue` hook, env-sourced values
|
|
308
|
+
* and the configured default are re-validated against the inner parser's
|
|
309
|
+
* CLI constraints (see issue #414). This is only called from the
|
|
310
|
+
* `preservesSourceValue: true` branch in {@link bindEnv}, so the source
|
|
311
|
+
* value type is guaranteed to equal `TValue`.
|
|
312
|
+
*
|
|
244
313
|
* @param state The wrapper state, which may carry env annotations.
|
|
245
314
|
* @param options The binding options with lookup and default settings.
|
|
246
315
|
* @param innerState The unwrapped inner state for delegated extraction.
|
|
247
316
|
* @param extractInnerSourceValue The wrapped parser's source extractor.
|
|
317
|
+
* @param innerParser The wrapped parser, used to revalidate fallback values.
|
|
248
318
|
* @returns The resolved source value, an async source value, or `undefined`.
|
|
249
319
|
* @throws {Error} Propagates errors thrown by the env source callback
|
|
250
320
|
* (`sourceData.source(fullKey)`).
|
|
251
321
|
* @throws {Error} Propagates errors thrown by `options.parser.parse(rawValue)`.
|
|
322
|
+
* @throws {Error} Propagates errors thrown by
|
|
323
|
+
* `innerParser.validateValue()` while revalidating a
|
|
324
|
+
* successful env-sourced value or the configured
|
|
325
|
+
* `default` against the inner CLI parser's constraints
|
|
326
|
+
* (see issue #414).
|
|
252
327
|
*/
|
|
253
|
-
function getEnvSourceValue(state, options, innerState, extractInnerSourceValue) {
|
|
328
|
+
function getEnvSourceValue(state, options, innerState, extractInnerSourceValue, innerParser) {
|
|
254
329
|
const annotations = getAnnotations(state);
|
|
255
330
|
const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
|
|
256
331
|
const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
|
|
257
332
|
const rawValue = sourceData?.source(fullKey);
|
|
333
|
+
const validateFallback = (parsed) => {
|
|
334
|
+
if (!parsed.success) return parsed;
|
|
335
|
+
if (innerParser == null || typeof innerParser.validateValue !== "function") return parsed;
|
|
336
|
+
return innerParser.validateValue(parsed.value);
|
|
337
|
+
};
|
|
258
338
|
if (rawValue !== void 0) {
|
|
259
339
|
if (typeof rawValue !== "string") {
|
|
260
340
|
const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
|
|
@@ -263,13 +343,12 @@ function getEnvSourceValue(state, options, innerState, extractInnerSourceValue)
|
|
|
263
343
|
error: message`Environment variable ${envVar(fullKey)} must be a string, but got: ${type}.`
|
|
264
344
|
};
|
|
265
345
|
}
|
|
266
|
-
|
|
267
|
-
return parsed;
|
|
346
|
+
return mapModeValue(options.parser.$mode, options.parser.parse(rawValue), (p) => validateFallback(p));
|
|
268
347
|
}
|
|
269
|
-
if (options.default !== void 0) return {
|
|
348
|
+
if (options.default !== void 0) return validateFallback({
|
|
270
349
|
success: true,
|
|
271
350
|
value: options.default
|
|
272
|
-
};
|
|
351
|
+
});
|
|
273
352
|
return extractInnerSourceValue(innerState);
|
|
274
353
|
}
|
|
275
354
|
const TRUE_LITERALS = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/env",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.1766+87276239",
|
|
4
4
|
"description": "Environment variable support for Optique",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"sideEffects": false,
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@optique/core": "1.0.0-dev.
|
|
57
|
+
"@optique/core": "1.0.0-dev.1766+87276239"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^20.19.9",
|