@fgv/ts-res 5.0.0-2 → 5.0.0-21
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/.vscode/4.json +3 -0
- package/.vscode/launch.json +16 -0
- package/.vscode/settings.json +3 -0
- package/config/api-extractor.json +343 -0
- package/config/rig.json +16 -0
- package/dist/ts-res.d.ts +1528 -161
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.d.ts +11 -2
- package/lib/index.js +25 -2
- package/lib/packlets/bundle/bundleBuilder.d.ts +41 -0
- package/lib/packlets/bundle/bundleBuilder.js +134 -0
- package/lib/packlets/bundle/bundleLoader.d.ts +72 -0
- package/lib/packlets/bundle/bundleLoader.js +105 -0
- package/lib/packlets/bundle/bundleNormalizer.d.ts +73 -0
- package/lib/packlets/bundle/bundleNormalizer.js +142 -0
- package/lib/packlets/bundle/bundleUtils.d.ts +70 -0
- package/lib/packlets/bundle/bundleUtils.js +117 -0
- package/lib/packlets/bundle/convert.d.ts +33 -0
- package/lib/packlets/bundle/convert.js +78 -0
- package/lib/packlets/bundle/index.d.ts +21 -0
- package/lib/packlets/bundle/index.js +83 -0
- package/lib/packlets/bundle/model.d.ts +100 -0
- package/lib/packlets/bundle/model.js +24 -0
- package/lib/packlets/common/helpers/resources.d.ts +7 -0
- package/lib/packlets/common/helpers/resources.js +12 -0
- package/lib/packlets/common/resources.d.ts +8 -0
- package/lib/packlets/conditions/conditionSet.d.ts +9 -0
- package/lib/packlets/conditions/conditionSet.js +74 -1
- package/lib/packlets/config/configInitFactory.d.ts +78 -0
- package/lib/packlets/config/configInitFactory.js +147 -0
- package/lib/packlets/config/convert.d.ts +9 -0
- package/lib/packlets/config/convert.js +11 -0
- package/lib/packlets/config/index.d.ts +1 -0
- package/lib/packlets/config/index.js +1 -0
- package/lib/packlets/config/systemConfiguration.d.ts +16 -3
- package/lib/packlets/config/systemConfiguration.js +19 -40
- package/lib/packlets/import/fsItem.js +8 -13
- package/lib/packlets/import/importers/jsonImporter.js +1 -0
- package/lib/packlets/qualifier-types/config/json.d.ts +13 -0
- package/lib/packlets/qualifier-types/config/json.js +11 -0
- package/lib/packlets/qualifier-types/literalValueHierarchy.js +1 -1
- package/lib/packlets/qualifiers/qualifierCollector.js +1 -2
- package/lib/packlets/resource-types/jsonResourceType.d.ts +9 -4
- package/lib/packlets/resource-types/jsonResourceType.js +8 -1
- package/lib/packlets/resource-types/resourceType.d.ts +102 -13
- package/lib/packlets/resource-types/resourceType.js +34 -2
- package/lib/packlets/resources/common.d.ts +26 -0
- package/lib/packlets/resources/resource.d.ts +6 -6
- package/lib/packlets/resources/resource.js +3 -8
- package/lib/packlets/resources/resourceCandidate.d.ts +5 -1
- package/lib/packlets/resources/resourceCandidate.js +6 -0
- package/lib/packlets/resources/resourceManagerBuilder.d.ts +182 -11
- package/lib/packlets/resources/resourceManagerBuilder.js +469 -15
- package/lib/packlets/runtime/cacheListener.d.ts +9 -0
- package/lib/packlets/runtime/cacheListener.js +6 -0
- package/lib/packlets/runtime/cacheMetrics.d.ts +6 -0
- package/lib/packlets/runtime/cacheMetrics.js +11 -0
- package/lib/packlets/runtime/compiledResourceCollection.d.ts +3 -3
- package/lib/packlets/runtime/compiledResourceCollection.js +7 -0
- package/lib/packlets/runtime/iResourceManager.d.ts +13 -5
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts +7 -7
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js +5 -5
- package/lib/packlets/runtime/resourceResolver.d.ts +21 -0
- package/lib/packlets/runtime/resourceResolver.js +39 -17
- package/lib/packlets/runtime/validate.js +1 -0
- package/lib/packlets/zip-archive/convert.d.ts +52 -0
- package/lib/packlets/zip-archive/convert.js +104 -0
- package/lib/packlets/zip-archive/index.d.ts +23 -0
- package/lib/packlets/zip-archive/index.js +95 -0
- package/lib/packlets/zip-archive/json.d.ts +64 -0
- package/lib/packlets/zip-archive/json.js +24 -0
- package/lib/packlets/zip-archive/types.d.ts +98 -0
- package/lib/packlets/zip-archive/types.js +39 -0
- package/lib/packlets/zip-archive/zipArchiveCreator.d.ts +35 -0
- package/lib/packlets/zip-archive/zipArchiveCreator.js +194 -0
- package/lib/packlets/zip-archive/zipArchiveFormat.d.ts +70 -0
- package/lib/packlets/zip-archive/zipArchiveFormat.js +184 -0
- package/lib/packlets/zip-archive/zipArchiveLoader.d.ts +70 -0
- package/lib/packlets/zip-archive/zipArchiveLoader.js +285 -0
- package/lib/test/data/sample.json +32 -0
- package/lib/test/unit/bundle/bundleBuilder.test.d.ts +2 -0
- package/lib/test/unit/bundle/bundleLoader.test.d.ts +2 -0
- package/lib/test/unit/bundle/bundleUtils.test.d.ts +2 -0
- package/lib/test/unit/bundle/convert.test.d.ts +2 -0
- package/lib/test/unit/bundle/integration.test.d.ts +2 -0
- package/lib/test/unit/bundle/model.test.d.ts +2 -0
- package/lib/test/unit/bundle/normalization.test.d.ts +2 -0
- package/lib/test/unit/common/conditions.test.d.ts +2 -0
- package/lib/test/unit/common/helpers/conditions.test.d.ts +2 -0
- package/lib/test/unit/common/helpers/contexts.test.d.ts +2 -0
- package/lib/test/unit/common/helpers/qualifierDefaultValues.test.d.ts +2 -0
- package/lib/test/unit/common/resources.test.d.ts +2 -0
- package/lib/test/unit/conditions/condition.test.d.ts +2 -0
- package/lib/test/unit/conditions/conditionCollector.test.d.ts +2 -0
- package/lib/test/unit/conditions/conditionScoreAsDefault.test.d.ts +2 -0
- package/lib/test/unit/conditions/conditionSet.test.d.ts +2 -0
- package/lib/test/unit/conditions/conditionSetCollector.test.d.ts +2 -0
- package/lib/test/unit/conditions/conditionToken.test.d.ts +2 -0
- package/lib/test/unit/conditions/convert.test.d.ts +2 -0
- package/lib/test/unit/config/common.test.d.ts +2 -0
- package/lib/test/unit/config/convert.test.d.ts +2 -0
- package/lib/test/unit/config/predefined/default.test.d.ts +2 -0
- package/lib/test/unit/config/predefined/extended.test.d.ts +2 -0
- package/lib/test/unit/config/systemConfiguration.test.d.ts +2 -0
- package/lib/test/unit/config/systemConfigurationInitParams.test.d.ts +2 -0
- package/lib/test/unit/context/contextToken.test.d.ts +2 -0
- package/lib/test/unit/context/convert.test.d.ts +2 -0
- package/lib/test/unit/decisions/abstractDecision.test.d.ts +2 -0
- package/lib/test/unit/decisions/abstractDecisionCollector.test.d.ts +2 -0
- package/lib/test/unit/decisions/candidate.test.d.ts +2 -0
- package/lib/test/unit/decisions/concreteDecision.test.d.ts +2 -0
- package/lib/test/unit/decisions/decision.test.d.ts +2 -0
- package/lib/test/unit/import/collectionImporter.test.d.ts +2 -0
- package/lib/test/unit/import/fsItem.test.d.ts +2 -0
- package/lib/test/unit/import/fsItemImporter.test.d.ts +2 -0
- package/lib/test/unit/import/importContext.test.d.ts +2 -0
- package/lib/test/unit/import/importManager.test.d.ts +2 -0
- package/lib/test/unit/import/jsonImporter.test.d.ts +2 -0
- package/lib/test/unit/import/pathImporter.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/convert.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/helpers.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/languageQualifierType.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/literalQualifierType.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/literalValueHierarchy.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/qualifierType.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/qualifierTypeCollector.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/territoryQualifierType.test.d.ts +2 -0
- package/lib/test/unit/qualifier-types/testQualifierType.d.ts +15 -0
- package/lib/test/unit/qualifier-types/testQualifierType.js +89 -0
- package/lib/test/unit/qualifiers/convert.test.d.ts +2 -0
- package/lib/test/unit/qualifiers/qualifierCollector.test.d.ts +2 -0
- package/lib/test/unit/qualifiers/qualifierDefaultValue.test.d.ts +2 -0
- package/lib/test/unit/qualifiers/qualifierDefaultValueToken.test.d.ts +2 -0
- package/lib/test/unit/resource-json/convert.test.d.ts +2 -0
- package/lib/test/unit/resource-json/nameInheritance.test.d.ts +2 -0
- package/lib/test/unit/resource-json/resourceDeclCollection.test.d.ts +2 -0
- package/lib/test/unit/resource-json/resourceDeclTree.test.d.ts +2 -0
- package/lib/test/unit/resource-types/jsonResourceType.test.d.ts +2 -0
- package/lib/test/unit/resource-types/resourceTypeCollector.test.d.ts +2 -0
- package/lib/test/unit/resources/candidateReducer.integration.test.d.ts +2 -0
- package/lib/test/unit/resources/candidateReducer.test.d.ts +2 -0
- package/lib/test/unit/resources/reduceCandidates.test.d.ts +2 -0
- package/lib/test/unit/resources/reduceQualifiers.comprehensive.test.d.ts +2 -0
- package/lib/test/unit/resources/reduceQualifiers.test.d.ts +2 -0
- package/lib/test/unit/resources/resource.test.d.ts +2 -0
- package/lib/test/unit/resources/resourceBuilder.test.d.ts +2 -0
- package/lib/test/unit/resources/resourceCandidate.test.d.ts +2 -0
- package/lib/test/unit/resources/resourceManagerBuilder.clone.test.d.ts +2 -0
- package/lib/test/unit/resources/resourceManagerBuilder.getBuiltResourceTree.test.d.ts +2 -0
- package/lib/test/unit/resources/resourceManagerBuilder.test.d.ts +2 -0
- package/lib/test/unit/runtime/cacheListener.test.d.ts +2 -0
- package/lib/test/unit/runtime/cacheMetrics.test.d.ts +2 -0
- package/lib/test/unit/runtime/compiledResourceCollection.test.d.ts +2 -0
- package/lib/test/unit/runtime/conditionSetResolutionResult.comprehensive.test.d.ts +2 -0
- package/lib/test/unit/runtime/conditionSetResolutionResult.test.d.ts +2 -0
- package/lib/test/unit/runtime/context/contextQualifierProvider.test.d.ts +2 -0
- package/lib/test/unit/runtime/context/contextQualifierProviderValidator.test.d.ts +2 -0
- package/lib/test/unit/runtime/context/simpleContextQualifierProvider.test.d.ts +2 -0
- package/lib/test/unit/runtime/context/validatingSimpleContextQualifierProvider.test.d.ts +2 -0
- package/lib/test/unit/runtime/resource-tree/readOnlyResourceTree.test.d.ts +2 -0
- package/lib/test/unit/runtime/resource-tree/resourceTreeChildren.test.d.ts +2 -0
- package/lib/test/unit/runtime/resource-tree/resourceTreeChildrenValidator.test.d.ts +2 -0
- package/lib/test/unit/runtime/resourceResolver.defaultResolution.test.d.ts +2 -0
- package/lib/test/unit/runtime/resourceResolver.test.d.ts +2 -0
- package/lib/test/unit/runtime/validate.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/convert.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/json.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/zipArchiveCreator.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/zipArchiveFormat.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/zipArchiveIdempotency.test.d.ts +2 -0
- package/lib/test/unit/zip-archive/zipArchiveLoader.test.d.ts +2 -0
- package/package.json +19 -25
- package/src/index.ts +75 -0
- package/src/packlets/bundle/bundleBuilder.ts +159 -0
- package/src/packlets/bundle/bundleLoader.ts +157 -0
- package/src/packlets/bundle/bundleNormalizer.ts +173 -0
- package/src/packlets/bundle/bundleUtils.ts +142 -0
- package/src/packlets/bundle/convert.ts +87 -0
- package/src/packlets/bundle/index.ts +52 -0
- package/src/packlets/bundle/model.ts +138 -0
- package/src/packlets/common/conditions.ts +226 -0
- package/src/packlets/common/convert.ts +184 -0
- package/src/packlets/common/helpers/conditions.ts +84 -0
- package/src/packlets/common/helpers/context.ts +88 -0
- package/src/packlets/common/helpers/index.ts +26 -0
- package/src/packlets/common/helpers/qualifierDefaultValues.ts +91 -0
- package/src/packlets/common/helpers/resources.ts +96 -0
- package/src/packlets/common/index.ts +30 -0
- package/src/packlets/common/resources.ts +78 -0
- package/src/packlets/common/validate/conditions.ts +595 -0
- package/src/packlets/common/validate/index.ts +27 -0
- package/src/packlets/common/validate/regularExpressions.ts +92 -0
- package/src/packlets/common/validate/resources.ts +170 -0
- package/src/packlets/conditions/condition.ts +351 -0
- package/src/packlets/conditions/conditionCollector.ts +103 -0
- package/src/packlets/conditions/conditionDecls.ts +50 -0
- package/src/packlets/conditions/conditionSet.ts +318 -0
- package/src/packlets/conditions/conditionSetCollector.ts +127 -0
- package/src/packlets/conditions/conditionSetDecls.ts +41 -0
- package/src/packlets/conditions/conditionToken.ts +180 -0
- package/src/packlets/conditions/convert/conditionSetDecls.ts +72 -0
- package/src/packlets/conditions/convert/decls.ts +95 -0
- package/src/packlets/conditions/convert/index.ts +24 -0
- package/src/packlets/conditions/index.ts +33 -0
- package/src/packlets/config/common.ts +107 -0
- package/src/packlets/config/configInitFactory.ts +142 -0
- package/src/packlets/config/convert.ts +61 -0
- package/src/packlets/config/index.ts +30 -0
- package/src/packlets/config/json.ts +43 -0
- package/src/packlets/config/predefined/default.ts +150 -0
- package/src/packlets/config/predefined/extended.ts +198 -0
- package/src/packlets/config/predefined/index.ts +26 -0
- package/src/packlets/config/systemConfiguration.ts +217 -0
- package/src/packlets/context/contextDecls.ts +76 -0
- package/src/packlets/context/contextToken.ts +252 -0
- package/src/packlets/context/convert/decls.ts +126 -0
- package/src/packlets/context/convert/index.ts +23 -0
- package/src/packlets/context/index.ts +27 -0
- package/src/packlets/decisions/abstractDecision.ts +87 -0
- package/src/packlets/decisions/abstractDecisionCollector.ts +122 -0
- package/src/packlets/decisions/candidate.ts +101 -0
- package/src/packlets/decisions/common.ts +37 -0
- package/src/packlets/decisions/concreteDecision.ts +157 -0
- package/src/packlets/decisions/decision.ts +172 -0
- package/src/packlets/decisions/index.ts +28 -0
- package/src/packlets/import/fsItem.ts +212 -0
- package/src/packlets/import/importContext.ts +183 -0
- package/src/packlets/import/importManager.ts +187 -0
- package/src/packlets/import/importable.ts +107 -0
- package/src/packlets/import/importers/collectionImporter.ts +153 -0
- package/src/packlets/import/importers/fsItemImporter.ts +154 -0
- package/src/packlets/import/importers/importer.ts +58 -0
- package/src/packlets/import/importers/index.ts +27 -0
- package/src/packlets/import/importers/jsonImporter.ts +133 -0
- package/src/packlets/import/importers/pathImporter.ts +134 -0
- package/src/packlets/import/index.ts +29 -0
- package/src/packlets/qualifier-types/config/convert.ts +108 -0
- package/src/packlets/qualifier-types/config/index.ts +27 -0
- package/src/packlets/qualifier-types/config/json.ts +126 -0
- package/src/packlets/qualifier-types/convert.ts +77 -0
- package/src/packlets/qualifier-types/helpers.ts +94 -0
- package/src/packlets/qualifier-types/index.ts +34 -0
- package/src/packlets/qualifier-types/languageQualifierType.ts +143 -0
- package/src/packlets/qualifier-types/literalQualifierType.ts +244 -0
- package/src/packlets/qualifier-types/literalValueHierarchy.ts +332 -0
- package/src/packlets/qualifier-types/qualifierType.ts +360 -0
- package/src/packlets/qualifier-types/qualifierTypeCollector.ts +102 -0
- package/src/packlets/qualifier-types/territoryQualifierType.ts +255 -0
- package/src/packlets/qualifiers/convert/decls.ts +90 -0
- package/src/packlets/qualifiers/convert/index.ts +24 -0
- package/src/packlets/qualifiers/convert/qualifier.ts +55 -0
- package/src/packlets/qualifiers/index.ts +31 -0
- package/src/packlets/qualifiers/qualifier.ts +169 -0
- package/src/packlets/qualifiers/qualifierCollector.ts +194 -0
- package/src/packlets/qualifiers/qualifierDecl.ts +80 -0
- package/src/packlets/qualifiers/qualifierDefaultValueDecls.ts +57 -0
- package/src/packlets/qualifiers/qualifierDefaultValueToken.ts +230 -0
- package/src/packlets/resource-json/compiled/common.ts +35 -0
- package/src/packlets/resource-json/compiled/convert.ts +143 -0
- package/src/packlets/resource-json/compiled/index.ts +27 -0
- package/src/packlets/resource-json/compiled/json.ts +239 -0
- package/src/packlets/resource-json/convert.ts +236 -0
- package/src/packlets/resource-json/helpers.ts +284 -0
- package/src/packlets/resource-json/index.ts +33 -0
- package/src/packlets/resource-json/json.ts +295 -0
- package/src/packlets/resource-json/normalized.ts +211 -0
- package/src/packlets/resource-json/resourceDeclCollection.ts +117 -0
- package/src/packlets/resource-json/resourceDeclContainer.ts +48 -0
- package/src/packlets/resource-json/resourceDeclTree.ts +116 -0
- package/src/packlets/resource-types/config/convert.ts +36 -0
- package/src/packlets/resource-types/config/index.ts +27 -0
- package/src/packlets/resource-types/config/json.ts +30 -0
- package/src/packlets/resource-types/helpers.ts +44 -0
- package/src/packlets/resource-types/index.ts +30 -0
- package/src/packlets/resource-types/jsonResourceType.ts +104 -0
- package/src/packlets/resource-types/resourceType.ts +259 -0
- package/src/packlets/resource-types/resourceTypeCollector.ts +79 -0
- package/src/packlets/resources/candidateReducer.ts +331 -0
- package/src/packlets/resources/common.ts +114 -0
- package/src/packlets/resources/index.ts +28 -0
- package/src/packlets/resources/resource.ts +307 -0
- package/src/packlets/resources/resourceBuilder.ts +269 -0
- package/src/packlets/resources/resourceCandidate.ts +333 -0
- package/src/packlets/resources/resourceManagerBuilder.ts +1169 -0
- package/src/packlets/runtime/cacheListener.ts +113 -0
- package/src/packlets/runtime/cacheMetrics.ts +206 -0
- package/src/packlets/runtime/compiledResourceCollection.ts +607 -0
- package/src/packlets/runtime/conditionSetResolutionResult.ts +160 -0
- package/src/packlets/runtime/context/contextQualifierProvider.ts +117 -0
- package/src/packlets/runtime/context/contextQualifierProviderValidator.ts +281 -0
- package/src/packlets/runtime/context/index.ts +26 -0
- package/src/packlets/runtime/context/simpleContextQualifierProvider.ts +225 -0
- package/src/packlets/runtime/context/validatingSimpleContextQualifierProvider.ts +96 -0
- package/src/packlets/runtime/iResourceManager.ts +130 -0
- package/src/packlets/runtime/index.ts +35 -0
- package/src/packlets/runtime/resource-tree/common.ts +126 -0
- package/src/packlets/runtime/resource-tree/index.ts +26 -0
- package/src/packlets/runtime/resource-tree/readOnlyResourceTree.ts +342 -0
- package/src/packlets/runtime/resource-tree/resourceTreeChildren.ts +125 -0
- package/src/packlets/runtime/resource-tree/resourceTreeChildrenValidator.ts +187 -0
- package/src/packlets/runtime/resourceResolver.ts +626 -0
- package/src/packlets/runtime/validate.ts +63 -0
- package/src/packlets/zip-archive/convert.ts +121 -0
- package/src/packlets/zip-archive/index.ts +76 -0
- package/src/packlets/zip-archive/json.ts +91 -0
- package/src/packlets/zip-archive/types.ts +140 -0
- package/src/packlets/zip-archive/zipArchiveCreator.ts +229 -0
- package/src/packlets/zip-archive/zipArchiveFormat.ts +158 -0
- package/src/packlets/zip-archive/zipArchiveLoader.ts +370 -0
- package/CHANGELOG.md +0 -14
- package/CLAUDE.md +0 -186
- package/EXAMPLE_INIT_PARAMS.md +0 -88
- package/PROGRESS_SUMMARY.md +0 -48
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/packlets/common/conditions.d.ts.map +0 -1
- package/lib/packlets/common/conditions.js.map +0 -1
- package/lib/packlets/common/convert.d.ts.map +0 -1
- package/lib/packlets/common/convert.js.map +0 -1
- package/lib/packlets/common/helpers/conditions.d.ts.map +0 -1
- package/lib/packlets/common/helpers/conditions.js.map +0 -1
- package/lib/packlets/common/helpers/context.d.ts.map +0 -1
- package/lib/packlets/common/helpers/context.js.map +0 -1
- package/lib/packlets/common/helpers/index.d.ts.map +0 -1
- package/lib/packlets/common/helpers/index.js.map +0 -1
- package/lib/packlets/common/helpers/qualifierDefaultValues.d.ts.map +0 -1
- package/lib/packlets/common/helpers/qualifierDefaultValues.js.map +0 -1
- package/lib/packlets/common/helpers/resources.d.ts.map +0 -1
- package/lib/packlets/common/helpers/resources.js.map +0 -1
- package/lib/packlets/common/index.d.ts.map +0 -1
- package/lib/packlets/common/index.js.map +0 -1
- package/lib/packlets/common/resources.d.ts.map +0 -1
- package/lib/packlets/common/resources.js.map +0 -1
- package/lib/packlets/common/validate/conditions.d.ts.map +0 -1
- package/lib/packlets/common/validate/conditions.js.map +0 -1
- package/lib/packlets/common/validate/index.d.ts.map +0 -1
- package/lib/packlets/common/validate/index.js.map +0 -1
- package/lib/packlets/common/validate/regularExpressions.d.ts.map +0 -1
- package/lib/packlets/common/validate/regularExpressions.js.map +0 -1
- package/lib/packlets/common/validate/resources.d.ts.map +0 -1
- package/lib/packlets/common/validate/resources.js.map +0 -1
- package/lib/packlets/conditions/condition.d.ts.map +0 -1
- package/lib/packlets/conditions/condition.js.map +0 -1
- package/lib/packlets/conditions/conditionCollector.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionCollector.js.map +0 -1
- package/lib/packlets/conditions/conditionDecls.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionDecls.js.map +0 -1
- package/lib/packlets/conditions/conditionSet.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionSet.js.map +0 -1
- package/lib/packlets/conditions/conditionSetCollector.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionSetCollector.js.map +0 -1
- package/lib/packlets/conditions/conditionSetDecls.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionSetDecls.js.map +0 -1
- package/lib/packlets/conditions/conditionToken.d.ts.map +0 -1
- package/lib/packlets/conditions/conditionToken.js.map +0 -1
- package/lib/packlets/conditions/convert/conditionSetDecls.d.ts.map +0 -1
- package/lib/packlets/conditions/convert/conditionSetDecls.js.map +0 -1
- package/lib/packlets/conditions/convert/decls.d.ts.map +0 -1
- package/lib/packlets/conditions/convert/decls.js.map +0 -1
- package/lib/packlets/conditions/convert/index.d.ts.map +0 -1
- package/lib/packlets/conditions/convert/index.js.map +0 -1
- package/lib/packlets/conditions/index.d.ts.map +0 -1
- package/lib/packlets/conditions/index.js.map +0 -1
- package/lib/packlets/config/common.d.ts.map +0 -1
- package/lib/packlets/config/common.js.map +0 -1
- package/lib/packlets/config/convert.d.ts.map +0 -1
- package/lib/packlets/config/convert.js.map +0 -1
- package/lib/packlets/config/index.d.ts.map +0 -1
- package/lib/packlets/config/index.js.map +0 -1
- package/lib/packlets/config/json.d.ts.map +0 -1
- package/lib/packlets/config/json.js.map +0 -1
- package/lib/packlets/config/predefined/default.d.ts.map +0 -1
- package/lib/packlets/config/predefined/default.js.map +0 -1
- package/lib/packlets/config/predefined/extended.d.ts.map +0 -1
- package/lib/packlets/config/predefined/extended.js.map +0 -1
- package/lib/packlets/config/predefined/index.d.ts.map +0 -1
- package/lib/packlets/config/predefined/index.js.map +0 -1
- package/lib/packlets/config/systemConfiguration.d.ts.map +0 -1
- package/lib/packlets/config/systemConfiguration.js.map +0 -1
- package/lib/packlets/context/contextDecls.d.ts.map +0 -1
- package/lib/packlets/context/contextDecls.js.map +0 -1
- package/lib/packlets/context/contextToken.d.ts.map +0 -1
- package/lib/packlets/context/contextToken.js.map +0 -1
- package/lib/packlets/context/convert/decls.d.ts.map +0 -1
- package/lib/packlets/context/convert/decls.js.map +0 -1
- package/lib/packlets/context/convert/index.d.ts.map +0 -1
- package/lib/packlets/context/convert/index.js.map +0 -1
- package/lib/packlets/context/index.d.ts.map +0 -1
- package/lib/packlets/context/index.js.map +0 -1
- package/lib/packlets/decisions/abstractDecision.d.ts.map +0 -1
- package/lib/packlets/decisions/abstractDecision.js.map +0 -1
- package/lib/packlets/decisions/abstractDecisionCollector.d.ts.map +0 -1
- package/lib/packlets/decisions/abstractDecisionCollector.js.map +0 -1
- package/lib/packlets/decisions/candidate.d.ts.map +0 -1
- package/lib/packlets/decisions/candidate.js.map +0 -1
- package/lib/packlets/decisions/common.d.ts.map +0 -1
- package/lib/packlets/decisions/common.js.map +0 -1
- package/lib/packlets/decisions/concreteDecision.d.ts.map +0 -1
- package/lib/packlets/decisions/concreteDecision.js.map +0 -1
- package/lib/packlets/decisions/decision.d.ts.map +0 -1
- package/lib/packlets/decisions/decision.js.map +0 -1
- package/lib/packlets/decisions/index.d.ts.map +0 -1
- package/lib/packlets/decisions/index.js.map +0 -1
- package/lib/packlets/import/fsItem.d.ts.map +0 -1
- package/lib/packlets/import/fsItem.js.map +0 -1
- package/lib/packlets/import/importContext.d.ts.map +0 -1
- package/lib/packlets/import/importContext.js.map +0 -1
- package/lib/packlets/import/importManager.d.ts.map +0 -1
- package/lib/packlets/import/importManager.js.map +0 -1
- package/lib/packlets/import/importable.d.ts.map +0 -1
- package/lib/packlets/import/importable.js.map +0 -1
- package/lib/packlets/import/importers/collectionImporter.d.ts.map +0 -1
- package/lib/packlets/import/importers/collectionImporter.js.map +0 -1
- package/lib/packlets/import/importers/fsItemImporter.d.ts.map +0 -1
- package/lib/packlets/import/importers/fsItemImporter.js.map +0 -1
- package/lib/packlets/import/importers/importer.d.ts.map +0 -1
- package/lib/packlets/import/importers/importer.js.map +0 -1
- package/lib/packlets/import/importers/index.d.ts.map +0 -1
- package/lib/packlets/import/importers/index.js.map +0 -1
- package/lib/packlets/import/importers/jsonImporter.d.ts.map +0 -1
- package/lib/packlets/import/importers/jsonImporter.js.map +0 -1
- package/lib/packlets/import/importers/pathImporter.d.ts.map +0 -1
- package/lib/packlets/import/importers/pathImporter.js.map +0 -1
- package/lib/packlets/import/index.d.ts.map +0 -1
- package/lib/packlets/import/index.js.map +0 -1
- package/lib/packlets/qualifier-types/config/convert.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/config/convert.js.map +0 -1
- package/lib/packlets/qualifier-types/config/index.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/config/index.js.map +0 -1
- package/lib/packlets/qualifier-types/config/json.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/config/json.js.map +0 -1
- package/lib/packlets/qualifier-types/convert.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/convert.js.map +0 -1
- package/lib/packlets/qualifier-types/helpers.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/helpers.js.map +0 -1
- package/lib/packlets/qualifier-types/index.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/index.js.map +0 -1
- package/lib/packlets/qualifier-types/languageQualifierType.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/languageQualifierType.js.map +0 -1
- package/lib/packlets/qualifier-types/literalQualifierType.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/literalQualifierType.js.map +0 -1
- package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/literalValueHierarchy.js.map +0 -1
- package/lib/packlets/qualifier-types/qualifierType.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/qualifierType.js.map +0 -1
- package/lib/packlets/qualifier-types/qualifierTypeCollector.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/qualifierTypeCollector.js.map +0 -1
- package/lib/packlets/qualifier-types/territoryQualifierType.d.ts.map +0 -1
- package/lib/packlets/qualifier-types/territoryQualifierType.js.map +0 -1
- package/lib/packlets/qualifiers/convert/decls.d.ts.map +0 -1
- package/lib/packlets/qualifiers/convert/decls.js.map +0 -1
- package/lib/packlets/qualifiers/convert/index.d.ts.map +0 -1
- package/lib/packlets/qualifiers/convert/index.js.map +0 -1
- package/lib/packlets/qualifiers/convert/qualifier.d.ts.map +0 -1
- package/lib/packlets/qualifiers/convert/qualifier.js.map +0 -1
- package/lib/packlets/qualifiers/index.d.ts.map +0 -1
- package/lib/packlets/qualifiers/index.js.map +0 -1
- package/lib/packlets/qualifiers/qualifier.d.ts.map +0 -1
- package/lib/packlets/qualifiers/qualifier.js.map +0 -1
- package/lib/packlets/qualifiers/qualifierCollector.d.ts.map +0 -1
- package/lib/packlets/qualifiers/qualifierCollector.js.map +0 -1
- package/lib/packlets/qualifiers/qualifierDecl.d.ts.map +0 -1
- package/lib/packlets/qualifiers/qualifierDecl.js.map +0 -1
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.d.ts.map +0 -1
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.js.map +0 -1
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.d.ts.map +0 -1
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.js.map +0 -1
- package/lib/packlets/resource-json/compiled/common.d.ts.map +0 -1
- package/lib/packlets/resource-json/compiled/common.js.map +0 -1
- package/lib/packlets/resource-json/compiled/convert.d.ts.map +0 -1
- package/lib/packlets/resource-json/compiled/convert.js.map +0 -1
- package/lib/packlets/resource-json/compiled/index.d.ts.map +0 -1
- package/lib/packlets/resource-json/compiled/index.js.map +0 -1
- package/lib/packlets/resource-json/compiled/json.d.ts.map +0 -1
- package/lib/packlets/resource-json/compiled/json.js.map +0 -1
- package/lib/packlets/resource-json/convert.d.ts.map +0 -1
- package/lib/packlets/resource-json/convert.js.map +0 -1
- package/lib/packlets/resource-json/helpers.d.ts.map +0 -1
- package/lib/packlets/resource-json/helpers.js.map +0 -1
- package/lib/packlets/resource-json/index.d.ts.map +0 -1
- package/lib/packlets/resource-json/index.js.map +0 -1
- package/lib/packlets/resource-json/json.d.ts.map +0 -1
- package/lib/packlets/resource-json/json.js.map +0 -1
- package/lib/packlets/resource-json/normalized.d.ts.map +0 -1
- package/lib/packlets/resource-json/normalized.js.map +0 -1
- package/lib/packlets/resource-json/resourceDeclCollection.d.ts.map +0 -1
- package/lib/packlets/resource-json/resourceDeclCollection.js.map +0 -1
- package/lib/packlets/resource-json/resourceDeclContainer.d.ts.map +0 -1
- package/lib/packlets/resource-json/resourceDeclContainer.js.map +0 -1
- package/lib/packlets/resource-json/resourceDeclTree.d.ts.map +0 -1
- package/lib/packlets/resource-json/resourceDeclTree.js.map +0 -1
- package/lib/packlets/resource-types/config/convert.d.ts.map +0 -1
- package/lib/packlets/resource-types/config/convert.js.map +0 -1
- package/lib/packlets/resource-types/config/index.d.ts.map +0 -1
- package/lib/packlets/resource-types/config/index.js.map +0 -1
- package/lib/packlets/resource-types/config/json.d.ts.map +0 -1
- package/lib/packlets/resource-types/config/json.js.map +0 -1
- package/lib/packlets/resource-types/helpers.d.ts.map +0 -1
- package/lib/packlets/resource-types/helpers.js.map +0 -1
- package/lib/packlets/resource-types/index.d.ts.map +0 -1
- package/lib/packlets/resource-types/index.js.map +0 -1
- package/lib/packlets/resource-types/jsonResourceType.d.ts.map +0 -1
- package/lib/packlets/resource-types/jsonResourceType.js.map +0 -1
- package/lib/packlets/resource-types/resourceType.d.ts.map +0 -1
- package/lib/packlets/resource-types/resourceType.js.map +0 -1
- package/lib/packlets/resource-types/resourceTypeCollector.d.ts.map +0 -1
- package/lib/packlets/resource-types/resourceTypeCollector.js.map +0 -1
- package/lib/packlets/resources/candidateReducer.d.ts.map +0 -1
- package/lib/packlets/resources/candidateReducer.js.map +0 -1
- package/lib/packlets/resources/common.d.ts.map +0 -1
- package/lib/packlets/resources/common.js.map +0 -1
- package/lib/packlets/resources/index.d.ts.map +0 -1
- package/lib/packlets/resources/index.js.map +0 -1
- package/lib/packlets/resources/resource.d.ts.map +0 -1
- package/lib/packlets/resources/resource.js.map +0 -1
- package/lib/packlets/resources/resourceBuilder.d.ts.map +0 -1
- package/lib/packlets/resources/resourceBuilder.js.map +0 -1
- package/lib/packlets/resources/resourceCandidate.d.ts.map +0 -1
- package/lib/packlets/resources/resourceCandidate.js.map +0 -1
- package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +0 -1
- package/lib/packlets/resources/resourceManagerBuilder.js.map +0 -1
- package/lib/packlets/runtime/cacheListener.d.ts.map +0 -1
- package/lib/packlets/runtime/cacheListener.js.map +0 -1
- package/lib/packlets/runtime/cacheMetrics.d.ts.map +0 -1
- package/lib/packlets/runtime/cacheMetrics.js.map +0 -1
- package/lib/packlets/runtime/compiledResourceCollection.d.ts.map +0 -1
- package/lib/packlets/runtime/compiledResourceCollection.js.map +0 -1
- package/lib/packlets/runtime/conditionSetResolutionResult.d.ts.map +0 -1
- package/lib/packlets/runtime/conditionSetResolutionResult.js.map +0 -1
- package/lib/packlets/runtime/context/contextQualifierProvider.d.ts.map +0 -1
- package/lib/packlets/runtime/context/contextQualifierProvider.js.map +0 -1
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.d.ts.map +0 -1
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.js.map +0 -1
- package/lib/packlets/runtime/context/index.d.ts.map +0 -1
- package/lib/packlets/runtime/context/index.js.map +0 -1
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts.map +0 -1
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.js.map +0 -1
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts.map +0 -1
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +0 -1
- package/lib/packlets/runtime/iResourceManager.d.ts.map +0 -1
- package/lib/packlets/runtime/iResourceManager.js.map +0 -1
- package/lib/packlets/runtime/index.d.ts.map +0 -1
- package/lib/packlets/runtime/index.js.map +0 -1
- package/lib/packlets/runtime/resource-tree/common.d.ts.map +0 -1
- package/lib/packlets/runtime/resource-tree/common.js.map +0 -1
- package/lib/packlets/runtime/resource-tree/index.d.ts.map +0 -1
- package/lib/packlets/runtime/resource-tree/index.js.map +0 -1
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.d.ts.map +0 -1
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.js.map +0 -1
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.d.ts.map +0 -1
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js.map +0 -1
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts.map +0 -1
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js.map +0 -1
- package/lib/packlets/runtime/resourceResolver.d.ts.map +0 -1
- package/lib/packlets/runtime/resourceResolver.js.map +0 -1
- package/lib/packlets/runtime/validate.d.ts.map +0 -1
- package/lib/packlets/runtime/validate.js.map +0 -1
|
@@ -0,0 +1,332 @@
|
|
|
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 { captureResult, MessageAggregator, Result, succeed, fail } from '@fgv/ts-utils';
|
|
24
|
+
import {
|
|
25
|
+
ConditionOperator,
|
|
26
|
+
NoMatch,
|
|
27
|
+
PerfectMatch,
|
|
28
|
+
QualifierConditionValue,
|
|
29
|
+
QualifierContextValue,
|
|
30
|
+
QualifierMatchScore,
|
|
31
|
+
Convert as CommonConverters
|
|
32
|
+
} from '../common';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Declares a hierarchy of literal values. The keys are the names of the values, and the
|
|
36
|
+
* values are the names of their parents.
|
|
37
|
+
* @remarks
|
|
38
|
+
* The hierarchy is defined as a tree, where each value can have multiple children but
|
|
39
|
+
* only one parent. The root of the tree has no parent. The hierarchy is used to
|
|
40
|
+
* determine the relationship between values when matching conditions and contexts.
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export type LiteralValueHierarchyDecl<T extends string> = Partial<Record<T, T>>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Describes a single valid literal value including optional parent and child values.
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export interface ILiteralValue<T extends string> {
|
|
50
|
+
readonly name: T;
|
|
51
|
+
readonly parent?: ILiteralValue<T>;
|
|
52
|
+
readonly children?: ReadonlyArray<T>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Describes the parameters used to create a new
|
|
57
|
+
* {@link QualifierTypes.LiteralValueHierarchy | LiteralValueHierarchy}.
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export interface ILiteralValueHierarchyCreateParams<T extends string = string> {
|
|
61
|
+
values: ReadonlyArray<T>;
|
|
62
|
+
hierarchy?: LiteralValueHierarchyDecl<T>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Internal interface used during hierarchy construction to build
|
|
67
|
+
* {@link QualifierTypes.ILiteralValue | ILiteralValue} objects.
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
interface ILiteralValueBuilder<T extends string> {
|
|
71
|
+
readonly name: T;
|
|
72
|
+
parent?: ILiteralValue<T>;
|
|
73
|
+
children?: T[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A class that implements a hierarchy of literal values. The hierarchy is defined as a
|
|
78
|
+
* tree, where each value can have multiple children but only one parent. The root of the
|
|
79
|
+
* tree has no parent. The hierarchy is used to determine the relationship between values
|
|
80
|
+
* when matching conditions and contexts.
|
|
81
|
+
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* The hierarchy can be created in two modes:
|
|
84
|
+
* - **Constrained mode**: When enumerated values are provided, only those values are allowed
|
|
85
|
+
* in the hierarchy and matching operations.
|
|
86
|
+
* - **Open values mode**: When no enumerated values are provided, all values referenced in
|
|
87
|
+
* the hierarchy are automatically collected and used. This allows for flexible hierarchies
|
|
88
|
+
* where any value can be used in matching operations.
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
export class LiteralValueHierarchy<T extends string = string> {
|
|
92
|
+
/**
|
|
93
|
+
* A map of all allowed literal values to the corresponding
|
|
94
|
+
* {@link QualifierTypes.ILiteralValue | ILiteralValue} validated definition.
|
|
95
|
+
*/
|
|
96
|
+
public readonly values: ReadonlyMap<T, ILiteralValue<T>>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Indicates whether this hierarchy was created with open values (no enumerated values
|
|
100
|
+
* provided), allowing any value to be used in matching operations.
|
|
101
|
+
*/
|
|
102
|
+
public readonly isOpenValues: boolean;
|
|
103
|
+
|
|
104
|
+
protected constructor(params: ILiteralValueHierarchyCreateParams<T>) {
|
|
105
|
+
const result = LiteralValueHierarchy._buildValuesFromHierarchy(params);
|
|
106
|
+
this.values = result.orThrow();
|
|
107
|
+
this.isOpenValues = !params.values || params.values.length === 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Creates a new {@link QualifierTypes.LiteralValueHierarchy | LiteralValueHierarchy} instance.
|
|
112
|
+
* @param params - The {@link QualifierTypes.ILiteralValueHierarchyCreateParams | parameters}
|
|
113
|
+
* used to create the hierarchy.
|
|
114
|
+
* @returns `Success` with the new hierarchy or `Failure` with an error message.
|
|
115
|
+
*/
|
|
116
|
+
public static create<T extends string>(
|
|
117
|
+
params: ILiteralValueHierarchyCreateParams<T>
|
|
118
|
+
): Result<LiteralValueHierarchy<T>> {
|
|
119
|
+
return captureResult(() => new LiteralValueHierarchy(params));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Checks if a value exists in the hierarchy.
|
|
124
|
+
* @param value - The value to check.
|
|
125
|
+
* @returns `true` if the value exists in the hierarchy, `false` otherwise.
|
|
126
|
+
*/
|
|
127
|
+
public hasValue(value: T): boolean {
|
|
128
|
+
return this.values.has(value);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Gets all root values (values with no parent) in the hierarchy.
|
|
133
|
+
* @returns `Success` with an array of root values.
|
|
134
|
+
*/
|
|
135
|
+
public getRoots(): Result<T[]> {
|
|
136
|
+
return succeed(
|
|
137
|
+
Array.from(this.values.values())
|
|
138
|
+
.filter((v) => !v.parent)
|
|
139
|
+
.map((v) => v.name)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Gets all ancestors of a value in the hierarchy.
|
|
145
|
+
* @param value - The value to get ancestors for.
|
|
146
|
+
* @returns `Success` with an array of ancestor values, ordered from immediate parent
|
|
147
|
+
* to root, or `Failure` if the value is not in the hierarchy.
|
|
148
|
+
*/
|
|
149
|
+
public getAncestors(value: T): Result<T[]> {
|
|
150
|
+
const current = this.values.get(value);
|
|
151
|
+
/* c8 ignore next 3 - functional error case tested but coverage intermittently missed */
|
|
152
|
+
if (!current) {
|
|
153
|
+
return fail(`${value}: not found in hierarchy`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const ancestors: T[] = [];
|
|
157
|
+
let ancestor = current.parent;
|
|
158
|
+
|
|
159
|
+
while (ancestor) {
|
|
160
|
+
ancestors.push(ancestor.name);
|
|
161
|
+
ancestor = ancestor.parent;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return succeed(ancestors);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Determines if a value is an ancestor of a possible ancestor value.
|
|
169
|
+
* @param value - The value to check.
|
|
170
|
+
* @param possibleAncestor - The possible ancestor value.
|
|
171
|
+
* @returns `true` if the value is an ancestor of the possible ancestor, `false` otherwise.
|
|
172
|
+
*/
|
|
173
|
+
public isAncestor(value: T, possibleAncestor: T): boolean {
|
|
174
|
+
const ancestors = this.getAncestors(value);
|
|
175
|
+
if (ancestors.isSuccess()) {
|
|
176
|
+
return ancestors.value.includes(possibleAncestor);
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Gets all descendants of a value in the hierarchy.
|
|
183
|
+
* @param value - The value to get descendants for.
|
|
184
|
+
* @returns `Success` with an array of descendant values, or `Failure` if the value
|
|
185
|
+
* is not in the hierarchy.
|
|
186
|
+
*/
|
|
187
|
+
public getDescendants(value: T): Result<T[]> {
|
|
188
|
+
const current = this.values.get(value);
|
|
189
|
+
if (!current) {
|
|
190
|
+
return fail(`${value}: not found in hierarchy`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const descendants: T[] = [];
|
|
194
|
+
if (current.children) {
|
|
195
|
+
for (const childName of current.children) {
|
|
196
|
+
descendants.push(childName);
|
|
197
|
+
const childDescendants = this.getDescendants(childName);
|
|
198
|
+
if (childDescendants.isSuccess()) {
|
|
199
|
+
descendants.push(...childDescendants.value);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return succeed(descendants);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public match(condition: T, context: T): QualifierMatchScore;
|
|
208
|
+
/**
|
|
209
|
+
* Matches a condition value against a context value, where an exact match of the
|
|
210
|
+
* condition and context returns {@link PerfectMatch | PerfectMatch}, a condition
|
|
211
|
+
* value that does not match the context value or any of its ancestors returns
|
|
212
|
+
* {@link NoMatch | NoMatch}, and a condition value that matches the context value
|
|
213
|
+
* or any of its ancestors returns a positive score that is less than
|
|
214
|
+
* {@link PerfectMatch | PerfectMatch}, with the score decreasing with each ancestor
|
|
215
|
+
* in the hierarchy.
|
|
216
|
+
* @param condition - The condition value to match.
|
|
217
|
+
* @param context - The context value to match against.
|
|
218
|
+
* @param __operator - The operator used for matching (not used in this implementation).
|
|
219
|
+
* @returns A {@link QualifierMatchScore | QualifierMatchScore} indicating the match score.
|
|
220
|
+
*/
|
|
221
|
+
public match(
|
|
222
|
+
condition: QualifierConditionValue,
|
|
223
|
+
context: QualifierContextValue,
|
|
224
|
+
__operator?: ConditionOperator
|
|
225
|
+
): QualifierMatchScore;
|
|
226
|
+
public match(condition: string, context: string, __operator?: ConditionOperator): QualifierMatchScore {
|
|
227
|
+
// For open hierarchies, skip validation and allow any values
|
|
228
|
+
if (!this.isOpenValues) {
|
|
229
|
+
// Validate that both condition and context exist in the hierarchy
|
|
230
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
231
|
+
if (!this.values.has(condition as T)) {
|
|
232
|
+
return NoMatch;
|
|
233
|
+
}
|
|
234
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
235
|
+
if (!this.values.has(context as T)) {
|
|
236
|
+
return NoMatch;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if ((condition as string) === (context as string)) {
|
|
241
|
+
return PerfectMatch;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// For open hierarchies, if values aren't in the hierarchy, treat as no match
|
|
245
|
+
// but don't fail validation
|
|
246
|
+
const values: ReadonlyMap<string, ILiteralValue<string>> = this.values;
|
|
247
|
+
/* c8 ignore next 1 - ? is defense in depth */
|
|
248
|
+
let value = values.get(context)?.parent;
|
|
249
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
250
|
+
if (!value) {
|
|
251
|
+
return NoMatch;
|
|
252
|
+
}
|
|
253
|
+
let score = PerfectMatch as number;
|
|
254
|
+
while (value) {
|
|
255
|
+
score *= 0.9;
|
|
256
|
+
if (value.name === condition) {
|
|
257
|
+
return CommonConverters.qualifierMatchScore.convert(score).orDefault(NoMatch);
|
|
258
|
+
}
|
|
259
|
+
value = value.parent;
|
|
260
|
+
}
|
|
261
|
+
return NoMatch;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
protected static _buildValuesFromHierarchy<T extends string>(
|
|
265
|
+
params: ILiteralValueHierarchyCreateParams<T>
|
|
266
|
+
): Result<ReadonlyMap<T, ILiteralValue<T>>> {
|
|
267
|
+
const errors = new MessageAggregator();
|
|
268
|
+
const values = params.values;
|
|
269
|
+
const hierarchy = params.hierarchy ?? {};
|
|
270
|
+
|
|
271
|
+
// If no values are provided, collect all values from the hierarchy
|
|
272
|
+
let allValues: T[];
|
|
273
|
+
if (!values || values.length === 0) {
|
|
274
|
+
const hierarchyValues = new Set<T>();
|
|
275
|
+
// Add all keys and values from the hierarchy
|
|
276
|
+
Object.keys(hierarchy).forEach((key) => hierarchyValues.add(key as T));
|
|
277
|
+
Object.values(hierarchy).forEach((value) => hierarchyValues.add(value as T));
|
|
278
|
+
allValues = Array.from(hierarchyValues);
|
|
279
|
+
} else {
|
|
280
|
+
allValues = [...values];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const valueMap = new Map<T, ILiteralValueBuilder<T>>(allValues.map((name) => [name, { name }]));
|
|
284
|
+
|
|
285
|
+
if (hierarchy) {
|
|
286
|
+
for (const [valueName, parentName] of Object.entries(hierarchy)) {
|
|
287
|
+
const value = valueMap.get(valueName as T);
|
|
288
|
+
if (!value) {
|
|
289
|
+
errors.addMessage(`${valueName}: invalid literal value.`);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const parent = valueMap.get(parentName as T);
|
|
294
|
+
if (!parent) {
|
|
295
|
+
errors.addMessage(`${valueName}: parent ${parentName} is not a valid literal value.`);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let ancestor = parent.parent;
|
|
300
|
+
let circular = false;
|
|
301
|
+
const ancestors: T[] = [];
|
|
302
|
+
|
|
303
|
+
while (ancestor) {
|
|
304
|
+
/* c8 ignore next 1 - defensive coding: complex circular reference detection intermittently missed */
|
|
305
|
+
ancestors.push(ancestor.name);
|
|
306
|
+
/* c8 ignore next 1 - defensive coding: ancestor.parent === value is very difficult to reach */
|
|
307
|
+
if (ancestor.parent === parent || ancestor.parent === value) {
|
|
308
|
+
/* c8 ignore next 3 - defensive coding: circular reference error reporting intermittently missed */
|
|
309
|
+
errors.addMessage(`${valueName}: Circular reference detected: ${ancestors.join('->')}`);
|
|
310
|
+
circular = true;
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
ancestor = ancestor.parent;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* c8 ignore next 2 - defensive coding: circular reference handling intermittently missed */
|
|
317
|
+
if (circular) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
value.parent = parent;
|
|
322
|
+
if (parent.children) {
|
|
323
|
+
parent.children.push(value.name);
|
|
324
|
+
} else {
|
|
325
|
+
parent.children = [value.name];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return errors.returnOrReport(succeed(valueMap));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,360 @@
|
|
|
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 { Collections, ICollectible, Result, fail, succeed } from '@fgv/ts-utils';
|
|
24
|
+
import {
|
|
25
|
+
ConditionOperator,
|
|
26
|
+
Convert,
|
|
27
|
+
NoMatch,
|
|
28
|
+
PerfectMatch,
|
|
29
|
+
QualifierConditionValue,
|
|
30
|
+
QualifierContextValue,
|
|
31
|
+
QualifierMatchScore,
|
|
32
|
+
QualifierTypeIndex,
|
|
33
|
+
QualifierTypeName,
|
|
34
|
+
Validate
|
|
35
|
+
} from '../common';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Interface for a qualifier type. A qualifier type implements the build and
|
|
39
|
+
* runtime semantics for some class of related qualifiers (e.g. language,
|
|
40
|
+
* territories, etc).
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export interface IQualifierType extends ICollectible<QualifierTypeName, QualifierTypeIndex> {
|
|
44
|
+
/**
|
|
45
|
+
* The name of the qualifier type.
|
|
46
|
+
*/
|
|
47
|
+
readonly name: QualifierTypeName;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Unique key for this qualifier.
|
|
51
|
+
*/
|
|
52
|
+
readonly key: QualifierTypeName;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Global index for this qualifier type. Immutable once set, either at
|
|
56
|
+
* construction or using {@link QualifierTypes.IQualifierType.setIndex | setIndex}.
|
|
57
|
+
*/
|
|
58
|
+
readonly index: QualifierTypeIndex | undefined;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Validates a condition value for this qualifier type.
|
|
62
|
+
* @param value - The string value to validate.
|
|
63
|
+
* @returns `Success` with the {@link QualifierConditionValue | validated value}
|
|
64
|
+
* if the value is valid for use in a condition, `Failure` with error details
|
|
65
|
+
* otherwise.
|
|
66
|
+
*/
|
|
67
|
+
isValidConditionValue(value: string): value is QualifierConditionValue;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Validates a context value for this qualifier type.
|
|
71
|
+
* @param value - The string value to validate.
|
|
72
|
+
* @returns `Success` with the {@link QualifierContextValue | validated value}
|
|
73
|
+
* if the value is valid for use in a runtime context, `Failure` with error
|
|
74
|
+
* details otherwise.
|
|
75
|
+
*/
|
|
76
|
+
isValidContextValue(value: string): value is QualifierContextValue;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Determines if a supplied condition value is a potential match for a possible context value.
|
|
80
|
+
* @param conditionValue - The condition value.
|
|
81
|
+
* @param contextValue - The context value.
|
|
82
|
+
* @returns `true` if the condition value is a potential match for the context value, `false` otherwise.
|
|
83
|
+
*/
|
|
84
|
+
isPotentialMatch(conditionValue: string, contextValue: string): boolean;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validates that a value and optional operator are valid for use in a condition
|
|
88
|
+
* for qualifiers of this type.
|
|
89
|
+
* @param value - The string value to validate.
|
|
90
|
+
* @param operator - An optional operator to validate. Defaults to 'matches'.
|
|
91
|
+
*/
|
|
92
|
+
validateCondition(value: string, operator?: ConditionOperator): Result<QualifierConditionValue>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Validates that a value is valid for use in a runtime context for qualifiers
|
|
96
|
+
* of this type.
|
|
97
|
+
* @param value - The string value to validate.
|
|
98
|
+
* @returns `Success` with the {@link QualifierContextValue | validated value}
|
|
99
|
+
* if the value is valid for use in a runtime context, `Failure` with error
|
|
100
|
+
* details otherwise.
|
|
101
|
+
*/
|
|
102
|
+
validateContextValue(value: string): Result<QualifierContextValue>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Determines the extent to which a condition matches a context value for this
|
|
106
|
+
* qualifier type.
|
|
107
|
+
* @param condition - The condition value to evaluate.
|
|
108
|
+
* @param context - The context value to evaluate.
|
|
109
|
+
* @param operator - The operator to use in evaluating the match.
|
|
110
|
+
* @returns a {@link QualifierMatchScore | score} indicating the extent to which
|
|
111
|
+
* the condition matches the context value.
|
|
112
|
+
*/
|
|
113
|
+
matches(
|
|
114
|
+
condition: QualifierConditionValue,
|
|
115
|
+
context: QualifierContextValue,
|
|
116
|
+
operator: ConditionOperator
|
|
117
|
+
): QualifierMatchScore;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Sets the index for this qualifier type. Once set, index is immutable.
|
|
121
|
+
*/
|
|
122
|
+
setIndex(index: number): Result<QualifierTypeIndex>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Parameters used to create a base {@link QualifierTypes.QualifierType | qualifier type}.
|
|
127
|
+
* @public
|
|
128
|
+
*/
|
|
129
|
+
export interface IQualifierTypeCreateParams {
|
|
130
|
+
/**
|
|
131
|
+
* The name of the qualifier type. No default value.
|
|
132
|
+
*/
|
|
133
|
+
name: string;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Global index for this qualifier type.
|
|
137
|
+
*/
|
|
138
|
+
index?: number;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Flag indicating whether this qualifier type allows a list of values in a context.
|
|
142
|
+
* Defaults to `false`.
|
|
143
|
+
*/
|
|
144
|
+
allowContextList?: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Abstract base class for qualifier types. Provides default implementations for
|
|
149
|
+
* the {@link QualifierTypes.IQualifierType | IQualifierType} interface.
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
export abstract class QualifierType implements IQualifierType {
|
|
153
|
+
/**
|
|
154
|
+
* {@inheritdoc QualifierTypes.IQualifierType.name}
|
|
155
|
+
*/
|
|
156
|
+
public readonly name: QualifierTypeName;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* {@inheritdoc QualifierTypes.IQualifierType.key}
|
|
160
|
+
*/
|
|
161
|
+
public get key(): QualifierTypeName {
|
|
162
|
+
return this._collectible.key;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* {@inheritdoc QualifierTypes.IQualifierType.index}
|
|
167
|
+
*/
|
|
168
|
+
public get index(): QualifierTypeIndex | undefined {
|
|
169
|
+
return this._collectible.index;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
protected readonly _collectible: Collections.Collectible<QualifierTypeName, QualifierTypeIndex>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Flag indicating whether this qualifier type allows a list of values in a context.
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
public readonly allowContextList: boolean;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Constructor for use by derived classes.
|
|
182
|
+
* @param name - The name of the qualifier type.
|
|
183
|
+
* @param allowContextList - Flag indicating whether this qualifier type allows a
|
|
184
|
+
* comma-separated list of runtime values in the context. Defaults to `false`.
|
|
185
|
+
*/
|
|
186
|
+
protected constructor({ name, index, allowContextList }: IQualifierTypeCreateParams) {
|
|
187
|
+
this.name = Convert.qualifierTypeName.convert(name).orThrow();
|
|
188
|
+
this.allowContextList = allowContextList === true;
|
|
189
|
+
this._collectible = new Collections.Collectible<QualifierTypeName, QualifierTypeIndex>({
|
|
190
|
+
key: this.name,
|
|
191
|
+
index: index,
|
|
192
|
+
indexConverter: Convert.qualifierTypeIndex
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* {@inheritdoc QualifierTypes.IQualifierType.isValidConditionValue}
|
|
198
|
+
*/
|
|
199
|
+
public abstract isValidConditionValue(value: string): value is QualifierConditionValue;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* {@inheritdoc QualifierTypes.IQualifierType.isValidContextValue}
|
|
203
|
+
*/
|
|
204
|
+
public isValidContextValue(value: string): value is QualifierContextValue {
|
|
205
|
+
if (this.isValidConditionValue(value)) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (this.allowContextList) {
|
|
209
|
+
/* c8 ignore next 1 - functional code tested but coverage intermittently missed */
|
|
210
|
+
return value.split(',').every((v) => this.isValidConditionValue(v.trim()));
|
|
211
|
+
}
|
|
212
|
+
/* c8 ignore next 1 - functional code tested but coverage intermittently missed */
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* {@inheritdoc QualifierTypes.IQualifierType.isPotentialMatch}
|
|
218
|
+
*/
|
|
219
|
+
public isPotentialMatch(conditionValue: string, contextValue: string): boolean {
|
|
220
|
+
if (this.isValidConditionValue(conditionValue) && this.isValidContextValue(contextValue)) {
|
|
221
|
+
return this._matchOne(conditionValue, contextValue, 'matches') !== NoMatch;
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* {@inheritdoc QualifierTypes.IQualifierType.validateCondition}
|
|
228
|
+
*/
|
|
229
|
+
public validateCondition(value: string, operator?: ConditionOperator): Result<QualifierConditionValue> {
|
|
230
|
+
operator = operator ?? 'matches';
|
|
231
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
232
|
+
if (operator !== 'matches') {
|
|
233
|
+
return fail(`${operator}: invalid condition operator`);
|
|
234
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
235
|
+
} else if (!this.isValidConditionValue(value)) {
|
|
236
|
+
return fail(`${value}: invalid condition value for qualifierType ${this.name}`);
|
|
237
|
+
}
|
|
238
|
+
return succeed(value);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* {@inheritdoc QualifierTypes.IQualifierType.validateContextValue}
|
|
243
|
+
*/
|
|
244
|
+
public validateContextValue(value: string): Result<QualifierContextValue> {
|
|
245
|
+
/* c8 ignore next 2 - functional error case tested but coverage intermittently missed */
|
|
246
|
+
if (!this.isValidContextValue(value)) {
|
|
247
|
+
return fail(`${value}: invalid context value for qualifierType ${this.name}`);
|
|
248
|
+
}
|
|
249
|
+
return succeed(value);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* {@inheritdoc QualifierTypes.IQualifierType.matches}
|
|
254
|
+
*/
|
|
255
|
+
public matches(
|
|
256
|
+
condition: QualifierConditionValue,
|
|
257
|
+
context: QualifierContextValue,
|
|
258
|
+
operator: ConditionOperator
|
|
259
|
+
): QualifierMatchScore {
|
|
260
|
+
if (this.allowContextList) {
|
|
261
|
+
return this._matchList(condition, QualifierType._splitContext(context), operator);
|
|
262
|
+
}
|
|
263
|
+
return this._matchOne(condition, context, operator);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* {@inheritdoc QualifierTypes.IQualifierType.setIndex}
|
|
268
|
+
*/
|
|
269
|
+
public setIndex(index: number): Result<QualifierTypeIndex> {
|
|
270
|
+
return this._collectible.setIndex(index);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* {@inheritdoc Validate.isValidQualifierTypeName}
|
|
275
|
+
*/
|
|
276
|
+
public static isValidName(name: string): name is QualifierTypeName {
|
|
277
|
+
return Validate.isValidQualifierTypeName(name);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* {@inheritdoc Validate.isValidQualifierTypeIndex}
|
|
282
|
+
*/
|
|
283
|
+
public static isValidIndex(index: number): index is QualifierTypeIndex {
|
|
284
|
+
return Validate.isValidQualifierTypeIndex(index);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Compares two qualifier types by index.
|
|
289
|
+
* @param t1 - The first qualifier type to compare.
|
|
290
|
+
* @param t2 - The second qualifier type to compare.
|
|
291
|
+
* @returns a number indicating the relative order of the two qualifier types.
|
|
292
|
+
*/
|
|
293
|
+
public static compare(t1: QualifierType, t2: QualifierType): number {
|
|
294
|
+
const i1 = t1._collectible.index ?? -1;
|
|
295
|
+
const i2 = t2._collectible.index ?? -1;
|
|
296
|
+
let diff = i1 - i2;
|
|
297
|
+
|
|
298
|
+
if (diff === 0) {
|
|
299
|
+
diff = t1.name.localeCompare(t2.name);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return diff;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Matches a single condition value against a single context value.
|
|
307
|
+
* @param condition - The {@link QualifierConditionValue | condition value} to match.
|
|
308
|
+
* @param context - The {@link QualifierContextValue | context value} to match.
|
|
309
|
+
* @param operator - The {@link ConditionOperator | operator} to use in the match.
|
|
310
|
+
* @returns a {@link QualifierMatchScore | score} indicating the extent to which
|
|
311
|
+
* the condition matches the context value.
|
|
312
|
+
* @public
|
|
313
|
+
*/
|
|
314
|
+
protected abstract _matchOne(
|
|
315
|
+
condition: QualifierConditionValue,
|
|
316
|
+
context: QualifierContextValue,
|
|
317
|
+
operator: ConditionOperator
|
|
318
|
+
): QualifierMatchScore;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Matches a single condition value against a list of context values.
|
|
322
|
+
* @param condition - The {@link QualifierConditionValue | condition value} to match.
|
|
323
|
+
* @param context - The comma-separated list of {@link QualifierContextValue | context values} to match.
|
|
324
|
+
* @param operator - The {@link ConditionOperator | operator} to use in the match.
|
|
325
|
+
* @returns a {@link QualifierMatchScore | score} indicating the extent to which
|
|
326
|
+
* the condition matches the context value.
|
|
327
|
+
* @public
|
|
328
|
+
*/
|
|
329
|
+
protected _matchList(
|
|
330
|
+
condition: QualifierConditionValue,
|
|
331
|
+
context: QualifierContextValue[],
|
|
332
|
+
operator: ConditionOperator
|
|
333
|
+
): QualifierMatchScore {
|
|
334
|
+
const scorePerPosition = 1 / context.length;
|
|
335
|
+
let baseScore = PerfectMatch - scorePerPosition;
|
|
336
|
+
|
|
337
|
+
for (let i = 0; i < context.length; i++) {
|
|
338
|
+
const score = this._matchOne(condition, context[i], operator);
|
|
339
|
+
if (score > NoMatch) {
|
|
340
|
+
const adjusted = baseScore + scorePerPosition * score;
|
|
341
|
+
if (Validate.isValidQualifierMatchScore(adjusted)) {
|
|
342
|
+
return adjusted;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
baseScore -= scorePerPosition;
|
|
346
|
+
}
|
|
347
|
+
return NoMatch;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Splits a comma-separated {@link QualifierContextValue | context value} into an
|
|
352
|
+
* array of individual values.
|
|
353
|
+
* @param value - The value to split.
|
|
354
|
+
* @returns an array of individual context values.
|
|
355
|
+
* @public
|
|
356
|
+
*/
|
|
357
|
+
protected static _splitContext(value: QualifierContextValue): QualifierContextValue[] {
|
|
358
|
+
return value.split(',').map((s) => s.trim() as QualifierContextValue);
|
|
359
|
+
}
|
|
360
|
+
}
|