@fgv/ts-res 5.0.1-0 → 5.0.1-2

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.
Files changed (39) hide show
  1. package/dist/ts-res.d.ts +212 -1
  2. package/lib/packlets/common/helpers/resources.d.ts +1 -1
  3. package/lib/packlets/common/helpers/resources.js +3 -2
  4. package/lib/packlets/common/resources.d.ts +4 -0
  5. package/lib/packlets/common/validate/conditions.js +14 -14
  6. package/lib/packlets/common/validate/resources.js +7 -7
  7. package/lib/packlets/conditions/conditionSet.js +1 -1
  8. package/lib/packlets/config/common.js +1 -0
  9. package/lib/packlets/config/configInitFactory.js +1 -0
  10. package/lib/packlets/config/systemConfiguration.js +1 -0
  11. package/lib/packlets/context/convert/decls.js +1 -1
  12. package/lib/packlets/import/importers/collectionImporter.js +1 -1
  13. package/lib/packlets/import/importers/jsonImporter.js +1 -1
  14. package/lib/packlets/qualifier-types/helpers.js +5 -4
  15. package/lib/packlets/qualifier-types/literalQualifierType.js +1 -1
  16. package/lib/packlets/qualifier-types/literalValueHierarchy.js +7 -6
  17. package/lib/packlets/qualifier-types/qualifierType.js +1 -0
  18. package/lib/packlets/qualifier-types/territoryQualifierType.js +1 -1
  19. package/lib/packlets/resource-json/helpers.js +4 -0
  20. package/lib/packlets/resource-types/helpers.js +1 -0
  21. package/lib/packlets/resource-types/resourceType.js +1 -0
  22. package/lib/packlets/resources/candidateValue.js +1 -0
  23. package/lib/packlets/resources/candidateValueCollector.js +4 -2
  24. package/lib/packlets/resources/deltaGenerator.d.ts +189 -0
  25. package/lib/packlets/resources/deltaGenerator.js +342 -0
  26. package/lib/packlets/resources/index.d.ts +1 -0
  27. package/lib/packlets/resources/index.js +1 -0
  28. package/lib/packlets/resources/resourceBuilder.js +4 -0
  29. package/lib/packlets/resources/resourceManagerBuilder.d.ts +4 -0
  30. package/lib/packlets/resources/resourceManagerBuilder.js +12 -0
  31. package/lib/packlets/runtime/compiledResourceCollection.d.ts +4 -0
  32. package/lib/packlets/runtime/compiledResourceCollection.js +7 -0
  33. package/lib/packlets/runtime/context/simpleContextQualifierProvider.js +4 -3
  34. package/lib/packlets/runtime/iResourceManager.d.ts +4 -0
  35. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js +3 -0
  36. package/lib/packlets/runtime/resourceResolver.d.ts +5 -1
  37. package/lib/packlets/runtime/resourceResolver.js +8 -4
  38. package/lib/packlets/runtime/resourceTreeResolver.js +2 -0
  39. package/package.json +7 -7
package/dist/ts-res.d.ts CHANGED
@@ -10,6 +10,7 @@ import { IReadOnlyResultMap } from '@fgv/ts-utils';
10
10
  import { JsonCompatible } from '@fgv/ts-json-base';
11
11
  import { JsonObject } from '@fgv/ts-json-base';
12
12
  import { JsonValue } from '@fgv/ts-json-base';
13
+ import { Logging } from '@fgv/ts-utils';
13
14
  import { ObjectConverter } from '@fgv/ts-utils';
14
15
  import { Result } from '@fgv/ts-utils';
15
16
  import { ResultMap } from '@fgv/ts-utils';
@@ -995,6 +996,10 @@ declare class CompiledResourceCollection implements IResourceManager<IResource>
995
996
  * contains the {@link Qualifiers.Qualifier | qualifiers} used in this collection.
996
997
  */
997
998
  get qualifiers(): IReadOnlyQualifierCollector;
999
+ /**
1000
+ * The resource IDs contained in this compiled resource collection.
1001
+ */
1002
+ get resourceIds(): ReadonlyArray<ResourceId>;
998
1003
  /**
999
1004
  * A {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector} which
1000
1005
  * contains the {@link ResourceTypes.ResourceType | resource types} used in this collection.
@@ -2552,6 +2557,150 @@ declare const DefaultResourceTypes: ReadonlyArray<ResourceTypes.Config.IResource
2552
2557
  */
2553
2558
  declare const DefaultSystemConfiguration: ISystemConfiguration;
2554
2559
 
