@fgv/ts-res 5.0.0-3 → 5.0.0-30
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/README.md +794 -137
- package/dist/ts-res.d.ts +2344 -187
- package/dist/tsdoc-metadata.json +1 -1
- package/eslint.config.js +16 -0
- 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/convert.d.ts +10 -0
- package/lib/packlets/common/convert.js +11 -1
- 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 +48 -1
- package/lib/packlets/common/validate/regularExpressions.d.ts +4 -0
- package/lib/packlets/common/validate/regularExpressions.js +5 -1
- package/lib/packlets/common/validate/resources.d.ts +35 -1
- package/lib/packlets/common/validate/resources.js +54 -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 +217 -0
- package/lib/packlets/config/configInitFactory.js +302 -0
- package/lib/packlets/config/convert.d.ts +9 -0
- package/lib/packlets/config/convert.js +12 -1
- package/lib/packlets/config/index.d.ts +1 -0
- package/lib/packlets/config/index.js +1 -0
- package/lib/packlets/config/json.d.ts +1 -1
- 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/convert.d.ts +22 -1
- package/lib/packlets/qualifier-types/config/convert.js +67 -2
- package/lib/packlets/qualifier-types/config/json.d.ts +24 -2
- package/lib/packlets/qualifier-types/config/json.js +11 -0
- package/lib/packlets/qualifier-types/convert.d.ts +1 -1
- package/lib/packlets/qualifier-types/helpers.d.ts +14 -5
- package/lib/packlets/qualifier-types/helpers.js +2 -2
- package/lib/packlets/qualifier-types/languageQualifierType.d.ts +28 -2
- package/lib/packlets/qualifier-types/languageQualifierType.js +73 -0
- package/lib/packlets/qualifier-types/literalQualifierType.d.ts +31 -5
- package/lib/packlets/qualifier-types/literalQualifierType.js +75 -0
- package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts +7 -11
- package/lib/packlets/qualifier-types/literalValueHierarchy.js +11 -1
- package/lib/packlets/qualifier-types/qualifierType.d.ts +31 -2
- package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +31 -5
- package/lib/packlets/qualifier-types/territoryQualifierType.js +77 -0
- package/lib/packlets/qualifiers/qualifierCollector.js +1 -2
- package/lib/packlets/resource-json/compiled/convert.js +2 -1
- package/lib/packlets/resource-json/compiled/json.d.ts +6 -2
- package/lib/packlets/resource-types/config/convert.d.ts +1 -1
- package/lib/packlets/resource-types/config/convert.js +3 -1
- package/lib/packlets/resource-types/config/json.d.ts +3 -1
- package/lib/packlets/resource-types/jsonResourceType.d.ts +14 -5
- package/lib/packlets/resource-types/jsonResourceType.js +8 -4
- package/lib/packlets/resource-types/resourceType.d.ts +115 -14
- package/lib/packlets/resource-types/resourceType.js +39 -3
- package/lib/packlets/resources/candidateValue.d.ts +92 -0
- package/lib/packlets/resources/candidateValue.js +128 -0
- package/lib/packlets/resources/candidateValueCollector.d.ts +55 -0
- package/lib/packlets/resources/candidateValueCollector.js +96 -0
- package/lib/packlets/resources/common.d.ts +26 -0
- package/lib/packlets/resources/index.d.ts +2 -0
- package/lib/packlets/resources/index.js +2 -0
- package/lib/packlets/resources/resource.d.ts +6 -6
- package/lib/packlets/resources/resource.js +5 -10
- package/lib/packlets/resources/resourceBuilder.d.ts +6 -0
- package/lib/packlets/resources/resourceBuilder.js +3 -1
- package/lib/packlets/resources/resourceCandidate.d.ts +15 -2
- package/lib/packlets/resources/resourceCandidate.js +17 -5
- package/lib/packlets/resources/resourceManagerBuilder.d.ts +189 -11
- package/lib/packlets/resources/resourceManagerBuilder.js +478 -17
- 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 +23 -11
- package/lib/packlets/runtime/compiledResourceCollection.js +32 -4
- package/lib/packlets/runtime/iResourceManager.d.ts +13 -5
- package/lib/packlets/runtime/index.d.ts +1 -0
- package/lib/packlets/runtime/index.js +1 -0
- package/lib/packlets/runtime/resource-tree/common.d.ts +1 -1
- 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 +60 -1
- package/lib/packlets/runtime/resourceResolver.js +84 -45
- package/lib/packlets/runtime/resourceTreeResolver.d.ts +152 -0
- package/lib/packlets/runtime/resourceTreeResolver.js +222 -0
- 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 +103 -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/package.json +26 -32
- 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
|
@@ -26,6 +26,7 @@ const ts_utils_1 = require("@fgv/ts-utils");
|
|
|
26
26
|
const ts_json_base_1 = require("@fgv/ts-json-base");
|
|
27
27
|
const ts_json_1 = require("@fgv/ts-json");
|
|
28
28
|
const common_1 = require("../common");
|
|
29
|
+
const context_1 = require("./context");
|
|
29
30
|
const conditionSetResolutionResult_1 = require("./conditionSetResolutionResult");
|
|
30
31
|
/**
|
|
31
32
|
* High-performance runtime resource resolver with O(1) condition caching.
|
|
@@ -34,6 +35,12 @@ const conditionSetResolutionResult_1 = require("./conditionSetResolutionResult")
|
|
|
34
35
|
* @public
|
|
35
36
|
*/
|
|
36
37
|
class ResourceResolver {
|
|
38
|
+
/**
|
|
39
|
+
* The readonly qualifier collector that provides qualifier implementations.
|
|
40
|
+
*/
|
|
41
|
+
get qualifiers() {
|
|
42
|
+
return this.contextQualifierProvider.qualifiers;
|
|
43
|
+
}
|
|
37
44
|
/**
|
|
38
45
|
* The cache array for resolved conditions, indexed by condition index for O(1) lookup.
|
|
39
46
|
* Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
|
|
@@ -61,9 +68,13 @@ class ResourceResolver {
|
|
|
61
68
|
* @param params - {@link Runtime.IResourceResolverCreateParams | Parameters} used to create the resolver.
|
|
62
69
|
*/
|
|
63
70
|
constructor(params) {
|
|
71
|
+
var _a, _b;
|
|
64
72
|
this.resourceManager = params.resourceManager;
|
|
65
73
|
this.qualifierTypes = params.qualifierTypes;
|
|
66
74
|
this.contextQualifierProvider = params.contextQualifierProvider;
|
|
75
|
+
this.options = {
|
|
76
|
+
suppressNullAsDelete: (_b = (_a = params.options) === null || _a === void 0 ? void 0 : _a.suppressNullAsDelete) !== null && _b !== void 0 ? _b : false
|
|
77
|
+
};
|
|
67
78
|
// Initialize condition cache array with size matching the condition collector
|
|
68
79
|
const conditionCollectorSize = this.resourceManager.conditions.size;
|
|
69
80
|
this._conditionCache = new Array(conditionCollectorSize);
|
|
@@ -94,7 +105,7 @@ class ResourceResolver {
|
|
|
94
105
|
* @public
|
|
95
106
|
*/
|
|
96
107
|
resolveCondition(condition) {
|
|
97
|
-
var _a, _b, _c
|
|
108
|
+
var _a, _b, _c;
|
|
98
109
|
// Get the condition's index for cache lookup
|
|
99
110
|
const conditionIndex = condition.index;
|
|
100
111
|
if (conditionIndex === undefined) {
|
|
@@ -107,16 +118,20 @@ class ResourceResolver {
|
|
|
107
118
|
return (0, ts_utils_1.succeed)(cachedResult);
|
|
108
119
|
}
|
|
109
120
|
// Resolve the condition by getting qualifier value and evaluating with qualifier type
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
const score = this.contextQualifierProvider
|
|
122
|
+
.get(condition.qualifier)
|
|
123
|
+
.onSuccess((qualifierValue) => {
|
|
124
|
+
// Evaluate the condition using the qualifier type's matching logic
|
|
125
|
+
return (0, ts_utils_1.succeed)(condition.qualifier.type.matches(condition.value, qualifierValue, condition.operator));
|
|
126
|
+
})
|
|
127
|
+
.onFailure((err) => {
|
|
128
|
+
var _a;
|
|
129
|
+
(_a = this._listener) === null || _a === void 0 ? void 0 : _a.onContextError(condition.qualifier.name, err);
|
|
130
|
+
return (0, ts_utils_1.fail)(err);
|
|
131
|
+
})
|
|
132
|
+
.orDefault(common_1.NoMatch);
|
|
118
133
|
const priority = condition.priority;
|
|
119
|
-
const scoreAsDefault = (
|
|
134
|
+
const scoreAsDefault = (_b = condition.scoreAsDefault) !== null && _b !== void 0 ? _b : common_1.NoMatch;
|
|
120
135
|
const matchResult = score > common_1.NoMatch
|
|
121
136
|
? { score, priority, matchType: 'match' }
|
|
122
137
|
: scoreAsDefault > common_1.NoMatch
|
|
@@ -124,7 +139,7 @@ class ResourceResolver {
|
|
|
124
139
|
: { score: common_1.NoMatch, priority, matchType: 'noMatch' };
|
|
125
140
|
// Cache the resolved value for future O(1) lookup
|
|
126
141
|
this._conditionCache[conditionIndex] = matchResult;
|
|
127
|
-
(
|
|
142
|
+
(_c = this._listener) === null || _c === void 0 ? void 0 : _c.onCacheMiss('condition', conditionIndex);
|
|
128
143
|
return (0, ts_utils_1.succeed)(matchResult);
|
|
129
144
|
}
|
|
130
145
|
/**
|
|
@@ -153,8 +168,8 @@ class ResourceResolver {
|
|
|
153
168
|
let matchType = 'match';
|
|
154
169
|
for (const condition of conditionSet.conditions) {
|
|
155
170
|
const { value: conditionResult, message: conditionMessage } = this.resolveCondition(condition);
|
|
171
|
+
/* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */
|
|
156
172
|
if (conditionMessage !== undefined) {
|
|
157
|
-
/* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */
|
|
158
173
|
(_b = this._listener) === null || _b === void 0 ? void 0 : _b.onCacheError('conditionSet', conditionSetIndex);
|
|
159
174
|
return (0, ts_utils_1.fail)(`Failed to resolve condition "${condition.key}": ${conditionMessage}`);
|
|
160
175
|
}
|
|
@@ -223,8 +238,8 @@ class ResourceResolver {
|
|
|
223
238
|
for (let instanceIndex = 0; instanceIndex < decision.candidates.length; instanceIndex++) {
|
|
224
239
|
const candidate = decision.candidates[instanceIndex];
|
|
225
240
|
const conditionSetResult = this.resolveConditionSet(candidate.conditionSet);
|
|
241
|
+
/* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */
|
|
226
242
|
if (conditionSetResult.isFailure()) {
|
|
227
|
-
/* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */
|
|
228
243
|
(_b = this._listener) === null || _b === void 0 ? void 0 : _b.onCacheError('decision', decisionIndex);
|
|
229
244
|
return (0, ts_utils_1.fail)(`${decision.key}: Failed to resolve condition set": ${conditionSetResult.message}`);
|
|
230
245
|
}
|
|
@@ -260,15 +275,13 @@ class ResourceResolver {
|
|
|
260
275
|
(_c = this._listener) === null || _c === void 0 ? void 0 : _c.onCacheMiss('decision', decisionIndex);
|
|
261
276
|
return (0, ts_utils_1.succeed)(successResult);
|
|
262
277
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
*/
|
|
271
|
-
resolveResource(resource) {
|
|
278
|
+
resolveResource(idOrResource) {
|
|
279
|
+
if (typeof idOrResource === 'string') {
|
|
280
|
+
return this.resourceManager
|
|
281
|
+
.getBuiltResource(idOrResource)
|
|
282
|
+
.onSuccess((resource) => this.resolveResource(resource));
|
|
283
|
+
}
|
|
284
|
+
const resource = idOrResource;
|
|
272
285
|
// Get the abstract decision from the resource's concrete decision
|
|
273
286
|
const abstractDecision = resource.decision.baseDecision;
|
|
274
287
|
// Resolve the decision to get candidate indices in priority order
|
|
@@ -293,15 +306,13 @@ class ResourceResolver {
|
|
|
293
306
|
const bestCandidate = resource.candidates[candidateIndex];
|
|
294
307
|
return (0, ts_utils_1.succeed)(bestCandidate);
|
|
295
308
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
*/
|
|
304
|
-
resolveAllResourceCandidates(resource) {
|
|
309
|
+
resolveAllResourceCandidates(idOrResource) {
|
|
310
|
+
if (typeof idOrResource === 'string') {
|
|
311
|
+
return this.resourceManager
|
|
312
|
+
.getBuiltResource(idOrResource)
|
|
313
|
+
.onSuccess((resource) => this.resolveAllResourceCandidates(resource));
|
|
314
|
+
}
|
|
315
|
+
const resource = idOrResource;
|
|
305
316
|
// Get the abstract decision from the resource's concrete decision
|
|
306
317
|
const abstractDecision = resource.decision.baseDecision;
|
|
307
318
|
// Resolve the decision to get candidate indices in priority order
|
|
@@ -337,16 +348,13 @@ class ResourceResolver {
|
|
|
337
348
|
}
|
|
338
349
|
return (0, ts_utils_1.succeed)(candidates);
|
|
339
350
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
* @public
|
|
348
|
-
*/
|
|
349
|
-
resolveComposedResourceValue(resource) {
|
|
351
|
+
resolveComposedResourceValue(idOrResource) {
|
|
352
|
+
if (typeof idOrResource === 'string') {
|
|
353
|
+
return this.resourceManager
|
|
354
|
+
.getBuiltResource(idOrResource)
|
|
355
|
+
.onSuccess((resource) => this.resolveComposedResourceValue(resource));
|
|
356
|
+
}
|
|
357
|
+
const resource = idOrResource;
|
|
350
358
|
return this.resolveAllResourceCandidates(resource).onSuccess((candidates) => {
|
|
351
359
|
/* c8 ignore next 3 - defense in depth should never occur */
|
|
352
360
|
if (candidates.length === 0) {
|
|
@@ -370,9 +378,22 @@ class ResourceResolver {
|
|
|
370
378
|
// If no full candidate found, use the last candidate as the base
|
|
371
379
|
const baseCandidateIndex = fullCandidateIndex >= 0 ? fullCandidateIndex : candidates.length - 1;
|
|
372
380
|
const baseCandidate = candidates[baseCandidateIndex];
|
|
373
|
-
// If there are no partial candidates to merge,
|
|
381
|
+
// If there are no partial candidates to merge, but null-as-delete is enabled,
|
|
382
|
+
// still process through JsonEditor to handle null properties in the base candidate
|
|
374
383
|
if (partialCandidates.length === 0) {
|
|
375
|
-
|
|
384
|
+
if (this.options.suppressNullAsDelete || !(0, ts_json_base_1.isJsonObject)(baseCandidate.json)) {
|
|
385
|
+
return (0, ts_utils_1.succeed)(baseCandidate.json);
|
|
386
|
+
}
|
|
387
|
+
// Process single candidate through JsonEditor to apply null-as-delete
|
|
388
|
+
const editor = ts_json_1.JsonEditor.create({
|
|
389
|
+
merge: {
|
|
390
|
+
arrayMergeBehavior: 'replace',
|
|
391
|
+
nullAsDelete: true
|
|
392
|
+
}
|
|
393
|
+
}).orThrow(); // Should never fail with valid options
|
|
394
|
+
return editor
|
|
395
|
+
.mergeObjectsInPlace({}, [baseCandidate.json])
|
|
396
|
+
.withErrorFormat((err) => `${resource.id}: Composition failed: ${err}`);
|
|
376
397
|
}
|
|
377
398
|
const allCandidates = [
|
|
378
399
|
baseCandidate.json,
|
|
@@ -382,10 +403,11 @@ class ResourceResolver {
|
|
|
382
403
|
if (allCandidates.length !== partialCandidates.length + 1) {
|
|
383
404
|
return (0, ts_utils_1.fail)(`${resource.id}: Unable to compose non-object candidate values.`);
|
|
384
405
|
}
|
|
385
|
-
// Create JsonEditor with array replacement behavior for resource composition
|
|
406
|
+
// Create JsonEditor with array replacement behavior and null-as-delete for resource composition
|
|
386
407
|
const editor = ts_json_1.JsonEditor.create({
|
|
387
408
|
merge: {
|
|
388
|
-
arrayMergeBehavior: 'replace'
|
|
409
|
+
arrayMergeBehavior: 'replace',
|
|
410
|
+
nullAsDelete: !this.options.suppressNullAsDelete
|
|
389
411
|
}
|
|
390
412
|
}).orThrow(); // Should never fail with valid options
|
|
391
413
|
return editor
|
|
@@ -393,6 +415,23 @@ class ResourceResolver {
|
|
|
393
415
|
.withErrorFormat((err) => `${resource.id}: Composition failed: ${err}`);
|
|
394
416
|
});
|
|
395
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* {@inheritDoc IResourceResolver.withContext}
|
|
420
|
+
*/
|
|
421
|
+
withContext(context) {
|
|
422
|
+
const { resourceManager, qualifierTypes, options } = this;
|
|
423
|
+
return context_1.ValidatingSimpleContextQualifierProvider.create({
|
|
424
|
+
qualifiers: this.qualifiers,
|
|
425
|
+
qualifierValues: context
|
|
426
|
+
}).onSuccess((contextQualifierProvider) => {
|
|
427
|
+
return ResourceResolver.create({
|
|
428
|
+
resourceManager,
|
|
429
|
+
qualifierTypes,
|
|
430
|
+
options,
|
|
431
|
+
contextQualifierProvider
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
}
|
|
396
435
|
/**
|
|
397
436
|
* Clears all caches (condition, condition set, and decision), forcing all cached items
|
|
398
437
|
* to be re-evaluated on next access. This should be called when the context changes and cached
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Result } from '@fgv/ts-utils';
|
|
2
|
+
import { JsonValue, JsonObject } from '@fgv/ts-json-base';
|
|
3
|
+
import { IResource } from './iResourceManager';
|
|
4
|
+
import { IReadOnlyResourceTreeNode, IReadOnlyResourceTreeRoot } from './resource-tree/common';
|
|
5
|
+
import { ResourceResolver } from './resourceResolver';
|
|
6
|
+
/**
|
|
7
|
+
* Type for handling resource resolution errors during tree traversal.
|
|
8
|
+
* The handler receives the resource that failed to resolve, the error message, and the resolver for recovery attempts.
|
|
9
|
+
* It can return:
|
|
10
|
+
* - Success(undefined) to omit the property from the result
|
|
11
|
+
* - Success(value) to use an alternate value
|
|
12
|
+
* - Failure to propagate the error
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export type ResourceErrorHandler = (resource: IResource, message: string, resolver: ResourceResolver) => Result<JsonValue | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* Type for handling empty branch nodes during tree composition.
|
|
18
|
+
* The handler receives the branch node, names of failed children, and the resolver for recovery attempts.
|
|
19
|
+
* It can return:
|
|
20
|
+
* - Success(undefined) to omit the branch from the result
|
|
21
|
+
* - Success(value) to use an alternate value for the branch
|
|
22
|
+
* - Failure to propagate the error
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export type EmptyBranchHandler = (branchNode: IReadOnlyResourceTreeNode<IResource>, failedChildNames: string[], resolver: ResourceResolver) => Result<JsonValue | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Options for configuring resource tree resolution.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export interface IResolveResourceTreeOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Controls how errors are handled when resolving individual resources in the tree.
|
|
33
|
+
* - 'fail': Aggregate all errors and fail if any resource fails to resolve
|
|
34
|
+
* - 'ignore': Skip failed resources and omit them from the result
|
|
35
|
+
* - callback: Custom error handler that can provide alternate values or propagate errors
|
|
36
|
+
* @defaultValue 'fail'
|
|
37
|
+
*/
|
|
38
|
+
onResourceError?: 'fail' | 'ignore' | ResourceErrorHandler;
|
|
39
|
+
/**
|
|
40
|
+
* Controls how empty branch nodes are handled during tree composition.
|
|
41
|
+
* - 'allow': Include empty branches as empty objects in the result
|
|
42
|
+
* - 'omit': Exclude empty branches from the parent object
|
|
43
|
+
* - callback: Custom handler that can provide alternate values or recovery logic
|
|
44
|
+
* @defaultValue 'allow'
|
|
45
|
+
*/
|
|
46
|
+
onEmptyBranch?: 'allow' | 'omit' | EmptyBranchHandler;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Specialized resolver for resource tree operations, providing enhanced APIs for
|
|
50
|
+
* resolving entire resource trees from either resource IDs or pre-built tree nodes.
|
|
51
|
+
*
|
|
52
|
+
* This class provides a clean separation between individual resource resolution
|
|
53
|
+
* (handled by ResourceResolver) and tree-based operations, with support for
|
|
54
|
+
* lazy tree construction and enhanced error handling.
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export declare class ResourceTreeResolver {
|
|
59
|
+
/**
|
|
60
|
+
* The {@link Runtime.ResourceResolver | ResourceResolver} to use for individual resource resolution
|
|
61
|
+
*/
|
|
62
|
+
readonly resolver: ResourceResolver;
|
|
63
|
+
/**
|
|
64
|
+
* The {@link Runtime.IResourceManager | IResourceManager} to use for lazy tree construction.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
private readonly _resourceManager;
|
|
68
|
+
/**
|
|
69
|
+
* The built resource tree, lazily built on first access.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
private _tree?;
|
|
73
|
+
/**
|
|
74
|
+
* Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
|
|
75
|
+
* @param resolver - The ResourceResolver to use for individual resource resolution
|
|
76
|
+
*/
|
|
77
|
+
constructor(resolver: ResourceResolver);
|
|
78
|
+
/**
|
|
79
|
+
* Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
|
|
80
|
+
* @param resolver - The ResourceResolver to use for individual resource resolution
|
|
81
|
+
*/
|
|
82
|
+
static create(resolver: ResourceResolver): Result<ResourceTreeResolver>;
|
|
83
|
+
/**
|
|
84
|
+
* Gets the built resource tree, building it lazily on first access.
|
|
85
|
+
* @returns The resource tree root
|
|
86
|
+
* @throws Error if no resource manager was provided or tree building fails
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
get tree(): IReadOnlyResourceTreeRoot<IResource>;
|
|
90
|
+
/**
|
|
91
|
+
* Resolves a resource tree from a resource ID, building the tree lazily from the resource manager.
|
|
92
|
+
* @param resourceId - The ID of the root resource to resolve
|
|
93
|
+
* @param options - Optional configuration for error handling during resolution
|
|
94
|
+
* @returns Success with the composed JsonObject or undefined, or Failure with error message
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
resolveComposedResourceTree(resourceId: string, options?: IResolveResourceTreeOptions): Result<JsonObject | undefined>;
|
|
98
|
+
/**
|
|
99
|
+
* Resolves a pre-built resource tree node.
|
|
100
|
+
* @param node - The resource tree node to resolve
|
|
101
|
+
* @param options - Optional configuration for error handling during resolution
|
|
102
|
+
* @returns Success with the composed JsonObject or undefined, or Failure with error message
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
resolveComposedResourceTree(node: IReadOnlyResourceTreeNode<IResource>, options?: IResolveResourceTreeOptions): Result<JsonObject | undefined>;
|
|
106
|
+
private _getTree;
|
|
107
|
+
/**
|
|
108
|
+
* Resolves a tree from a resource ID by first building the tree from the resource manager.
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
private _resolveFromResourceId;
|
|
112
|
+
/**
|
|
113
|
+
* Resolves a pre-built tree node using the extracted tree resolution logic.
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
private _resolveFromTreeNode;
|
|
117
|
+
/**
|
|
118
|
+
* Handles resource resolution errors according to the specified mode.
|
|
119
|
+
* @param resource - The resource that failed to resolve
|
|
120
|
+
* @param message - The error message from the failed resolution
|
|
121
|
+
* @param mode - The error handling mode
|
|
122
|
+
* @param path - The path to the resource in the tree (for error context)
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
private _handleResourceError;
|
|
126
|
+
/**
|
|
127
|
+
* Handles empty branch nodes according to the specified mode.
|
|
128
|
+
* @param node - The empty branch node
|
|
129
|
+
* @param failedChildren - Names of children that failed to resolve
|
|
130
|
+
* @param mode - The empty branch handling mode
|
|
131
|
+
* @param path - The path to the branch in the tree (for error context)
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
134
|
+
private _handleEmptyBranch;
|
|
135
|
+
/**
|
|
136
|
+
* Processes a leaf node by resolving its resource value.
|
|
137
|
+
* @param node - The leaf node to process (must be a leaf node)
|
|
138
|
+
* @param path - The path to the node in the tree
|
|
139
|
+
* @param resourceErrorMode - How to handle resource resolution errors
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
private _processLeafNode;
|
|
143
|
+
/**
|
|
144
|
+
* Processes a branch node by recursively resolving all its children.
|
|
145
|
+
* @param node - The branch node to process (must be a branch node)
|
|
146
|
+
* @param path - The path to the node in the tree
|
|
147
|
+
* @param options - Resolution options
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
private _processBranchNode;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=resourceTreeResolver.d.ts.map
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.ResourceTreeResolver = void 0;
|
|
25
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
26
|
+
const ts_json_base_1 = require("@fgv/ts-json-base");
|
|
27
|
+
/**
|
|
28
|
+
* Specialized resolver for resource tree operations, providing enhanced APIs for
|
|
29
|
+
* resolving entire resource trees from either resource IDs or pre-built tree nodes.
|
|
30
|
+
*
|
|
31
|
+
* This class provides a clean separation between individual resource resolution
|
|
32
|
+
* (handled by ResourceResolver) and tree-based operations, with support for
|
|
33
|
+
* lazy tree construction and enhanced error handling.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
class ResourceTreeResolver {
|
|
38
|
+
/**
|
|
39
|
+
* Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
|
|
40
|
+
* @param resolver - The ResourceResolver to use for individual resource resolution
|
|
41
|
+
*/
|
|
42
|
+
constructor(resolver) {
|
|
43
|
+
this.resolver = resolver;
|
|
44
|
+
this._resourceManager = resolver.resourceManager;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
|
|
48
|
+
* @param resolver - The ResourceResolver to use for individual resource resolution
|
|
49
|
+
*/
|
|
50
|
+
static create(resolver) {
|
|
51
|
+
return (0, ts_utils_1.captureResult)(() => new ResourceTreeResolver(resolver));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Gets the built resource tree, building it lazily on first access.
|
|
55
|
+
* @returns The resource tree root
|
|
56
|
+
* @throws Error if no resource manager was provided or tree building fails
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
get tree() {
|
|
60
|
+
return this._getTree().orThrow();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Implementation for both overloads.
|
|
64
|
+
*/
|
|
65
|
+
resolveComposedResourceTree(idOrNode, options) {
|
|
66
|
+
if (typeof idOrNode === 'string') {
|
|
67
|
+
return this._resolveFromResourceId(idOrNode, options);
|
|
68
|
+
}
|
|
69
|
+
return this._resolveFromTreeNode(idOrNode, options);
|
|
70
|
+
}
|
|
71
|
+
_getTree() {
|
|
72
|
+
if (!this._tree) {
|
|
73
|
+
this._tree = this._resourceManager.getBuiltResourceTree();
|
|
74
|
+
}
|
|
75
|
+
return this._tree;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolves a tree from a resource ID by first building the tree from the resource manager.
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
_resolveFromResourceId(resourceId, options) {
|
|
82
|
+
return this._getTree().onSuccess((tree) => {
|
|
83
|
+
return tree.children.validating
|
|
84
|
+
.getById(resourceId)
|
|
85
|
+
.onFailure((message) => (0, ts_utils_1.fail)(`${resourceId}: Resource not found in resource tree: ${message}`))
|
|
86
|
+
.onSuccess((rootNode) => this._resolveFromTreeNode(rootNode, options));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolves a pre-built tree node using the extracted tree resolution logic.
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
_resolveFromTreeNode(node, options) {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
const resourceErrorMode = (_a = options === null || options === void 0 ? void 0 : options.onResourceError) !== null && _a !== void 0 ? _a : 'fail';
|
|
96
|
+
const emptyBranchMode = (_b = options === null || options === void 0 ? void 0 : options.onEmptyBranch) !== null && _b !== void 0 ? _b : 'allow';
|
|
97
|
+
// Handle root node with proper Result chaining
|
|
98
|
+
return node.isLeaf
|
|
99
|
+
? this._processLeafNode(node, '', resourceErrorMode).onSuccess((value) => value !== undefined ? ts_json_base_1.Converters.jsonObject.convert(value) : (0, ts_utils_1.succeed)(undefined))
|
|
100
|
+
: this._processBranchNode(node, '', {
|
|
101
|
+
onResourceError: resourceErrorMode,
|
|
102
|
+
onEmptyBranch: emptyBranchMode
|
|
103
|
+
}).onSuccess((value) => {
|
|
104
|
+
// Only convert undefined to {} if emptyBranchMode is 'allow'
|
|
105
|
+
// For 'omit' mode or custom handlers returning undefined, preserve undefined
|
|
106
|
+
return (0, ts_utils_1.succeed)(value === undefined && emptyBranchMode === 'allow' ? {} : value);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Handles resource resolution errors according to the specified mode.
|
|
111
|
+
* @param resource - The resource that failed to resolve
|
|
112
|
+
* @param message - The error message from the failed resolution
|
|
113
|
+
* @param mode - The error handling mode
|
|
114
|
+
* @param path - The path to the resource in the tree (for error context)
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
_handleResourceError(resource, message, mode, path) {
|
|
118
|
+
if (mode === 'ignore') {
|
|
119
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
120
|
+
}
|
|
121
|
+
if (mode === 'fail') {
|
|
122
|
+
const errorMessage = path ? `${path}: ${message}` : message;
|
|
123
|
+
return (0, ts_utils_1.fail)(errorMessage);
|
|
124
|
+
}
|
|
125
|
+
// Custom handler - pass the resolver for recovery attempts
|
|
126
|
+
return mode(resource, message, this.resolver);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handles empty branch nodes according to the specified mode.
|
|
130
|
+
* @param node - The empty branch node
|
|
131
|
+
* @param failedChildren - Names of children that failed to resolve
|
|
132
|
+
* @param mode - The empty branch handling mode
|
|
133
|
+
* @param path - The path to the branch in the tree (for error context)
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
_handleEmptyBranch(node, failedChildren, mode, path) {
|
|
137
|
+
if (mode === 'omit') {
|
|
138
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
139
|
+
}
|
|
140
|
+
if (mode === 'allow') {
|
|
141
|
+
return (0, ts_utils_1.succeed)({});
|
|
142
|
+
}
|
|
143
|
+
// Custom handler - pass the resolver for recovery attempts
|
|
144
|
+
return mode(node, failedChildren, this.resolver);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Processes a leaf node by resolving its resource value.
|
|
148
|
+
* @param node - The leaf node to process (must be a leaf node)
|
|
149
|
+
* @param path - The path to the node in the tree
|
|
150
|
+
* @param resourceErrorMode - How to handle resource resolution errors
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
_processLeafNode(node, path, resourceErrorMode) {
|
|
154
|
+
/* c8 ignore next 3 - defense in depth */
|
|
155
|
+
if (!node.isLeaf) {
|
|
156
|
+
return (0, ts_utils_1.fail)(`Internal error: processLeafNode called on non-leaf node at ${path}`);
|
|
157
|
+
}
|
|
158
|
+
return this.resolver
|
|
159
|
+
.resolveComposedResourceValue(node.resource)
|
|
160
|
+
.onSuccess((value) => (0, ts_utils_1.succeed)(value))
|
|
161
|
+
.onFailure((message) => this._handleResourceError(node.resource, message, resourceErrorMode, path));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Processes a branch node by recursively resolving all its children.
|
|
165
|
+
* @param node - The branch node to process (must be a branch node)
|
|
166
|
+
* @param path - The path to the node in the tree
|
|
167
|
+
* @param options - Resolution options
|
|
168
|
+
* @internal
|
|
169
|
+
*/
|
|
170
|
+
_processBranchNode(node, path, options) {
|
|
171
|
+
var _a, _b;
|
|
172
|
+
/* c8 ignore next 3 - defense in depth */
|
|
173
|
+
if (node.isLeaf) {
|
|
174
|
+
return (0, ts_utils_1.fail)(`Internal error: processBranchNode called on leaf node at ${path}`);
|
|
175
|
+
}
|
|
176
|
+
const resourceErrorMode = (_a = options.onResourceError) !== null && _a !== void 0 ? _a : 'fail';
|
|
177
|
+
const emptyBranchMode = (_b = options.onEmptyBranch) !== null && _b !== void 0 ? _b : 'allow';
|
|
178
|
+
const aggregator = new ts_utils_1.MessageAggregator();
|
|
179
|
+
// Process all children
|
|
180
|
+
const childResults = {};
|
|
181
|
+
const failedChildren = [];
|
|
182
|
+
for (const [childName, childNode] of node.children) {
|
|
183
|
+
const childPath = path ? `${path}.${childName}` : childName;
|
|
184
|
+
const childResult = childNode.isLeaf
|
|
185
|
+
? this._processLeafNode(childNode, childPath, resourceErrorMode)
|
|
186
|
+
: this._processBranchNode(childNode, childPath, options);
|
|
187
|
+
// Process the child result and update our state
|
|
188
|
+
if (childResult.isSuccess()) {
|
|
189
|
+
const value = childResult.value;
|
|
190
|
+
if (value !== undefined) {
|
|
191
|
+
childResults[childName] = value;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
failedChildren.push(childName);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (resourceErrorMode === 'fail') {
|
|
199
|
+
aggregator.addMessage(childResult.message);
|
|
200
|
+
}
|
|
201
|
+
failedChildren.push(childName);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Check for accumulated errors in 'fail' mode
|
|
205
|
+
if (resourceErrorMode === 'fail' && aggregator.hasMessages) {
|
|
206
|
+
return (0, ts_utils_1.fail)(aggregator.toString('; '));
|
|
207
|
+
}
|
|
208
|
+
// Handle empty branch
|
|
209
|
+
if (Object.keys(childResults).length === 0) {
|
|
210
|
+
return this._handleEmptyBranch(node, failedChildren, emptyBranchMode, path).onSuccess((value) => {
|
|
211
|
+
if (value === undefined) {
|
|
212
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
213
|
+
}
|
|
214
|
+
// Ensure we return JsonObject or undefined
|
|
215
|
+
return ts_json_base_1.Converters.jsonObject.convert(value);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return (0, ts_utils_1.succeed)(childResults);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.ResourceTreeResolver = ResourceTreeResolver;
|
|
222
|
+
//# sourceMappingURL=resourceTreeResolver.js.map
|
|
@@ -42,6 +42,7 @@ exports.resourceCandidate = ts_utils_1.Validators.object({
|
|
|
42
42
|
*/
|
|
43
43
|
exports.resource = ts_utils_1.Validators.object({
|
|
44
44
|
id: ts_utils_1.Validators.isA('ResourceId', (v) => typeof v === 'string' && common_1.Validate.isValidResourceId(v)),
|
|
45
|
+
name: ts_utils_1.Validators.isA('ResourceName', (v) => typeof v === 'string' && common_1.Validate.isValidResourceName(v)),
|
|
45
46
|
resourceType: ts_utils_1.Validators.isA('ResourceType instance', (v) => v instanceof resource_types_1.ResourceType),
|
|
46
47
|
decision: ts_utils_1.Validators.isA('ConcreteDecision instance', (v) => v instanceof decisions_1.ConcreteDecision),
|
|
47
48
|
candidates: ts_utils_1.Validators.arrayOf(exports.resourceCandidate)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Validator, Converter } from '@fgv/ts-utils';
|
|
2
|
+
import * as Json from './json';
|
|
3
|
+
import { Model as ConfigModel } from '../config';
|
|
4
|
+
/**
|
|
5
|
+
* Validator for ZIP archive input type
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare const zipArchiveInputType: Validator<'file' | 'directory'>;
|
|
9
|
+
/**
|
|
10
|
+
* Validator for ZIP archive config type
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export declare const zipArchiveConfigType: Validator<'file'>;
|
|
14
|
+
/**
|
|
15
|
+
* Validator for ZIP archive input information
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare const zipArchiveInputInfo: Validator<Json.IZipArchiveInputInfo>;
|
|
19
|
+
/**
|
|
20
|
+
* Validator for ZIP archive config information
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export declare const zipArchiveConfigInfo: Validator<Json.IZipArchiveConfigInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* Validator for ZIP archive manifest
|
|
26
|
+
* Compatible with existing tools from ts-res-browser-cli
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export declare const zipArchiveManifest: Validator<Json.IZipArchiveManifest>;
|
|
30
|
+
/**
|
|
31
|
+
* Validator for MIME type strings
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export declare const mimeType: Validator<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Converter for imported file
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export declare const importedFile: Converter<Json.IImportedFile>;
|
|
40
|
+
/**
|
|
41
|
+
* Converter for imported directory structure (recursive)
|
|
42
|
+
* Note: Uses Converter pattern because Validators don't support recursion with self parameter
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare const importedDirectory: Converter<Json.IImportedDirectory>;
|
|
46
|
+
/**
|
|
47
|
+
* Validator for system configuration (delegates to config packlet)
|
|
48
|
+
* This validates that the parsed JSON conforms to the system configuration schema
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare const systemConfiguration: Validator<ConfigModel.ISystemConfiguration>;
|
|
52
|
+
//# sourceMappingURL=convert.d.ts.map
|