@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.
Files changed (362) hide show
  1. package/README.md +794 -137
  2. package/dist/ts-res.d.ts +2344 -187
  3. package/dist/tsdoc-metadata.json +1 -1
  4. package/eslint.config.js +16 -0
  5. package/lib/index.d.ts +11 -2
  6. package/lib/index.js +25 -2
  7. package/lib/packlets/bundle/bundleBuilder.d.ts +41 -0
  8. package/lib/packlets/bundle/bundleBuilder.js +134 -0
  9. package/lib/packlets/bundle/bundleLoader.d.ts +72 -0
  10. package/lib/packlets/bundle/bundleLoader.js +105 -0
  11. package/lib/packlets/bundle/bundleNormalizer.d.ts +73 -0
  12. package/lib/packlets/bundle/bundleNormalizer.js +142 -0
  13. package/lib/packlets/bundle/bundleUtils.d.ts +70 -0
  14. package/lib/packlets/bundle/bundleUtils.js +117 -0
  15. package/lib/packlets/bundle/convert.d.ts +33 -0
  16. package/lib/packlets/bundle/convert.js +78 -0
  17. package/lib/packlets/bundle/index.d.ts +21 -0
  18. package/lib/packlets/bundle/index.js +83 -0
  19. package/lib/packlets/bundle/model.d.ts +100 -0
  20. package/lib/packlets/bundle/model.js +24 -0
  21. package/lib/packlets/common/convert.d.ts +10 -0
  22. package/lib/packlets/common/convert.js +11 -1
  23. package/lib/packlets/common/helpers/resources.d.ts +7 -0
  24. package/lib/packlets/common/helpers/resources.js +12 -0
  25. package/lib/packlets/common/resources.d.ts +48 -1
  26. package/lib/packlets/common/validate/regularExpressions.d.ts +4 -0
  27. package/lib/packlets/common/validate/regularExpressions.js +5 -1
  28. package/lib/packlets/common/validate/resources.d.ts +35 -1
  29. package/lib/packlets/common/validate/resources.js +54 -0
  30. package/lib/packlets/conditions/conditionSet.d.ts +9 -0
  31. package/lib/packlets/conditions/conditionSet.js +74 -1
  32. package/lib/packlets/config/configInitFactory.d.ts +217 -0
  33. package/lib/packlets/config/configInitFactory.js +302 -0
  34. package/lib/packlets/config/convert.d.ts +9 -0
  35. package/lib/packlets/config/convert.js +12 -1
  36. package/lib/packlets/config/index.d.ts +1 -0
  37. package/lib/packlets/config/index.js +1 -0
  38. package/lib/packlets/config/json.d.ts +1 -1
  39. package/lib/packlets/config/systemConfiguration.d.ts +16 -3
  40. package/lib/packlets/config/systemConfiguration.js +19 -40
  41. package/lib/packlets/import/fsItem.js +8 -13
  42. package/lib/packlets/import/importers/jsonImporter.js +1 -0
  43. package/lib/packlets/qualifier-types/config/convert.d.ts +22 -1
  44. package/lib/packlets/qualifier-types/config/convert.js +67 -2
  45. package/lib/packlets/qualifier-types/config/json.d.ts +24 -2
  46. package/lib/packlets/qualifier-types/config/json.js +11 -0
  47. package/lib/packlets/qualifier-types/convert.d.ts +1 -1
  48. package/lib/packlets/qualifier-types/helpers.d.ts +14 -5
  49. package/lib/packlets/qualifier-types/helpers.js +2 -2
  50. package/lib/packlets/qualifier-types/languageQualifierType.d.ts +28 -2
  51. package/lib/packlets/qualifier-types/languageQualifierType.js +73 -0
  52. package/lib/packlets/qualifier-types/literalQualifierType.d.ts +31 -5
  53. package/lib/packlets/qualifier-types/literalQualifierType.js +75 -0
  54. package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts +7 -11
  55. package/lib/packlets/qualifier-types/literalValueHierarchy.js +11 -1
  56. package/lib/packlets/qualifier-types/qualifierType.d.ts +31 -2
  57. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +31 -5
  58. package/lib/packlets/qualifier-types/territoryQualifierType.js +77 -0
  59. package/lib/packlets/qualifiers/qualifierCollector.js +1 -2
  60. package/lib/packlets/resource-json/compiled/convert.js +2 -1
  61. package/lib/packlets/resource-json/compiled/json.d.ts +6 -2
  62. package/lib/packlets/resource-types/config/convert.d.ts +1 -1
  63. package/lib/packlets/resource-types/config/convert.js +3 -1
  64. package/lib/packlets/resource-types/config/json.d.ts +3 -1
  65. package/lib/packlets/resource-types/jsonResourceType.d.ts +14 -5
  66. package/lib/packlets/resource-types/jsonResourceType.js +8 -4
  67. package/lib/packlets/resource-types/resourceType.d.ts +115 -14
  68. package/lib/packlets/resource-types/resourceType.js +39 -3
  69. package/lib/packlets/resources/candidateValue.d.ts +92 -0
  70. package/lib/packlets/resources/candidateValue.js +128 -0
  71. package/lib/packlets/resources/candidateValueCollector.d.ts +55 -0
  72. package/lib/packlets/resources/candidateValueCollector.js +96 -0
  73. package/lib/packlets/resources/common.d.ts +26 -0
  74. package/lib/packlets/resources/index.d.ts +2 -0
  75. package/lib/packlets/resources/index.js +2 -0
  76. package/lib/packlets/resources/resource.d.ts +6 -6
  77. package/lib/packlets/resources/resource.js +5 -10
  78. package/lib/packlets/resources/resourceBuilder.d.ts +6 -0
  79. package/lib/packlets/resources/resourceBuilder.js +3 -1
  80. package/lib/packlets/resources/resourceCandidate.d.ts +15 -2
  81. package/lib/packlets/resources/resourceCandidate.js +17 -5
  82. package/lib/packlets/resources/resourceManagerBuilder.d.ts +189 -11
  83. package/lib/packlets/resources/resourceManagerBuilder.js +478 -17
  84. package/lib/packlets/runtime/cacheListener.d.ts +9 -0
  85. package/lib/packlets/runtime/cacheListener.js +6 -0
  86. package/lib/packlets/runtime/cacheMetrics.d.ts +6 -0
  87. package/lib/packlets/runtime/cacheMetrics.js +11 -0
  88. package/lib/packlets/runtime/compiledResourceCollection.d.ts +23 -11
  89. package/lib/packlets/runtime/compiledResourceCollection.js +32 -4
  90. package/lib/packlets/runtime/iResourceManager.d.ts +13 -5
  91. package/lib/packlets/runtime/index.d.ts +1 -0
  92. package/lib/packlets/runtime/index.js +1 -0
  93. package/lib/packlets/runtime/resource-tree/common.d.ts +1 -1
  94. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts +7 -7
  95. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js +5 -5
  96. package/lib/packlets/runtime/resourceResolver.d.ts +60 -1
  97. package/lib/packlets/runtime/resourceResolver.js +84 -45
  98. package/lib/packlets/runtime/resourceTreeResolver.d.ts +152 -0
  99. package/lib/packlets/runtime/resourceTreeResolver.js +222 -0
  100. package/lib/packlets/runtime/validate.js +1 -0
  101. package/lib/packlets/zip-archive/convert.d.ts +52 -0
  102. package/lib/packlets/zip-archive/convert.js +103 -0
  103. package/lib/packlets/zip-archive/index.d.ts +23 -0
  104. package/lib/packlets/zip-archive/index.js +95 -0
  105. package/lib/packlets/zip-archive/json.d.ts +64 -0
  106. package/lib/packlets/zip-archive/json.js +24 -0
  107. package/lib/packlets/zip-archive/types.d.ts +98 -0
  108. package/lib/packlets/zip-archive/types.js +39 -0
  109. package/lib/packlets/zip-archive/zipArchiveCreator.d.ts +35 -0
  110. package/lib/packlets/zip-archive/zipArchiveCreator.js +194 -0
  111. package/lib/packlets/zip-archive/zipArchiveFormat.d.ts +70 -0
  112. package/lib/packlets/zip-archive/zipArchiveFormat.js +184 -0
  113. package/lib/packlets/zip-archive/zipArchiveLoader.d.ts +70 -0
  114. package/lib/packlets/zip-archive/zipArchiveLoader.js +285 -0
  115. package/package.json +26 -32
  116. package/CLAUDE.md +0 -186
  117. package/EXAMPLE_INIT_PARAMS.md +0 -88
  118. package/PROGRESS_SUMMARY.md +0 -48
  119. package/lib/index.d.ts.map +0 -1
  120. package/lib/index.js.map +0 -1
  121. package/lib/packlets/common/conditions.d.ts.map +0 -1
  122. package/lib/packlets/common/conditions.js.map +0 -1
  123. package/lib/packlets/common/convert.d.ts.map +0 -1
  124. package/lib/packlets/common/convert.js.map +0 -1
  125. package/lib/packlets/common/helpers/conditions.d.ts.map +0 -1
  126. package/lib/packlets/common/helpers/conditions.js.map +0 -1
  127. package/lib/packlets/common/helpers/context.d.ts.map +0 -1
  128. package/lib/packlets/common/helpers/context.js.map +0 -1
  129. package/lib/packlets/common/helpers/index.d.ts.map +0 -1
  130. package/lib/packlets/common/helpers/index.js.map +0 -1
  131. package/lib/packlets/common/helpers/qualifierDefaultValues.d.ts.map +0 -1
  132. package/lib/packlets/common/helpers/qualifierDefaultValues.js.map +0 -1
  133. package/lib/packlets/common/helpers/resources.d.ts.map +0 -1
  134. package/lib/packlets/common/helpers/resources.js.map +0 -1
  135. package/lib/packlets/common/index.d.ts.map +0 -1
  136. package/lib/packlets/common/index.js.map +0 -1
  137. package/lib/packlets/common/resources.d.ts.map +0 -1
  138. package/lib/packlets/common/resources.js.map +0 -1
  139. package/lib/packlets/common/validate/conditions.d.ts.map +0 -1
  140. package/lib/packlets/common/validate/conditions.js.map +0 -1
  141. package/lib/packlets/common/validate/index.d.ts.map +0 -1
  142. package/lib/packlets/common/validate/index.js.map +0 -1
  143. package/lib/packlets/common/validate/regularExpressions.d.ts.map +0 -1
  144. package/lib/packlets/common/validate/regularExpressions.js.map +0 -1
  145. package/lib/packlets/common/validate/resources.d.ts.map +0 -1
  146. package/lib/packlets/common/validate/resources.js.map +0 -1
  147. package/lib/packlets/conditions/condition.d.ts.map +0 -1
  148. package/lib/packlets/conditions/condition.js.map +0 -1
  149. package/lib/packlets/conditions/conditionCollector.d.ts.map +0 -1
  150. package/lib/packlets/conditions/conditionCollector.js.map +0 -1
  151. package/lib/packlets/conditions/conditionDecls.d.ts.map +0 -1
  152. package/lib/packlets/conditions/conditionDecls.js.map +0 -1
  153. package/lib/packlets/conditions/conditionSet.d.ts.map +0 -1
  154. package/lib/packlets/conditions/conditionSet.js.map +0 -1
  155. package/lib/packlets/conditions/conditionSetCollector.d.ts.map +0 -1
  156. package/lib/packlets/conditions/conditionSetCollector.js.map +0 -1
  157. package/lib/packlets/conditions/conditionSetDecls.d.ts.map +0 -1
  158. package/lib/packlets/conditions/conditionSetDecls.js.map +0 -1
  159. package/lib/packlets/conditions/conditionToken.d.ts.map +0 -1
  160. package/lib/packlets/conditions/conditionToken.js.map +0 -1
  161. package/lib/packlets/conditions/convert/conditionSetDecls.d.ts.map +0 -1
  162. package/lib/packlets/conditions/convert/conditionSetDecls.js.map +0 -1
  163. package/lib/packlets/conditions/convert/decls.d.ts.map +0 -1
  164. package/lib/packlets/conditions/convert/decls.js.map +0 -1
  165. package/lib/packlets/conditions/convert/index.d.ts.map +0 -1
  166. package/lib/packlets/conditions/convert/index.js.map +0 -1
  167. package/lib/packlets/conditions/index.d.ts.map +0 -1
  168. package/lib/packlets/conditions/index.js.map +0 -1
  169. package/lib/packlets/config/common.d.ts.map +0 -1
  170. package/lib/packlets/config/common.js.map +0 -1
  171. package/lib/packlets/config/convert.d.ts.map +0 -1
  172. package/lib/packlets/config/convert.js.map +0 -1
  173. package/lib/packlets/config/index.d.ts.map +0 -1
  174. package/lib/packlets/config/index.js.map +0 -1
  175. package/lib/packlets/config/json.d.ts.map +0 -1
  176. package/lib/packlets/config/json.js.map +0 -1
  177. package/lib/packlets/config/predefined/default.d.ts.map +0 -1
  178. package/lib/packlets/config/predefined/default.js.map +0 -1
  179. package/lib/packlets/config/predefined/extended.d.ts.map +0 -1
  180. package/lib/packlets/config/predefined/extended.js.map +0 -1
  181. package/lib/packlets/config/predefined/index.d.ts.map +0 -1
  182. package/lib/packlets/config/predefined/index.js.map +0 -1
  183. package/lib/packlets/config/systemConfiguration.d.ts.map +0 -1
  184. package/lib/packlets/config/systemConfiguration.js.map +0 -1
  185. package/lib/packlets/context/contextDecls.d.ts.map +0 -1
  186. package/lib/packlets/context/contextDecls.js.map +0 -1
  187. package/lib/packlets/context/contextToken.d.ts.map +0 -1
  188. package/lib/packlets/context/contextToken.js.map +0 -1
  189. package/lib/packlets/context/convert/decls.d.ts.map +0 -1
  190. package/lib/packlets/context/convert/decls.js.map +0 -1
  191. package/lib/packlets/context/convert/index.d.ts.map +0 -1
  192. package/lib/packlets/context/convert/index.js.map +0 -1
  193. package/lib/packlets/context/index.d.ts.map +0 -1
  194. package/lib/packlets/context/index.js.map +0 -1
  195. package/lib/packlets/decisions/abstractDecision.d.ts.map +0 -1
  196. package/lib/packlets/decisions/abstractDecision.js.map +0 -1
  197. package/lib/packlets/decisions/abstractDecisionCollector.d.ts.map +0 -1
  198. package/lib/packlets/decisions/abstractDecisionCollector.js.map +0 -1
  199. package/lib/packlets/decisions/candidate.d.ts.map +0 -1
  200. package/lib/packlets/decisions/candidate.js.map +0 -1
  201. package/lib/packlets/decisions/common.d.ts.map +0 -1
  202. package/lib/packlets/decisions/common.js.map +0 -1
  203. package/lib/packlets/decisions/concreteDecision.d.ts.map +0 -1
  204. package/lib/packlets/decisions/concreteDecision.js.map +0 -1
  205. package/lib/packlets/decisions/decision.d.ts.map +0 -1
  206. package/lib/packlets/decisions/decision.js.map +0 -1
  207. package/lib/packlets/decisions/index.d.ts.map +0 -1
  208. package/lib/packlets/decisions/index.js.map +0 -1
  209. package/lib/packlets/import/fsItem.d.ts.map +0 -1
  210. package/lib/packlets/import/fsItem.js.map +0 -1
  211. package/lib/packlets/import/importContext.d.ts.map +0 -1
  212. package/lib/packlets/import/importContext.js.map +0 -1
  213. package/lib/packlets/import/importManager.d.ts.map +0 -1
  214. package/lib/packlets/import/importManager.js.map +0 -1
  215. package/lib/packlets/import/importable.d.ts.map +0 -1
  216. package/lib/packlets/import/importable.js.map +0 -1
  217. package/lib/packlets/import/importers/collectionImporter.d.ts.map +0 -1
  218. package/lib/packlets/import/importers/collectionImporter.js.map +0 -1
  219. package/lib/packlets/import/importers/fsItemImporter.d.ts.map +0 -1
  220. package/lib/packlets/import/importers/fsItemImporter.js.map +0 -1
  221. package/lib/packlets/import/importers/importer.d.ts.map +0 -1
  222. package/lib/packlets/import/importers/importer.js.map +0 -1
  223. package/lib/packlets/import/importers/index.d.ts.map +0 -1
  224. package/lib/packlets/import/importers/index.js.map +0 -1
  225. package/lib/packlets/import/importers/jsonImporter.d.ts.map +0 -1
  226. package/lib/packlets/import/importers/jsonImporter.js.map +0 -1
  227. package/lib/packlets/import/importers/pathImporter.d.ts.map +0 -1
  228. package/lib/packlets/import/importers/pathImporter.js.map +0 -1
  229. package/lib/packlets/import/index.d.ts.map +0 -1
  230. package/lib/packlets/import/index.js.map +0 -1
  231. package/lib/packlets/qualifier-types/config/convert.d.ts.map +0 -1
  232. package/lib/packlets/qualifier-types/config/convert.js.map +0 -1
  233. package/lib/packlets/qualifier-types/config/index.d.ts.map +0 -1
  234. package/lib/packlets/qualifier-types/config/index.js.map +0 -1
  235. package/lib/packlets/qualifier-types/config/json.d.ts.map +0 -1
  236. package/lib/packlets/qualifier-types/config/json.js.map +0 -1
  237. package/lib/packlets/qualifier-types/convert.d.ts.map +0 -1
  238. package/lib/packlets/qualifier-types/convert.js.map +0 -1
  239. package/lib/packlets/qualifier-types/helpers.d.ts.map +0 -1
  240. package/lib/packlets/qualifier-types/helpers.js.map +0 -1
  241. package/lib/packlets/qualifier-types/index.d.ts.map +0 -1
  242. package/lib/packlets/qualifier-types/index.js.map +0 -1
  243. package/lib/packlets/qualifier-types/languageQualifierType.d.ts.map +0 -1
  244. package/lib/packlets/qualifier-types/languageQualifierType.js.map +0 -1
  245. package/lib/packlets/qualifier-types/literalQualifierType.d.ts.map +0 -1
  246. package/lib/packlets/qualifier-types/literalQualifierType.js.map +0 -1
  247. package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts.map +0 -1
  248. package/lib/packlets/qualifier-types/literalValueHierarchy.js.map +0 -1
  249. package/lib/packlets/qualifier-types/qualifierType.d.ts.map +0 -1
  250. package/lib/packlets/qualifier-types/qualifierType.js.map +0 -1
  251. package/lib/packlets/qualifier-types/qualifierTypeCollector.d.ts.map +0 -1
  252. package/lib/packlets/qualifier-types/qualifierTypeCollector.js.map +0 -1
  253. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts.map +0 -1
  254. package/lib/packlets/qualifier-types/territoryQualifierType.js.map +0 -1
  255. package/lib/packlets/qualifiers/convert/decls.d.ts.map +0 -1
  256. package/lib/packlets/qualifiers/convert/decls.js.map +0 -1
  257. package/lib/packlets/qualifiers/convert/index.d.ts.map +0 -1
  258. package/lib/packlets/qualifiers/convert/index.js.map +0 -1
  259. package/lib/packlets/qualifiers/convert/qualifier.d.ts.map +0 -1
  260. package/lib/packlets/qualifiers/convert/qualifier.js.map +0 -1
  261. package/lib/packlets/qualifiers/index.d.ts.map +0 -1
  262. package/lib/packlets/qualifiers/index.js.map +0 -1
  263. package/lib/packlets/qualifiers/qualifier.d.ts.map +0 -1
  264. package/lib/packlets/qualifiers/qualifier.js.map +0 -1
  265. package/lib/packlets/qualifiers/qualifierCollector.d.ts.map +0 -1
  266. package/lib/packlets/qualifiers/qualifierCollector.js.map +0 -1
  267. package/lib/packlets/qualifiers/qualifierDecl.d.ts.map +0 -1
  268. package/lib/packlets/qualifiers/qualifierDecl.js.map +0 -1
  269. package/lib/packlets/qualifiers/qualifierDefaultValueDecls.d.ts.map +0 -1
  270. package/lib/packlets/qualifiers/qualifierDefaultValueDecls.js.map +0 -1
  271. package/lib/packlets/qualifiers/qualifierDefaultValueToken.d.ts.map +0 -1
  272. package/lib/packlets/qualifiers/qualifierDefaultValueToken.js.map +0 -1
  273. package/lib/packlets/resource-json/compiled/common.d.ts.map +0 -1
  274. package/lib/packlets/resource-json/compiled/common.js.map +0 -1
  275. package/lib/packlets/resource-json/compiled/convert.d.ts.map +0 -1
  276. package/lib/packlets/resource-json/compiled/convert.js.map +0 -1
  277. package/lib/packlets/resource-json/compiled/index.d.ts.map +0 -1
  278. package/lib/packlets/resource-json/compiled/index.js.map +0 -1
  279. package/lib/packlets/resource-json/compiled/json.d.ts.map +0 -1
  280. package/lib/packlets/resource-json/compiled/json.js.map +0 -1
  281. package/lib/packlets/resource-json/convert.d.ts.map +0 -1
  282. package/lib/packlets/resource-json/convert.js.map +0 -1
  283. package/lib/packlets/resource-json/helpers.d.ts.map +0 -1
  284. package/lib/packlets/resource-json/helpers.js.map +0 -1
  285. package/lib/packlets/resource-json/index.d.ts.map +0 -1
  286. package/lib/packlets/resource-json/index.js.map +0 -1
  287. package/lib/packlets/resource-json/json.d.ts.map +0 -1
  288. package/lib/packlets/resource-json/json.js.map +0 -1
  289. package/lib/packlets/resource-json/normalized.d.ts.map +0 -1
  290. package/lib/packlets/resource-json/normalized.js.map +0 -1
  291. package/lib/packlets/resource-json/resourceDeclCollection.d.ts.map +0 -1
  292. package/lib/packlets/resource-json/resourceDeclCollection.js.map +0 -1
  293. package/lib/packlets/resource-json/resourceDeclContainer.d.ts.map +0 -1
  294. package/lib/packlets/resource-json/resourceDeclContainer.js.map +0 -1
  295. package/lib/packlets/resource-json/resourceDeclTree.d.ts.map +0 -1
  296. package/lib/packlets/resource-json/resourceDeclTree.js.map +0 -1
  297. package/lib/packlets/resource-types/config/convert.d.ts.map +0 -1
  298. package/lib/packlets/resource-types/config/convert.js.map +0 -1
  299. package/lib/packlets/resource-types/config/index.d.ts.map +0 -1
  300. package/lib/packlets/resource-types/config/index.js.map +0 -1
  301. package/lib/packlets/resource-types/config/json.d.ts.map +0 -1
  302. package/lib/packlets/resource-types/config/json.js.map +0 -1
  303. package/lib/packlets/resource-types/helpers.d.ts.map +0 -1
  304. package/lib/packlets/resource-types/helpers.js.map +0 -1
  305. package/lib/packlets/resource-types/index.d.ts.map +0 -1
  306. package/lib/packlets/resource-types/index.js.map +0 -1
  307. package/lib/packlets/resource-types/jsonResourceType.d.ts.map +0 -1
  308. package/lib/packlets/resource-types/jsonResourceType.js.map +0 -1
  309. package/lib/packlets/resource-types/resourceType.d.ts.map +0 -1
  310. package/lib/packlets/resource-types/resourceType.js.map +0 -1
  311. package/lib/packlets/resource-types/resourceTypeCollector.d.ts.map +0 -1
  312. package/lib/packlets/resource-types/resourceTypeCollector.js.map +0 -1
  313. package/lib/packlets/resources/candidateReducer.d.ts.map +0 -1
  314. package/lib/packlets/resources/candidateReducer.js.map +0 -1
  315. package/lib/packlets/resources/common.d.ts.map +0 -1
  316. package/lib/packlets/resources/common.js.map +0 -1
  317. package/lib/packlets/resources/index.d.ts.map +0 -1
  318. package/lib/packlets/resources/index.js.map +0 -1
  319. package/lib/packlets/resources/resource.d.ts.map +0 -1
  320. package/lib/packlets/resources/resource.js.map +0 -1
  321. package/lib/packlets/resources/resourceBuilder.d.ts.map +0 -1
  322. package/lib/packlets/resources/resourceBuilder.js.map +0 -1
  323. package/lib/packlets/resources/resourceCandidate.d.ts.map +0 -1
  324. package/lib/packlets/resources/resourceCandidate.js.map +0 -1
  325. package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +0 -1
  326. package/lib/packlets/resources/resourceManagerBuilder.js.map +0 -1
  327. package/lib/packlets/runtime/cacheListener.d.ts.map +0 -1
  328. package/lib/packlets/runtime/cacheListener.js.map +0 -1
  329. package/lib/packlets/runtime/cacheMetrics.d.ts.map +0 -1
  330. package/lib/packlets/runtime/cacheMetrics.js.map +0 -1
  331. package/lib/packlets/runtime/compiledResourceCollection.d.ts.map +0 -1
  332. package/lib/packlets/runtime/compiledResourceCollection.js.map +0 -1
  333. package/lib/packlets/runtime/conditionSetResolutionResult.d.ts.map +0 -1
  334. package/lib/packlets/runtime/conditionSetResolutionResult.js.map +0 -1
  335. package/lib/packlets/runtime/context/contextQualifierProvider.d.ts.map +0 -1
  336. package/lib/packlets/runtime/context/contextQualifierProvider.js.map +0 -1
  337. package/lib/packlets/runtime/context/contextQualifierProviderValidator.d.ts.map +0 -1
  338. package/lib/packlets/runtime/context/contextQualifierProviderValidator.js.map +0 -1
  339. package/lib/packlets/runtime/context/index.d.ts.map +0 -1
  340. package/lib/packlets/runtime/context/index.js.map +0 -1
  341. package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts.map +0 -1
  342. package/lib/packlets/runtime/context/simpleContextQualifierProvider.js.map +0 -1
  343. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts.map +0 -1
  344. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +0 -1
  345. package/lib/packlets/runtime/iResourceManager.d.ts.map +0 -1
  346. package/lib/packlets/runtime/iResourceManager.js.map +0 -1
  347. package/lib/packlets/runtime/index.d.ts.map +0 -1
  348. package/lib/packlets/runtime/index.js.map +0 -1
  349. package/lib/packlets/runtime/resource-tree/common.d.ts.map +0 -1
  350. package/lib/packlets/runtime/resource-tree/common.js.map +0 -1
  351. package/lib/packlets/runtime/resource-tree/index.d.ts.map +0 -1
  352. package/lib/packlets/runtime/resource-tree/index.js.map +0 -1
  353. package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.d.ts.map +0 -1
  354. package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.js.map +0 -1
  355. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.d.ts.map +0 -1
  356. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js.map +0 -1
  357. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts.map +0 -1
  358. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js.map +0 -1
  359. package/lib/packlets/runtime/resourceResolver.d.ts.map +0 -1
  360. package/lib/packlets/runtime/resourceResolver.js.map +0 -1
  361. package/lib/packlets/runtime/validate.d.ts.map +0 -1
  362. 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, _d;
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 qualifierValueResult = this.contextQualifierProvider.get(condition.qualifier);
111
- if (qualifierValueResult.isFailure()) {
112
- (_b = this._listener) === null || _b === void 0 ? void 0 : _b.onCacheError('condition', conditionIndex);
113
- return (0, ts_utils_1.fail)(`Failed to get qualifier value for "${condition.qualifier.name}": ${qualifierValueResult.message}`);
114
- }
115
- const qualifierValue = qualifierValueResult.value;
116
- // Evaluate the condition using the qualifier type's matching logic
117
- const score = condition.qualifier.type.matches(condition.value, qualifierValue, condition.operator);
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 = (_c = condition.scoreAsDefault) !== null && _c !== void 0 ? _c : common_1.NoMatch;
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
- (_d = this._listener) === null || _d === void 0 ? void 0 : _d.onCacheMiss('condition', conditionIndex);
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
- * Resolves a resource by finding the best matching candidate.
265
- * Uses the resource's associated decision to determine the best match based on the current context.
266
- * @param resource - The {@link Resources.Resource | resource} to resolve.
267
- * @returns `Success` with the best matching candidate if successful,
268
- * or `Failure` with an error message if no candidates match or resolution fails.
269
- * @public
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
- * Resolves all matching resource candidates in priority order.
298
- * Uses the resource's associated decision to determine all matching candidates based on the current context.
299
- * @param resource - The {@link Resources.Resource | resource} to resolve.
300
- * @returns `Success` with an array of all matching candidates in priority order if successful,
301
- * or `Failure` with an error message if no candidates match or resolution fails.
302
- * @public
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
- * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
342
- * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
343
- * priority "partial" candidates into it in ascending order of priority.
344
- * @param resource - The {@link Resources.Resource | resource} to resolve.
345
- * @returns `Success` with the composed JsonValue if successful,
346
- * or `Failure` with an error message if no candidates match or resolution fails.
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, return the base candidate's value
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
- return (0, ts_utils_1.succeed)(baseCandidate.json);
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