2560
+ /**
2561
+ * Class for generating resource deltas between baseline and delta resolvers.
2562
+ * Creates partial/augment candidates for updated resources and full/replace candidates for new resources.
2563
+ * Uses Diff.jsonThreeWayDiff for efficient delta computation.
2564
+ * @public
2565
+ */
2566
+ declare class DeltaGenerator {
2567
+ /**
2568
+ * The baseline resource resolver to compare against.
2569
+ * @internal
2570
+ */
2571
+ private readonly _baselineResolver;
2572
+ /**
2573
+ * The delta resource resolver containing changes.
2574
+ * @internal
2575
+ */
2576
+ private readonly _deltaResolver;
2577
+ /**
2578
+ * The resource manager to clone and update.
2579
+ * @internal
2580
+ */
2581
+ private readonly _resourceManager;
2582
+ /**
2583
+ * Logger for status and error reporting.
2584
+ * @internal
2585
+ */
2586
+ private readonly _logger;
2587
+ /**
2588
+ * Constructor for a {@link Resources.DeltaGenerator | DeltaGenerator} object.
2589
+ * @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
2590
+ * @internal
2591
+ */
2592
+ protected constructor(params: IDeltaGeneratorParams);
2593
+ /**
2594
+ * Creates a new {@link Resources.DeltaGenerator | DeltaGenerator} object.
2595
+ * @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
2596
+ * @returns `Success` with the new {@link Resources.DeltaGenerator | DeltaGenerator} object if successful,
2597
+ * or `Failure` with an error message if not.
2598
+ * @public
2599
+ */
2600
+ static create(params: IDeltaGeneratorParams): Result<DeltaGenerator>;
2601
+ /**
2602
+ * Generates deltas between baseline and delta resolvers.
2603
+ * Creates a cloned resource manager with partial/augment candidates for updates
2604
+ * and full/replace candidates for new resources.
2605
+ *
2606
+ * @param options - Options controlling delta generation behavior.
2607
+ * @returns `Success` with the updated resource manager if successful,
2608
+ * or `Failure` with an error message if not.
2609
+ * @public
2610
+ */
2611
+ generate(options?: IDeltaGeneratorOptions): Result<ResourceManagerBuilder>;
2612
+ /**
2613
+ * Validates the provided context declaration.
2614
+ * @param context - The context declaration to validate.
2615
+ * @returns `Success` with the validated context if successful, `Failure` otherwise.
2616
+ * @internal
2617
+ */
2618
+ private _validateContext;
2619
+ /**
2620
+ * Enumerates target resource IDs for delta generation.
2621
+ * If specific resource IDs are provided, uses those. Otherwise, discovers all resources
2622
+ * from both the baseline resource manager and the delta resolver to ensure comprehensive
2623
+ * coverage of all potential resources.
2624
+ *
2625
+ * @param requestedIds - Optional array of specific resource IDs to target.
2626
+ * @param context - The validated context to use for resource discovery.
2627
+ * @returns `Success` with array of resource IDs if successful, `Failure` otherwise.
2628
+ * @internal
2629
+ */
2630
+ private _enumerateTargetResources;
2631
+ /**
2632
+ * Discovers all unique resource IDs from both baseline and delta resolvers.
2633
+ * Creates a union of resource IDs from the baseline resource manager and delta resolver
2634
+ * to ensure comprehensive coverage of all resources.
2635
+ *
2636
+ * @returns `Success` with array of unique resource IDs if successful, `Failure` otherwise.
2637
+ * @internal
2638
+ */
2639
+ private _discoverAllResourceIds;
2640
+ /**
2641
+ * Creates a clone of the resource manager for delta operations.
2642
+ * @returns `Success` with the cloned resource manager if successful, `Failure` otherwise.
2643
+ * @internal
2644
+ */
2645
+ private _cloneResourceManager;
2646
+ /**
2647
+ * Generates deltas for the specified resources and adds them to the cloned manager.
2648
+ *
2649
+ * @param clonedManager - The cloned resource manager to update.
2650
+ * @param resourceIds - Array of resource IDs to process.
2651
+ * @param context - The context to use for resource resolution.
2652
+ * @param skipUnchanged - Whether to skip resources that haven't changed.
2653
+ * @returns `Success` with the updated manager if successful, `Failure` otherwise.
2654
+ * @internal
2655
+ */
2656
+ private _generateDeltas;
2657
+ /**
2658
+ * Generates a delta for a single resource and adds appropriate candidates to the manager.
2659
+ *
2660
+ * @param manager - The resource manager to update.
2661
+ * @param resourceId - The resource ID to process.
2662
+ * @param context - The context to use for resource resolution.
2663
+ * @param skipUnchanged - Whether to skip resources that haven't changed.
2664
+ * @returns `Success` with the resource delta result if successful, `Failure` otherwise.
2665
+ * @internal
2666
+ */
2667
+ private _generateResourceDelta;
2668
+ /**
2669
+ * Checks if two JSON values are identical.
2670
+ * @param value1 - First value to compare.
2671
+ * @param value2 - Second value to compare.
2672
+ * @returns True if values are identical, false otherwise.
2673
+ * @internal
2674
+ */
2675
+ private _areValuesIdentical;
2676
+ /**
2677
+ * Creates a new resource candidate for a newly discovered resource.
2678
+ * Uses full/replace merge method since this is a completely new resource.
2679
+ *
2680
+ * @param manager - The resource manager to update.
2681
+ * @param resourceId - The resource ID for the new resource.
2682
+ * @param value - The resolved value for the new resource.
2683
+ * @param context - The context used for resolution.
2684
+ * @returns `Success` if the candidate was added successfully, `Failure` otherwise.
2685
+ * @internal
2686
+ */
2687
+ private _createNewResourceCandidate;
2688
+ /**
2689
+ * Creates a delta candidate for an updated resource.
2690
+ * Computes the difference between baseline and delta values and creates
2691
+ * a partial/augment candidate with only the changed properties.
2692
+ *
2693
+ * @param manager - The resource manager to update.
2694
+ * @param resourceId - The resource ID for the updated resource.
2695
+ * @param baselineValue - The baseline resolved value.
2696
+ * @param deltaValue - The delta resolved value.
2697
+ * @param context - The context used for resolution.
2698
+ * @returns `Success` if the candidate was added successfully, `Failure` otherwise.
2699
+ * @internal
2700
+ */
2701
+ private _createDeltaCandidate;
2702
+ }
2703
+
2555
2704
  /**
2556
2705
  * Type for handling empty branch nodes during tree composition.
2557
2706
  * The handler receives the branch node, names of failed children, and the resolver for recovery attempts.
@@ -2727,7 +2876,7 @@ declare function getDirectoryName(path: string): string;
2727
2876
  /**
2728
2877
  * Gets the name for a resource ID.
2729
2878
  * @param id - The resource ID to get the name for.
2730
- * @returns The resource name if found, or undefined if not.
2879
+ * @returns `Success` with the resource name if found, or `Failure` with an error message if not.
2731
2880
  * @public
2732
2881
  */
