@optique/env 1.0.0-dev.1616 → 1.0.0-dev.1659

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 CHANGED
@@ -24,6 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  const __optique_core_annotations = __toESM(require("@optique/core/annotations"));
25
25
  const __optique_core_message = __toESM(require("@optique/core/message"));
26
26
  const __optique_core_mode_dispatch = __toESM(require("@optique/core/mode-dispatch"));
27
+ const __optique_core_parser = __toESM(require("@optique/core/parser"));
27
28
  const __optique_core_valueparser = __toESM(require("@optique/core/valueparser"));
28
29
 
29
30
  //#region src/index.ts
@@ -127,6 +128,7 @@ function bindEnv(parser, options) {
127
128
  $valueType: parser.$valueType,
128
129
  $stateType: parser.$stateType,
129
130
  priority: parser.priority,
131
+ [__optique_core_parser.unmatchedNonCliDependencySourceStateMarker]: true,
130
132
  usage: options.default !== void 0 ? [{
131
133
  type: "optional",
132
134
  terms: parser.usage
@@ -134,6 +136,10 @@ function bindEnv(parser, options) {
134
136
  leadingNames: parser.leadingNames,
135
137
  acceptingAnyToken: parser.acceptingAnyToken,
136
138
  initialState: parser.initialState,
139
+ getSuggestRuntimeNodes(state, path) {
140
+ const innerState = isEnvBindState(state) ? state.cliState === void 0 ? parser.initialState : state.cliState : state;
141
+ return (0, __optique_core_parser.getDelegatingSuggestRuntimeNodes)(parser, boundParser, state, path, innerState);
142
+ },
137
143
  parse: (context) => {
138
144
  const annotations = (0, __optique_core_annotations.getAnnotations)(context.state);
139
145
  const innerState = isEnvBindState(context.state) ? context.state.hasCliValue ? context.state.cliState : parser.initialState : context.state;
@@ -178,7 +184,7 @@ function bindEnv(parser, options) {
178
184
  },
179
185
  complete: (state, exec) => {
180
186
  if (isEnvBindState(state) && state.hasCliValue) return parser.complete(state.cliState, exec);
181
- return getEnvOrDefault(state, options, parser.$mode, parser, isEnvBindState(state) ? state.cliState : void 0, exec);
187
+ return getEnvOrDefault(state, options, parser.$mode, parser, isEnvBindState(state) ? state.cliState : (0, __optique_core_annotations.isInjectedAnnotationWrapper)(state) ? void 0 : state, exec);
182
188
  },
183
189
  suggest: parser.suggest,
184
190
  ...typeof deferPromptUntilConfigResolves === "function" ? { shouldDeferCompletion: (state, exec) => deferPromptUntilConfigResolves.call(parser, state, exec) } : {},
@@ -187,6 +193,7 @@ function bindEnv(parser, options) {
187
193
  return parser.getDocFragments(state, defaultValue);
188
194
  }
189
195
  };
196
+ (0, __optique_core_parser.defineInheritedAnnotationParser)(boundParser);
190
197
  if ("placeholder" in parser) Object.defineProperty(boundParser, "placeholder", {
191
198
  get() {
192
199
  return parser.placeholder;
@@ -199,6 +206,24 @@ function bindEnv(parser, options) {
199
206
  configurable: true,
200
207
  enumerable: false
201
208
  });
209
+ const dependencyMetadata = (0, __optique_core_parser.composeWrappedSourceMetadata)(parser.dependencyMetadata, (sourceMetadata) => ({
210
+ ...sourceMetadata,
211
+ extractSourceValue: (state) => {
212
+ if (!isEnvBindState(state)) {
213
+ if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue);
214
+ return sourceMetadata.extractSourceValue(state);
215
+ }
216
+ if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
217
+ const innerState = state.cliState ?? state;
218
+ if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(innerState);
219
+ return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue);
220
+ }
221
+ }));
222
+ if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
223
+ value: dependencyMetadata,
224
+ configurable: true,
225
+ enumerable: false
226
+ });
202
227
  return boundParser;
203
228
  }
204
229
  function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
@@ -222,7 +247,7 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
222
247
  value: options.default
223
248
  });
224
249
  if (innerParser != null) {
225
- const completeState = innerState ?? innerParser.initialState;
250
+ 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);
226
251
  return (0, __optique_core_mode_dispatch.wrapForMode)(mode, innerParser.complete(completeState, exec));
227
252
  }
228
253
  return (0, __optique_core_mode_dispatch.wrapForMode)(mode, {
@@ -230,6 +255,45 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
230
255
  error: __optique_core_message.message`Missing required environment variable: ${(0, __optique_core_message.envVar)(fullKey)}`
231
256
  });
232
257
  }
