@fgv/ts-res 5.0.0-21 → 5.0.0-23

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 (197) hide show
  1. package/README.md +794 -137
  2. package/dist/ts-res.d.ts +506 -33
  3. package/lib/packlets/common/convert.d.ts +10 -0
  4. package/lib/packlets/common/convert.js +11 -1
  5. package/lib/packlets/common/resources.d.ts +40 -1
  6. package/lib/packlets/common/validate/regularExpressions.d.ts +4 -0
  7. package/lib/packlets/common/validate/regularExpressions.js +5 -1
  8. package/lib/packlets/common/validate/resources.d.ts +35 -1
  9. package/lib/packlets/common/validate/resources.js +54 -0
  10. package/lib/packlets/config/convert.js +1 -1
  11. package/lib/packlets/config/json.d.ts +1 -1
  12. package/lib/packlets/qualifier-types/config/convert.d.ts +22 -1
  13. package/lib/packlets/qualifier-types/config/convert.js +67 -2
  14. package/lib/packlets/qualifier-types/config/json.d.ts +11 -2
  15. package/lib/packlets/qualifier-types/helpers.d.ts +1 -2
  16. package/lib/packlets/qualifier-types/languageQualifierType.d.ts +27 -1
  17. package/lib/packlets/qualifier-types/languageQualifierType.js +75 -0
  18. package/lib/packlets/qualifier-types/literalQualifierType.d.ts +30 -4
  19. package/lib/packlets/qualifier-types/literalQualifierType.js +77 -0
  20. package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts +6 -10
  21. package/lib/packlets/qualifier-types/literalValueHierarchy.js +10 -0
  22. package/lib/packlets/qualifier-types/qualifierType.d.ts +28 -0
  23. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +28 -4
  24. package/lib/packlets/qualifier-types/territoryQualifierType.js +77 -0
  25. package/lib/packlets/resource-json/compiled/convert.js +2 -1
  26. package/lib/packlets/resource-json/compiled/json.d.ts +6 -2
  27. package/lib/packlets/resource-types/config/convert.js +3 -1
  28. package/lib/packlets/resource-types/config/json.d.ts +2 -0
  29. package/lib/packlets/resource-types/jsonResourceType.d.ts +10 -6
  30. package/lib/packlets/resource-types/jsonResourceType.js +7 -10
  31. package/lib/packlets/resource-types/resourceType.d.ts +20 -8
  32. package/lib/packlets/resource-types/resourceType.js +20 -16
  33. package/lib/packlets/resources/candidateValue.d.ts +92 -0
  34. package/lib/packlets/resources/candidateValue.js +128 -0
  35. package/lib/packlets/resources/candidateValueCollector.d.ts +55 -0
  36. package/lib/packlets/resources/candidateValueCollector.js +96 -0
  37. package/lib/packlets/resources/index.d.ts +2 -0
  38. package/lib/packlets/resources/index.js +2 -0
  39. package/lib/packlets/resources/resource.js +2 -2
  40. package/lib/packlets/resources/resourceBuilder.d.ts +6 -0
  41. package/lib/packlets/resources/resourceBuilder.js +3 -1
  42. package/lib/packlets/resources/resourceCandidate.d.ts +10 -1
  43. package/lib/packlets/resources/resourceCandidate.js +11 -5
  44. package/lib/packlets/resources/resourceManagerBuilder.d.ts +7 -0
  45. package/lib/packlets/resources/resourceManagerBuilder.js +13 -6
  46. package/lib/packlets/runtime/compiledResourceCollection.d.ts +20 -8
  47. package/lib/packlets/runtime/compiledResourceCollection.js +25 -4
  48. package/lib/packlets/runtime/resource-tree/common.d.ts +1 -1
  49. package/lib/packlets/runtime/resourceResolver.d.ts +39 -1
  50. package/lib/packlets/runtime/resourceResolver.js +45 -28
  51. package/lib/test/unit/qualifier-types/testQualifierType.d.ts +4 -0
  52. package/lib/test/unit/qualifier-types/testQualifierType.js +24 -0
  53. package/lib/test/unit/resource-types/derivedResourceType.test.d.ts +2 -0
  54. package/lib/test/unit/resource-types/testDerivedResourceType.d.ts +79 -0
  55. package/lib/test/unit/resource-types/testDerivedResourceType.js +113 -0
  56. package/lib/test/unit/resources/candidateValue.test.d.ts +2 -0
  57. package/lib/test/unit/resources/candidateValueCollector.test.d.ts +2 -0
  58. package/lib/test/unit/runtime/resourceResolver.coverage.test.d.ts +2 -0
  59. package/lib/test/unit/runtime/resourceResolver.newFeatures.test.d.ts +2 -0
  60. package/package.json +7 -7
  61. package/src/index.ts +0 -75
  62. package/src/packlets/bundle/bundleBuilder.ts +0 -159
  63. package/src/packlets/bundle/bundleLoader.ts +0 -157
  64. package/src/packlets/bundle/bundleNormalizer.ts +0 -173
  65. package/src/packlets/bundle/bundleUtils.ts +0 -142
  66. package/src/packlets/bundle/convert.ts +0 -87
  67. package/src/packlets/bundle/index.ts +0 -52
  68. package/src/packlets/bundle/model.ts +0 -138
  69. package/src/packlets/common/conditions.ts +0 -226
  70. package/src/packlets/common/convert.ts +0 -184
  71. package/src/packlets/common/helpers/conditions.ts +0 -84
  72. package/src/packlets/common/helpers/context.ts +0 -88
  73. package/src/packlets/common/helpers/index.ts +0 -26
  74. package/src/packlets/common/helpers/qualifierDefaultValues.ts +0 -91
  75. package/src/packlets/common/helpers/resources.ts +0 -96
  76. package/src/packlets/common/index.ts +0 -30
  77. package/src/packlets/common/resources.ts +0 -78
  78. package/src/packlets/common/validate/conditions.ts +0 -595
  79. package/src/packlets/common/validate/index.ts +0 -27
  80. package/src/packlets/common/validate/regularExpressions.ts +0 -92
  81. package/src/packlets/common/validate/resources.ts +0 -170
  82. package/src/packlets/conditions/condition.ts +0 -351
  83. package/src/packlets/conditions/conditionCollector.ts +0 -103
  84. package/src/packlets/conditions/conditionDecls.ts +0 -50
  85. package/src/packlets/conditions/conditionSet.ts +0 -318
  86. package/src/packlets/conditions/conditionSetCollector.ts +0 -127
  87. package/src/packlets/conditions/conditionSetDecls.ts +0 -41
  88. package/src/packlets/conditions/conditionToken.ts +0 -180
  89. package/src/packlets/conditions/convert/conditionSetDecls.ts +0 -72
  90. package/src/packlets/conditions/convert/decls.ts +0 -95
  91. package/src/packlets/conditions/convert/index.ts +0 -24
  92. package/src/packlets/conditions/index.ts +0 -33
  93. package/src/packlets/config/common.ts +0 -107
  94. package/src/packlets/config/configInitFactory.ts +0 -142
  95. package/src/packlets/config/convert.ts +0 -61
  96. package/src/packlets/config/index.ts +0 -30
  97. package/src/packlets/config/json.ts +0 -43
  98. package/src/packlets/config/predefined/default.ts +0 -150
  99. package/src/packlets/config/predefined/extended.ts +0 -198
  100. package/src/packlets/config/predefined/index.ts +0 -26
  101. package/src/packlets/config/systemConfiguration.ts +0 -217
  102. package/src/packlets/context/contextDecls.ts +0 -76
  103. package/src/packlets/context/contextToken.ts +0 -252
  104. package/src/packlets/context/convert/decls.ts +0 -126
  105. package/src/packlets/context/convert/index.ts +0 -23
  106. package/src/packlets/context/index.ts +0 -27
  107. package/src/packlets/decisions/abstractDecision.ts +0 -87
  108. package/src/packlets/decisions/abstractDecisionCollector.ts +0 -122
  109. package/src/packlets/decisions/candidate.ts +0 -101
  110. package/src/packlets/decisions/common.ts +0 -37
  111. package/src/packlets/decisions/concreteDecision.ts +0 -157
  112. package/src/packlets/decisions/decision.ts +0 -172
  113. package/src/packlets/decisions/index.ts +0 -28
  114. package/src/packlets/import/fsItem.ts +0 -212
  115. package/src/packlets/import/importContext.ts +0 -183
  116. package/src/packlets/import/importManager.ts +0 -187
  117. package/src/packlets/import/importable.ts +0 -107
  118. package/src/packlets/import/importers/collectionImporter.ts +0 -153
  119. package/src/packlets/import/importers/fsItemImporter.ts +0 -154
  120. package/src/packlets/import/importers/importer.ts +0 -58
  121. package/src/packlets/import/importers/index.ts +0 -27
  122. package/src/packlets/import/importers/jsonImporter.ts +0 -133
  123. package/src/packlets/import/importers/pathImporter.ts +0 -134
  124. package/src/packlets/import/index.ts +0 -29
  125. package/src/packlets/qualifier-types/config/convert.ts +0 -108
  126. package/src/packlets/qualifier-types/config/index.ts +0 -27
  127. package/src/packlets/qualifier-types/config/json.ts +0 -126
  128. package/src/packlets/qualifier-types/convert.ts +0 -77
  129. package/src/packlets/qualifier-types/helpers.ts +0 -94
  130. package/src/packlets/qualifier-types/index.ts +0 -34
  131. package/src/packlets/qualifier-types/languageQualifierType.ts +0 -143
  132. package/src/packlets/qualifier-types/literalQualifierType.ts +0 -244
  133. package/src/packlets/qualifier-types/literalValueHierarchy.ts +0 -332
  134. package/src/packlets/qualifier-types/qualifierType.ts +0 -360
  135. package/src/packlets/qualifier-types/qualifierTypeCollector.ts +0 -102
  136. package/src/packlets/qualifier-types/territoryQualifierType.ts +0 -255
  137. package/src/packlets/qualifiers/convert/decls.ts +0 -90
  138. package/src/packlets/qualifiers/convert/index.ts +0 -24
  139. package/src/packlets/qualifiers/convert/qualifier.ts +0 -55
  140. package/src/packlets/qualifiers/index.ts +0 -31
  141. package/src/packlets/qualifiers/qualifier.ts +0 -169
  142. package/src/packlets/qualifiers/qualifierCollector.ts +0 -194
  143. package/src/packlets/qualifiers/qualifierDecl.ts +0 -80
  144. package/src/packlets/qualifiers/qualifierDefaultValueDecls.ts +0 -57
  145. package/src/packlets/qualifiers/qualifierDefaultValueToken.ts +0 -230
  146. package/src/packlets/resource-json/compiled/common.ts +0 -35
  147. package/src/packlets/resource-json/compiled/convert.ts +0 -143
  148. package/src/packlets/resource-json/compiled/index.ts +0 -27
  149. package/src/packlets/resource-json/compiled/json.ts +0 -239
  150. package/src/packlets/resource-json/convert.ts +0 -236
  151. package/src/packlets/resource-json/helpers.ts +0 -284
  152. package/src/packlets/resource-json/index.ts +0 -33
  153. package/src/packlets/resource-json/json.ts +0 -295
  154. package/src/packlets/resource-json/normalized.ts +0 -211
  155. package/src/packlets/resource-json/resourceDeclCollection.ts +0 -117
  156. package/src/packlets/resource-json/resourceDeclContainer.ts +0 -48
  157. package/src/packlets/resource-json/resourceDeclTree.ts +0 -116
  158. package/src/packlets/resource-types/config/convert.ts +0 -36
  159. package/src/packlets/resource-types/config/index.ts +0 -27
  160. package/src/packlets/resource-types/config/json.ts +0 -30
  161. package/src/packlets/resource-types/helpers.ts +0 -44
  162. package/src/packlets/resource-types/index.ts +0 -30
  163. package/src/packlets/resource-types/jsonResourceType.ts +0 -104
  164. package/src/packlets/resource-types/resourceType.ts +0 -259
  165. package/src/packlets/resource-types/resourceTypeCollector.ts +0 -79
  166. package/src/packlets/resources/candidateReducer.ts +0 -331
  167. package/src/packlets/resources/common.ts +0 -114
  168. package/src/packlets/resources/index.ts +0 -28
  169. package/src/packlets/resources/resource.ts +0 -307
  170. package/src/packlets/resources/resourceBuilder.ts +0 -269
  171. package/src/packlets/resources/resourceCandidate.ts +0 -333
  172. package/src/packlets/resources/resourceManagerBuilder.ts +0 -1169
  173. package/src/packlets/runtime/cacheListener.ts +0 -113
  174. package/src/packlets/runtime/cacheMetrics.ts +0 -206
  175. package/src/packlets/runtime/compiledResourceCollection.ts +0 -607
  176. package/src/packlets/runtime/conditionSetResolutionResult.ts +0 -160
  177. package/src/packlets/runtime/context/contextQualifierProvider.ts +0 -117
  178. package/src/packlets/runtime/context/contextQualifierProviderValidator.ts +0 -281
  179. package/src/packlets/runtime/context/index.ts +0 -26
  180. package/src/packlets/runtime/context/simpleContextQualifierProvider.ts +0 -225
  181. package/src/packlets/runtime/context/validatingSimpleContextQualifierProvider.ts +0 -96
  182. package/src/packlets/runtime/iResourceManager.ts +0 -130
  183. package/src/packlets/runtime/index.ts +0 -35
  184. package/src/packlets/runtime/resource-tree/common.ts +0 -126
  185. package/src/packlets/runtime/resource-tree/index.ts +0 -26
  186. package/src/packlets/runtime/resource-tree/readOnlyResourceTree.ts +0 -342
  187. package/src/packlets/runtime/resource-tree/resourceTreeChildren.ts +0 -125
  188. package/src/packlets/runtime/resource-tree/resourceTreeChildrenValidator.ts +0 -187
  189. package/src/packlets/runtime/resourceResolver.ts +0 -626
  190. package/src/packlets/runtime/validate.ts +0 -63
  191. package/src/packlets/zip-archive/convert.ts +0 -121
  192. package/src/packlets/zip-archive/index.ts +0 -76
  193. package/src/packlets/zip-archive/json.ts +0 -91
  194. package/src/packlets/zip-archive/types.ts +0 -140
  195. package/src/packlets/zip-archive/zipArchiveCreator.ts +0 -229
  196. package/src/packlets/zip-archive/zipArchiveFormat.ts +0 -158
  197. package/src/packlets/zip-archive/zipArchiveLoader.ts +0 -370