2733
2882
  declare function getNameForResourceId(id: string | undefined): Result<ResourceName>;
@@ -3813,6 +3962,49 @@ declare interface IDeclarationOptions {
3813
3962
  normalized?: boolean;
3814
3963
  }
3815
3964
 
3965
+ /**
3966
+ * Interface for options controlling delta generation behavior.
3967
+ * @public
3968
+ */
3969
+ declare interface IDeltaGeneratorOptions {
3970
+ /**
3971
+ * Context to use when resolving resources. If not provided, uses empty context.
3972
+ */
3973
+ context?: Context.IContextDecl;
3974
+ /**
3975
+ * Array of specific resource IDs to include in delta generation.
3976
+ * If not provided, generates deltas for all resources in the delta resolver.
3977
+ */
3978
+ resourceIds?: ReadonlyArray<string>;
3979
+ /**
3980
+ * Whether to skip resources that haven't changed. Default: true.
3981
+ */
3982
+ skipUnchanged?: boolean;
3983
+ }
3984
+
3985
+ /**
3986
+ * Interface for parameters to create a {@link Resources.DeltaGenerator | DeltaGenerator}.
3987
+ * @public
3988
+ */
3989
+ declare interface IDeltaGeneratorParams {
3990
+ /**
3991
+ * The baseline resource resolver to compare against.
3992
+ */
3993
+ baselineResolver: IResourceResolver;
3994
+ /**
3995
+ * The delta resource resolver containing changes.
3996
+ */
3997
+ deltaResolver: IResourceResolver;
3998
+ /**
3999
+ * The resource manager to clone and update.
4000
+ */
4001
+ resourceManager: ResourceManagerBuilder;
4002
+ /**
4003
+ * Optional logger for status and error reporting.
4004
+ */
4005
+ logger?: Logging.ILogger;
4006
+ }
4007
+
3816
4008
  /**
3817
4009
  * @internal
3818
4010
  */