258
+ /**
259
+ * Resolves an env-backed dependency source with env and default fallbacks.
260
+ *
261
+ * This first checks annotations or the active env registry for the bound
262
+ * variable. If no env-backed value is available, it falls back to
263
+ * `options.default` and finally delegates to the wrapped parser's source
264
+ * extractor.
265
+ *
266
+ * @param state The wrapper state, which may carry env annotations.
267
+ * @param options The binding options with lookup and default settings.
268
+ * @param innerState The unwrapped inner state for delegated extraction.
269
+ * @param extractInnerSourceValue The wrapped parser's source extractor.
270
+ * @returns The resolved source value, an async source value, or `undefined`.
271
+ * @throws {Error} Propagates errors thrown by the env source callback
272
+ * (`sourceData.source(fullKey)`).
273
+ * @throws {Error} Propagates errors thrown by `options.parser.parse(rawValue)`.
274
+ */
275
+ function getEnvSourceValue(state, options, innerState, extractInnerSourceValue) {
276
+ const annotations = (0, __optique_core_annotations.getAnnotations)(state);
277
+ const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
278
+ const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
279
+ const rawValue = sourceData?.source(fullKey);
280
+ if (rawValue !== void 0) {
281
+ if (typeof rawValue !== "string") {
282
+ const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
283
+ return {
284
+ success: false,
285
+ error: __optique_core_message.message`Environment variable ${(0, __optique_core_message.envVar)(fullKey)} must be a string, but got: ${type}.`
286
+ };
287
+ }
288
+ const parsed = options.parser.parse(rawValue);
289
+ return parsed;
290
+ }
291
+ if (options.default !== void 0) return {
292
+ success: true,
293
+ value: options.default
294
+ };
295
+ return extractInnerSourceValue(innerState);
296
+ }
233
297
  const TRUE_LITERALS = [
234
298
  "true",
235
299
  "1",
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Message } from "@optique/core/message";
2
+ import { Mode, Parser } from "@optique/core/parser";
2
3
  import { NonEmptyString, ValueParser } from "@optique/core/valueparser";
3
4
  import { SourceContext } from "@optique/core/context";
4
- import { Mode, Parser } from "@optique/core/parser";
5
5
 
6
6
  //#region src/index.d.ts
7
7
 
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
- import { annotationKey, getAnnotations } from "@optique/core/annotations";
1
+ import { annotationKey, getAnnotations, injectAnnotations, isInjectedAnnotationWrapper } from "@optique/core/annotations";
2
2
  import { envVar, message, valueSet } from "@optique/core/message";
3
3
  import { mapModeValue, wrapForMode } from "@optique/core/mode-dispatch";
