@optique/config 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
@@ -23,6 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  //#endregion
24
24
  const node_fs = __toESM(require("node:fs"));
25
25
  const node_path = __toESM(require("node:path"));
26
+ const __optique_core_parser = __toESM(require("@optique/core/parser"));
26
27
  const __optique_core_annotations = __toESM(require("@optique/core/annotations"));
27
28
  const __optique_core_message = __toESM(require("@optique/core/message"));
28
29
  const __optique_core_mode_dispatch = __toESM(require("@optique/core/mode-dispatch"));
@@ -298,11 +299,13 @@ function bindConfig(parser, options) {
298
299
  const annotations = (0, __optique_core_annotations.getAnnotations)(state);
299
300
  return annotations?.[options.context.id] === phase1ConfigAnnotationMarker;
300
301
  }
302
+ const getSuggestInnerState = (state) => isConfigBindState(state) ? state.cliState === void 0 ? (0, __optique_core_annotations.inheritAnnotations)(state, parser.initialState) : state.cliState : state;
301
303
  const boundParser = {
302
304
  $mode: parser.$mode,
303
305
  $valueType: parser.$valueType,
304
306
  $stateType: parser.$stateType,
305
307
  priority: parser.priority,
308
+ [__optique_core_parser.unmatchedNonCliDependencySourceStateMarker]: true,
306
309
  usage: options.default !== void 0 ? [{
307
310
  type: "optional",
308
311
  terms: parser.usage
@@ -310,6 +313,10 @@ function bindConfig(parser, options) {
310
313
  leadingNames: parser.leadingNames,
311
314
  acceptingAnyToken: parser.acceptingAnyToken,
312
315
  initialState: parser.initialState,
316
+ getSuggestRuntimeNodes(state, path) {
317
+ const innerState = getSuggestInnerState(state);
318
+ return (0, __optique_core_parser.getDelegatingSuggestRuntimeNodes)(parser, boundParser, state, path, innerState);
319
+ },
313
320
  parse: (context) => {
314
321
  const annotations = (0, __optique_core_annotations.getAnnotations)(context.state);
315
322
  const innerState = isConfigBindState(context.state) ? context.state.hasCliValue ? context.state.cliState : parser.initialState : context.state;
@@ -356,7 +363,14 @@ function bindConfig(parser, options) {
356
363
  if (isConfigBindState(state) && state.hasCliValue) return parser.complete(state.cliState, exec);
357
364
  return (0, __optique_core_mode_dispatch.wrapForMode)(parser.$mode, getConfigOrDefault(state, options));
358
365
  },
359
- suggest: parser.suggest,
366
+ suggest: (context, prefix) => {
367
+ const innerState = getSuggestInnerState(context.state);
368
+ const innerContext = innerState !== context.state ? {
369
+ ...context,
370
+ state: innerState
371
+ } : context;
372
+ return parser.suggest(innerContext, prefix);
373
+ },
360
374
  shouldDeferCompletion: shouldDeferPromptUntilConfigResolves,
361
375
  getDocFragments(state, upperDefaultValue) {
362
376
  const defaultValue = upperDefaultValue ?? options.default;
@@ -375,6 +389,29 @@ function bindConfig(parser, options) {
375
389
  configurable: true,
376
390
  enumerable: false
377
391
  });
392
+ (0, __optique_core_parser.defineInheritedAnnotationParser)(boundParser);
393
+ const dependencyMetadata = (0, __optique_core_parser.composeWrappedSourceMetadata)(parser.dependencyMetadata, (sourceMetadata) => ({
394
+ ...sourceMetadata,
395
+ getMissingSourceValue: sourceMetadata.preservesSourceValue !== false && options.default !== void 0 ? () => ({
396
+ success: true,
397
+ value: options.default
398
+ }) : void 0,
399
+ extractSourceValue: (state) => {
400
+ if (!isConfigBindState(state)) {
401
+ if (sourceMetadata.preservesSourceValue) return getConfigSourceValue(state, options, state, sourceMetadata.extractSourceValue);
402
+ return sourceMetadata.extractSourceValue(state);
403
+ }
404
+ if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
405
+ const fallbackState = state.cliState ?? state;
406
+ if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(fallbackState);
407
+ return getConfigSourceValue(state, options, fallbackState, sourceMetadata.extractSourceValue);
408
+ }
409
+ }));
410
+ if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
411
+ value: dependencyMetadata,
412
+ configurable: true,
413
+ enumerable: false
414
+ });
378
415
  return boundParser;
379
416
  }
380
417
  /**
@@ -412,6 +449,37 @@ function getConfigOrDefault(state, options) {
412
449
  error: __optique_core_message.message`Missing required configuration value.`
413
450
  };
414
451
  }
452
+ /**
453
+ * Resolves a config-backed dependency source with fallback priority.
454
+ *
455
+ * This first checks annotations or the active config registry via
456
+ * {@link getConfigOrDefault}. If no config-backed value is available, it falls
457
+ * back to `options.default` and finally delegates to the wrapped parser's
458
+ * source extractor.
459
+ *
460
+ * @param state The wrapper state, which may carry config annotations.
461
+ * @param options The binding options with lookup and default settings.
462
+ * @param innerState The unwrapped inner state for delegated extraction.
463
+ * @param extractInnerSourceValue The wrapped parser's source extractor.
464
+ * @returns The resolved source value, an async source value, or `undefined`.
465
+ * @throws {TypeError} If {@link getConfigOrDefault} rejects a thenable-returning
466
+ * key callback.
467
+ */
468
+ function getConfigSourceValue(state, options, innerState, extractInnerSourceValue) {
469
+ const annotations = (0, __optique_core_annotations.getAnnotations)(state);
470
+ const contextId = options.context.id;
471
+ const annotationValue = annotations?.[contextId];
472
+ const configData = annotationValue?.data ?? getActiveConfig(contextId);
473
+ if (configData !== void 0 && configData !== null) {
474
+ const resolved = getConfigOrDefault(state, options);
475
+ if (resolved.success) return resolved;
476
+ }
477
+ if (options.default !== void 0) return {
478
+ success: true,
479
+ value: options.default
480
+ };
481
+ return extractInnerSourceValue(innerState);
482
+ }
415
483
 
416
484
  //#endregion
417
485
  exports.bindConfig = bindConfig;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { Parser } from "@optique/core/parser";
1
2
  import { StandardSchemaV1 } from "@standard-schema/spec";
2
3
  import { ParserValuePlaceholder, SourceContext } from "@optique/core/context";
3
- import { Parser } from "@optique/core/parser";
4
4
 
5
5
  //#region src/index.d.ts
6
6
 
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { dirname, resolve } from "node:path";
3
- import { annotationKey, getAnnotations } from "@optique/core/annotations";
3
+ import { composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "@optique/core/parser";
4
+ import { annotationKey, getAnnotations, inheritAnnotations } from "@optique/core/annotations";
4
5
  import { message } from "@optique/core/message";
5
6
  import { mapModeValue, wrapForMode } from "@optique/core/mode-dispatch";
6
7
 
@@ -275,11 +276,13 @@ function bindConfig(parser, options) {
275
276
  const annotations = getAnnotations(state);
276
277
  return annotations?.[options.context.id] === phase1ConfigAnnotationMarker;
277
278
  }
279
+ const getSuggestInnerState = (state) => isConfigBindState(state) ? state.cliState === void 0 ? inheritAnnotations(state, parser.initialState) : state.cliState : state;
278
280
  const boundParser = {
279
281
  $mode: parser.$mode,
280
282
  $valueType: parser.$valueType,
281
283
  $stateType: parser.$stateType,
282
284
  priority: parser.priority,
285
+ [unmatchedNonCliDependencySourceStateMarker]: true,
283
286
  usage: options.default !== void 0 ? [{
284
287
  type: "optional",
285
288
  terms: parser.usage
@@ -287,6 +290,10 @@ function bindConfig(parser, options) {
287
290
  leadingNames: parser.leadingNames,
288
291
  acceptingAnyToken: parser.acceptingAnyToken,
289
292
  initialState: parser.initialState,
293
+ getSuggestRuntimeNodes(state, path) {
294
+ const innerState = getSuggestInnerState(state);
295
+ return getDelegatingSuggestRuntimeNodes(parser, boundParser, state, path, innerState);
296
+ },
290
297
  parse: (context) => {
291
298
  const annotations = getAnnotations(context.state);
292
299
  const innerState = isConfigBindState(context.state) ? context.state.hasCliValue ? context.state.cliState : parser.initialState : context.state;
@@ -333,7 +340,14 @@ function bindConfig(parser, options) {
333
340
  if (isConfigBindState(state) && state.hasCliValue) return parser.complete(state.cliState, exec);
334
341
  return wrapForMode(parser.$mode, getConfigOrDefault(state, options));
335
342
  },
336
- suggest: parser.suggest,
343
+ suggest: (context, prefix) => {
344
+ const innerState = getSuggestInnerState(context.state);
345
+ const innerContext = innerState !== context.state ? {
346
+ ...context,
347
+ state: innerState
348
+ } : context;
349
+ return parser.suggest(innerContext, prefix);
350
+ },
337
351
  shouldDeferCompletion: shouldDeferPromptUntilConfigResolves,
338
352
  getDocFragments(state, upperDefaultValue) {
339
353
  const defaultValue = upperDefaultValue ?? options.default;
@@ -352,6 +366,29 @@ function bindConfig(parser, options) {
352
366
  configurable: true,
353
367
  enumerable: false
354
368
  });
369
+ defineInheritedAnnotationParser(boundParser);
370
+ const dependencyMetadata = composeWrappedSourceMetadata(parser.dependencyMetadata, (sourceMetadata) => ({
371
+ ...sourceMetadata,
372
+ getMissingSourceValue: sourceMetadata.preservesSourceValue !== false && options.default !== void 0 ? () => ({
373
+ success: true,
374
+ value: options.default
375
+ }) : void 0,
376
+ extractSourceValue: (state) => {
377
+ if (!isConfigBindState(state)) {
378
+ if (sourceMetadata.preservesSourceValue) return getConfigSourceValue(state, options, state, sourceMetadata.extractSourceValue);
379
+ return sourceMetadata.extractSourceValue(state);
380
+ }
381
+ if (state.hasCliValue) return sourceMetadata.extractSourceValue(state.cliState);
382
+ const fallbackState = state.cliState ?? state;
383
+ if (!sourceMetadata.preservesSourceValue) return sourceMetadata.extractSourceValue(fallbackState);
384
+ return getConfigSourceValue(state, options, fallbackState, sourceMetadata.extractSourceValue);
385
+ }
386
+ }));
387
+ if (dependencyMetadata != null) Object.defineProperty(boundParser, "dependencyMetadata", {
388
+ value: dependencyMetadata,
389
+ configurable: true,
390
+ enumerable: false
391
+ });
355
392
  return boundParser;
356
393
  }
357
394
  /**
@@ -389,6 +426,37 @@ function getConfigOrDefault(state, options) {
389
426
  error: message`Missing required configuration value.`
390
427
  };
391
428
  }
429
+ /**
430
+ * Resolves a config-backed dependency source with fallback priority.
431
+ *
432
+ * This first checks annotations or the active config registry via
433
+ * {@link getConfigOrDefault}. If no config-backed value is available, it falls
434
+ * back to `options.default` and finally delegates to the wrapped parser's
435
+ * source extractor.
436
+ *
437
+ * @param state The wrapper state, which may carry config annotations.
438
+ * @param options The binding options with lookup and default settings.
439
+ * @param innerState The unwrapped inner state for delegated extraction.
440
+ * @param extractInnerSourceValue The wrapped parser's source extractor.
441
+ * @returns The resolved source value, an async source value, or `undefined`.
442
+ * @throws {TypeError} If {@link getConfigOrDefault} rejects a thenable-returning
443
+ * key callback.
444
+ */
445
+ function getConfigSourceValue(state, options, innerState, extractInnerSourceValue) {
446
+ const annotations = getAnnotations(state);
447
+ const contextId = options.context.id;
448
+ const annotationValue = annotations?.[contextId];
449
+ const configData = annotationValue?.data ?? getActiveConfig(contextId);
450
+ if (configData !== void 0 && configData !== null) {
451
+ const resolved = getConfigOrDefault(state, options);
452
+ if (resolved.success) return resolved;
453
+ }
454
+ if (options.default !== void 0) return {
455
+ success: true,
456
+ value: options.default
457
+ };
458
+ return extractInnerSourceValue(innerState);
459
+ }
392
460
 
393
461
  //#endregion
394
462
  export { bindConfig, clearActiveConfig, clearActiveConfigMeta, createConfigContext, getActiveConfig, getActiveConfigMeta, setActiveConfig, setActiveConfigMeta };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/config",
3
- "version": "1.0.0-dev.1616+17abc525",
3
+ "version": "1.0.0-dev.1659+94dcbc28",
4
4
  "description": "Configuration file support for Optique with Standard Schema validation",
5
5
  "keywords": [
6
6
  "CLI",
@@ -59,7 +59,7 @@
59
59
  "@standard-schema/spec": "^1.1.0"
60
60
  },
61
61
  "dependencies": {
62
- "@optique/core": "1.0.0-dev.1616+17abc525"
62
+ "@optique/core": "1.0.0-dev.1659+94dcbc28"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@standard-schema/spec": "^1.1.0",
@@ -67,7 +67,7 @@
67
67
  "tsdown": "^0.13.0",
68
68
  "typescript": "^5.8.3",
69
69
  "zod": "^3.25.0 || ^4.0.0",
70
- "@optique/env": "1.0.0-dev.1616+17abc525"
70
+ "@optique/env": "1.0.0-dev.1659+94dcbc28"
71
71
  },
72
72
  "scripts": {
73
73
  "build": "tsdown",