@@ -1,333 +0,0 @@
1
- /*
2
- * Copyright (c) 2025 Erik Fortune
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in all
12
- * copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
- import { JsonObject } from '@fgv/ts-json-base';
24
- import {
25
- CandidateCompleteness,
26
- PerfectMatch,
27
- QualifierName,
28
- ResourceId,
29
- ResourceValueMergeMethod,
30
- Validate
31
- } from '../common';
32
- import { Condition, ConditionSet, ConditionSetCollector } from '../conditions';
33
- import * as ResourceJson from '../resource-json';
34
- import { ResourceType } from '../resource-types';
35
- import { captureResult, mapResults, Hash, MessageAggregator, Result, fail, succeed } from '@fgv/ts-utils';
36
- import * as Context from '../context';
37
- import { IResourceCandidate } from '../runtime';
38
-
39
- /**
40
- * Parameters to create a {@link Resources.ResourceCandidate | ResourceCandidate}.
41
- * @public
42
- */
43
- export interface IResourceCandidateCreateParams {
44
- id: string;
45
- decl: ResourceJson.Json.IChildResourceCandidateDecl;
46
- resourceType?: ResourceType;
47
- parentConditions?: ReadonlyArray<Condition>;
48
- conditionSets: ConditionSetCollector;
49
- }
50
-
51
- /**
52
- * Options for creating a {@link Resources.ResourceCandidate | ResourceCandidate} declaration.
53
- * @remarks
54
- * This interface extends the {@link ResourceJson.Helpers.IDeclarationOptions | declaration options}
55
- * interface to include a `reduceQualifiers` option.
56
- * @public
57
- */
58
- export interface ICandidateDeclOptions extends ResourceJson.Helpers.IDeclarationOptions {
59
- /**
60
- * If provided, reduces the qualifiers of the candidate by removing qualifiers that are made
61
- * irrelevant by the filterForContext.
62
- */
63
- qualifiersToReduce?: ReadonlySet<QualifierName>;
64
- }
65
-
66
- /**
67
- * A {@link Resources.ResourceCandidate | resource candidate} represents a single possible
68
- * instance value for some resource, with the conditions under which it applies
69
- * and instructions on how to merge it with other instances.
70
- * @public
71
- */
72
- export class ResourceCandidate implements IResourceCandidate {
73
- /**
74
- * The unique identifier of the resource for which this candidate
75
- * is a possible instance.
76
- */
77
- public readonly id: ResourceId;
78
-
79
- /**
80
- * The JSON representation of the instance data to be applied.
81
- */
82
- public readonly json: JsonObject;
83
-
84
- /**
85
- * The conditions under which this candidate applies.
86
- */
87
- public readonly conditions: ConditionSet;
88
-
89
- /**
90
- * True if this candidate is a partial instance.
91
- */
92
- public readonly isPartial: boolean;
93
-
94
- /**
95
- * The method to use when merging this candidate with other instances.
96
- */
97
- public readonly mergeMethod: ResourceValueMergeMethod;
98
-
99
- /**
100
- * The {@link ResourceTypes.ResourceType | resource type} for the resource to which
101
- * this candidate belongs.
102
- */
103
- public readonly resourceType: ResourceType | undefined;
104
-
105
- /**
106
- * The completeness of the candidate value.
107
- */
108
- public get completeness(): CandidateCompleteness {
109
- return this.isPartial ? 'partial' : 'full';
110
- }
111
-
112
- /**
113
- * Constructor for a {@link Resources.ResourceCandidate | ResourceCandidate} object.
114
- * @param params - Parameters to create a new {@link Resources.ResourceCandidate | ResourceCandidate}.
115
- * @public
116
- */
117
- protected constructor(params: IResourceCandidateCreateParams) {
118
- this.id = Validate.toResourceId(params.id).orThrow();
119
- this.json = params.decl.json;
120
- this.conditions = ResourceCandidate._mergeConditions(
121
- params.conditionSets,
122
- params.decl.conditions,
123
- params.parentConditions
124
- ).orThrow();
125
- this.isPartial = params.decl.isPartial ?? false;
126
- this.mergeMethod = params.decl.mergeMethod ?? 'augment';
127
- this.resourceType = params.resourceType;
128
- if (this.resourceType) {
129
- this.resourceType.validateDeclaration(this).orThrow();
130
- }
131
- }
132
-
133
- /**
134
- * Creates a new {@link Resources.ResourceCandidate | ResourceCandidate} object.
135
- * @param params - Parameters to create a new {@link Resources.ResourceCandidate | ResourceCandidate}.
136
- * @returns `Success` with the new {@link Resources.ResourceCandidate | ResourceCandidate} object if successful,
137
- * or `Failure` with an error message if not.
138
- * @public
139
- */
140
- public static create(params: IResourceCandidateCreateParams): Result<ResourceCandidate> {
141
- return captureResult(() => new ResourceCandidate(params));
142
- }
143
-
144
- /**
145
- * Determines if this candidate can match the supplied context (possibly partial).
146
- * @param context - The context to match.
147
- * @param options - Options to use when matching.
148
- * @returns `true` if the candidate can match the context, `false` otherwise.
149
- */
150
- public canMatchPartialContext(
151
- context: Context.IValidatedContextDecl,
152
- options?: Context.IContextMatchOptions
153
- ): boolean {
154
- return this.conditions.canMatchPartialContext(context, options);
155
- }
156
-
157
- /**
158
- * Gets the {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}
159
- * for this candidate.
160
- * @param options - {@link ResourceJson.Helpers.IDeclarationOptions | options} to use when creating the declaration.
161
- * @returns The {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}.
162
- */
163
- public toChildResourceCandidateDecl(
164
- options?: ICandidateDeclOptions
165
- ): ResourceJson.Json.IChildResourceCandidateDecl {
166
- const showDefaults = options?.showDefaults === true;
167
- return {
168
- json: this.json as JsonObject,
169
- conditions: this.conditions.toConditionSetRecordDecl(options),
170
- ...(showDefaults || this.isPartial ? { isPartial: this.isPartial } : {}),
171
- ...(showDefaults || this.mergeMethod !== 'augment' ? { mergeMethod: this.mergeMethod } : {})
172
- };
173
- }
174
-
175
- /**
176
- * Gets the {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}
177
- * for this candidate.
178
- * @param options - {@link ResourceJson.Helpers.IDeclarationOptions | options} to use when creating the declaration.
179
- * @returns The {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}.
180
- */
181
- public toLooseResourceCandidateDecl(
182
- options?: ICandidateDeclOptions
183
- ): ResourceJson.Json.ILooseResourceCandidateDecl {
184
- const showDefaults = options?.showDefaults === true;
185
- const resourceTypeName = this.resourceType?.key;
186
- return {
187
- id: this.id.toString(),
188
- json: this.json as JsonObject,
189
- conditions: this.conditions.toConditionSetRecordDecl(options),
190
- ...(showDefaults || this.isPartial ? { isPartial: this.isPartial } : {}),
191
- ...(showDefaults || this.mergeMethod !== 'augment' ? { mergeMethod: this.mergeMethod } : {}),
192
- ...(resourceTypeName ? { resourceTypeName } : {})
193
- };
194
- }
195
-
196
- /**
197
- * Extracts the {@link ResourceTypes.ResourceType | resource type} from a list of {@link Resources.ResourceCandidate | resource candidates},
198
- * if present.
199
- * @param candidates - The list of candidates from which to extract the resource type.
200
- * @returns `Success` with the resource type if successful, `Success` with `undefined` if none of the candidates
201
- * specify a resource tap, and `Failure` with an error message if clients specify conflicting resource types.
202
- * @public
203
- */
204
- public static validateResourceTypes(
205
- candidates: ReadonlyArray<ResourceCandidate>,
206
- expectedType?: ResourceType
207
- ): Result<ResourceType | undefined> {
208
- const errors = new MessageAggregator();
209
- let selectedType: ResourceType | undefined = expectedType;
210
- for (const candidate of candidates) {
211
- if (selectedType === undefined) {
212
- /* c8 ignore next 1 - functional code path tested but coverage intermittently missed */
213
- selectedType = candidate.resourceType;
214
- } else if (candidate.resourceType && selectedType !== candidate.resourceType) {
215
- /* c8 ignore next 4 - functional code path tested but coverage intermittently missed */
216
- errors.addMessage(
217
- `${candidate.id}: resource type mismatch (${selectedType.key} != ${candidate.resourceType.key})`
218
- );
219
- }
220
- }
221
- return errors.returnOrReport(succeed(selectedType));
222
- }
223
-
224
- /**
225
- * Compares two {@link Resources.ResourceCandidate | ResourceCandidates} for sorting purposes.
226
- * @param rc1 - The first candidate to compare.
227
- * @param rc2 - The second candidate to compare.
228
- * @returns A negative number if `rc1` should come before `rc2`, a positive number if `rc2` should come before `rc1`,
229
- * or zero if they are equivalent.
230
- * @public
231
- */
232
- public static compare(rc1: ResourceCandidate, rc2: ResourceCandidate): number {
233
- return ConditionSet.compare(rc1.conditions, rc2.conditions);
234
- }
235
-
236
- /**
237
- * Compares two {@link Resources.ResourceCandidate | ResourceCandidates} for equality.
238
- * @param rc1 - The first candidate to compare.
239
- * @param rc2 - The second candidate to compare.
240
- * @returns `true` if the candidates are equal, `false` otherwise.
241
- * @public
242
- */
243
- public static equal(rc1: ResourceCandidate, rc2: ResourceCandidate): boolean {
244
- /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
245
- if (rc1 === rc2) {
246
- return true;
247
- }
248
- let equal =
249
- rc1.id === rc2.id &&
250
- rc1.isPartial === rc2.isPartial &&
251
- rc1.mergeMethod === rc2.mergeMethod &&
252
- ConditionSet.compare(rc1.conditions, rc2.conditions) === 0;
253
- if (equal) {
254
- const normalizer = new Hash.Crc32Normalizer();
255
- const n1 = normalizer.computeHash(rc1.json).orDefault('(n1 normalization failed)');
256
- const n2 = normalizer.computeHash(rc2.json).orDefault('(n2 normalization failed)');
257
- equal = n1 === n2;
258
- }
259
- return equal;
260
- }
261
-
262
- /**
263
- * Validates declared conditions and merges them with parent conditions.
264
- * @param conditionSets - The {@link Conditions.ConditionSetCollector | condition set collector}
265
- * to use for this candidate.
266
- * @param declared - The declared conditions for the candidate.
267
- * @param parent - The parent conditions to merge with the declared conditions.
268
- * @returns `Success` with the merged conditions if successful, `Failure` otherwise.
269
- * @internal
270
- */
271
- private static _mergeConditions(
272
- conditionSets: ConditionSetCollector,
273
- declared: ResourceJson.Json.ConditionSetDecl | undefined,
274
- parent: ReadonlyArray<Condition> | undefined
275
- ): Result<ConditionSet> {
276
- /* c8 ignore next 2 - code coverage is flaky */
277
- declared = declared ?? {};
278
- parent = parent ?? [];
279
-
280
- const { value: conditionDecls, message } = ResourceJson.Convert.conditionSetDecl.convert(declared);
281
- /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */
282
- if (message !== undefined) {
283
- return fail(message);
284
- }
285
-
286
- return mapResults(
287
- // get or add all declared conditions from our condition collector
288
- conditionDecls.map((decl) => conditionSets.conditions.validating.getOrAdd(decl))
289
- ).onSuccess((declaredConditions) => {
290
- // make sure our parent conditions all come from our condition collector too
291
- return mapResults(parent.map((c) => conditionSets.conditions.getOrAdd(c))).onSuccess(
292
- (parentConditions) => {
293
- const conditions = [...parentConditions, ...declaredConditions];
294
- return conditionSets.validating.getOrAdd(conditions);
295
- }
296
- );
297
- });
298
- }
299
-
300
- /**
301
- * Finds the qualifiers that are made irrelevant by the supplied filterForContext.
302
- * @param candidates - The candidates to find the reducible qualifiers for.
303
- * @param filterForContext - The filter for context to use.
304
- * @returns The qualifiers that are made irrelevant by the filterForContext.
305
- * @remarks
306
- * For any given set of candidates, qualifiers that match every candidate perfectly
307
- * are irrelevant to the filtered content and can be removed. Qualifiers that do not
308
- * match, that are not in the filterForContext, or which partially match at least one
309
- * candidate remain relevant and must not be removed.
310
- * @public
311
- */
312
- public static findReducibleQualifiers(
313
- candidates: ReadonlyArray<ResourceCandidate>,
314
- filterForContext: Context.IValidatedContextDecl
315
- ): ReadonlySet<QualifierName> | undefined {
316
- const qualifiersToReduce = new Set<QualifierName>(Object.keys(filterForContext) as QualifierName[]);
317
- for (const candidate of candidates) {
318
- for (const condition of candidate.conditions.conditions) {
319
- if (qualifiersToReduce.has(condition.qualifier.name)) {
320
- const match = condition.qualifier.type.matches(
321
- condition.value,
322
- filterForContext[condition.qualifier.name],
323
- 'matches'
324
- );
325
- if (match !== PerfectMatch) {
326
- qualifiersToReduce.delete(condition.qualifier.name);
327
- }
328
- }
329
- }
330
- }
331
- return qualifiersToReduce.size > 0 ? qualifiersToReduce : undefined;
332
- }
333
- }