@@ -5266,6 +5458,10 @@ export declare interface IResourceManager<TR extends IResource = IResource> {
5266
5458
  * The number of resources in this resource manager.
5267
5459
  */
5268
5460
  readonly numResources: number;
5461
+ /**
5462
+ * The resource IDs that this resource manager can resolve.
5463
+ */
5464
+ readonly resourceIds: ReadonlyArray<ResourceId>;
5269
5465
  /**
5270
5466
  * The number of candidates in this resource manager.
5271
5467
  */
@@ -5317,6 +5513,10 @@ declare interface IResourceManagerCloneOptions extends IResourceDeclarationOptio
5317
5513
  * @public
5318
5514
  */
5319
5515
  export declare interface IResourceResolver {
5516
+ /**
5517
+ * The resource IDs that this resolver can resolve.
5518
+ */
5519
+ readonly resourceIds: ReadonlyArray<ResourceId>;
5320
5520
  /**
5321
5521
  * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
5322
5522
  * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
@@ -8457,6 +8657,10 @@ export declare class ResourceManagerBuilder implements IResourceManager<Resource
8457
8657
  * the {@link Resources.ResourceCandidate | resource candidates} in this manager.
8458
8658
  */
8459
8659
  get conditions(): ReadOnlyConditionCollector;
8660
+ /**
8661
+ * The resource IDs that this resource manager can resolve.
8662
+ */
8663
+ get resourceIds(): ReadonlyArray<ResourceId>;
8460
8664
  /**
8461
8665
  * A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which
8462
8666
  * contains the {@link Conditions.ConditionSet | condition sets} used so far by
@@ -8805,6 +9009,10 @@ export declare class ResourceResolver implements IResourceResolver {
8805
9009
  * The readonly qualifier collector that provides qualifier implementations.
8806
9010
  */
8807
9011
  get qualifiers(): IReadOnlyQualifierCollector;
9012
+ /**
9013
+ * The resource IDs that this resolver can resolve.
9014
+ */
9015
+ get resourceIds(): ReadonlyArray<ResourceId>;
8808
9016
  /**
8809
9017
  * The cache array for resolved conditions, indexed by condition index for O(1) lookup.
8810
9018
  * Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
@@ -9032,6 +9240,9 @@ declare namespace Resources {
9032
9240
  CandidateValue,
9033
9241
  ICandidateValueCollectorCreateParams,
9034
9242
  CandidateValueCollector,
9243
+ IDeltaGeneratorParams,
9244
+ IDeltaGeneratorOptions,
9245
+ DeltaGenerator,
9035
9246
  IResourceCandidateCreateParams,
9036
9247
  ICandidateDeclOptions,
9037
9248
  ResourceCandidate,
@@ -34,7 +34,7 @@ export declare function joinOptionalResourceIds(...ids: (string | undefined)[]):
34
34
  /**
35
35
  * Gets the name for a resource ID.
36
36
  * @param id - The resource ID to get the name for.
37
- * @returns The resource name if found, or undefined if not.
37
+ * @returns `Success` with the resource name if found, or `Failure` with an error message if not.
38
38
  * @public
39
39
  */
40
40
  export declare function getNameForResourceId(id: string | undefined): Result<ResourceName>;
@@ -87,12 +87,13 @@ function joinOptionalResourceIds(...ids) {
87
87
  /**
88
88
  * Gets the name for a resource ID.
89
89
  * @param id - The resource ID to get the name for.
90
- * @returns The resource name if found, or undefined if not.
90
+ * @returns `Success` with the resource name if found, or `Failure` with an error message if not.
91
91
  * @public
92
92
  */
93
93
  function getNameForResourceId(id) {
94
94
  return splitResourceId(id).onSuccess((parts) => {
95
- return parts.length > 0 ? (0, ts_utils_1.succeed)(parts[parts.length - 1]) : fail('Empty id has no name');
95
+ /* c8 ignore next 1 - tested but coverage having issues */
96
+ return parts.length > 0 ? (0, ts_utils_1.succeed)(parts[parts.length - 1]) : fail(`${id}: invalid resource id`);
96
97
  });
97
98
  }
98
99
  //# sourceMappingURL=resources.js.map
@@ -66,6 +66,10 @@ export type CandidateValueKey = Brand<string, 'CandidateValueKey'>;
66
66
  * @public
67
67
  */
68
68
  export interface IResourceResolver {
69
+ /**
70
+ * The resource IDs that this resolver can resolve.
71
+ */
72
+ readonly resourceIds: ReadonlyArray<ResourceId>;
69
73
  /**
70
74
  * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
71
75
  * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
@@ -316,7 +316,7 @@ function toQualifierTypeIndex(index) {
316
316
  function toQualifierMatchScore(value) {
317
317
  /* c8 ignore next 3 - coverage is having a bad day */
318
318
  if (!isValidQualifierMatchScore(value)) {
319
- return (0, ts_utils_1.fail)(`${value}: not a valid match score`);
319
+ return (0, ts_utils_1.fail)(`${value}: invalid match score`);
320
320
  }
321
321
  return (0, ts_utils_1.succeed)(value);
322
322
  }
@@ -330,7 +330,7 @@ function toQualifierMatchScore(value) {
330
330
  function toConditionPriority(priority) {
331
331
  /* c8 ignore next 3 - coverage is having a bad day */
332
332
  if (!isValidConditionPriority(priority)) {
333
- return (0, ts_utils_1.fail)(`${priority}: not a valid priority`);
333
+ return (0, ts_utils_1.fail)(`${priority}: invalid priority`);
334
334
  }
335
335
  return (0, ts_utils_1.succeed)(priority);
336
336
  }
@@ -344,7 +344,7 @@ function toConditionPriority(priority) {
344
344
  function toConditionIndex(index) {
345
345
  /* c8 ignore next 3 - coverage is having a bad day */
346
346
  if (!isValidConditionIndex(index)) {
347
- return (0, ts_utils_1.fail)(`${index}: not a valid condition index`);
347
+ return (0, ts_utils_1.fail)(`${index}: invalid condition index`);
348
348
  }
349
349
  return (0, ts_utils_1.succeed)(index);
350
350
  }
@@ -357,7 +357,7 @@ function toConditionIndex(index) {
357
357
  */
358
358
  function toConditionOperator(operator) {
359
359
  if (!isValidConditionOperator(operator)) {
360
- return (0, ts_utils_1.fail)(`${operator}: not a valid condition operator`);
360
+ return (0, ts_utils_1.fail)(`${operator}: invalid condition operator`);
361
361
  }
362
362
  return (0, ts_utils_1.succeed)(operator);
363
363
  }
@@ -371,7 +371,7 @@ function toConditionOperator(operator) {
371
371
  function toConditionKey(key) {
372
372
  /* c8 ignore next 3 - coverage is having a bad day */
373
373
  if (!isValidConditionKey(key)) {
374
- return (0, ts_utils_1.fail)(`${key}: not a valid condition key`);
374
+ return (0, ts_utils_1.fail)(`${key}: invalid condition key`);
375
375
  }
376
376
  return (0, ts_utils_1.succeed)(key);
377
377
  }
@@ -385,7 +385,7 @@ function toConditionKey(key) {
385
385
  function toConditionToken(token) {
386
386
  /* c8 ignore next 3 - coverage is having a bad day */
387
387
  if (!isValidConditionToken(token)) {
388
- return (0, ts_utils_1.fail)(`${token}: not a valid condition token`);
388
+ return (0, ts_utils_1.fail)(`${token}: invalid condition token`);
389
389
  }
390
390
  return (0, ts_utils_1.succeed)(token);
391
391
  }
@@ -399,7 +399,7 @@ function toConditionToken(token) {
399
399
  function toConditionSetIndex(index) {
400
400
  /* c8 ignore next 3 - coverage is having a bad day */
401
401
  if (!isValidConditionSetIndex(index)) {
402
- return (0, ts_utils_1.fail)(`${index}: not a valid condition set index`);
402
+ return (0, ts_utils_1.fail)(`${index}: invalid condition set index`);
403
403
  }
404
404
  return (0, ts_utils_1.succeed)(index);
405
405
  }
@@ -413,7 +413,7 @@ function toConditionSetIndex(index) {
413
413
  function toConditionSetKey(key) {
414
414
  /* c8 ignore next 3 - coverage is having a bad day */
415
415
  if (!isValidConditionSetKey(key)) {
416
- return (0, ts_utils_1.fail)(`${key}: not a valid condition set key`);
416
+ return (0, ts_utils_1.fail)(`${key}: invalid condition set key`);
417
417
  }
418
418
  return (0, ts_utils_1.succeed)(key);
419
419
  }
@@ -427,7 +427,7 @@ function toConditionSetKey(key) {
427
427
  function toConditionSetToken(token) {
428
428
  /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
429
429
  if (!isValidConditionSetToken(token)) {
430
- return (0, ts_utils_1.fail)(`${token}: not a valid condition set token`);
430
+ return (0, ts_utils_1.fail)(`${token}: invalid condition set token`);
431
431
  }
432
432
  return (0, ts_utils_1.succeed)(token);
433
433
  }
@@ -440,7 +440,7 @@ function toConditionSetToken(token) {
440
440
  */
441
441
  function toConditionSetHash(hash) {
442
442
  if (!isValidConditionSetHash(hash)) {
443
- return (0, ts_utils_1.fail)(`${hash}: not a valid condition set hash`);
443
+ return (0, ts_utils_1.fail)(`${hash}: invalid condition set hash`);
444
444
  }
445
445
  return (0, ts_utils_1.succeed)(hash);
446
446
  }
@@ -454,7 +454,7 @@ function toConditionSetHash(hash) {
454
454
  function toDecisionKey(key) {
455
455
  /* c8 ignore next 3 - coverage is having a bad day */
456
456
  if (!isValidDecisionKey(key)) {
457
- return (0, ts_utils_1.fail)(`${key}: not a valid decision key`);
457
+ return (0, ts_utils_1.fail)(`${key}: invalid decision key`);
458
458
  }
459
459
  return (0, ts_utils_1.succeed)(key);
460
460
  }
@@ -468,7 +468,7 @@ function toDecisionKey(key) {
468
468
  function toDecisionIndex(index) {
469
469
  /* c8 ignore next 3 - coverage is having a bad day */
470
470
  if (!isValidDecisionIndex(index)) {
471
- return (0, ts_utils_1.fail)(`${index}: not a valid decision index`);
471
+ return (0, ts_utils_1.fail)(`${index}: invalid decision index`);
472
472
  }
473
473
  return (0, ts_utils_1.succeed)(index);
474
474
  }
@@ -513,7 +513,7 @@ function isValidContextToken(token) {
513
513
  function toContextQualifierToken(token) {
514
514
  /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
515
515
  if (!isValidContextQualifierToken(token)) {
516
- return (0, ts_utils_1.fail)(`${token}: not a valid context qualifier token`);
516
+ return (0, ts_utils_1.fail)(`${token}: invalid context qualifier token`);
517
517
  }
518
518
  return (0, ts_utils_1.succeed)(token);
519
519
  }
@@ -527,7 +527,7 @@ function toContextQualifierToken(token) {
527
527
  function toContextToken(token) {
528
528
  /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
529
529
  if (!isValidContextToken(token)) {
530
- return (0, ts_utils_1.fail)(`${token}: not a valid context token`);
530
+ return (0, ts_utils_1.fail)(`${token}: invalid context token`);
531
531
  }
532
532
  return (0, ts_utils_1.succeed)(token);
533
533
  }
@@ -119,7 +119,7 @@ function isValidCandidateValueKey(key) {
119
119
  function toResourceName(name) {
120
120
  /* c8 ignore next 3 - coverage having issues */
121
121
  if (!isValidResourceName(name)) {
122
- return (0, ts_utils_1.fail)(`${name}: not a valid resource name.`);
122
+ return (0, ts_utils_1.fail)(`${name}: invalid resource name.`);
123
123
  }
124
124
  return (0, ts_utils_1.succeed)(name);
125
125
  }
@@ -134,7 +134,7 @@ function toResourceName(name) {
134
134
  function toResourceId(id) {
135
135
  /* c8 ignore next 3 - defensive coding: resource ID validation should prevent invalid IDs */
136
136
  if (!isValidResourceId(id)) {
137
- return (0, ts_utils_1.fail)(`${id}: not a valid resource ID.`);
137
+ return (0, ts_utils_1.fail)(`${id}: invalid resource ID.`);
138
138
  }
139
139
  return (0, ts_utils_1.succeed)(id);
140
140
  }
@@ -159,7 +159,7 @@ function toOptionalResourceId(id) {
159
159
  */
160
160
  function toResourceIndex(index) {
161
161
  if (!isValidResourceIndex(index)) {
162
- return (0, ts_utils_1.fail)(`${index}: not a valid resource index.`);
162
+ return (0, ts_utils_1.fail)(`${index}: invalid resource index.`);
163
163
  }
164
164
  return (0, ts_utils_1.succeed)(index);
165
165
  }
@@ -174,7 +174,7 @@ function toResourceIndex(index) {
174
174
  function toResourceTypeName(name) {
175
175
  /* c8 ignore next 3 - coverage having issues */
176
176
  if (!isValidResourceTypeName(name)) {
177
- return (0, ts_utils_1.fail)(`${name}: not a valid resource type name.`);
177
+ return (0, ts_utils_1.fail)(`${name}: invalid resource type name.`);
178
178
  }
179
179
  return (0, ts_utils_1.succeed)(name);
180
180
  }
@@ -189,7 +189,7 @@ function toResourceTypeName(name) {
189
189
  function toResourceTypeIndex(index) {
190
190
  /* c8 ignore next 3 - coverage having issues */
191
191
  if (!isValidResourceTypeIndex(index)) {
192
- return (0, ts_utils_1.fail)(`${index}: not a valid resource type index.`);
192
+ return (0, ts_utils_1.fail)(`${index}: invalid resource type index.`);
193
193
  }
194
194
  return (0, ts_utils_1.succeed)(index);
195
195
  }
@@ -204,7 +204,7 @@ function toResourceTypeIndex(index) {
204
204
  function toCandidateValueKey(key) {
205
205
  /* c8 ignore next 3 - coverage having issues */
206
206
  if (!isValidCandidateValueKey(key)) {
207
- return (0, ts_utils_1.fail)(`${key}: not a valid candidate value key.`);
207
+ return (0, ts_utils_1.fail)(`${key}: invalid candidate value key.`);
208
208
  }
209
209
  return (0, ts_utils_1.succeed)(key);
210
210
  }
@@ -219,7 +219,7 @@ function toCandidateValueKey(key) {
219
219
  function toCandidateValueIndex(index) {
220
220
  /* c8 ignore next 3 - coverage having issues */
221
221
  if (!isValidCandidateValueIndex(index)) {
222
- return (0, ts_utils_1.fail)(`${index}: not a valid candidate value index.`);
222
+ return (0, ts_utils_1.fail)(`${index}: invalid candidate value index.`);
223
223
  }
224
224
  return (0, ts_utils_1.succeed)(index);
225
225
  }
@@ -185,9 +185,9 @@ class ConditionSet {
185
185
  const conditions = Object.entries(conditionSet).map(([qualifierName, value]) => {
186
186
  if (typeof value === 'string') {
187
187
  return { qualifierName, value };
188
+ /* c8 ignore next 3 - edge case */
188
189
  }
189
190
  else {
190
- /* c8 ignore next 1 - edge case: object spread pattern rarely used */
191
191
  return Object.assign({ qualifierName }, value);
192
192
  }
193
193
  });
@@ -76,6 +76,7 @@ function getPredefinedDeclaration(name, initParams) {
76
76
  }
77
77
  return baseConfig;
78
78
  }
79
+ /* c8 ignore next 3 - defense in depth */
79
80
  return (0, ts_utils_1.fail)(`Unknown predefined system configuration: ${name}`);
80
81
  }
81
82
  /**
@@ -123,6 +123,7 @@ class BuiltInQualifierTypeFactory {
123
123
  if (QualifierTypes.Config.isSystemQualifierTypeConfig(config)) {
124
124
  return QualifierTypes.createQualifierTypeFromSystemConfig(config);
125
125
  }
126
+ /* c8 ignore next 2 - functional code tested but coverage intermittently missed */
126
127
  return (0, ts_utils_1.fail)(`${config.name}: unknown built-in qualifier type (${config.systemType})`);
127
128
  }
128
129
  }
@@ -122,6 +122,7 @@ class SystemConfiguration {
122
122
  */
123
123
  static create(config, initParams) {
124
124
  if (initParams === null || initParams === void 0 ? void 0 : initParams.qualifierDefaultValues) {
125
+ /* c8 ignore next 9 - functional code tested but coverage intermittently missed */
125
126
  return updateSystemConfigurationQualifierDefaultValues(config, initParams.qualifierDefaultValues).onSuccess((updatedConfig) => (0, ts_utils_1.captureResult)(() => new SystemConfiguration(updatedConfig, (0, ts_utils_1.omit)(initParams, ['qualifierDefaultValues']))));
126
127
  }
127
128
  return (0, ts_utils_1.captureResult)(() => new SystemConfiguration(config, initParams));
@@ -67,8 +67,8 @@ exports.validatedContextQualifierValueDecl = ts_utils_1.Converters.generic((from
67
67
  * @public
68
68
  */
69
69
  exports.validatedContextDecl = ts_utils_1.Converters.generic((from, __self, context) => {
70
+ /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
70
71
  if (!context) {
71
- /* c8 ignore next 2 - functional code path tested but coverage intermittently missed */
72
72
  return ts_utils_1.Failure.with('validatedContextDecl converter requires a context');
73
73
  }
74
74
  return exports.contextDecl.convert(from).onSuccess((decl) => {
@@ -91,7 +91,7 @@ class CollectionImporter {
91
91
  if (!(0, importable_1.isImportable)(item) || (item.type !== 'resourceCollection' && item.type !== 'resourceTree')) {
92
92
  /* c8 ignore next 1 - defense in depth */
93
93
  const name = (_b = (_a = item.context) === null || _a === void 0 ? void 0 : _a.baseId) !== null && _b !== void 0 ? _b : 'unknown';
94
- return (0, ts_utils_1.failWithDetail)(`${name}: not a valid resource collection importable (${item.type})`, 'skipped');
94
+ return (0, ts_utils_1.failWithDetail)(`${name}: invalid resource collection importable (${item.type})`, 'skipped');
95
95
  }
96
96
  const container = item.type === 'resourceCollection' ? item.collection : item.tree;
97
97
  return importContext_1.ImportContext.forContainerImport(container.context, item.context)
@@ -89,7 +89,7 @@ class JsonImporter {
89
89
  if (!(0, importable_1.isImportable)(item) || item.type !== 'json') {
90
90
  /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
91
91
  const name = (_b = (_a = item.context) === null || _a === void 0 ? void 0 : _a.baseId) !== null && _b !== void 0 ? _b : 'unknown';
92
- return (0, ts_utils_1.failWithDetail)(`${name}: not a valid JSON importable (${item.type})`, 'skipped');
92
+ return (0, ts_utils_1.failWithDetail)(`${name}: invalid JSON importable (${item.type})`, 'skipped');
93
93
  }
94
94
  return (this._tryImportResourceCollection(item)
95
95
  .onFailure(() => this._tryImportResourceTree(item))
@@ -88,9 +88,9 @@ function createQualifierTypeFromConfig(typeConfig) {
88
88
  return Config.Convert.literalQualifierTypeConfig
89
89
  .convert(childConfig)
90
90
  .onSuccess((configuration) => literalQualifierType_1.LiteralQualifierType.createFromConfig(Object.assign(Object.assign({}, typeConfig), { configuration })));
91
- default:
92
- return (0, ts_utils_1.fail)(`Unknown qualifier type: ${typeConfig.systemType}`);
93
91
  }
92
+ /* c8 ignore next 1 - defense in depth */
93
+ return (0, ts_utils_1.fail)(`Unknown qualifier type: ${typeConfig.systemType}`);
94
94
  }
95
95
  /**
96
96
  * Creates a {@link QualifierTypes.SystemQualifierType | SystemQualifierType} from a system configuration object.
@@ -111,8 +111,9 @@ function createQualifierTypeFromSystemConfig(typeConfig) {
111
111
  return territoryQualifierType_1.TerritoryQualifierType.createFromConfig(typeConfig);
112
112
  case 'literal':
113
113
  return literalQualifierType_1.LiteralQualifierType.createFromConfig(typeConfig);
114
- default:
115
- return (0, ts_utils_1.fail)(`${systemType}: Unknown system qualifier type.`);
116
114
  }
115
+ /* c8 ignore next 3 - should not happen */
116
+ // @ts-expect-error
117
+ return (0, ts_utils_1.fail)(`${systemType}: Unknown system qualifier type.`);
117
118
  }
118
119
  //# sourceMappingURL=helpers.js.map
@@ -230,7 +230,7 @@ class LiteralQualifierType extends qualifierType_1.QualifierType {
230
230
  static toLiteralConditionValue(from) {
231
231
  return LiteralQualifierType.isValidLiteralConditionValue(from)
232
232
  ? (0, ts_utils_1.succeed)(from)
233
- : (0, ts_utils_1.fail)(`${from}: not a valid literal condition value.`);
233
+ : (0, ts_utils_1.fail)(`${from}: invalid literal condition value.`);
234
234
  }
235
235
  }
236
236
  exports.LiteralQualifierType = LiteralQualifierType;
@@ -102,7 +102,7 @@ class LiteralValueHierarchy {
102
102
  if (ancestors.isSuccess()) {
103
103
  return ancestors.value.includes(possibleAncestor);
104
104
  }
105
- /* c8 ignore next 1 - edge case: ancestor validation fallback */
105
+ /* c8 ignore next 2 - edge case: ancestor validation fallback */
106
106
  return false;
107
107
  }
108
108
  /**
@@ -133,11 +133,11 @@ class LiteralValueHierarchy {
133
133
  // For open hierarchies, skip validation and allow any values
134
134
  if (!this.isOpenValues) {
135
135
  // Validate that both condition and context exist in the hierarchy
136
- /* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
136
+ /* c8 ignore next 3 - functional error case tested but coverage intermittently missed */
137
137
  if (!this.values.has(condition)) {
138
138
  return common_1.NoMatch;
139
139
  }
140
- /* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
140
+ /* c8 ignore next 3 - functional error case tested but coverage intermittently missed */
141
141
  if (!this.values.has(context)) {
142
142
  return common_1.NoMatch;
143
143
  }
@@ -168,6 +168,7 @@ class LiteralValueHierarchy {
168
168
  var _a;
169
169
  const errors = new ts_utils_1.MessageAggregator();
170
170
  const values = params.values;
171
+ /* c8 ignore next 1 - defense in depth */
171
172
  const hierarchy = (_a = params.hierarchy) !== null && _a !== void 0 ? _a : {};
172
173
  // If no values are provided, collect all values from the hierarchy
173
174
  let allValues;
@@ -191,7 +192,7 @@ class LiteralValueHierarchy {
191
192
  }
192
193
  const parent = valueMap.get(parentName);
193
194
  if (!parent) {
194
- errors.addMessage(`${valueName}: parent ${parentName} is not a valid literal value.`);
195
+ errors.addMessage(`${valueName}: parent ${parentName} is invalid literal value.`);
195
196
  continue;
196
197
  }
197
198
  let ancestor = parent.parent;
@@ -202,14 +203,14 @@ class LiteralValueHierarchy {
202
203
  ancestors.push(ancestor.name);
203
204
  /* c8 ignore next 1 - defensive coding: ancestor.parent === value is very difficult to reach */
204
205
  if (ancestor.parent === parent || ancestor.parent === value) {
205
- /* c8 ignore next 3 - defensive coding: circular reference error reporting intermittently missed */
206
+ /* c8 ignore next 4 - defensive coding: circular reference error reporting intermittently missed */
206
207
  errors.addMessage(`${valueName}: Circular reference detected: ${ancestors.join('->')}`);
207
208
  circular = true;
208
209
  break;
209
210
  }
210
211
  ancestor = ancestor.parent;
211
212
  }
212
- /* c8 ignore next 2 - defensive coding: circular reference handling intermittently missed */
213
+ /* c8 ignore next 3 - defensive coding: circular reference handling intermittently missed */
213
214
  if (circular) {
214
215
  continue;
215
216
  }