@fgv/ts-res 4.5.0-3 → 5.0.0-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +26 -0
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +186 -0
- package/EXAMPLE_INIT_PARAMS.md +88 -0
- package/PROGRESS_SUMMARY.md +48 -0
- package/README.md +535 -14
- package/dist/ts-res.d.ts +4241 -318
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -1
- package/lib/index.js.map +1 -1
- package/lib/packlets/common/conditions.d.ts +30 -0
- package/lib/packlets/common/conditions.d.ts.map +1 -1
- package/lib/packlets/common/conditions.js.map +1 -1
- package/lib/packlets/common/convert.d.ts +22 -2
- package/lib/packlets/common/convert.d.ts.map +1 -1
- package/lib/packlets/common/convert.js +21 -1
- package/lib/packlets/common/convert.js.map +1 -1
- package/lib/packlets/common/helpers/context.d.ts +39 -0
- package/lib/packlets/common/helpers/context.d.ts.map +1 -0
- package/lib/packlets/common/helpers/context.js +108 -0
- package/lib/packlets/common/helpers/context.js.map +1 -0
- package/lib/packlets/common/helpers/index.d.ts +2 -0
- package/lib/packlets/common/helpers/index.d.ts.map +1 -1
- package/lib/packlets/common/helpers/index.js +2 -0
- package/lib/packlets/common/helpers/index.js.map +1 -1
- package/lib/packlets/common/helpers/qualifierDefaultValues.d.ts +39 -0
- package/lib/packlets/common/helpers/qualifierDefaultValues.d.ts.map +1 -0
- package/lib/packlets/common/helpers/qualifierDefaultValues.js +105 -0
- package/lib/packlets/common/helpers/qualifierDefaultValues.js.map +1 -0
- package/lib/packlets/common/helpers/resources.d.ts.map +1 -1
- package/lib/packlets/common/helpers/resources.js +6 -2
- package/lib/packlets/common/helpers/resources.js.map +1 -1
- package/lib/packlets/common/validate/conditions.d.ts +69 -1
- package/lib/packlets/common/validate/conditions.d.ts.map +1 -1
- package/lib/packlets/common/validate/conditions.js +126 -0
- package/lib/packlets/common/validate/conditions.js.map +1 -1
- package/lib/packlets/common/validate/regularExpressions.d.ts +20 -0
- package/lib/packlets/common/validate/regularExpressions.d.ts.map +1 -1
- package/lib/packlets/common/validate/regularExpressions.js +21 -1
- package/lib/packlets/common/validate/regularExpressions.js.map +1 -1
- package/lib/packlets/conditions/condition.d.ts +37 -0
- package/lib/packlets/conditions/condition.d.ts.map +1 -1
- package/lib/packlets/conditions/condition.js +67 -1
- package/lib/packlets/conditions/condition.js.map +1 -1
- package/lib/packlets/conditions/conditionCollector.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionCollector.js +1 -0
- package/lib/packlets/conditions/conditionCollector.js.map +1 -1
- package/lib/packlets/conditions/conditionSet.d.ts +34 -3
- package/lib/packlets/conditions/conditionSet.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionSet.js +31 -3
- package/lib/packlets/conditions/conditionSet.js.map +1 -1
- package/lib/packlets/conditions/conditionSetCollector.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionSetCollector.js +3 -0
- package/lib/packlets/conditions/conditionSetCollector.js.map +1 -1
- package/lib/packlets/conditions/conditionToken.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionToken.js +2 -1
- package/lib/packlets/conditions/conditionToken.js.map +1 -1
- package/lib/packlets/conditions/convert/decls.js +1 -1
- package/lib/packlets/conditions/convert/decls.js.map +1 -1
- package/lib/packlets/config/common.d.ts +35 -0
- package/lib/packlets/config/common.d.ts.map +1 -0
- package/lib/packlets/config/common.js +96 -0
- package/lib/packlets/config/common.js.map +1 -0
- package/lib/packlets/config/convert.d.ts +14 -0
- package/lib/packlets/config/convert.d.ts.map +1 -0
- package/lib/packlets/config/convert.js +82 -0
- package/lib/packlets/config/convert.js.map +1 -0
- package/lib/packlets/config/index.d.ts +6 -0
- package/lib/packlets/config/index.d.ts.map +1 -0
- package/lib/packlets/config/index.js +67 -0
- package/lib/packlets/config/index.js.map +1 -0
- package/lib/packlets/config/json.d.ts +20 -0
- package/lib/packlets/config/json.d.ts.map +1 -0
- package/lib/packlets/config/json.js +24 -0
- package/lib/packlets/config/json.js.map +1 -0
- package/lib/packlets/config/predefined/default.d.ts +57 -0
- package/lib/packlets/config/predefined/default.d.ts.map +1 -0
- package/lib/packlets/config/predefined/default.js +141 -0
- package/lib/packlets/config/predefined/default.js.map +1 -0
- package/lib/packlets/config/predefined/extended.d.ts +25 -0
- package/lib/packlets/config/predefined/extended.d.ts.map +1 -0
- package/lib/packlets/config/predefined/extended.js +193 -0
- package/lib/packlets/config/predefined/extended.js.map +1 -0
- package/lib/packlets/config/predefined/index.d.ts +4 -0
- package/lib/packlets/config/predefined/index.d.ts.map +1 -0
- package/lib/packlets/config/predefined/index.js +62 -0
- package/lib/packlets/config/predefined/index.js.map +1 -0
- package/lib/packlets/config/systemConfiguration.d.ts +81 -0
- package/lib/packlets/config/systemConfiguration.d.ts.map +1 -0
- package/lib/packlets/config/systemConfiguration.js +172 -0
- package/lib/packlets/config/systemConfiguration.js.map +1 -0
- package/lib/packlets/context/contextDecls.d.ts +49 -0
- package/lib/packlets/context/contextDecls.d.ts.map +1 -0
- package/lib/packlets/context/contextDecls.js +24 -0
- package/lib/packlets/context/contextDecls.js.map +1 -0
- package/lib/packlets/context/contextToken.d.ts +111 -0
- package/lib/packlets/context/contextToken.d.ts.map +1 -0
- package/lib/packlets/context/contextToken.js +206 -0
- package/lib/packlets/context/contextToken.js.map +1 -0
- package/lib/packlets/context/convert/decls.d.ts +37 -0
- package/lib/packlets/context/convert/decls.d.ts.map +1 -0
- package/lib/packlets/context/convert/decls.js +94 -0
- package/lib/packlets/context/convert/decls.js.map +1 -0
- package/lib/packlets/context/convert/index.d.ts +2 -0
- package/lib/packlets/context/convert/index.d.ts.map +1 -0
- package/lib/packlets/context/convert/index.js +39 -0
- package/lib/packlets/context/convert/index.js.map +1 -0
- package/lib/packlets/context/index.d.ts +5 -0
- package/lib/packlets/context/index.d.ts.map +1 -0
- package/lib/packlets/context/index.js +65 -0
- package/lib/packlets/context/index.js.map +1 -0
- package/lib/packlets/decisions/abstractDecision.d.ts +8 -0
- package/lib/packlets/decisions/abstractDecision.d.ts.map +1 -1
- package/lib/packlets/decisions/abstractDecision.js +9 -0
- package/lib/packlets/decisions/abstractDecision.js.map +1 -1
- package/lib/packlets/decisions/abstractDecisionCollector.d.ts.map +1 -1
- package/lib/packlets/decisions/abstractDecisionCollector.js +2 -0
- package/lib/packlets/decisions/abstractDecisionCollector.js.map +1 -1
- package/lib/packlets/decisions/concreteDecision.d.ts.map +1 -1
- package/lib/packlets/decisions/concreteDecision.js +1 -0
- package/lib/packlets/decisions/concreteDecision.js.map +1 -1
- package/lib/packlets/decisions/decision.d.ts.map +1 -1
- package/lib/packlets/decisions/decision.js +4 -0
- package/lib/packlets/decisions/decision.js.map +1 -1
- package/lib/packlets/import/fsItem.d.ts.map +1 -1
- package/lib/packlets/import/fsItem.js +1 -0
- package/lib/packlets/import/fsItem.js.map +1 -1
- package/lib/packlets/import/importContext.d.ts +19 -0
- package/lib/packlets/import/importContext.d.ts.map +1 -1
- package/lib/packlets/import/importContext.js +39 -0
- package/lib/packlets/import/importContext.js.map +1 -1
- package/lib/packlets/import/importManager.d.ts +5 -5
- package/lib/packlets/import/importManager.d.ts.map +1 -1
- package/lib/packlets/import/importManager.js.map +1 -1
- package/lib/packlets/import/importers/collectionImporter.d.ts +11 -13
- package/lib/packlets/import/importers/collectionImporter.d.ts.map +1 -1
- package/lib/packlets/import/importers/collectionImporter.js +29 -20
- package/lib/packlets/import/importers/collectionImporter.js.map +1 -1
- package/lib/packlets/import/importers/fsItemImporter.d.ts +2 -2
- package/lib/packlets/import/importers/fsItemImporter.d.ts.map +1 -1
- package/lib/packlets/import/importers/fsItemImporter.js +2 -2
- package/lib/packlets/import/importers/fsItemImporter.js.map +1 -1
- package/lib/packlets/import/importers/importer.d.ts +3 -3
- package/lib/packlets/import/importers/importer.d.ts.map +1 -1
- package/lib/packlets/import/importers/importer.js.map +1 -1
- package/lib/packlets/import/importers/jsonImporter.d.ts +2 -3
- package/lib/packlets/import/importers/jsonImporter.d.ts.map +1 -1
- package/lib/packlets/import/importers/jsonImporter.js +10 -20
- package/lib/packlets/import/importers/jsonImporter.js.map +1 -1
- package/lib/packlets/import/importers/pathImporter.d.ts +2 -2
- package/lib/packlets/import/importers/pathImporter.d.ts.map +1 -1
- package/lib/packlets/import/importers/pathImporter.js.map +1 -1
- package/lib/packlets/qualifier-types/config/convert.d.ts +44 -0
- package/lib/packlets/qualifier-types/config/convert.d.ts.map +1 -0
- package/lib/packlets/qualifier-types/config/convert.js +96 -0
- package/lib/packlets/qualifier-types/config/convert.js.map +1 -0
- package/lib/packlets/qualifier-types/config/index.d.ts +4 -0
- package/lib/packlets/qualifier-types/config/index.d.ts.map +1 -0
- package/lib/packlets/qualifier-types/config/index.js +64 -0
- package/lib/packlets/qualifier-types/config/index.js.map +1 -0
- package/lib/packlets/qualifier-types/config/json.d.ts +69 -0
- package/lib/packlets/qualifier-types/config/json.d.ts.map +1 -0
- package/lib/packlets/qualifier-types/config/json.js +24 -0
- package/lib/packlets/qualifier-types/config/json.js.map +1 -0
- package/lib/packlets/qualifier-types/convert.d.ts +10 -2
- package/lib/packlets/qualifier-types/convert.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/convert.js +15 -0
- package/lib/packlets/qualifier-types/convert.js.map +1 -1
- package/lib/packlets/qualifier-types/helpers.d.ts +27 -0
- package/lib/packlets/qualifier-types/helpers.d.ts.map +1 -0
- package/lib/packlets/qualifier-types/helpers.js +118 -0
- package/lib/packlets/qualifier-types/helpers.js.map +1 -0
- package/lib/packlets/qualifier-types/index.d.ts +4 -1
- package/lib/packlets/qualifier-types/index.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/index.js +5 -1
- package/lib/packlets/qualifier-types/index.js.map +1 -1
- package/lib/packlets/qualifier-types/languageQualifierType.d.ts +19 -8
- package/lib/packlets/qualifier-types/languageQualifierType.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/languageQualifierType.js +28 -9
- package/lib/packlets/qualifier-types/languageQualifierType.js.map +1 -1
- package/lib/packlets/qualifier-types/literalQualifierType.d.ts +42 -13
- package/lib/packlets/qualifier-types/literalQualifierType.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/literalQualifierType.js +58 -10
- package/lib/packlets/qualifier-types/literalQualifierType.js.map +1 -1
- package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts +114 -0
- package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts.map +1 -0
- package/lib/packlets/qualifier-types/literalValueHierarchy.js +228 -0
- package/lib/packlets/qualifier-types/literalValueHierarchy.js.map +1 -0
- package/lib/packlets/qualifier-types/qualifierType.d.ts +33 -18
- package/lib/packlets/qualifier-types/qualifierType.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/qualifierType.js +18 -4
- package/lib/packlets/qualifier-types/qualifierType.js.map +1 -1
- package/lib/packlets/qualifier-types/qualifierTypeCollector.d.ts +4 -2
- package/lib/packlets/qualifier-types/qualifierTypeCollector.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/qualifierTypeCollector.js +2 -1
- package/lib/packlets/qualifier-types/qualifierTypeCollector.js.map +1 -1
- package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +47 -11
- package/lib/packlets/qualifier-types/territoryQualifierType.d.ts.map +1 -1
- package/lib/packlets/qualifier-types/territoryQualifierType.js +61 -17
- package/lib/packlets/qualifier-types/territoryQualifierType.js.map +1 -1
- package/lib/packlets/qualifiers/convert/decls.d.ts.map +1 -1
- package/lib/packlets/qualifiers/convert/decls.js +17 -15
- package/lib/packlets/qualifiers/convert/decls.js.map +1 -1
- package/lib/packlets/qualifiers/index.d.ts +2 -0
- package/lib/packlets/qualifiers/index.d.ts.map +1 -1
- package/lib/packlets/qualifiers/index.js +2 -0
- package/lib/packlets/qualifiers/index.js.map +1 -1
- package/lib/packlets/qualifiers/qualifier.d.ts +22 -2
- package/lib/packlets/qualifiers/qualifier.d.ts.map +1 -1
- package/lib/packlets/qualifiers/qualifier.js +26 -1
- package/lib/packlets/qualifiers/qualifier.js.map +1 -1
- package/lib/packlets/qualifiers/qualifierCollector.d.ts.map +1 -1
- package/lib/packlets/qualifiers/qualifierCollector.js +4 -0
- package/lib/packlets/qualifiers/qualifierCollector.js.map +1 -1
- package/lib/packlets/qualifiers/qualifierDecl.d.ts +6 -1
- package/lib/packlets/qualifiers/qualifierDecl.d.ts.map +1 -1
- package/lib/packlets/qualifiers/qualifierDecl.js.map +1 -1
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.d.ts +32 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.d.ts.map +1 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.js +24 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueDecls.js.map +1 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.d.ts +96 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.d.ts.map +1 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.js +179 -0
- package/lib/packlets/qualifiers/qualifierDefaultValueToken.js.map +1 -0
- package/lib/packlets/resource-json/compiled/common.d.ts +14 -0
- package/lib/packlets/resource-json/compiled/common.d.ts.map +1 -0
- package/lib/packlets/resource-json/compiled/common.js +24 -0
- package/lib/packlets/resource-json/compiled/common.js.map +1 -0
- package/lib/packlets/resource-json/compiled/convert.d.ts +63 -0
- package/lib/packlets/resource-json/compiled/convert.d.ts.map +1 -0
- package/lib/packlets/resource-json/compiled/convert.js +167 -0
- package/lib/packlets/resource-json/compiled/convert.js.map +1 -0
- package/lib/packlets/resource-json/compiled/index.d.ts +5 -0
- package/lib/packlets/resource-json/compiled/index.d.ts.map +1 -0
- package/lib/packlets/resource-json/compiled/index.js +65 -0
- package/lib/packlets/resource-json/compiled/index.js.map +1 -0
- package/lib/packlets/resource-json/compiled/json.d.ts +204 -0
- package/lib/packlets/resource-json/compiled/json.d.ts.map +1 -0
- package/lib/packlets/resource-json/compiled/json.js +3 -0
- package/lib/packlets/resource-json/compiled/json.js.map +1 -0
- package/lib/packlets/resource-json/convert.d.ts +16 -0
- package/lib/packlets/resource-json/convert.d.ts.map +1 -1
- package/lib/packlets/resource-json/convert.js +41 -6
- package/lib/packlets/resource-json/convert.js.map +1 -1
- package/lib/packlets/resource-json/helpers.d.ts +82 -3
- package/lib/packlets/resource-json/helpers.d.ts.map +1 -1
- package/lib/packlets/resource-json/helpers.js +185 -2
- package/lib/packlets/resource-json/helpers.js.map +1 -1
- package/lib/packlets/resource-json/index.d.ts +2 -1
- package/lib/packlets/resource-json/index.d.ts.map +1 -1
- package/lib/packlets/resource-json/index.js +3 -1
- package/lib/packlets/resource-json/index.js.map +1 -1
- package/lib/packlets/resource-json/json.d.ts +55 -3
- package/lib/packlets/resource-json/json.d.ts.map +1 -1
- package/lib/packlets/resource-json/json.js +16 -0
- package/lib/packlets/resource-json/json.js.map +1 -1
- package/lib/packlets/resource-json/normalized.d.ts +46 -3
- package/lib/packlets/resource-json/normalized.d.ts.map +1 -1
- package/lib/packlets/resource-json/normalized.js.map +1 -1
- package/lib/packlets/resource-json/resourceDeclCollection.d.ts +14 -10
- package/lib/packlets/resource-json/resourceDeclCollection.d.ts.map +1 -1
- package/lib/packlets/resource-json/resourceDeclCollection.js +18 -14
- package/lib/packlets/resource-json/resourceDeclCollection.js.map +1 -1
- package/lib/packlets/resource-json/resourceDeclContainer.d.ts +15 -2
- package/lib/packlets/resource-json/resourceDeclContainer.d.ts.map +1 -1
- package/lib/packlets/resource-json/resourceDeclContainer.js.map +1 -1
- package/lib/packlets/resource-json/resourceDeclTree.d.ts +6 -2
- package/lib/packlets/resource-json/resourceDeclTree.d.ts.map +1 -1
- package/lib/packlets/resource-json/resourceDeclTree.js +12 -3
- package/lib/packlets/resource-json/resourceDeclTree.js.map +1 -1
- package/lib/packlets/resource-types/config/convert.d.ts +8 -0
- package/lib/packlets/resource-types/config/convert.d.ts.map +1 -0
- package/lib/packlets/resource-types/config/convert.js +36 -0
- package/lib/packlets/resource-types/config/convert.js.map +1 -0
- package/lib/packlets/resource-types/config/index.d.ts +4 -0
- package/lib/packlets/resource-types/config/index.d.ts.map +1 -0
- package/lib/packlets/resource-types/config/index.js +64 -0
- package/lib/packlets/resource-types/config/index.js.map +1 -0
- package/lib/packlets/resource-types/config/json.d.ts +9 -0
- package/lib/packlets/resource-types/config/json.d.ts.map +1 -0
- package/lib/packlets/resource-types/config/json.js +24 -0
- package/lib/packlets/resource-types/config/json.js.map +1 -0
- package/lib/packlets/resource-types/helpers.d.ts +13 -0
- package/lib/packlets/resource-types/helpers.d.ts.map +1 -0
- package/lib/packlets/resource-types/helpers.js +44 -0
- package/lib/packlets/resource-types/helpers.js.map +1 -0
- package/lib/packlets/resource-types/index.d.ts +3 -0
- package/lib/packlets/resource-types/index.d.ts.map +1 -1
- package/lib/packlets/resource-types/index.js +26 -0
- package/lib/packlets/resource-types/index.js.map +1 -1
- package/lib/packlets/resource-types/jsonResourceType.d.ts +5 -13
- package/lib/packlets/resource-types/jsonResourceType.d.ts.map +1 -1
- package/lib/packlets/resource-types/jsonResourceType.js +5 -2
- package/lib/packlets/resource-types/jsonResourceType.js.map +1 -1
- package/lib/packlets/resource-types/resourceType.d.ts +31 -30
- package/lib/packlets/resource-types/resourceType.d.ts.map +1 -1
- package/lib/packlets/resource-types/resourceType.js.map +1 -1
- package/lib/packlets/resources/candidateReducer.d.ts +98 -0
- package/lib/packlets/resources/candidateReducer.d.ts.map +1 -0
- package/lib/packlets/resources/candidateReducer.js +247 -0
- package/lib/packlets/resources/candidateReducer.js.map +1 -0
- package/lib/packlets/resources/common.d.ts +60 -0
- package/lib/packlets/resources/common.d.ts.map +1 -0
- package/lib/packlets/resources/common.js +24 -0
- package/lib/packlets/resources/common.js.map +1 -0
- package/lib/packlets/resources/index.d.ts +3 -1
- package/lib/packlets/resources/index.d.ts.map +1 -1
- package/lib/packlets/resources/index.js +3 -1
- package/lib/packlets/resources/index.js.map +1 -1
- package/lib/packlets/resources/resource.d.ts +57 -5
- package/lib/packlets/resources/resource.d.ts.map +1 -1
- package/lib/packlets/resources/resource.js +96 -6
- package/lib/packlets/resources/resource.js.map +1 -1
- package/lib/packlets/resources/resourceBuilder.d.ts +14 -0
- package/lib/packlets/resources/resourceBuilder.d.ts.map +1 -1
- package/lib/packlets/resources/resourceBuilder.js +19 -1
- package/lib/packlets/resources/resourceBuilder.js.map +1 -1
- package/lib/packlets/resources/resourceCandidate.d.ts +42 -6
- package/lib/packlets/resources/resourceCandidate.d.ts.map +1 -1
- package/lib/packlets/resources/resourceCandidate.js +40 -1
- package/lib/packlets/resources/resourceCandidate.js.map +1 -1
- package/lib/packlets/resources/resourceManagerBuilder.d.ts +220 -0
- package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +1 -0
- package/lib/packlets/resources/resourceManagerBuilder.js +451 -0
- package/lib/packlets/resources/resourceManagerBuilder.js.map +1 -0
- package/lib/packlets/runtime/cacheListener.d.ts +62 -0
- package/lib/packlets/runtime/cacheListener.d.ts.map +1 -0
- package/lib/packlets/runtime/cacheListener.js +56 -0
- package/lib/packlets/runtime/cacheListener.js.map +1 -0
- package/lib/packlets/runtime/cacheMetrics.d.ts +82 -0
- package/lib/packlets/runtime/cacheMetrics.d.ts.map +1 -0
- package/lib/packlets/runtime/cacheMetrics.js +143 -0
- package/lib/packlets/runtime/cacheMetrics.js.map +1 -0
- package/lib/packlets/runtime/compiledResourceCollection.d.ts +167 -0
- package/lib/packlets/runtime/compiledResourceCollection.d.ts.map +1 -0
- package/lib/packlets/runtime/compiledResourceCollection.js +466 -0
- package/lib/packlets/runtime/compiledResourceCollection.js.map +1 -0
- package/lib/packlets/runtime/conditionSetResolutionResult.d.ts +70 -0
- package/lib/packlets/runtime/conditionSetResolutionResult.d.ts.map +1 -0
- package/lib/packlets/runtime/conditionSetResolutionResult.js +135 -0
- package/lib/packlets/runtime/conditionSetResolutionResult.js.map +1 -0
- package/lib/packlets/runtime/context/contextQualifierProvider.d.ts +80 -0
- package/lib/packlets/runtime/context/contextQualifierProvider.d.ts.map +1 -0
- package/lib/packlets/runtime/context/contextQualifierProvider.js +33 -0
- package/lib/packlets/runtime/context/contextQualifierProvider.js.map +1 -0
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.d.ts +165 -0
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.d.ts.map +1 -0
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.js +179 -0
- package/lib/packlets/runtime/context/contextQualifierProviderValidator.js.map +1 -0
- package/lib/packlets/runtime/context/index.d.ts +5 -0
- package/lib/packlets/runtime/context/index.d.ts.map +1 -0
- package/lib/packlets/runtime/context/index.js +42 -0
- package/lib/packlets/runtime/context/index.js.map +1 -0
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts +111 -0
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts.map +1 -0
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.js +177 -0
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.js.map +1 -0
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts +47 -0
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts.map +1 -0
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +64 -0
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +1 -0
- package/lib/packlets/runtime/iResourceManager.d.ts +88 -0
- package/lib/packlets/runtime/iResourceManager.d.ts.map +1 -0
- package/lib/packlets/runtime/iResourceManager.js +24 -0
- package/lib/packlets/runtime/iResourceManager.js.map +1 -0
- package/lib/packlets/runtime/index.d.ts +12 -0
- package/lib/packlets/runtime/index.d.ts.map +1 -0
- package/lib/packlets/runtime/index.js +73 -0
- package/lib/packlets/runtime/index.js.map +1 -0
- package/lib/packlets/runtime/resource-tree/common.d.ts +91 -0
- package/lib/packlets/runtime/resource-tree/common.d.ts.map +1 -0
- package/lib/packlets/runtime/resource-tree/common.js +24 -0
- package/lib/packlets/runtime/resource-tree/common.js.map +1 -0
- package/lib/packlets/runtime/resource-tree/index.d.ts +5 -0
- package/lib/packlets/runtime/resource-tree/index.d.ts.map +1 -0
- package/lib/packlets/runtime/resource-tree/index.js +42 -0
- package/lib/packlets/runtime/resource-tree/index.js.map +1 -0
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.d.ts +141 -0
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.d.ts.map +1 -0
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.js +224 -0
- package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.js.map +1 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.d.ts +24 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.d.ts.map +1 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js +98 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js.map +1 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts +99 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts.map +1 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js +165 -0
- package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js.map +1 -0
- package/lib/packlets/runtime/resourceResolver.d.ts +196 -0
- package/lib/packlets/runtime/resourceResolver.d.ts.map +1 -0
- package/lib/packlets/runtime/resourceResolver.js +437 -0
- package/lib/packlets/runtime/resourceResolver.js.map +1 -0
- package/lib/packlets/runtime/validate.d.ts +13 -0
- package/lib/packlets/runtime/validate.d.ts.map +1 -0
- package/lib/packlets/runtime/validate.js +49 -0
- package/lib/packlets/runtime/validate.js.map +1 -0
- package/package.json +76 -75
- package/lib/packlets/resources/resourceManager.d.ts +0 -104
- package/lib/packlets/resources/resourceManager.d.ts.map +0 -1
- package/lib/packlets/resources/resourceManager.js +0 -201
- package/lib/packlets/resources/resourceManager.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,27 +1,548 @@
|
|
|
1
|
-
|
|
2
|
-
<h1>@fgv/ts-res</h1>
|
|
3
|
-
Multidimensional Resource Runtime for Typescript
|
|
4
|
-
</div>
|
|
1
|
+
# @fgv/ts-res
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@fgv/ts-res)
|
|
4
|
+
[](LICENSE)
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
A TypeScript library for multidimensional resource management with internationalization and localization support. `@fgv/ts-res` provides a sophisticated system for managing resources with complex conditional logic based on qualifiers like language, territory, and custom dimensions.
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Multidimensional Resource Management**: Organize resources by language, territory, and custom qualifiers
|
|
11
|
+
- **Conditional Resource Resolution**: Automatic selection of the most appropriate resource based on context
|
|
12
|
+
- **Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
13
|
+
- **Flexible Resource Formats**: Support for JSON resources with extensible resource types
|
|
14
|
+
- **Hierarchical Organization**: Tree-based and collection-based resource structures
|
|
15
|
+
- **File System Integration**: Import resources from file systems with automatic condition inference
|
|
16
|
+
- **Priority-Based Resolution**: Configurable priority levels for different qualifiers
|
|
17
|
+
- **Resource Merging**: Support for augmenting and replacing resources
|
|
18
|
+
- **BCP47 Language Support**: Built-in support for BCP47 language tags
|
|
19
|
+
- **Extensible Architecture**: Plugin-based system for custom qualifier types
|
|
11
20
|
|
|
12
21
|
## Installation
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
```sh
|
|
23
|
+
```bash
|
|
16
24
|
npm install @fgv/ts-res
|
|
17
25
|
```
|
|
18
26
|
|
|
19
|
-
##
|
|
20
|
-
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import * as TsRes from '@fgv/ts-res';
|
|
31
|
+
|
|
32
|
+
// 1. Set up qualifier types
|
|
33
|
+
const qualifierTypes = TsRes.QualifierTypes.QualifierTypeCollector.create({
|
|
34
|
+
qualifierTypes: [
|
|
35
|
+
TsRes.QualifierTypes.LanguageQualifierType.create().orThrow(),
|
|
36
|
+
TsRes.QualifierTypes.TerritoryQualifierType.create().orThrow()
|
|
37
|
+
]
|
|
38
|
+
}).orThrow();
|
|
39
|
+
|
|
40
|
+
// 2. Define qualifiers with priorities
|
|
41
|
+
const qualifiers = TsRes.Qualifiers.QualifierCollector.create({
|
|
42
|
+
qualifierTypes,
|
|
43
|
+
qualifiers: [
|
|
44
|
+
{ name: 'language', typeName: 'language', defaultPriority: 600 },
|
|
45
|
+
{ name: 'territory', typeName: 'territory', defaultPriority: 700 }
|
|
46
|
+
]
|
|
47
|
+
}).orThrow();
|
|
48
|
+
|
|
49
|
+
// 3. Set up resource types
|
|
50
|
+
const resourceTypes = TsRes.ResourceTypes.ResourceTypeCollector.create({
|
|
51
|
+
resourceTypes: [
|
|
52
|
+
TsRes.ResourceTypes.JsonResourceType.create().orThrow()
|
|
53
|
+
]
|
|
54
|
+
}).orThrow();
|
|
55
|
+
|
|
56
|
+
// 4. Create resource manager
|
|
57
|
+
const manager = TsRes.Resources.ResourceManager.create({
|
|
58
|
+
qualifiers,
|
|
59
|
+
resourceTypes
|
|
60
|
+
}).orThrow();
|
|
61
|
+
|
|
62
|
+
// 5. Add resources
|
|
63
|
+
const resources = [
|
|
64
|
+
{
|
|
65
|
+
id: 'greeting.message',
|
|
66
|
+
json: { message: 'Hello' },
|
|
67
|
+
conditions: { language: 'en' }
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'greeting.message',
|
|
71
|
+
json: { message: 'Bonjour' },
|
|
72
|
+
conditions: { language: 'fr' }
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'greeting.message',
|
|
76
|
+
json: { message: 'Hello from Canada' },
|
|
77
|
+
conditions: {
|
|
78
|
+
language: 'en-CA',
|
|
79
|
+
territory: 'CA'
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
resources.forEach(resource => {
|
|
85
|
+
manager.addLooseCandidate(resource).orThrow();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 6. Build and resolve resources
|
|
89
|
+
manager.build().orThrow();
|
|
90
|
+
|
|
91
|
+
const greetingResource = manager.getBuiltResource('greeting.message').orThrow();
|
|
92
|
+
const context = { language: 'en-CA', territory: 'CA' };
|
|
93
|
+
const candidates = greetingResource.getCandidatesForContext(context);
|
|
94
|
+
|
|
95
|
+
// Returns the most specific match: "Hello from Canada"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Core Concepts
|
|
99
|
+
|
|
100
|
+
### Qualifiers
|
|
101
|
+
|
|
102
|
+
Qualifiers are dimensions along which resources can vary. Common qualifiers include:
|
|
103
|
+
|
|
104
|
+
- **Language**: BCP47 language tags (e.g., 'en', 'fr', 'en-CA')
|
|
105
|
+
- **Territory**: Geographic regions (e.g., 'US', 'CA', 'FR')
|
|
106
|
+
- **Custom**: Application-specific dimensions (e.g., 'theme', 'userType')
|
|
107
|
+
|
|
108
|
+
### Conditions
|
|
109
|
+
|
|
110
|
+
Conditions determine when a resource candidate applies. They consist of qualifier-value pairs:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
{
|
|
114
|
+
language: 'en-CA',
|
|
115
|
+
territory: 'CA',
|
|
116
|
+
theme: 'dark'
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Resource Resolution
|
|
121
|
+
|
|
122
|
+
The library automatically selects the most appropriate resource based on:
|
|
123
|
+
|
|
124
|
+
1. **Specificity**: More specific conditions take precedence
|
|
125
|
+
2. **Priority**: Higher priority qualifiers are weighted more heavily
|
|
126
|
+
3. **Fallback**: Graceful degradation when exact matches aren't found
|
|
127
|
+
|
|
128
|
+
## Advanced Usage
|
|
129
|
+
|
|
130
|
+
### Resource Building with ResourceBuilder
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const builder = TsRes.Resources.ResourceBuilder.create({
|
|
134
|
+
qualifiers,
|
|
135
|
+
resourceTypes
|
|
136
|
+
}).orThrow();
|
|
137
|
+
|
|
138
|
+
const resource = builder
|
|
139
|
+
.withId('user.profile')
|
|
140
|
+
.withResourceTypeName('json')
|
|
141
|
+
.withCandidate({
|
|
142
|
+
json: { title: 'Profile', button: 'Edit' },
|
|
143
|
+
conditions: { language: 'en' }
|
|
144
|
+
})
|
|
145
|
+
.withCandidate({
|
|
146
|
+
json: { title: 'Profil', button: 'Modifier' },
|
|
147
|
+
conditions: { language: 'fr' }
|
|
148
|
+
})
|
|
149
|
+
.build()
|
|
150
|
+
.orThrow();
|
|
151
|
+
|
|
152
|
+
manager.addResource(resource).orThrow();
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### File System Integration
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Import resources from file system
|
|
159
|
+
const importManager = TsRes.Import.ImportManager.create({
|
|
160
|
+
filetree: fileTree,
|
|
161
|
+
resources: resourceManager,
|
|
162
|
+
importers: TsRes.Import.ImportManager.getDefaultImporters(),
|
|
163
|
+
initialContext: TsRes.Import.ImportContext.create().orThrow()
|
|
164
|
+
}).orThrow();
|
|
165
|
+
|
|
166
|
+
const importResult = importManager.importFromFileSystem({
|
|
167
|
+
type: 'path',
|
|
168
|
+
path: './resources'
|
|
169
|
+
}).orThrow();
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Resource Merging
|
|
173
|
+
|
|
174
|
+
Resources support different merge strategies:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
{
|
|
178
|
+
id: 'app.config',
|
|
179
|
+
json: { apiUrl: 'https://api.example.com' },
|
|
180
|
+
conditions: { environment: 'production' },
|
|
181
|
+
mergeMethod: 'replace' // or 'augment' (default)
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Custom Qualifier Types
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const customType = TsRes.QualifierTypes.LiteralQualifierType.create({
|
|
189
|
+
key: 'userType',
|
|
190
|
+
values: ['admin', 'user', 'guest'],
|
|
191
|
+
hierarchy: {
|
|
192
|
+
'admin': ['user', 'guest'],
|
|
193
|
+
'user': ['guest']
|
|
194
|
+
}
|
|
195
|
+
}).orThrow();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## API Reference
|
|
199
|
+
|
|
200
|
+
### Core Classes
|
|
201
|
+
|
|
202
|
+
- **ResourceManager**: Central orchestrator for resource operations
|
|
203
|
+
- **Resource**: Individual resource with candidates for different contexts
|
|
204
|
+
- **ResourceCandidate**: Specific resource variant with conditions
|
|
205
|
+
- **ResourceBuilder**: Builder pattern for constructing resources
|
|
206
|
+
- **QualifierCollector**: Manages qualifier definitions
|
|
207
|
+
- **ConditionSet**: Collection of conditions for resource matching
|
|
208
|
+
|
|
209
|
+
### Namespaces
|
|
210
|
+
|
|
211
|
+
- **Resources**: Core resource management classes
|
|
212
|
+
- **Qualifiers**: Qualifier definition and management
|
|
213
|
+
- **Conditions**: Condition and condition set management
|
|
214
|
+
- **QualifierTypes**: Built-in and custom qualifier type definitions
|
|
215
|
+
- **Context**: Context definition for resource resolution
|
|
216
|
+
- **Import**: File system and external resource import utilities
|
|
217
|
+
- **ResourceJson**: JSON serialization and deserialization
|
|
218
|
+
|
|
219
|
+
## Context Filtering and Qualifier Reduction
|
|
220
|
+
|
|
221
|
+
One feature of ts-res is its ability to create filtered, context-specific resource bundles with reduced qualifiers. This is particularly useful for operational scenarios like feature flag management across different environments.
|
|
222
|
+
|
|
223
|
+
### The Problem: Noisy Environment-Specific Bundles
|
|
224
|
+
|
|
225
|
+
Consider a feature flag system with different settings across environments:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Feature flags with environment-specific settings
|
|
229
|
+
const featureFlags = [
|
|
230
|
+
{
|
|
231
|
+
id: 'features.newDashboard',
|
|
232
|
+
json: { enabled: false, rolloutPercent: 0 },
|
|
233
|
+
conditions: { environment: 'production' }
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'features.newDashboard',
|
|
237
|
+
json: { enabled: true, rolloutPercent: 50 },
|
|
238
|
+
conditions: { environment: 'integration' }
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'features.newDashboard',
|
|
242
|
+
json: { enabled: true, rolloutPercent: 100 },
|
|
243
|
+
conditions: { environment: 'development' }
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: 'features.betaAPI',
|
|
247
|
+
json: { enabled: false, version: 'v1' },
|
|
248
|
+
conditions: { environment: 'production' }
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
id: 'features.betaAPI',
|
|
252
|
+
json: { enabled: true, version: 'v2' },
|
|
253
|
+
conditions: { environment: 'integration' }
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: 'features.betaAPI',
|
|
257
|
+
json: { enabled: true, version: 'v2-beta' },
|
|
258
|
+
conditions: { environment: 'development' }
|
|
259
|
+
}
|
|
260
|
+
];
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Step 1: No Filtering (Complete Bundle)
|
|
264
|
+
|
|
265
|
+
Without filtering, your complete bundle contains all environments:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const completeBundle = resourceManager.getResourceCollectionDecl().orThrow();
|
|
269
|
+
|
|
270
|
+
// Result: All candidates with all environment conditions
|
|
271
|
+
{
|
|
272
|
+
"resources": [
|
|
273
|
+
{
|
|
274
|
+
"id": "features.newDashboard",
|
|
275
|
+
"candidates": [
|
|
276
|
+
{
|
|
277
|
+
"json": { "enabled": false, "rolloutPercent": 0 },
|
|
278
|
+
"conditions": { "environment": "production" }
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"json": { "enabled": true, "rolloutPercent": 50 },
|
|
282
|
+
"conditions": { "environment": "integration" }
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"json": { "enabled": true, "rolloutPercent": 100 },
|
|
286
|
+
"conditions": { "environment": "development" }
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
},
|
|
290
|
+
// ... more resources with similar environment conditions
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Problem**: Bundle contains all environments, making it difficult to compare environment-specific configurations.
|
|
296
|
+
|
|
297
|
+
### Step 2: Context Filtering Only
|
|
298
|
+
|
|
299
|
+
Filter for a specific environment (e.g., production):
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
const productionContext = resourceManager.validateContext({
|
|
303
|
+
environment: 'production'
|
|
304
|
+
}).orThrow();
|
|
305
|
+
|
|
306
|
+
const filteredBundle = resourceManager.getResourceCollectionDecl({
|
|
307
|
+
filterForContext: productionContext
|
|
308
|
+
// reduceQualifiers: false (default)
|
|
309
|
+
}).orThrow();
|
|
310
|
+
|
|
311
|
+
// Result: Only production candidates, but environment conditions remain
|
|
312
|
+
{
|
|
313
|
+
"resources": [
|
|
314
|
+
{
|
|
315
|
+
"id": "features.newDashboard",
|
|
316
|
+
"candidates": [
|
|
317
|
+
{
|
|
318
|
+
"json": { "enabled": false, "rolloutPercent": 0 },
|
|
319
|
+
"conditions": { "environment": "production" } // Environment condition still present
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "features.betaAPI",
|
|
325
|
+
"candidates": [
|
|
326
|
+
{
|
|
327
|
+
"json": { "enabled": false, "version": "v1" },
|
|
328
|
+
"conditions": { "environment": "production" } // Environment condition still present
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Improvement**: Bundle size reduced, but environment conditions add noise when comparing between environments.
|
|
337
|
+
|
|
338
|
+
### Step 3: Context Filtering + Qualifier Reduction
|
|
339
|
+
|
|
340
|
+
Filter for production AND reduce redundant qualifiers:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
const cleanProductionBundle = resourceManager.getResourceCollectionDecl({
|
|
344
|
+
filterForContext: productionContext,
|
|
345
|
+
reduceQualifiers: true // Enable qualifier reduction
|
|
346
|
+
}).orThrow();
|
|
347
|
+
|
|
348
|
+
// Result: Clean production bundle with environment conditions removed
|
|
349
|
+
{
|
|
350
|
+
"resources": [
|
|
351
|
+
{
|
|
352
|
+
"id": "features.newDashboard",
|
|
353
|
+
"candidates": [
|
|
354
|
+
{
|
|
355
|
+
"json": { "enabled": false, "rolloutPercent": 0 }
|
|
356
|
+
// conditions: {} - Environment condition removed!
|
|
357
|
+
}
|
|
358
|
+
]
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"id": "features.betaAPI",
|
|
362
|
+
"candidates": [
|
|
363
|
+
{
|
|
364
|
+
"json": { "enabled": false, "version": "v1" }
|
|
365
|
+
// conditions: {} - Environment condition removed!
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Benefits**:
|
|
374
|
+
- **Clean bundles**: No irrelevant environment conditions
|
|
375
|
+
- **Easy comparison**: Compare bundles between environments to see actual differences
|
|
376
|
+
- **Reduced noise**: Focus on configuration values, not deployment context
|
|
377
|
+
|
|
378
|
+
### Easy Environment Comparison
|
|
379
|
+
|
|
380
|
+
Now you can easily compare configuration differences between environments:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// Get clean bundles for each environment
|
|
384
|
+
const [prodBundle, devBundle] = await Promise.all([
|
|
385
|
+
getCleanBundle('production'),
|
|
386
|
+
getCleanBundle('development')
|
|
387
|
+
]);
|
|
388
|
+
|
|
389
|
+
// Compare actual differences without environment noise
|
|
390
|
+
function compareFeatureFlags(prod, dev) {
|
|
391
|
+
prod.resources.forEach(prodResource => {
|
|
392
|
+
const devResource = dev.resources.find(r => r.id === prodResource.id);
|
|
393
|
+
const prodConfig = prodResource.candidates[0].json;
|
|
394
|
+
const devConfig = devResource.candidates[0].json;
|
|
395
|
+
|
|
396
|
+
if (JSON.stringify(prodConfig) !== JSON.stringify(devConfig)) {
|
|
397
|
+
console.log(`${prodResource.id} differs:`, {
|
|
398
|
+
production: prodConfig,
|
|
399
|
+
development: devConfig
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Output:
|
|
406
|
+
// features.newDashboard differs: {
|
|
407
|
+
// production: { enabled: false, rolloutPercent: 0 },
|
|
408
|
+
// development: { enabled: true, rolloutPercent: 100 }
|
|
409
|
+
// }
|
|
410
|
+
// features.betaAPI differs: {
|
|
411
|
+
// production: { enabled: false, version: 'v1' },
|
|
412
|
+
// development: { enabled: true, version: 'v2-beta' }
|
|
413
|
+
// }
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Advanced: Multi-Qualifier Scenarios
|
|
417
|
+
|
|
418
|
+
Qualifier reduction is intelligent - it only removes qualifiers that match perfectly across ALL filtered candidates:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
// Resource with environment + language conditions
|
|
422
|
+
const multiQualifierResource = {
|
|
423
|
+
id: 'features.localized',
|
|
424
|
+
candidates: [
|
|
425
|
+
{
|
|
426
|
+
json: { enabled: true, locale: 'en-US' },
|
|
427
|
+
conditions: { environment: 'production', language: 'en', territory: 'US' }
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
json: { enabled: true, locale: 'en-GB' },
|
|
431
|
+
conditions: { environment: 'production', language: 'en', territory: 'GB' }
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
json: { enabled: true, locale: 'fr-FR' },
|
|
435
|
+
conditions: { environment: 'production', language: 'fr', territory: 'FR' }
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
// Filter by environment only
|
|
441
|
+
const result = resource.toLooseResourceDecl({
|
|
442
|
+
filterForContext: { environment: 'production' },
|
|
443
|
+
reduceQualifiers: true
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Result: Environment reduced (all match 'production'), language/territory preserved (they differ)
|
|
447
|
+
{
|
|
448
|
+
"candidates": [
|
|
449
|
+
{
|
|
450
|
+
"json": { "enabled": true, "locale": "en-US" },
|
|
451
|
+
"conditions": { "language": "en", "territory": "US" } // environment removed, others preserved
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"json": { "enabled": true, "locale": "en-GB" },
|
|
455
|
+
"conditions": { "language": "en", "territory": "GB" } // environment removed, others preserved
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"json": { "enabled": true, "locale": "fr-FR" },
|
|
459
|
+
"conditions": { "language": "fr", "territory": "FR" } // environment removed, others preserved
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Use Cases
|
|
466
|
+
|
|
467
|
+
**Feature Flag Management**: Clean environment-specific bundles for operational analysis
|
|
468
|
+
**Configuration Deployment**: Environment-specific configs without deployment noise
|
|
469
|
+
**A/B Testing**: Clean experiment configurations for specific user segments
|
|
470
|
+
**Internationalization**: Language-specific bundles without region clutter
|
|
471
|
+
**Multi-tenant Applications**: Tenant-specific configurations without organizational context
|
|
472
|
+
|
|
473
|
+
## Common Patterns
|
|
474
|
+
|
|
475
|
+
### Web Application Localization
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
// Set up for multi-language, multi-region application
|
|
479
|
+
const qualifiers = [
|
|
480
|
+
{ name: 'language', typeName: 'language', defaultPriority: 600 },
|
|
481
|
+
{ name: 'homeTerritory', typeName: 'territory', defaultPriority: 700 },
|
|
482
|
+
{ name: 'currentTerritory', typeName: 'territory', defaultPriority: 800 }
|
|
483
|
+
];
|
|
484
|
+
|
|
485
|
+
// Resources with fallback chains
|
|
486
|
+
const resources = [
|
|
487
|
+
// Default English
|
|
488
|
+
{ id: 'app.title', json: { title: 'My App' }, conditions: { language: 'en' } },
|
|
489
|
+
// Canadian English variant
|
|
490
|
+
{ id: 'app.title', json: { title: 'My App, eh!' }, conditions: { language: 'en-CA' } },
|
|
491
|
+
// French
|
|
492
|
+
{ id: 'app.title', json: { title: 'Mon App' }, conditions: { language: 'fr' } }
|
|
493
|
+
];
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Configuration Management
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
// Environment-specific configurations
|
|
500
|
+
const configs = [
|
|
501
|
+
{ id: 'api.config', json: { url: 'localhost:3000' }, conditions: { env: 'development' } },
|
|
502
|
+
{ id: 'api.config', json: { url: 'api.staging.com' }, conditions: { env: 'staging' } },
|
|
503
|
+
{ id: 'api.config', json: { url: 'api.production.com' }, conditions: { env: 'production' } }
|
|
504
|
+
];
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Dependencies
|
|
508
|
+
|
|
509
|
+
- **@fgv/ts-utils**: Core utilities and Result pattern
|
|
510
|
+
- **@fgv/ts-extras**: Additional utility functions
|
|
511
|
+
- **@fgv/ts-json-base**: JSON validation and processing
|
|
512
|
+
- **@fgv/ts-bcp47**: BCP47 language tag processing
|
|
513
|
+
- **@fgv/ts-json**: JSON schema validation
|
|
514
|
+
- **luxon**: Date/time handling
|
|
515
|
+
|
|
516
|
+
## Development
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Install dependencies
|
|
520
|
+
npm install
|
|
521
|
+
|
|
522
|
+
# Build the project
|
|
523
|
+
npm run build
|
|
524
|
+
|
|
525
|
+
# Run tests
|
|
526
|
+
npm run test
|
|
527
|
+
|
|
528
|
+
# Run tests with coverage
|
|
529
|
+
npm run coverage
|
|
530
|
+
|
|
531
|
+
# Lint code
|
|
532
|
+
npm run lint
|
|
533
|
+
|
|
534
|
+
# Generate documentation
|
|
535
|
+
npm run build-docs
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## License
|
|
539
|
+
|
|
540
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
21
541
|
|
|
22
|
-
##
|
|
542
|
+
## Contributing
|
|
23
543
|
|
|
544
|
+
Contributions are welcome! Please read the contributing guidelines and submit pull requests to the [main repository](https://github.com/ErikFortune/fgv).
|
|
24
545
|
|
|
25
|
-
|
|
26
|
-
*Note:* This library uses the `Result` pattern, so the return value from any method that might fail is a `Result` object that must be tested for success or failure. These examples use either [orThrow](https://github.com/ErikFortune/fgv/blob/main/libraries/ts-utils/docs/ts-utils.iresult.orthrow.md) or [orDefault](https://github.com/ErikFortune/fgv/blob/main/libraries/ts-utils/docs/ts-utils.iresult.ordefault.md) to convert an error result to either an exception or undefined.
|
|
546
|
+
## Support
|
|
27
547
|
|
|
548
|
+
For questions, issues, or feature requests, please visit the [GitHub issues page](https://github.com/ErikFortune/fgv/issues).
|