4
+ import { composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "@optique/core/parser";
4
5
  import { ensureNonEmptyString, isValueParser } from "@optique/core/valueparser";
5
6
 
6
7
  //#region src/index.ts
@@ -104,6 +105,7 @@ function bindEnv(parser, options) {
104
105
  $valueType: parser.$valueType,
105
106
  $stateType: parser.$stateType,
106
107
  priority: parser.priority,
108
+ [unmatchedNonCliDependencySourceStateMarker]: true,
107
109
  usage: options.default !== void 0 ? [{
108
110
  type: "optional",
109
111
  terms: parser.usage
@@ -111,6 +113,10 @@ function bindEnv(parser, options) {
111
113
  leadingNames: parser.leadingNames,
112
114
  acceptingAnyToken: parser.acceptingAnyToken,
113
115
  initialState: parser.initialState,
116
+ getSuggestRuntimeNodes(state, path) {
117
+ const innerState = isEnvBindState(state) ? state.cliState === void 0 ? parser.initialState : state.cliState : state;
118
+ return getDelegatingSuggestRuntimeNodes(parser, boundParser, state, path, innerState);
119
+ },
114
120
  parse: (context) => {
115
121
  const annotations = getAnnotations(context.state);
116
122
  const innerState = isEnvBindState(context.state) ? context.state.hasCliValue ? context.state.cliState : parser.initialState : context.state;
@@ -155,7 +161,7 @@ function bindEnv(parser, options) {
155
161
  },
156
162
  complete: (state, exec) => {
157
163
  if (isEnvBindState(state) && state.hasCliValue) return parser.complete(state.cliState, exec);
158
- return getEnvOrDefault(state, options, parser.$mode, parser, isEnvBindState(state) ? state.cliState : void 0, exec);
164
+ return getEnvOrDefault(state, options, parser.$mode, parser, isEnvBindState(state) ? state.cliState : isInjectedAnnotationWrapper(state) ? void 0 : state, exec);
159
165
  },
160
166
  suggest: parser.suggest,
161
167
  ...typeof deferPromptUntilConfigResolves === "function" ? { shouldDeferCompletion: (state, exec) => deferPromptUntilConfigResolves.call(parser, state, exec) } : {},
@@ -164,6 +170,7 @@ function bindEnv(parser, options) {
164
170
  return parser.getDocFragments(state, defaultValue);
165
171
  }
166
172
  };
173
+ defineInheritedAnnotationParser(boundParser);
167
174
  if ("placeholder" in parser) Object.defineProperty(boundParser, "placeholder", {
168
175
  get() {
169
176
  return parser.placeholder;
@@ -176,6 +183,24 @@ function bindEnv(parser, options) {
176
183
  configurable: true,
177
184
  enumerable: false
178
185
  });
186
+ const dependencyMetadata = composeWrappedSourceMetadata(parser.dependencyMetadata, (sourceMetadata) => ({
187
+ ...sourceMetadata,
188
+ extractSourceValue: (state) => {
189
+ if (!isEnvBindState(state)) {
190
+ if (sourceMetadata.preservesSourceValue) return getEnvSourceValue(state, options, state, sourceMetadata.extractSourceValue);
191
+ return sourceMetadata.extractSourceValue(state);
192
+ }
193
+ if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
194
+ const innerState = state.cliState ?? state;
195
+ if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(innerState);
196
+ return getEnvSourceValue(state, options, innerState, sourceMetadata.extractSourceValue);
197
+ }
198
+ }));
199
+ if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
200
+ value: dependencyMetadata,
201
+ configurable: true,
202
+ enumerable: false
203
+ });
179
204
  return boundParser;
180
205
  }
181
206
  function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
@@ -199,7 +224,7 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
199
224
  value: options.default
200
225
  });
201
226
  if (innerParser != null) {
202
- const completeState = innerState ?? innerParser.initialState;
227
+ const completeState = innerState ?? (annotations != null && innerParser.initialState == null && Reflect.get(innerParser, inheritParentAnnotationsKey) === true ? injectAnnotations(innerParser.initialState, annotations) : innerParser.initialState);
203
228
  return wrapForMode(mode, innerParser.complete(completeState, exec));
204
229
  }
205
230
  return wrapForMode(mode, {
@@ -207,6 +232,45 @@ function getEnvOrDefault(state, options, mode, innerParser, innerState, exec) {
207
232
  error: message`Missing required environment variable: ${envVar(fullKey)}`
208
233
  });
209
234
  }
235
+ /**
236
+ * Resolves an env-backed dependency source with env and default fallbacks.
237
+ *
238
+ * This first checks annotations or the active env registry for the bound
239
+ * variable. If no env-backed value is available, it falls back to
240
+ * `options.default` and finally delegates to the wrapped parser's source
241
+ * extractor.
242
+ *
243
+ * @param state The wrapper state, which may carry env annotations.
244
+ * @param options The binding options with lookup and default settings.
245
+ * @param innerState The unwrapped inner state for delegated extraction.
246
+ * @param extractInnerSourceValue The wrapped parser's source extractor.
247
+ * @returns The resolved source value, an async source value, or `undefined`.
248
+ * @throws {Error} Propagates errors thrown by the env source callback
249
+ * (`sourceData.source(fullKey)`).
250
+ * @throws {Error} Propagates errors thrown by `options.parser.parse(rawValue)`.
251
+ */
252
+ function getEnvSourceValue(state, options, innerState, extractInnerSourceValue) {
253
+ const annotations = getAnnotations(state);
254
+ const sourceData = annotations?.[options.context.id] ?? getActiveEnvSource(options.context.id);
255
+ const fullKey = `${sourceData?.prefix ?? options.context.prefix}${options.key}`;
256
+ const rawValue = sourceData?.source(fullKey);
257
+ if (rawValue !== void 0) {
258
+ if (typeof rawValue !== "string") {
259
+ const type = rawValue === null ? "null" : Array.isArray(rawValue) ? "array" : typeof rawValue;
260
+ return {
261
+ success: false,
262
+ error: message`Environment variable ${envVar(fullKey)} must be a string, but got: ${type}.`
263
+ };
264
+ }
265
+ const parsed = options.parser.parse(rawValue);
266
+ return parsed;
267
+ }
268
+ if (options.default !== void 0) return {
269
+ success: true,
270
+ value: options.default
271
+ };
272
+ return extractInnerSourceValue(innerState);
273
+ }
210
274
  const TRUE_LITERALS = [
211
275
  "true",
212
276
  "1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/env",
3
- "version": "1.0.0-dev.1616+17abc525",
3
+ "version": "1.0.0-dev.1659+94dcbc28",
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.1616+17abc525"
57
+ "@optique/core": "1.0.0-dev.1659+94dcbc28"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^20.19.9",