@fgv/ts-res 5.1.0-3 → 5.1.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 (545) hide show
  1. package/dist/index.browser.js.map +1 -0
  2. package/dist/index.js.map +1 -0
  3. package/dist/packlets/bundle/bundleBuilder.js.map +1 -0
  4. package/dist/packlets/bundle/bundleLoader.js.map +1 -0
  5. package/dist/packlets/bundle/bundleNormalizer.js.map +1 -0
  6. package/dist/packlets/bundle/bundleUtils.js.map +1 -0
  7. package/dist/packlets/bundle/convert.js.map +1 -0
  8. package/dist/packlets/bundle/index.js.map +1 -0
  9. package/dist/packlets/bundle/model.js.map +1 -0
  10. package/dist/packlets/common/conditions.js.map +1 -0
  11. package/dist/packlets/common/convert.js.map +1 -0
  12. package/dist/packlets/common/helpers/conditions.js.map +1 -0
  13. package/dist/packlets/common/helpers/context.js.map +1 -0
  14. package/dist/packlets/common/helpers/index.js.map +1 -0
  15. package/dist/packlets/common/helpers/qualifierDefaultValues.js.map +1 -0
  16. package/dist/packlets/common/helpers/resources.js +2 -4
  17. package/dist/packlets/common/helpers/resources.js.map +1 -0
  18. package/dist/packlets/common/index.js.map +1 -0
  19. package/dist/packlets/common/resources.js.map +1 -0
  20. package/dist/packlets/common/validate/conditions.js +4 -4
  21. package/dist/packlets/common/validate/conditions.js.map +1 -0
  22. package/dist/packlets/common/validate/index.js.map +1 -0
  23. package/dist/packlets/common/validate/regularExpressions.js +2 -2
  24. package/dist/packlets/common/validate/regularExpressions.js.map +1 -0
  25. package/dist/packlets/common/validate/resources.js +1 -1
  26. package/dist/packlets/common/validate/resources.js.map +1 -0
  27. package/dist/packlets/conditions/condition.js +3 -7
  28. package/dist/packlets/conditions/condition.js.map +1 -0
  29. package/dist/packlets/conditions/conditionCollector.js.map +1 -0
  30. package/dist/packlets/conditions/conditionDecls.js.map +1 -0
  31. package/dist/packlets/conditions/conditionSet.js +14 -5
  32. package/dist/packlets/conditions/conditionSet.js.map +1 -0
  33. package/dist/packlets/conditions/conditionSetCollector.js.map +1 -0
  34. package/dist/packlets/conditions/conditionSetDecls.js.map +1 -0
  35. package/dist/packlets/conditions/conditionToken.js.map +1 -0
  36. package/dist/packlets/conditions/convert/conditionSetDecls.js +50 -6
  37. package/dist/packlets/conditions/convert/conditionSetDecls.js.map +1 -0
  38. package/dist/packlets/conditions/convert/decls.js +61 -5
  39. package/dist/packlets/conditions/convert/decls.js.map +1 -0
  40. package/dist/packlets/conditions/convert/index.js.map +1 -0
  41. package/dist/packlets/conditions/index.js.map +1 -0
  42. package/dist/packlets/config/common.js.map +1 -0
  43. package/dist/packlets/config/configInitFactory.js.map +1 -0
  44. package/dist/packlets/config/convert.js.map +1 -0
  45. package/dist/packlets/config/index.browser.js.map +1 -0
  46. package/dist/packlets/config/index.js.map +1 -0
  47. package/dist/packlets/config/json.js.map +1 -0
  48. package/dist/packlets/config/predefined/default.js.map +1 -0
  49. package/dist/packlets/config/predefined/extended.js.map +1 -0
  50. package/dist/packlets/config/predefined/index.js.map +1 -0
  51. package/dist/packlets/config/systemConfiguration.js.map +1 -0
  52. package/dist/packlets/context/contextDecls.js.map +1 -0
  53. package/dist/packlets/context/contextToken.js.map +1 -0
  54. package/dist/packlets/context/convert/decls.js.map +1 -0
  55. package/dist/packlets/context/convert/index.js.map +1 -0
  56. package/dist/packlets/context/index.js.map +1 -0
  57. package/dist/packlets/decisions/abstractDecision.js.map +1 -0
  58. package/dist/packlets/decisions/abstractDecisionCollector.js.map +1 -0
  59. package/dist/packlets/decisions/candidate.js.map +1 -0
  60. package/dist/packlets/decisions/common.js.map +1 -0
  61. package/dist/packlets/decisions/concreteDecision.js.map +1 -0
  62. package/dist/packlets/decisions/decision.js +1 -1
  63. package/dist/packlets/decisions/decision.js.map +1 -0
  64. package/dist/packlets/decisions/index.js.map +1 -0
  65. package/dist/packlets/import/fsItem.js +1 -4
  66. package/dist/packlets/import/fsItem.js.map +1 -0
  67. package/dist/packlets/import/importContext.js +3 -3
  68. package/dist/packlets/import/importContext.js.map +1 -0
  69. package/dist/packlets/import/importManager.js +7 -3
  70. package/dist/packlets/import/importManager.js.map +1 -0
  71. package/dist/packlets/import/importable.js.map +1 -0
  72. package/dist/packlets/import/importers/collectionImporter.js +2 -2
  73. package/dist/packlets/import/importers/collectionImporter.js.map +1 -0
  74. package/dist/packlets/import/importers/fsItemImporter.js +30 -14
  75. package/dist/packlets/import/importers/fsItemImporter.js.map +1 -0
  76. package/dist/packlets/import/importers/importer.js.map +1 -0
  77. package/dist/packlets/import/importers/index.browser.js.map +1 -0
  78. package/dist/packlets/import/importers/index.js.map +1 -0
  79. package/dist/packlets/import/importers/jsonImporter.js +2 -2
  80. package/dist/packlets/import/importers/jsonImporter.js.map +1 -0
  81. package/dist/packlets/import/importers/pathImporter.js +1 -1
  82. package/dist/packlets/import/importers/pathImporter.js.map +1 -0
  83. package/dist/packlets/import/index.browser.js.map +1 -0
  84. package/dist/packlets/import/index.js.map +1 -0
  85. package/dist/packlets/qualifier-types/config/convert.js.map +1 -0
  86. package/dist/packlets/qualifier-types/config/index.js.map +1 -0
  87. package/dist/packlets/qualifier-types/config/json.js.map +1 -0
  88. package/dist/packlets/qualifier-types/convert.js.map +1 -0
  89. package/dist/packlets/qualifier-types/helpers.js.map +1 -0
  90. package/dist/packlets/qualifier-types/index.js.map +1 -0
  91. package/dist/packlets/qualifier-types/languageQualifierType.js +6 -7
  92. package/dist/packlets/qualifier-types/languageQualifierType.js.map +1 -0
  93. package/dist/packlets/qualifier-types/literalQualifierType.js +7 -10
  94. package/dist/packlets/qualifier-types/literalQualifierType.js.map +1 -0
  95. package/dist/packlets/qualifier-types/literalValueHierarchy.js.map +1 -0
  96. package/dist/packlets/qualifier-types/qualifierType.js +12 -13
  97. package/dist/packlets/qualifier-types/qualifierType.js.map +1 -0
  98. package/dist/packlets/qualifier-types/qualifierTypeCollector.js.map +1 -0
  99. package/dist/packlets/qualifier-types/territoryQualifierType.js +5 -5
  100. package/dist/packlets/qualifier-types/territoryQualifierType.js.map +1 -0
  101. package/dist/packlets/qualifiers/convert/decls.js.map +1 -0
  102. package/dist/packlets/qualifiers/convert/index.js.map +1 -0
  103. package/dist/packlets/qualifiers/convert/qualifier.js.map +1 -0
  104. package/dist/packlets/qualifiers/index.js.map +1 -0
  105. package/dist/packlets/qualifiers/qualifier.js +6 -7
  106. package/dist/packlets/qualifiers/qualifier.js.map +1 -0
  107. package/dist/packlets/qualifiers/qualifierCollector.js +153 -9
  108. package/dist/packlets/qualifiers/qualifierCollector.js.map +1 -0
  109. package/dist/packlets/qualifiers/qualifierDecl.js.map +1 -0
  110. package/dist/packlets/qualifiers/qualifierDefaultValueDecls.js.map +1 -0
  111. package/dist/packlets/qualifiers/qualifierDefaultValueToken.js.map +1 -0
  112. package/dist/packlets/resource-json/compiled/common.js.map +1 -0
  113. package/dist/packlets/resource-json/compiled/convert.js.map +1 -0
  114. package/dist/packlets/resource-json/compiled/index.js.map +1 -0
  115. package/dist/packlets/resource-json/compiled/json.js.map +1 -0
  116. package/dist/packlets/resource-json/convert.js +225 -0
  117. package/dist/packlets/resource-json/convert.js.map +1 -0
  118. package/dist/packlets/resource-json/helpers.js.map +1 -0
  119. package/dist/packlets/resource-json/index.js.map +1 -0
  120. package/dist/packlets/resource-json/json.js +2 -2
  121. package/dist/packlets/resource-json/json.js.map +1 -0
  122. package/dist/packlets/resource-json/normalized.js.map +1 -0
  123. package/dist/packlets/resource-json/resourceDeclCollection.js +1 -1
  124. package/dist/packlets/resource-json/resourceDeclCollection.js.map +1 -0
  125. package/dist/packlets/resource-json/resourceDeclContainer.js.map +1 -0
  126. package/dist/packlets/resource-json/resourceDeclTree.js +1 -1
  127. package/dist/packlets/resource-json/resourceDeclTree.js.map +1 -0
  128. package/dist/packlets/resource-types/config/convert.js.map +1 -0
  129. package/dist/packlets/resource-types/config/index.js.map +1 -0
  130. package/dist/packlets/resource-types/config/json.js.map +1 -0
  131. package/dist/packlets/resource-types/helpers.js.map +1 -0
  132. package/dist/packlets/resource-types/index.js.map +1 -0
  133. package/dist/packlets/resource-types/jsonResourceType.js +2 -2
  134. package/dist/packlets/resource-types/jsonResourceType.js.map +1 -0
  135. package/dist/packlets/resource-types/resourceType.js +2 -2
  136. package/dist/packlets/resource-types/resourceType.js.map +1 -0
  137. package/dist/packlets/resource-types/resourceTypeCollector.js.map +1 -0
  138. package/dist/packlets/resources/candidateReducer.js.map +1 -0
  139. package/dist/packlets/resources/candidateValue.js.map +1 -0
  140. package/dist/packlets/resources/candidateValueCollector.js.map +1 -0
  141. package/dist/packlets/resources/common.js.map +1 -0
  142. package/dist/packlets/resources/deltaGenerator.js.map +1 -0
  143. package/dist/packlets/resources/index.js.map +1 -0
  144. package/dist/packlets/resources/resource.js.map +1 -0
  145. package/dist/packlets/resources/resourceBuilder.js +2 -2
  146. package/dist/packlets/resources/resourceBuilder.js.map +1 -0
  147. package/dist/packlets/resources/resourceCandidate.js.map +1 -0
  148. package/dist/packlets/resources/resourceManagerBuilder.js +5 -5
  149. package/dist/packlets/resources/resourceManagerBuilder.js.map +1 -0
  150. package/dist/packlets/runtime/cacheListener.js.map +1 -0
  151. package/dist/packlets/runtime/cacheMetrics.js.map +1 -0
  152. package/dist/packlets/runtime/compiledResourceCollection.js +5 -5
  153. package/dist/packlets/runtime/compiledResourceCollection.js.map +1 -0
  154. package/dist/packlets/runtime/conditionSetResolutionResult.js.map +1 -0
  155. package/dist/packlets/runtime/context/contextQualifierProvider.js.map +1 -0
  156. package/dist/packlets/runtime/context/contextQualifierProviderValidator.js.map +1 -0
  157. package/dist/packlets/runtime/context/index.js.map +1 -0
  158. package/dist/packlets/runtime/context/simpleContextQualifierProvider.js +3 -0
  159. package/dist/packlets/runtime/context/simpleContextQualifierProvider.js.map +1 -0
  160. package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +3 -5
  161. package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +1 -0
  162. package/dist/packlets/runtime/iResourceManager.js.map +1 -0
  163. package/dist/packlets/runtime/index.js.map +1 -0
  164. package/dist/packlets/runtime/resource-tree/common.js.map +1 -0
  165. package/dist/packlets/runtime/resource-tree/index.js.map +1 -0
  166. package/dist/packlets/runtime/resource-tree/readOnlyResourceTree.js.map +1 -0
  167. package/dist/packlets/runtime/resource-tree/resourceTreeChildren.js.map +1 -0
  168. package/dist/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js.map +1 -0
  169. package/dist/packlets/runtime/resourceResolver.js.map +1 -0
  170. package/dist/packlets/runtime/resourceTreeResolver.js.map +1 -0
  171. package/dist/packlets/runtime/validate.js.map +1 -0
  172. package/dist/packlets/zip-archive/convert.js.map +1 -0
  173. package/dist/packlets/zip-archive/index.browser.js.map +1 -0
  174. package/dist/packlets/zip-archive/index.js.map +1 -0
  175. package/dist/packlets/zip-archive/json.js.map +1 -0
  176. package/dist/packlets/zip-archive/types.js.map +1 -0
  177. package/dist/packlets/zip-archive/zipArchiveCreator.js.map +1 -0
  178. package/dist/packlets/zip-archive/zipArchiveFormat.js.map +1 -0
  179. package/dist/packlets/zip-archive/zipArchiveLoader.js.map +1 -0
  180. package/dist/ts-res.d.ts +576 -164
  181. package/dist/tsdoc-metadata.json +1 -1
  182. package/lib/index.browser.d.ts.map +1 -0
  183. package/lib/index.browser.js.map +1 -0
  184. package/lib/index.d.ts.map +1 -0
  185. package/lib/index.js.map +1 -0
  186. package/lib/packlets/bundle/bundleBuilder.d.ts.map +1 -0
  187. package/lib/packlets/bundle/bundleBuilder.js.map +1 -0
  188. package/lib/packlets/bundle/bundleLoader.d.ts.map +1 -0
  189. package/lib/packlets/bundle/bundleLoader.js.map +1 -0
  190. package/lib/packlets/bundle/bundleNormalizer.d.ts.map +1 -0
  191. package/lib/packlets/bundle/bundleNormalizer.js.map +1 -0
  192. package/lib/packlets/bundle/bundleUtils.d.ts.map +1 -0
  193. package/lib/packlets/bundle/bundleUtils.js.map +1 -0
  194. package/lib/packlets/bundle/convert.d.ts.map +1 -0
  195. package/lib/packlets/bundle/convert.js.map +1 -0
  196. package/lib/packlets/bundle/index.d.ts.map +1 -0
  197. package/lib/packlets/bundle/index.js.map +1 -0
  198. package/lib/packlets/bundle/model.d.ts.map +1 -0
  199. package/lib/packlets/bundle/model.js.map +1 -0
  200. package/lib/packlets/common/conditions.d.ts.map +1 -0
  201. package/lib/packlets/common/conditions.js.map +1 -0
  202. package/lib/packlets/common/convert.d.ts.map +1 -0
  203. package/lib/packlets/common/convert.js.map +1 -0
  204. package/lib/packlets/common/helpers/conditions.d.ts.map +1 -0
  205. package/lib/packlets/common/helpers/conditions.js.map +1 -0
  206. package/lib/packlets/common/helpers/context.d.ts.map +1 -0
  207. package/lib/packlets/common/helpers/context.js.map +1 -0
  208. package/lib/packlets/common/helpers/index.d.ts.map +1 -0
  209. package/lib/packlets/common/helpers/index.js.map +1 -0
  210. package/lib/packlets/common/helpers/qualifierDefaultValues.d.ts.map +1 -0
  211. package/lib/packlets/common/helpers/qualifierDefaultValues.js.map +1 -0
  212. package/lib/packlets/common/helpers/resources.d.ts +2 -4
  213. package/lib/packlets/common/helpers/resources.d.ts.map +1 -0
  214. package/lib/packlets/common/helpers/resources.js +2 -4
  215. package/lib/packlets/common/helpers/resources.js.map +1 -0
  216. package/lib/packlets/common/index.d.ts.map +1 -0
  217. package/lib/packlets/common/index.js.map +1 -0
  218. package/lib/packlets/common/resources.d.ts.map +1 -0
  219. package/lib/packlets/common/resources.js.map +1 -0
  220. package/lib/packlets/common/validate/conditions.d.ts +4 -4
  221. package/lib/packlets/common/validate/conditions.d.ts.map +1 -0
  222. package/lib/packlets/common/validate/conditions.js +4 -4
  223. package/lib/packlets/common/validate/conditions.js.map +1 -0
  224. package/lib/packlets/common/validate/index.d.ts.map +1 -0
  225. package/lib/packlets/common/validate/index.js.map +1 -0
  226. package/lib/packlets/common/validate/regularExpressions.d.ts +2 -2
  227. package/lib/packlets/common/validate/regularExpressions.d.ts.map +1 -0
  228. package/lib/packlets/common/validate/regularExpressions.js +2 -2
  229. package/lib/packlets/common/validate/regularExpressions.js.map +1 -0
  230. package/lib/packlets/common/validate/resources.d.ts +1 -1
  231. package/lib/packlets/common/validate/resources.d.ts.map +1 -0
  232. package/lib/packlets/common/validate/resources.js +1 -1
  233. package/lib/packlets/common/validate/resources.js.map +1 -0
  234. package/lib/packlets/conditions/condition.d.ts +3 -7
  235. package/lib/packlets/conditions/condition.d.ts.map +1 -0
  236. package/lib/packlets/conditions/condition.js +3 -7
  237. package/lib/packlets/conditions/condition.js.map +1 -0
  238. package/lib/packlets/conditions/conditionCollector.d.ts.map +1 -0
  239. package/lib/packlets/conditions/conditionCollector.js.map +1 -0
  240. package/lib/packlets/conditions/conditionDecls.d.ts +6 -1
  241. package/lib/packlets/conditions/conditionDecls.d.ts.map +1 -0
  242. package/lib/packlets/conditions/conditionDecls.js.map +1 -0
  243. package/lib/packlets/conditions/conditionSet.d.ts.map +1 -0
  244. package/lib/packlets/conditions/conditionSet.js +14 -5
  245. package/lib/packlets/conditions/conditionSet.js.map +1 -0
  246. package/lib/packlets/conditions/conditionSetCollector.d.ts.map +1 -0
  247. package/lib/packlets/conditions/conditionSetCollector.js.map +1 -0
  248. package/lib/packlets/conditions/conditionSetDecls.d.ts +7 -2
  249. package/lib/packlets/conditions/conditionSetDecls.d.ts.map +1 -0
  250. package/lib/packlets/conditions/conditionSetDecls.js.map +1 -0
  251. package/lib/packlets/conditions/conditionToken.d.ts.map +1 -0
  252. package/lib/packlets/conditions/conditionToken.js.map +1 -0
  253. package/lib/packlets/conditions/convert/conditionSetDecls.d.ts +30 -2
  254. package/lib/packlets/conditions/convert/conditionSetDecls.d.ts.map +1 -0
  255. package/lib/packlets/conditions/convert/conditionSetDecls.js +51 -5
  256. package/lib/packlets/conditions/convert/conditionSetDecls.js.map +1 -0
  257. package/lib/packlets/conditions/convert/decls.d.ts +39 -3
  258. package/lib/packlets/conditions/convert/decls.d.ts.map +1 -0
  259. package/lib/packlets/conditions/convert/decls.js +63 -5
  260. package/lib/packlets/conditions/convert/decls.js.map +1 -0
  261. package/lib/packlets/conditions/convert/index.d.ts.map +1 -0
  262. package/lib/packlets/conditions/convert/index.js.map +1 -0
  263. package/lib/packlets/conditions/index.d.ts.map +1 -0
  264. package/lib/packlets/conditions/index.js.map +1 -0
  265. package/lib/packlets/config/common.d.ts.map +1 -0
  266. package/lib/packlets/config/common.js.map +1 -0
  267. package/lib/packlets/config/configInitFactory.d.ts.map +1 -0
  268. package/lib/packlets/config/configInitFactory.js.map +1 -0
  269. package/lib/packlets/config/convert.d.ts.map +1 -0
  270. package/lib/packlets/config/convert.js.map +1 -0
  271. package/lib/packlets/config/index.browser.d.ts.map +1 -0
  272. package/lib/packlets/config/index.browser.js.map +1 -0
  273. package/lib/packlets/config/index.d.ts.map +1 -0
  274. package/lib/packlets/config/index.js.map +1 -0
  275. package/lib/packlets/config/json.d.ts.map +1 -0
  276. package/lib/packlets/config/json.js.map +1 -0
  277. package/lib/packlets/config/predefined/default.d.ts.map +1 -0
  278. package/lib/packlets/config/predefined/default.js.map +1 -0
  279. package/lib/packlets/config/predefined/extended.d.ts.map +1 -0
  280. package/lib/packlets/config/predefined/extended.js.map +1 -0
  281. package/lib/packlets/config/predefined/index.d.ts.map +1 -0
  282. package/lib/packlets/config/predefined/index.js.map +1 -0
  283. package/lib/packlets/config/systemConfiguration.d.ts.map +1 -0
  284. package/lib/packlets/config/systemConfiguration.js.map +1 -0
  285. package/lib/packlets/context/contextDecls.d.ts.map +1 -0
  286. package/lib/packlets/context/contextDecls.js.map +1 -0
  287. package/lib/packlets/context/contextToken.d.ts.map +1 -0
  288. package/lib/packlets/context/contextToken.js.map +1 -0
  289. package/lib/packlets/context/convert/decls.d.ts.map +1 -0
  290. package/lib/packlets/context/convert/decls.js.map +1 -0
  291. package/lib/packlets/context/convert/index.d.ts.map +1 -0
  292. package/lib/packlets/context/convert/index.js.map +1 -0
  293. package/lib/packlets/context/index.d.ts.map +1 -0
  294. package/lib/packlets/context/index.js.map +1 -0
  295. package/lib/packlets/decisions/abstractDecision.d.ts.map +1 -0
  296. package/lib/packlets/decisions/abstractDecision.js.map +1 -0
  297. package/lib/packlets/decisions/abstractDecisionCollector.d.ts.map +1 -0
  298. package/lib/packlets/decisions/abstractDecisionCollector.js.map +1 -0
  299. package/lib/packlets/decisions/candidate.d.ts.map +1 -0
  300. package/lib/packlets/decisions/candidate.js.map +1 -0
  301. package/lib/packlets/decisions/common.d.ts.map +1 -0
  302. package/lib/packlets/decisions/common.js.map +1 -0
  303. package/lib/packlets/decisions/concreteDecision.d.ts.map +1 -0
  304. package/lib/packlets/decisions/concreteDecision.js.map +1 -0
  305. package/lib/packlets/decisions/decision.d.ts +1 -1
  306. package/lib/packlets/decisions/decision.d.ts.map +1 -0
  307. package/lib/packlets/decisions/decision.js +1 -1
  308. package/lib/packlets/decisions/decision.js.map +1 -0
  309. package/lib/packlets/decisions/index.d.ts.map +1 -0
  310. package/lib/packlets/decisions/index.js.map +1 -0
  311. package/lib/packlets/import/fsItem.d.ts +1 -4
  312. package/lib/packlets/import/fsItem.d.ts.map +1 -0
  313. package/lib/packlets/import/fsItem.js +1 -4
  314. package/lib/packlets/import/fsItem.js.map +1 -0
  315. package/lib/packlets/import/importContext.d.ts +5 -5
  316. package/lib/packlets/import/importContext.d.ts.map +1 -0
  317. package/lib/packlets/import/importContext.js +3 -3
  318. package/lib/packlets/import/importContext.js.map +1 -0
  319. package/lib/packlets/import/importManager.d.ts +15 -1
  320. package/lib/packlets/import/importManager.d.ts.map +1 -0
  321. package/lib/packlets/import/importManager.js +7 -3
  322. package/lib/packlets/import/importManager.js.map +1 -0
  323. package/lib/packlets/import/importable.d.ts.map +1 -0
  324. package/lib/packlets/import/importable.js.map +1 -0
  325. package/lib/packlets/import/importers/collectionImporter.d.ts +2 -2
  326. package/lib/packlets/import/importers/collectionImporter.d.ts.map +1 -0
  327. package/lib/packlets/import/importers/collectionImporter.js +2 -2
  328. package/lib/packlets/import/importers/collectionImporter.js.map +1 -0
  329. package/lib/packlets/import/importers/fsItemImporter.d.ts +16 -2
  330. package/lib/packlets/import/importers/fsItemImporter.d.ts.map +1 -0
  331. package/lib/packlets/import/importers/fsItemImporter.js +29 -13
  332. package/lib/packlets/import/importers/fsItemImporter.js.map +1 -0
  333. package/lib/packlets/import/importers/importer.d.ts.map +1 -0
  334. package/lib/packlets/import/importers/importer.js.map +1 -0
  335. package/lib/packlets/import/importers/index.browser.d.ts.map +1 -0
  336. package/lib/packlets/import/importers/index.browser.js.map +1 -0
  337. package/lib/packlets/import/importers/index.d.ts.map +1 -0
  338. package/lib/packlets/import/importers/index.js.map +1 -0
  339. package/lib/packlets/import/importers/jsonImporter.d.ts +2 -2
  340. package/lib/packlets/import/importers/jsonImporter.d.ts.map +1 -0
  341. package/lib/packlets/import/importers/jsonImporter.js +2 -2
  342. package/lib/packlets/import/importers/jsonImporter.js.map +1 -0
  343. package/lib/packlets/import/importers/pathImporter.d.ts +1 -1
  344. package/lib/packlets/import/importers/pathImporter.d.ts.map +1 -0
  345. package/lib/packlets/import/importers/pathImporter.js +1 -1
  346. package/lib/packlets/import/importers/pathImporter.js.map +1 -0
  347. package/lib/packlets/import/index.browser.d.ts.map +1 -0
  348. package/lib/packlets/import/index.browser.js.map +1 -0
  349. package/lib/packlets/import/index.d.ts.map +1 -0
  350. package/lib/packlets/import/index.js.map +1 -0
  351. package/lib/packlets/qualifier-types/config/convert.d.ts.map +1 -0
  352. package/lib/packlets/qualifier-types/config/convert.js.map +1 -0
  353. package/lib/packlets/qualifier-types/config/index.d.ts.map +1 -0
  354. package/lib/packlets/qualifier-types/config/index.js.map +1 -0
  355. package/lib/packlets/qualifier-types/config/json.d.ts.map +1 -0
  356. package/lib/packlets/qualifier-types/config/json.js.map +1 -0
  357. package/lib/packlets/qualifier-types/convert.d.ts.map +1 -0
  358. package/lib/packlets/qualifier-types/convert.js.map +1 -0
  359. package/lib/packlets/qualifier-types/helpers.d.ts.map +1 -0
  360. package/lib/packlets/qualifier-types/helpers.js.map +1 -0
  361. package/lib/packlets/qualifier-types/index.d.ts.map +1 -0
  362. package/lib/packlets/qualifier-types/index.js.map +1 -0
  363. package/lib/packlets/qualifier-types/languageQualifierType.d.ts +6 -7
  364. package/lib/packlets/qualifier-types/languageQualifierType.d.ts.map +1 -0
  365. package/lib/packlets/qualifier-types/languageQualifierType.js +6 -7
  366. package/lib/packlets/qualifier-types/languageQualifierType.js.map +1 -0
  367. package/lib/packlets/qualifier-types/literalQualifierType.d.ts +7 -10
  368. package/lib/packlets/qualifier-types/literalQualifierType.d.ts.map +1 -0
  369. package/lib/packlets/qualifier-types/literalQualifierType.js +7 -10
  370. package/lib/packlets/qualifier-types/literalQualifierType.js.map +1 -0
  371. package/lib/packlets/qualifier-types/literalValueHierarchy.d.ts.map +1 -0
  372. package/lib/packlets/qualifier-types/literalValueHierarchy.js.map +1 -0
  373. package/lib/packlets/qualifier-types/qualifierType.d.ts +17 -18
  374. package/lib/packlets/qualifier-types/qualifierType.d.ts.map +1 -0
  375. package/lib/packlets/qualifier-types/qualifierType.js +12 -13
  376. package/lib/packlets/qualifier-types/qualifierType.js.map +1 -0
  377. package/lib/packlets/qualifier-types/qualifierTypeCollector.d.ts.map +1 -0
  378. package/lib/packlets/qualifier-types/qualifierTypeCollector.js.map +1 -0
  379. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +8 -8
  380. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts.map +1 -0
  381. package/lib/packlets/qualifier-types/territoryQualifierType.js +5 -5
  382. package/lib/packlets/qualifier-types/territoryQualifierType.js.map +1 -0
  383. package/lib/packlets/qualifiers/convert/decls.d.ts.map +1 -0
  384. package/lib/packlets/qualifiers/convert/decls.js.map +1 -0
  385. package/lib/packlets/qualifiers/convert/index.d.ts.map +1 -0
  386. package/lib/packlets/qualifiers/convert/index.js.map +1 -0
  387. package/lib/packlets/qualifiers/convert/qualifier.d.ts.map +1 -0
  388. package/lib/packlets/qualifiers/convert/qualifier.js.map +1 -0
  389. package/lib/packlets/qualifiers/index.d.ts.map +1 -0
  390. package/lib/packlets/qualifiers/index.js.map +1 -0
  391. package/lib/packlets/qualifiers/qualifier.d.ts +6 -7
  392. package/lib/packlets/qualifiers/qualifier.d.ts.map +1 -0
  393. package/lib/packlets/qualifiers/qualifier.js +6 -7
  394. package/lib/packlets/qualifiers/qualifier.js.map +1 -0
  395. package/lib/packlets/qualifiers/qualifierCollector.d.ts +107 -9
  396. package/lib/packlets/qualifiers/qualifierCollector.d.ts.map +1 -0
  397. package/lib/packlets/qualifiers/qualifierCollector.js +152 -8
  398. package/lib/packlets/qualifiers/qualifierCollector.js.map +1 -0
  399. package/lib/packlets/qualifiers/qualifierDecl.d.ts.map +1 -0
  400. package/lib/packlets/qualifiers/qualifierDecl.js.map +1 -0
  401. package/lib/packlets/qualifiers/qualifierDefaultValueDecls.d.ts.map +1 -0
  402. package/lib/packlets/qualifiers/qualifierDefaultValueDecls.js.map +1 -0
  403. package/lib/packlets/qualifiers/qualifierDefaultValueToken.d.ts.map +1 -0
  404. package/lib/packlets/qualifiers/qualifierDefaultValueToken.js.map +1 -0
  405. package/lib/packlets/resource-json/compiled/common.d.ts.map +1 -0
  406. package/lib/packlets/resource-json/compiled/common.js.map +1 -0
  407. package/lib/packlets/resource-json/compiled/convert.d.ts.map +1 -0
  408. package/lib/packlets/resource-json/compiled/convert.js.map +1 -0
  409. package/lib/packlets/resource-json/compiled/index.d.ts.map +1 -0
  410. package/lib/packlets/resource-json/compiled/index.js.map +1 -0
  411. package/lib/packlets/resource-json/compiled/json.d.ts.map +1 -0
  412. package/lib/packlets/resource-json/compiled/json.js.map +1 -0
  413. package/lib/packlets/resource-json/convert.d.ts +85 -0
  414. package/lib/packlets/resource-json/convert.d.ts.map +1 -0
  415. package/lib/packlets/resource-json/convert.js +237 -0
  416. package/lib/packlets/resource-json/convert.js.map +1 -0
  417. package/lib/packlets/resource-json/helpers.d.ts.map +1 -0
  418. package/lib/packlets/resource-json/helpers.js.map +1 -0
  419. package/lib/packlets/resource-json/index.d.ts.map +1 -0
  420. package/lib/packlets/resource-json/index.js.map +1 -0
  421. package/lib/packlets/resource-json/json.d.ts +128 -39
  422. package/lib/packlets/resource-json/json.d.ts.map +1 -0
  423. package/lib/packlets/resource-json/json.js +2 -2
  424. package/lib/packlets/resource-json/json.js.map +1 -0
  425. package/lib/packlets/resource-json/normalized.d.ts.map +1 -0
  426. package/lib/packlets/resource-json/normalized.js.map +1 -0
  427. package/lib/packlets/resource-json/resourceDeclCollection.d.ts +1 -1
  428. package/lib/packlets/resource-json/resourceDeclCollection.d.ts.map +1 -0
  429. package/lib/packlets/resource-json/resourceDeclCollection.js +1 -1
  430. package/lib/packlets/resource-json/resourceDeclCollection.js.map +1 -0
  431. package/lib/packlets/resource-json/resourceDeclContainer.d.ts.map +1 -0
  432. package/lib/packlets/resource-json/resourceDeclContainer.js.map +1 -0
  433. package/lib/packlets/resource-json/resourceDeclTree.d.ts +1 -1
  434. package/lib/packlets/resource-json/resourceDeclTree.d.ts.map +1 -0
  435. package/lib/packlets/resource-json/resourceDeclTree.js +1 -1
  436. package/lib/packlets/resource-json/resourceDeclTree.js.map +1 -0
  437. package/lib/packlets/resource-types/config/convert.d.ts.map +1 -0
  438. package/lib/packlets/resource-types/config/convert.js.map +1 -0
  439. package/lib/packlets/resource-types/config/index.d.ts.map +1 -0
  440. package/lib/packlets/resource-types/config/index.js.map +1 -0
  441. package/lib/packlets/resource-types/config/json.d.ts.map +1 -0
  442. package/lib/packlets/resource-types/config/json.js.map +1 -0
  443. package/lib/packlets/resource-types/helpers.d.ts.map +1 -0
  444. package/lib/packlets/resource-types/helpers.js.map +1 -0
  445. package/lib/packlets/resource-types/index.d.ts.map +1 -0
  446. package/lib/packlets/resource-types/index.js.map +1 -0
  447. package/lib/packlets/resource-types/jsonResourceType.d.ts +17 -5
  448. package/lib/packlets/resource-types/jsonResourceType.d.ts.map +1 -0
  449. package/lib/packlets/resource-types/jsonResourceType.js +2 -2
  450. package/lib/packlets/resource-types/jsonResourceType.js.map +1 -0
  451. package/lib/packlets/resource-types/resourceType.d.ts +5 -5
  452. package/lib/packlets/resource-types/resourceType.d.ts.map +1 -0
  453. package/lib/packlets/resource-types/resourceType.js +2 -2
  454. package/lib/packlets/resource-types/resourceType.js.map +1 -0
  455. package/lib/packlets/resource-types/resourceTypeCollector.d.ts.map +1 -0
  456. package/lib/packlets/resource-types/resourceTypeCollector.js.map +1 -0
  457. package/lib/packlets/resources/candidateReducer.d.ts.map +1 -0
  458. package/lib/packlets/resources/candidateReducer.js.map +1 -0
  459. package/lib/packlets/resources/candidateValue.d.ts.map +1 -0
  460. package/lib/packlets/resources/candidateValue.js.map +1 -0
  461. package/lib/packlets/resources/candidateValueCollector.d.ts.map +1 -0
  462. package/lib/packlets/resources/candidateValueCollector.js.map +1 -0
  463. package/lib/packlets/resources/common.d.ts.map +1 -0
  464. package/lib/packlets/resources/common.js.map +1 -0
  465. package/lib/packlets/resources/deltaGenerator.d.ts.map +1 -0
  466. package/lib/packlets/resources/deltaGenerator.js.map +1 -0
  467. package/lib/packlets/resources/index.d.ts.map +1 -0
  468. package/lib/packlets/resources/index.js.map +1 -0
  469. package/lib/packlets/resources/resource.d.ts.map +1 -0
  470. package/lib/packlets/resources/resource.js.map +1 -0
  471. package/lib/packlets/resources/resourceBuilder.d.ts +2 -2
  472. package/lib/packlets/resources/resourceBuilder.d.ts.map +1 -0
  473. package/lib/packlets/resources/resourceBuilder.js +2 -2
  474. package/lib/packlets/resources/resourceBuilder.js.map +1 -0
  475. package/lib/packlets/resources/resourceCandidate.d.ts.map +1 -0
  476. package/lib/packlets/resources/resourceCandidate.js.map +1 -0
  477. package/lib/packlets/resources/resourceManagerBuilder.d.ts +5 -5
  478. package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +1 -0
  479. package/lib/packlets/resources/resourceManagerBuilder.js +5 -5
  480. package/lib/packlets/resources/resourceManagerBuilder.js.map +1 -0
  481. package/lib/packlets/runtime/cacheListener.d.ts.map +1 -0
  482. package/lib/packlets/runtime/cacheListener.js.map +1 -0
  483. package/lib/packlets/runtime/cacheMetrics.d.ts.map +1 -0
  484. package/lib/packlets/runtime/cacheMetrics.js.map +1 -0
  485. package/lib/packlets/runtime/compiledResourceCollection.d.ts +5 -5
  486. package/lib/packlets/runtime/compiledResourceCollection.d.ts.map +1 -0
  487. package/lib/packlets/runtime/compiledResourceCollection.js +5 -5
  488. package/lib/packlets/runtime/compiledResourceCollection.js.map +1 -0
  489. package/lib/packlets/runtime/conditionSetResolutionResult.d.ts.map +1 -0
  490. package/lib/packlets/runtime/conditionSetResolutionResult.js.map +1 -0
  491. package/lib/packlets/runtime/context/contextQualifierProvider.d.ts.map +1 -0
  492. package/lib/packlets/runtime/context/contextQualifierProvider.js.map +1 -0
  493. package/lib/packlets/runtime/context/contextQualifierProviderValidator.d.ts.map +1 -0
  494. package/lib/packlets/runtime/context/contextQualifierProviderValidator.js.map +1 -0
  495. package/lib/packlets/runtime/context/index.d.ts.map +1 -0
  496. package/lib/packlets/runtime/context/index.js.map +1 -0
  497. package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts +9 -2
  498. package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts.map +1 -0
  499. package/lib/packlets/runtime/context/simpleContextQualifierProvider.js +3 -0
  500. package/lib/packlets/runtime/context/simpleContextQualifierProvider.js.map +1 -0
  501. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts +8 -1
  502. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts.map +1 -0
  503. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +3 -5
  504. package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +1 -0
  505. package/lib/packlets/runtime/iResourceManager.d.ts.map +1 -0
  506. package/lib/packlets/runtime/iResourceManager.js.map +1 -0
  507. package/lib/packlets/runtime/index.d.ts.map +1 -0
  508. package/lib/packlets/runtime/index.js.map +1 -0
  509. package/lib/packlets/runtime/resource-tree/common.d.ts.map +1 -0
  510. package/lib/packlets/runtime/resource-tree/common.js.map +1 -0
  511. package/lib/packlets/runtime/resource-tree/index.d.ts.map +1 -0
  512. package/lib/packlets/runtime/resource-tree/index.js.map +1 -0
  513. package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.d.ts.map +1 -0
  514. package/lib/packlets/runtime/resource-tree/readOnlyResourceTree.js.map +1 -0
  515. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.d.ts.map +1 -0
  516. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js.map +1 -0
  517. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.d.ts.map +1 -0
  518. package/lib/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js.map +1 -0
  519. package/lib/packlets/runtime/resourceResolver.d.ts.map +1 -0
  520. package/lib/packlets/runtime/resourceResolver.js.map +1 -0
  521. package/lib/packlets/runtime/resourceTreeResolver.d.ts.map +1 -0
  522. package/lib/packlets/runtime/resourceTreeResolver.js.map +1 -0
  523. package/lib/packlets/runtime/validate.d.ts.map +1 -0
  524. package/lib/packlets/runtime/validate.js.map +1 -0
  525. package/lib/packlets/zip-archive/convert.d.ts.map +1 -0
  526. package/lib/packlets/zip-archive/convert.js.map +1 -0
  527. package/lib/packlets/zip-archive/index.browser.d.ts.map +1 -0
  528. package/lib/packlets/zip-archive/index.browser.js.map +1 -0
  529. package/lib/packlets/zip-archive/index.d.ts.map +1 -0
  530. package/lib/packlets/zip-archive/index.js.map +1 -0
  531. package/lib/packlets/zip-archive/json.d.ts.map +1 -0
  532. package/lib/packlets/zip-archive/json.js.map +1 -0
  533. package/lib/packlets/zip-archive/types.d.ts.map +1 -0
  534. package/lib/packlets/zip-archive/types.js.map +1 -0
  535. package/lib/packlets/zip-archive/zipArchiveCreator.d.ts.map +1 -0
  536. package/lib/packlets/zip-archive/zipArchiveCreator.js.map +1 -0
  537. package/lib/packlets/zip-archive/zipArchiveFormat.d.ts.map +1 -0
  538. package/lib/packlets/zip-archive/zipArchiveFormat.js.map +1 -0
  539. package/lib/packlets/zip-archive/zipArchiveLoader.d.ts.map +1 -0
  540. package/lib/packlets/zip-archive/zipArchiveLoader.js.map +1 -0
  541. package/package.json +12 -10
  542. package/dist/test/data/sample.json +0 -32
  543. package/dist/test/unit/qualifier-types/testQualifierType.js +0 -76
  544. package/dist/test/unit/resource-types/testDerivedResourceType.js +0 -109
  545. package/dist/test/unit/resources/deltaGenerator.helpers.js +0 -282
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceType.js","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceType.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,YAAY,EAAyB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAwB,OAAO,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAEL,OAAO,IAAI,aAAa,EACxB,QAAQ,EAMT,MAAM,WAAW,CAAC;AAiHnB;;;;;GAKG;AACH,MAAM,OAAgB,YAAY;IAGhC;;OAEG;IACH,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;IAC/B,CAAC;IAOD;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IACjC,CAAC;IAED,YAAsB,GAAqB,EAAE,KAAc,EAAE,QAAqB;QAChF,IAAI,CAAC,YAAY,GAAG,IAAI,WAAW,CAAC,WAAW,CAAsC;YACnF,GAAG;YACH,qDAAqD;YACrD,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;YACtF,cAAc,EAAE,aAAa,CAAC,iBAAiB;SAChD,CAAC,CAAC;QACH,yCAAyC;QACzC,IAAI,CAAC,SAAS,GAAG,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC;IAClC,CAAC;IAoDD;;OAEG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;OAUG;IACI,cAAc,CACnB,UAAsB,EACtB,IAAgB,EAChB,UAA+C,EAC/C,QAA4B;QAE5B,OAAO,IAAI,CAAC,2BAA2B,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAC1F,OAAO,CAAC;YACN,EAAE,EAAE,UAAU;YACd,gBAAgB,EAAE,IAAI,CAAC,GAAG;YAC1B,UAAU,EAAE,CAAC,SAAS,CAAC;SACxB,CAAC,CACH,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,2BAA2B,CAChC,IAAgB,EAChB,UAA+C,EAC/C,UAA8B;QAE9B,IAAI,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,IAAI,CAAC,SAAS,CAAC;QAE9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,4BAA4B,IAAI,wBAAwB,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,SAAS,iCACb,IAAI,IACD,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACrC,WAAW,EAAE,SAAS,GACvB,CAAC;QAEF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;aAC/B,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,iCAAM,SAAS,KAAE,SAAS,EAAE,KAAK,IAAG,CAAC;aAChE,SAAS,CAAC,GAAG,EAAE,CACd,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,iCAAM,SAAS,KAAE,SAAS,EAAE,IAAI,IAAG,CAAC,CAC/F,CAAC;IACN,CAAC;CACF","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { isJsonObject, JsonObject, JsonValue } from '@fgv/ts-json-base';\nimport { Collections, fail, ICollectible, Result, succeed } from '@fgv/ts-utils';\nimport {\n CandidateCompleteness,\n Convert as CommonConvert,\n Validate,\n ResourceTypeIndex,\n ResourceTypeName,\n ResourceValueMergeMethod,\n ResourceId,\n IResourceResolver\n} from '../common';\nimport * as ResourceJson from '../resource-json';\n\n/**\n * Parameters used to validate a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}.\n * @public\n */\nexport interface IResourceCandidateValidationProperties {\n /**\n * {@inheritDoc ResourceJson.Json.ILooseResourceCandidateDecl.id}\n * @public\n */\n id: ResourceId;\n\n /**\n * Describes how complete the candidate value is.\n * @public\n */\n completeness: CandidateCompleteness;\n\n /**\n * {@inheritDoc ResourceJson.Json.ILooseResourceCandidateDecl.json}\n * @public\n */\n json: JsonValue;\n\n /**\n * {@inheritDoc ResourceJson.Json.ILooseResourceCandidateDecl.mergeMethod}\n * @public\n */\n mergeMethod: ResourceValueMergeMethod;\n}\n\n/**\n * Interface for a resource type. Resource types are responsible for\n * validating and converting JSON values into the appropriate strongly-typed\n * resource value.\n * @public\n */\nexport interface IResourceType<T = unknown> extends ICollectible<ResourceTypeName, ResourceTypeIndex> {\n /**\n * The key for this resource type.\n */\n readonly key: ResourceTypeName;\n\n /**\n * The index for this resource type.\n */\n readonly index: ResourceTypeIndex | undefined;\n\n /**\n * Validates properties of a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration} for\n * a resource instance value.\n * @param props - The {@link ResourceTypes.IResourceCandidateValidationProperties | properties } to validate.\n * @returns `Success` with the strongly-typed resource value if the JSON and merge method\n * are valid, `Failure` with an error message otherwise.\n * @public\n */\n validateDeclaration(props: IResourceCandidateValidationProperties): Result<T | Partial<T>>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n validate(json: JsonValue, completeness: CandidateCompleteness): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a complete resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n validate(json: JsonValue, completeness: 'full'): Result<T>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n validate(json: JsonValue, completeness: 'partial'): Result<Partial<T>>;\n\n /**\n * Sets the index for this resource type. Once set, the index cannot be changed.\n */\n setIndex(index: number): Result<ResourceTypeIndex>;\n\n /**\n * Creates a template for a new resource of this type.\n * The template provides a default structure for creating new resource instances.\n * @param resourceId - The id for the new resource.\n * @param init - An optional initial value for the resource.\n * @param resolver - An optional resource resolver that can be used to create the template.\n * @param conditions - An optional set of conditions that must be met for the resource to be selected.\n * @returns A loose resource declaration with default values for this resource type.\n * @public\n */\n createTemplate(\n resourceId: ResourceId,\n init?: JsonValue,\n conditions?: ResourceJson.Json.ConditionSetDecl,\n resolver?: IResourceResolver\n ): Result<ResourceJson.Json.ILooseResourceDecl>;\n}\n\n/**\n * Abstract base class for resource types which are responsible for\n * validating and converting JSON values into the appropriate strongly-typed\n * resource value.\n * @public\n */\nexport abstract class ResourceType<T = unknown> implements IResourceType<T> {\n private _collectible: Collections.Collectible<ResourceTypeName, ResourceTypeIndex>;\n private _template: JsonObject;\n /**\n * {@inheritDoc ResourceTypes.IResourceType.key}\n */\n public get key(): ResourceTypeName {\n return this._collectible.key;\n }\n\n /**\n * Name of the underlying system type.\n */\n public abstract readonly systemTypeName: ResourceTypeName;\n\n /**\n * {@inheritDoc ResourceTypes.IResourceType.index}\n */\n public get index(): ResourceTypeIndex | undefined {\n return this._collectible.index;\n }\n\n protected constructor(key: ResourceTypeName, index?: number, template?: JsonObject) {\n this._collectible = new Collections.Collectible<ResourceTypeName, ResourceTypeIndex>({\n key,\n /* c8 ignore next 1 - coverage having a rough time */\n index: index !== undefined ? Validate.toResourceTypeIndex(index).orThrow() : undefined,\n indexConverter: CommonConvert.resourceTypeIndex\n });\n /* c8 ignore next 1 - defense in depth */\n this._template = template ?? {};\n }\n\n /**\n * Validates properties of a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration} for\n * a resource instance value.\n * @param props - The {@link ResourceTypes.IResourceCandidateValidationProperties | properties } to validate.\n * @returns `Success` with the strongly-typed resource value if the JSON and merge method\n * are valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validateDeclaration(props: IResourceCandidateValidationProperties): Result<T | Partial<T>>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: CandidateCompleteness): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a complete resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: 'full'): Result<T>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: 'partial'): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a full or partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed full or partial resource value if\n * the JSON is valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness?: CandidateCompleteness): Result<T | Partial<T>>;\n\n /**\n * Sets the index for this resource type. Once set, the index cannot be changed.\n */\n public setIndex(index: number): Result<ResourceTypeIndex> {\n return this._collectible.setIndex(index);\n }\n\n /**\n * Creates a template for a new resource of this type.\n * Default implementation provides a basic template.\n * Subclasses can override to provide type-specific templates.\n * @param resourceId - The id for the new resource\n * @param init - An optional initial value for the resource.\n * @param conditions - An optional set of conditions that must be met for the resource to be selected.\n * @param resolver - An optional resource resolver that can be used to create the template.\n * @returns A loose resource declaration with default values for this resource type\n * @public\n */\n public createTemplate(\n resourceId: ResourceId,\n init?: JsonValue,\n conditions?: ResourceJson.Json.ConditionSetDecl,\n resolver?: IResourceResolver\n ): Result<ResourceJson.Json.ILooseResourceDecl> {\n return this.getDefaultTemplateCandidate(init, conditions, resolver).onSuccess((candidate) =>\n succeed({\n id: resourceId,\n resourceTypeName: this.key,\n candidates: [candidate]\n })\n );\n }\n\n /**\n * Gets the default template value for this resource type.\n * Subclasses should override this to provide type-specific default values.\n * @returns The default JSON value for a new resource of this type\n * @public\n */\n public getDefaultTemplateCandidate(\n json?: JsonValue,\n conditions?: ResourceJson.Json.ConditionSetDecl,\n __resolver?: IResourceResolver\n ): Result<ResourceJson.Json.IChildResourceCandidateDecl> {\n json = json ?? this._template;\n\n if (!isJsonObject(json)) {\n return fail(`${this.key}: Invalid initial value \"${json}\" must be JSON object.`);\n }\n\n const candidate: ResourceJson.Json.IChildResourceCandidateDecl = {\n json,\n ...(conditions ? { conditions } : {}),\n mergeMethod: 'replace'\n };\n\n return this.validate(json, 'full')\n .onSuccess((json) => succeed({ ...candidate, isPartial: false }))\n .onFailure(() =>\n this.validate(json, 'partial').onSuccess((json) => succeed({ ...candidate, isPartial: true }))\n );\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceTypeCollector.js","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceTypeCollector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,WAAW,EAAU,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAoB,MAAM,WAAW,CAAC;AAUvE;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,mBAAiC;IAC1E,YAAsB,EAAE,aAAa,EAAkC;QACrE,oDAAoD;QACpD,aAAa,GAAG,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC;QAEpC,KAAK,CAAC;YACJ,UAAU,EAAE,IAAI,WAAW,CAAC,kBAAkB,CAAiC;gBAC7E,GAAG,EAAE,aAAa,CAAC,gBAAgB;gBACnC,KAAK,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;aACrD,CAAC;SACH,CAAC,CAAC;QACH,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;YACrC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,MAAM,CAAC,MAAuC;QAC1D,oDAAoD;QACpD,MAAM,GAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;QACtB,OAAO,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;IAES,eAAe,CAAC,IAAa;QACrC,IAAI,IAAI,YAAY,YAAY,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;CACF","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Collections, Result, fail, succeed, ValidatingCollector, captureResult } from '@fgv/ts-utils';\nimport { ResourceType } from './resourceType';\nimport { Convert as CommonConvert, ResourceTypeName } from '../common';\n\n/**\n * Parameters for creating a {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector}.\n * @public\n */\nexport interface IResourceCollectorCreateParams {\n resourceTypes?: ResourceType[];\n}\n\n/**\n * Map {@link ResourceTypeName | resource type names} to {@link ResourceTypes.ResourceType | resource types}.\n * @public\n */\nexport class ResourceTypeCollector extends ValidatingCollector<ResourceType> {\n protected constructor({ resourceTypes }: IResourceCollectorCreateParams) {\n /* c8 ignore next 1 - coverage having a rough day */\n resourceTypes = resourceTypes ?? [];\n\n super({\n converters: new Collections.KeyValueConverters<ResourceTypeName, ResourceType>({\n key: CommonConvert.resourceTypeName,\n value: (from: unknown) => this._toResourceType(from)\n })\n });\n resourceTypes.forEach((resourceType) => {\n this.add(resourceType).orThrow();\n });\n }\n\n /**\n * Creates a new {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector}.\n * @param params - Optional for creating the new collector.\n * @returns `Success` with the new instance, or `Failure` with an error\n * message if the collector could not be created.\n */\n public static create(params?: IResourceCollectorCreateParams): Result<ResourceTypeCollector> {\n /* c8 ignore next 1 - coverage having a rough day */\n params = params ?? {};\n return captureResult(() => new ResourceTypeCollector(params));\n }\n\n protected _toResourceType(from: unknown): Result<ResourceType> {\n if (from instanceof ResourceType) {\n return succeed(from);\n }\n return fail('Not a resource type.');\n }\n}\n\n/**\n * A read-only version of {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector}.\n * @public\n */\nexport type ReadOnlyResourceTypeCollector = Collections.IReadOnlyValidatingCollector<ResourceType>;\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidateReducer.js","sourceRoot":"","sources":["../../../src/packlets/resources/candidateReducer.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { QualifierName, ResourceId, ResourceValueMergeMethod } from '../common';\nimport * as Context from '../context';\nimport * as ResourceJson from '../resource-json';\nimport { ResourceCandidate } from './resourceCandidate';\nimport { JsonObject } from '@fgv/ts-json-base';\nimport { JsonEditor } from '@fgv/ts-json';\nimport { Result, succeed, fail, mapResults } from '@fgv/ts-utils';\n\n/**\n * Action taken on a candidate during reduction processing.\n * @public\n */\nexport type CandidateAction = 'unchanged' | 'reduced' | 'suppressed';\n\n/**\n * Information about a candidate being processed by the reducer.\n * @public\n */\nexport interface ICandidateInfo {\n readonly originalCandidate: ResourceCandidate;\n action: CandidateAction;\n conditions: ResourceJson.Json.ILooseConditionDecl[];\n conditionSetKey: string;\n readonly json?: JsonObject;\n}\n\n/**\n * Represents a reduced candidate after applying reduction logic.\n * @public\n */\nexport interface IReducedCandidate {\n readonly candidate: ResourceCandidate;\n readonly conditions: ResourceJson.Json.ConditionSetDecl;\n readonly json?: JsonObject;\n readonly isPartial?: boolean;\n readonly mergeMethod?: ResourceValueMergeMethod;\n}\n\n/**\n * Manages candidate reduction logic for filtering and qualifier reduction operations.\n * Encapsulates the state and logic needed to consistently process candidates for reduction.\n * @public\n */\nexport class CandidateReducer {\n private readonly _candidateInfos: ICandidateInfo[];\n private readonly _filterForContext: Context.IValidatedContextDecl;\n private readonly _qualifiersToReduce: ReadonlySet<QualifierName>;\n\n /**\n * Constructor for CandidateReducer.\n * @param candidates - The set of candidates to potentially reduce\n * @param filterForContext - Context to filter candidates against\n */\n public constructor(\n candidates: ReadonlyArray<ResourceCandidate>,\n filterForContext: Context.IValidatedContextDecl\n ) {\n this._filterForContext = filterForContext;\n\n // Use existing logic to determine reducible qualifiers\n this._qualifiersToReduce =\n ResourceCandidate.findReducibleQualifiers(candidates, filterForContext) ?? new Set();\n\n // Initialize candidate info array with initial reduction attempts\n this._candidateInfos = candidates.map((candidate): ICandidateInfo => {\n const filteredConditions = candidate.conditions.conditions.filter(\n (c) => !this._qualifiersToReduce.has(c.qualifier.name)\n );\n\n const reducedConditions = filteredConditions.map((c) => c.toLooseConditionDecl());\n const conditionSetKey = CandidateReducer._computeConditionSetKey(reducedConditions);\n\n const action: CandidateAction =\n filteredConditions.length < candidate.conditions.conditions.length ? 'reduced' : 'unchanged';\n\n return {\n originalCandidate: candidate,\n action,\n conditions: reducedConditions,\n conditionSetKey,\n json: undefined // Will be set later when needed\n };\n });\n\n // Resolve collisions by reverting reduced candidates to unchanged when they collide\n this._resolveCollisions();\n }\n\n /**\n * Computes a string key for a set of condition declarations for collision detection.\n * @param conditions - The conditions to compute a key for\n * @returns A string key representing the condition set\n */\n private static _computeConditionSetKey(conditions: ResourceJson.Json.ILooseConditionDecl[]): string {\n if (conditions.length === 0) {\n return '{}';\n }\n\n // Sort conditions by qualifier name for consistent keys\n const sortedConditions = [...conditions].sort((a, b) => a.qualifierName.localeCompare(b.qualifierName));\n const pairs = sortedConditions.map((c) => `${c.qualifierName}:${c.value}`);\n return `{${pairs.join(',')}}`;\n }\n\n /**\n * Merges a partial candidate's JSON value into a base candidate's JSON value.\n * @param baseJson - The base JSON value to merge into\n * @param partialJson - The partial JSON value to merge from\n * @returns The merged JSON value\n * @internal\n */\n private static _mergeJsonValues(baseJson: JsonObject, partialJson: JsonObject): JsonObject {\n // Create JsonEditor with array replacement behavior for candidate merging\n const editor = JsonEditor.create({\n merge: {\n arrayMergeBehavior: 'replace'\n }\n }).orThrow(); // Should never fail with valid options\n\n return editor.mergeObjectsInPlace({}, [baseJson, partialJson]).orThrow(); // Internal method should throw on error - this indicates a serious bug\n }\n\n /**\n * Resolves collisions using smart collision resolution rules.\n * - If a reduced candidate collides with an unchanged candidate and only one reduced candidate collides:\n * - If reduced candidate is complete: suppress unchanged, keep reduced\n * - If reduced candidate is partial: merge into unchanged, suppress reduced\n * - Otherwise: revert reduced candidates to unchanged to avoid collisions\n * @internal\n */\n private _resolveCollisions(): void {\n let hasCollisions = true;\n let iterationCount = 0;\n const maxIterations = this._candidateInfos.length; // Safety limit\n\n while (hasCollisions && iterationCount < maxIterations) {\n hasCollisions = false;\n iterationCount++;\n\n // Group candidates by their condition set keys (excluding suppressed)\n const conditionKeyGroups = new Map<string, ICandidateInfo[]>();\n\n for (const candidateInfo of this._candidateInfos) {\n if (candidateInfo.action !== 'suppressed') {\n // Don't include suppressed candidates\n const key = candidateInfo.conditionSetKey;\n if (!conditionKeyGroups.has(key)) {\n conditionKeyGroups.set(key, []);\n }\n conditionKeyGroups.get(key)!.push(candidateInfo);\n }\n }\n\n // Apply smart collision resolution\n for (const [, candidatesWithSameKey] of conditionKeyGroups) {\n if (candidatesWithSameKey.length > 1) {\n // Categorize candidates\n const unchangedCandidates = candidatesWithSameKey.filter((c) => c.action === 'unchanged');\n const reducedCandidates = candidatesWithSameKey.filter((c) => c.action === 'reduced');\n\n if (unchangedCandidates.length === 1 && reducedCandidates.length === 1) {\n // Simple case: one unchanged vs one reduced - apply smart resolution\n const unchangedCandidate = unchangedCandidates[0];\n const reducedCandidate = reducedCandidates[0];\n\n if (!reducedCandidate.originalCandidate.isPartial) {\n // Complete reduced candidate wins - suppress unchanged\n unchangedCandidate.action = 'suppressed';\n hasCollisions = true;\n } else {\n /* c8 ignore next 12 - complex collision handling for partial candidates rarely triggered */\n // Partial reduced candidate - merge into unchanged and suppress reduced\n const mergedJson = CandidateReducer._mergeJsonValues(\n unchangedCandidate.originalCandidate.json,\n reducedCandidate.originalCandidate.json\n );\n\n // Update unchanged candidate with merged JSON, keeping its isPartial status\n (unchangedCandidate as { json?: JsonObject }).json = mergedJson;\n\n // Suppress the reduced candidate\n reducedCandidate.action = 'suppressed';\n hasCollisions = true;\n }\n } else {\n /* c8 ignore next 15 - complex collision reversion logic rarely triggered in practice */\n // Complex collision case - revert all reduced candidates to unchanged\n for (const candidateInfo of reducedCandidates) {\n // Revert to original conditions and mark as unchanged\n const originalConditions = candidateInfo.originalCandidate.conditions.conditions.map((c) =>\n c.toLooseConditionDecl()\n );\n const originalKey = CandidateReducer._computeConditionSetKey(originalConditions);\n\n // Update the candidate info to revert to original state\n candidateInfo.action = 'unchanged';\n candidateInfo.conditions = originalConditions;\n candidateInfo.conditionSetKey = originalKey;\n\n hasCollisions = true;\n }\n }\n }\n }\n }\n }\n\n /**\n * Static convenience method to construct an array of properly reduced\n * {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declarations}\n * from a set of {@link Resources.ResourceCandidate | resource candidates}.\n * @param candidates - The candidates to reduce\n * @param filterForContext - Optional context to filter against\n * @returns Result with array of reduced candidate declarations, or Failure if reduction fails\n */\n public static reduceToChildResourceCandidateDecls(\n candidates: ReadonlyArray<ResourceCandidate>,\n filterForContext?: Context.IValidatedContextDecl\n ): Result<ResourceJson.Json.IChildResourceCandidateDecl[]> {\n if (!filterForContext || Object.keys(filterForContext).length === 0) {\n return succeed(candidates.map((candidate) => candidate.toChildResourceCandidateDecl()));\n }\n\n const reducer = new CandidateReducer(candidates, filterForContext);\n const reductionResults = mapResults(candidates.map((candidate) => reducer.reduceCandidate(candidate)));\n\n return reductionResults.onSuccess((reductions) => {\n const validReductions = reductions.filter(\n (reduction): reduction is IReducedCandidate => reduction !== undefined\n );\n\n return succeed(\n validReductions.map((reduction) => ({\n /* c8 ignore next 3 -- defense in depth */\n json: reduction.json ?? reduction.candidate.json,\n isPartial: reduction.isPartial ?? reduction.candidate.isPartial,\n mergeMethod: reduction.mergeMethod ?? reduction.candidate.mergeMethod,\n conditions: reduction.conditions\n }))\n );\n });\n }\n\n /**\n * Static convenience method to construct an array of properly reduced\n * {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declarations}\n * from a set of {@link Resources.ResourceCandidate | resource candidates}.\n * @param id - The id of the resource\n * @param candidates - The candidates to reduce\n * @param filterForContext - Optional context to filter against\n * @returns Result with array of reduced candidate declarations, or Failure if reduction fails\n */\n public static reduceToLooseResourceCandidateDecls(\n id: ResourceId,\n candidates: ReadonlyArray<ResourceCandidate>,\n filterForContext?: Context.IValidatedContextDecl\n ): Result<ResourceJson.Json.ILooseResourceCandidateDecl[]> {\n if (!filterForContext || Object.keys(filterForContext).length === 0) {\n return succeed(candidates.map((candidate) => candidate.toLooseResourceCandidateDecl()));\n }\n\n const reducer = new CandidateReducer(candidates, filterForContext);\n const reductionResults = mapResults(candidates.map((candidate) => reducer.reduceCandidate(candidate)));\n\n return reductionResults.onSuccess((reductions) => {\n const validReductions = reductions.filter(\n (reduction): reduction is IReducedCandidate => reduction !== undefined\n );\n\n return succeed(\n validReductions.map((reduction) => ({\n id,\n /* c8 ignore next 3 -- defense in depth */\n json: reduction.json ?? reduction.candidate.json,\n isPartial: reduction.isPartial ?? reduction.candidate.isPartial,\n mergeMethod: reduction.mergeMethod ?? reduction.candidate.mergeMethod,\n conditions: reduction.conditions\n }))\n );\n });\n }\n\n /**\n * Reduces a single candidate according to the configured reduction rules.\n * @param candidate - The candidate to reduce\n * @returns Either a reduced candidate declaration or an error if the candidate is not found\n */\n public reduceCandidate(candidate: ResourceCandidate): Result<IReducedCandidate | undefined> {\n const candidateInfo = this._candidateInfos.find((info) => info.originalCandidate === candidate);\n /* c8 ignore next 3 - defensive coding: candidate should always be found if properly managed */\n if (!candidateInfo) {\n return fail(`Candidate not found in reducer state`);\n }\n\n if (candidateInfo.action === 'suppressed') {\n return succeed(undefined);\n }\n\n // Convert array of conditions back to ConditionSetDecl for compatibility\n const conditionsAsRecord = candidateInfo.conditions.reduce((acc, condition) => {\n return { ...acc, [condition.qualifierName]: condition.value };\n }, {} as ResourceJson.Json.ConditionSetDecl);\n\n return succeed({\n candidate,\n conditions: conditionsAsRecord,\n json: candidateInfo.json ?? candidate.json,\n isPartial: candidate.isPartial,\n mergeMethod: candidate.mergeMethod\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidateValue.js","sourceRoot":"","sources":["../../../src/packlets/resources/candidateValue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,WAAW,EAAE,IAAI,EAAU,aAAa,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAA0C,OAAO,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAsDpC;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IAIzB;;OAEG;IACH,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,YAAsB,MAAmC;;QACvD,yCAAyC;QACzC,MAAM,UAAU,GAAG,MAAA,MAAM,CAAC,UAAU,mCAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QAEnE,2BAA2B;QAC3B,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAExC,2DAA2D;QAC3D,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAEtF,yDAAyD;QACzD,IAAI,CAAC,YAAY,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC;YAC9C,GAAG;YACH,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,mBAAmB;SACnD,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,MAAmC;QACtD,OAAO,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,CAAC;IAED;;;;;OAKG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;CACF","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Collections, Hash, Result, captureResult } from '@fgv/ts-utils';\nimport { CandidateValueIndex, CandidateValueKey, Convert as CommonConverters } from '../common';\nimport * as Common from '../common';\n\n/**\n * Interface for a candidate value that can be collected and indexed.\n * Candidate values are normalized JSON values that can be shared across\n * multiple resource candidates to reduce duplication.\n * @public\n */\nexport interface ICandidateValue extends Collections.ICollectible<CandidateValueKey, CandidateValueIndex> {\n /**\n * The unique key for this candidate value, derived from the hash of the normalized JSON.\n */\n readonly key: CandidateValueKey;\n\n /**\n * The index of this candidate value in the collection.\n */\n readonly index: CandidateValueIndex | undefined;\n\n /**\n * The normalized JSON value.\n */\n readonly json: JsonValue;\n\n /**\n * Sets the index of this candidate value.\n * @param index - The index to set.\n * @returns `Success` with the index if successful, or `Failure` with an error message if not.\n */\n setIndex(index: number): Result<CandidateValueIndex>;\n}\n\n/**\n * Parameters for creating a {@link Resources.CandidateValue | CandidateValue}.\n * @public\n */\nexport interface ICandidateValueCreateParams {\n /**\n * The JSON value to store. Will be normalized during creation.\n */\n json: JsonValue;\n\n /**\n * Optional normalizer to use for normalizing the JSON value.\n * If not provided, a default Crc32Normalizer will be used.\n */\n normalizer?: Hash.Crc32Normalizer;\n\n /**\n * Optional index if the value is already indexed.\n */\n index?: number;\n}\n\n/**\n * Implementation of a candidate value that stores normalized JSON data.\n * The value is normalized on creation and a hash-based key is generated\n * for efficient deduplication.\n * @public\n */\nexport class CandidateValue implements ICandidateValue {\n private readonly _collectible: Collections.Collectible<CandidateValueKey, CandidateValueIndex>;\n private readonly _json: JsonValue;\n\n /**\n * The unique key for this candidate value.\n */\n public get key(): CandidateValueKey {\n return this._collectible.key;\n }\n\n /**\n * The index of this candidate value in the collection.\n */\n public get index(): CandidateValueIndex | undefined {\n return this._collectible.index;\n }\n\n /**\n * The normalized JSON value.\n */\n public get json(): JsonValue {\n return this._json;\n }\n\n /**\n * Constructor for a {@link Resources.CandidateValue} object.\n * @param params - Parameters to create the candidate value.\n * @internal\n */\n protected constructor(params: ICandidateValueCreateParams) {\n /* c8 ignore next 1 - defense in depth */\n const normalizer = params.normalizer ?? new Hash.Crc32Normalizer();\n\n // Normalize the JSON value\n const normalizedResult = normalizer.normalize(params.json);\n this._json = normalizedResult.orThrow();\n\n // Generate key from the normalized value using computeHash\n const keyResult = normalizer.computeHash(this._json);\n const key = CommonConverters.candidateValueKey.convert(keyResult.orThrow()).orThrow();\n\n // Create the collectible with the key and optional index\n this._collectible = new Collections.Collectible({\n key,\n index: params.index,\n indexConverter: Common.Convert.candidateValueIndex\n });\n }\n\n /**\n * Creates a new {@link Resources.CandidateValue} object.\n * @param params - Parameters to create the candidate value.\n * @returns `Success` with the new candidate value if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: ICandidateValueCreateParams): Result<CandidateValue> {\n return captureResult(() => new CandidateValue(params));\n }\n\n /**\n * Sets the index of this candidate value.\n * @param index - The index to set.\n * @returns `Success` with the index if successful, or `Failure` with an error message if not.\n * @public\n */\n public setIndex(index: number): Result<CandidateValueIndex> {\n return this._collectible.setIndex(index);\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidateValueCollector.js","sourceRoot":"","sources":["../../../src/packlets/resources/candidateValueCollector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAa,UAAU,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,IAAI,EAAU,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,OAAO,IAAI,aAAa,EAAqB,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAmBlD;;;;;GAKG;AACH,MAAM,OAAO,uBAAwB,SAAQ,mBAAmC;IAG9E;;;;OAIG;IACH,YAAsB,MAA6C;;QACjE,KAAK,CAAC;YACJ,UAAU,EAAE,IAAI,WAAW,CAAC,kBAAkB,CAAoC;gBAChF,GAAG,EAAE,aAAa,CAAC,iBAAiB;gBACpC,KAAK,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;aACvD,CAAC;SACH,CAAC,CAAC;QACH,yCAAyC;QACzC,MAAM,GAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,MAAA,MAAM,CAAC,UAAU,mCAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QAClE,MAAA,MAAM,CAAC,eAAe,0CAAE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,MAA6C;QAChE,OAAO,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACI,gBAAgB;QACrB,mFAAmF;QACnF,iCAAiC;QACjC,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACK,iBAAiB,CAAC,IAAa;QACrC,kFAAkF;QAClF,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;YACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,sDAAsD;QACtD,OAAO,cAAc,CAAC,SAAS;aAC5B,QAAQ,CAAC,IAAI,CAAC;aACd,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAuB,GAAG,EAAE,CAAC;aACtD,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE;YACvB,OAAO,cAAc,CAAC,MAAM,CAAC;gBAC3B,IAAI,EAAE,SAAS;gBACf,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACF","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { JsonValue, Validators as JsonValidators } from '@fgv/ts-json-base';\nimport { Collections, Hash, Result, captureResult, succeed, ValidatingCollector } from '@fgv/ts-utils';\nimport { Convert as CommonConvert, CandidateValueKey } from '../common';\nimport { CandidateValue } from './candidateValue';\n\n/**\n * Parameters for creating a {@link Resources.CandidateValueCollector}.\n * @public\n */\nexport interface ICandidateValueCollectorCreateParams {\n /**\n * Optional normalizer to use for normalizing JSON values.\n * If not provided, a default Crc32Normalizer will be used.\n */\n normalizer?: Hash.HashingNormalizer;\n\n /**\n * Optional initial candidate values to add to the collection.\n */\n candidateValues?: (CandidateValue | JsonValue)[];\n}\n\n/**\n * A `ValidatingCollector` for {@link Resources.CandidateValue | CandidateValues},\n * which collects candidate values supplied as either {@link Resources.CandidateValue | CandidateValue} or\n * `JsonValue`.\n * @public\n */\nexport class CandidateValueCollector extends ValidatingCollector<CandidateValue> {\n public readonly normalizer: Hash.HashingNormalizer;\n\n /**\n * Constructor for a {@link Resources.CandidateValueCollector} object.\n * @param params - Parameters to create the collector.\n * @internal\n */\n protected constructor(params?: ICandidateValueCollectorCreateParams) {\n super({\n converters: new Collections.KeyValueConverters<CandidateValueKey, CandidateValue>({\n key: CommonConvert.candidateValueKey,\n value: (from: unknown) => this._toCandidateValue(from)\n })\n });\n /* c8 ignore next 3 - defense in depth */\n params = params ?? {};\n this.normalizer = params.normalizer ?? new Hash.Crc32Normalizer();\n params.candidateValues?.forEach((candidateValue) => this.validating.add(candidateValue));\n }\n\n /**\n * Creates a new {@link Resources.CandidateValueCollector} object.\n * @param params - Parameters to create the collector.\n * @returns `Success` with the new collector if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params?: ICandidateValueCollectorCreateParams): Result<CandidateValueCollector> {\n return captureResult(() => new CandidateValueCollector(params));\n }\n\n /**\n * Returns an array of JSON values ordered by their indices.\n * @returns Array of JsonValue objects in index order.\n * @public\n */\n public getValuesByIndex(): JsonValue[] {\n // Use the base class valuesByIndex() method to get CandidateValues in index order,\n // then extract their JSON values\n return this.valuesByIndex().map((candidateValue) => candidateValue.json);\n }\n\n /**\n * Converter method to handle CandidateValue | JsonValue.\n * @param from - The value to convert.\n * @returns `Success` with the CandidateValue if successful, or `Failure` with an error message if not.\n * @internal\n */\n private _toCandidateValue(from: unknown): Result<CandidateValue> {\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (from instanceof CandidateValue) {\n return succeed(from);\n }\n\n // Validate as JsonValue and create new CandidateValue\n return JsonValidators.jsonValue\n .validate(from)\n .withErrorFormat((msg) => `Invalid JSON value: ${msg}`)\n .onSuccess((jsonValue) => {\n return CandidateValue.create({\n json: jsonValue,\n normalizer: this.normalizer\n });\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/resources/common.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as ResourceJson from '../resource-json';\nimport { IValidatedContextDecl } from '../context';\nimport { IReadOnlyQualifierCollector } from '../qualifiers';\nimport { ReadOnlyResourceTypeCollector } from '../resource-types';\n\n/**\n * Options for resource declaration operations with strongly-typed context filtering.\n * Extends the base IDeclarationOptions with proper type safety for context filtering.\n *\n * @example\n * ```typescript\n * // Preferred Result pattern with onSuccess chaining\n * resourceManager.validateContext({ language: 'en' })\n * .onSuccess((validatedContext) => {\n * return resourceManager.clone({ filterForContext: validatedContext });\n * })\n * .onSuccess((clonedManager) => {\n * return clonedManager.getResourceCollectionDecl();\n * })\n * .onFailure((error) => {\n * console.error('Failed to create filtered clone:', error);\n * });\n * ```\n * @public\n */\nexport interface IResourceDeclarationOptions extends ResourceJson.Helpers.IDeclarationOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n\n /**\n * If true, reduces the qualifiers of the resource candidates by removing qualifiers that are made\n * irrelevant by the filterForContext.\n * @defaultValue false\n */\n reduceQualifiers?: boolean;\n\n /**\n * Whether to include metadata in compiled outputs.\n * Metadata includes human-readable information like semantic keys\n * that can be useful for debugging or tooling.\n * @defaultValue false\n */\n includeMetadata?: boolean;\n}\n\n/**\n * Extended compiled resource options that includes context filtering capabilities.\n * This interface combines the standard compilation options with strongly-typed\n * context filtering for resource candidates.\n * @public\n */\nexport interface ICompiledResourceOptionsWithFilter extends ResourceJson.Compiled.ICompiledResourceOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n}\n\n/**\n * Options for ResourceManagerBuilder clone operations.\n * Extends IDeclarationOptions to include support for applying edits when cloning.\n * @public\n */\nexport interface IResourceManagerCloneOptions extends IResourceDeclarationOptions {\n /**\n * Optional array of loose condition declarations to be applied as edits during the clone operation.\n * These conditions can modify or extend the resource candidates in the cloned manager.\n */\n readonly candidates?: ReadonlyArray<ResourceJson.Json.ILooseResourceCandidateDecl>;\n\n /**\n * Optional qualifier collector to use for the cloned manager.\n * If not provided, uses the same qualifiers as the original manager.\n * This allows creating clones with different qualifier configurations.\n */\n readonly qualifiers?: IReadOnlyQualifierCollector;\n\n /**\n * Optional resource type collector to use for the cloned manager.\n * If not provided, uses the same resource types as the original manager.\n * This allows creating clones with different resource type configurations.\n */\n readonly resourceTypes?: ReadOnlyResourceTypeCollector;\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaGenerator.js","sourceRoot":"","sources":["../../../src/packlets/resources/deltaGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { captureResult, fail, Logging, MessageAggregator, Result, succeed } from '@fgv/ts-utils';\nimport { JsonValue, isJsonObject } from '@fgv/ts-json-base';\nimport { Diff } from '@fgv/ts-json';\nimport { ResourceId } from '../common';\nimport { IResourceResolver } from '../common';\nimport { ResourceManagerBuilder } from './resourceManagerBuilder';\nimport * as ResourceJson from '../resource-json';\nimport * as Context from '../context';\n\n/**\n * Interface for parameters to create a {@link Resources.DeltaGenerator | DeltaGenerator}.\n * @public\n */\nexport interface IDeltaGeneratorParams {\n /**\n * The baseline resource resolver to compare against.\n */\n baselineResolver: IResourceResolver;\n\n /**\n * The delta resource resolver containing changes.\n */\n deltaResolver: IResourceResolver;\n\n /**\n * The resource manager to clone and update.\n */\n resourceManager: ResourceManagerBuilder;\n\n /**\n * Optional logger for status and error reporting.\n */\n logger?: Logging.ILogger;\n}\n\n/**\n * Interface for options controlling delta generation behavior.\n * @public\n */\nexport interface IDeltaGeneratorOptions {\n /**\n * Context to use when resolving resources. If not provided, uses empty context.\n */\n context?: Context.IContextDecl;\n\n /**\n * Array of specific resource IDs to include in delta generation.\n * If not provided, generates deltas for all resources in the delta resolver.\n */\n resourceIds?: ReadonlyArray<string>;\n\n /**\n * Whether to skip resources that haven't changed. Default: true.\n */\n skipUnchanged?: boolean;\n}\n\n/**\n * Result of processing a single resource delta.\n * @internal\n */\ninterface IResourceDeltaResult {\n type: 'updated' | 'new' | 'skipped';\n resourceId: ResourceId;\n}\n\n/**\n * Class for generating resource deltas between baseline and delta resolvers.\n * Creates partial/augment candidates for updated resources and full/replace candidates for new resources.\n * Uses Diff.jsonThreeWayDiff for efficient delta computation.\n * @public\n */\nexport class DeltaGenerator {\n /**\n * The baseline resource resolver to compare against.\n * @internal\n */\n private readonly _baselineResolver: IResourceResolver;\n\n /**\n * The delta resource resolver containing changes.\n * @internal\n */\n private readonly _deltaResolver: IResourceResolver;\n\n /**\n * The resource manager to clone and update.\n * @internal\n */\n private readonly _resourceManager: ResourceManagerBuilder;\n\n /**\n * Logger for status and error reporting.\n * @internal\n */\n private readonly _logger: Logging.ILogger;\n\n /**\n * Constructor for a {@link Resources.DeltaGenerator | DeltaGenerator} object.\n * @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.\n * @internal\n */\n protected constructor(params: IDeltaGeneratorParams) {\n this._baselineResolver = params.baselineResolver;\n this._deltaResolver = params.deltaResolver;\n this._resourceManager = params.resourceManager;\n this._logger = params.logger ?? new Logging.NoOpLogger();\n }\n\n /**\n * Creates a new {@link Resources.DeltaGenerator | DeltaGenerator} object.\n * @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.\n * @returns `Success` with the new {@link Resources.DeltaGenerator | DeltaGenerator} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IDeltaGeneratorParams): Result<DeltaGenerator> {\n return captureResult(() => new DeltaGenerator(params));\n }\n\n /**\n * Generates deltas between baseline and delta resolvers.\n * Creates a cloned resource manager with partial/augment candidates for updates\n * and full/replace candidates for new resources.\n *\n * @param options - Options controlling delta generation behavior.\n * @returns `Success` with the updated resource manager if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public generate(options?: IDeltaGeneratorOptions): Result<ResourceManagerBuilder> {\n this._logger.info('Starting delta generation');\n\n const context = options?.context ?? {};\n const skipUnchanged = options?.skipUnchanged ?? true;\n\n return this._validateContext(context)\n .onSuccess((validatedContext) => this._enumerateTargetResources(options?.resourceIds, validatedContext))\n .onSuccess((resourceIds) => {\n return this._cloneResourceManager()\n .onSuccess((clonedManager) =>\n this._generateDeltas(clonedManager, resourceIds, context, skipUnchanged)\n )\n .onSuccess((manager) => {\n this._logger.info(`Delta generation completed successfully with ${manager.size} resources`);\n return succeed(manager);\n });\n });\n }\n\n /**\n * Validates the provided context declaration.\n * @param context - The context declaration to validate.\n * @returns `Success` with the validated context if successful, `Failure` otherwise.\n * @internal\n */\n private _validateContext(context: Context.IContextDecl): Result<Context.IValidatedContextDecl> {\n return this._resourceManager.validateContext(context);\n }\n\n /**\n * Enumerates target resource IDs for delta generation.\n * If specific resource IDs are provided, uses those. Otherwise, discovers all resources\n * from both the baseline resource manager and the delta resolver to ensure comprehensive\n * coverage of all potential resources.\n *\n * @param requestedIds - Optional array of specific resource IDs to target.\n * @param context - The validated context to use for resource discovery.\n * @returns `Success` with array of resource IDs if successful, `Failure` otherwise.\n * @internal\n */\n private _enumerateTargetResources(\n requestedIds: ReadonlyArray<string> | undefined,\n context: Context.IValidatedContextDecl\n ): Result<ReadonlyArray<ResourceId>> {\n /* c8 ignore next 20 - functional code tested but coverage intermittently missed */\n if (requestedIds && requestedIds.length > 0) {\n this._logger.info(`Using ${requestedIds.length} specified resource IDs`);\n // Validate the requested IDs\n const validatedIds: ResourceId[] = [];\n const errors = new MessageAggregator();\n\n for (const id of requestedIds) {\n const validationResult = this._resourceManager.getBuiltResource(id);\n if (validationResult.isSuccess()) {\n validatedIds.push(id as ResourceId);\n } else {\n errors.addMessage(`Invalid resource ID \"${id}\": ${validationResult.message}`);\n }\n }\n\n if (errors.hasMessages) {\n return fail(errors.toString());\n }\n\n return succeed(validatedIds);\n }\n\n // Discover resources from both baseline and delta resolvers to ensure comprehensive coverage\n this._logger.info('Discovering resources from both baseline and delta resolvers');\n\n return this._discoverAllResourceIds().onSuccess((allResourceIds) => {\n this._logger.info(`Discovered ${allResourceIds.length} unique resources across both resolvers`);\n return succeed(allResourceIds);\n });\n }\n\n /**\n * Discovers all unique resource IDs from both baseline and delta resolvers.\n * Creates a union of resource IDs from the baseline resource manager and delta resolver\n * to ensure comprehensive coverage of all resources.\n *\n * @returns `Success` with array of unique resource IDs if successful, `Failure` otherwise.\n * @internal\n */\n private _discoverAllResourceIds(): Result<ReadonlyArray<ResourceId>> {\n // Get resource IDs from baseline resource manager\n return this._resourceManager.getAllBuiltResources().onSuccess((baselineResources) => {\n const baselineResourceIds = baselineResources.map((r) => r.id);\n this._logger.detail(`Found ${baselineResourceIds.length} resources in baseline`);\n\n // Get resource IDs from delta resolver using the public interface\n const deltaResourceIds = this._deltaResolver.resourceIds;\n this._logger.detail(`Found ${deltaResourceIds.length} resources in delta`);\n\n // Create a union of resource IDs from both sources\n const allResourceIds = new Set<ResourceId>();\n\n // Add baseline resource IDs\n baselineResourceIds.forEach((id) => {\n allResourceIds.add(id);\n });\n\n // Add delta resource IDs\n deltaResourceIds.forEach((id) => {\n allResourceIds.add(id);\n });\n\n const uniqueResourceIds = Array.from(allResourceIds);\n this._logger.detail(`Created union of ${uniqueResourceIds.length} unique resource IDs`);\n\n return succeed(uniqueResourceIds);\n });\n }\n\n /**\n * Creates a clone of the resource manager for delta operations.\n * @returns `Success` with the cloned resource manager if successful, `Failure` otherwise.\n * @internal\n */\n private _cloneResourceManager(): Result<ResourceManagerBuilder> {\n this._logger.info('Cloning resource manager');\n return this._resourceManager.clone();\n }\n\n /**\n * Generates deltas for the specified resources and adds them to the cloned manager.\n *\n * @param clonedManager - The cloned resource manager to update.\n * @param resourceIds - Array of resource IDs to process.\n * @param context - The context to use for resource resolution.\n * @param skipUnchanged - Whether to skip resources that haven't changed.\n * @returns `Success` with the updated manager if successful, `Failure` otherwise.\n * @internal\n */\n private _generateDeltas(\n clonedManager: ResourceManagerBuilder,\n resourceIds: ReadonlyArray<ResourceId>,\n context: Context.IContextDecl,\n skipUnchanged: boolean\n ): Result<ResourceManagerBuilder> {\n this._logger.info(`Generating deltas for ${resourceIds.length} resources`);\n\n const errors = new MessageAggregator();\n let processedCount = 0;\n let changedCount = 0;\n let newCount = 0;\n let skippedCount = 0;\n\n for (const resourceId of resourceIds) {\n this._logger.detail(`Processing resource: ${resourceId}`);\n\n const result = this._generateResourceDelta(clonedManager, resourceId, context, skipUnchanged);\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (result.isFailure()) {\n errors.addMessage(`${resourceId}: ${result.message}`);\n continue;\n }\n\n processedCount++;\n\n // Track statistics based on result\n const deltaResult = result.value;\n if (deltaResult.type === 'skipped') {\n skippedCount++;\n } else if (deltaResult.type === 'new') {\n newCount++;\n } else {\n changedCount++;\n }\n }\n\n this._logger.info(\n `Processed ${processedCount} resources: ${changedCount} updated, ${newCount} new, ${skippedCount} skipped`\n );\n\n /* c8 ignore next 2 - functional code tested but coverage intermittently missed */\n if (errors.hasMessages) {\n return fail(`Delta generation failed with errors:\\n${errors.toString()}`);\n }\n\n return succeed(clonedManager);\n }\n\n /**\n * Generates a delta for a single resource and adds appropriate candidates to the manager.\n *\n * @param manager - The resource manager to update.\n * @param resourceId - The resource ID to process.\n * @param context - The context to use for resource resolution.\n * @param skipUnchanged - Whether to skip resources that haven't changed.\n * @returns `Success` with the resource delta result if successful, `Failure` otherwise.\n * @internal\n */\n private _generateResourceDelta(\n manager: ResourceManagerBuilder,\n resourceId: ResourceId,\n context: Context.IContextDecl,\n skipUnchanged: boolean\n ): Result<IResourceDeltaResult> {\n // Resolve values from both resolvers\n const baselineResult = this._baselineResolver.resolveComposedResourceValue(resourceId);\n const deltaResult = this._deltaResolver.resolveComposedResourceValue(resourceId);\n\n const baselineExists = baselineResult.isSuccess();\n const deltaExists = deltaResult.isSuccess();\n\n if (deltaExists && !baselineExists) {\n // New resource - exists in delta but not in baseline\n this._logger.detail(`${resourceId}: New resource detected (exists in delta only)`);\n return this._createNewResourceCandidate(manager, resourceId, deltaResult.value, context).onSuccess(() =>\n succeed({ type: 'new' as const, resourceId })\n );\n }\n\n if (baselineExists && !deltaExists) {\n // Baseline-only resource - exists in baseline but not in delta (potential deletion)\n // For now, skip these resources since delete merge method is not yet implemented\n // TODO: When 'delete' merge method is available, create deletion candidates here\n this._logger.detail(\n `${resourceId}: Baseline-only resource detected, skipping (delete merge method not yet implemented)`\n );\n return succeed({ type: 'skipped' as const, resourceId });\n }\n\n /* c8 ignore next 4 - defense in depth should not happen in practice */\n if (!baselineExists && !deltaExists) {\n // Resource doesn't exist in either resolver - this shouldn't happen due to enumeration logic\n return fail(`Resource ${resourceId} not found in either baseline or delta resolvers`);\n }\n\n // Both resolvers have the resource - check for changes\n // At this point, both results are successful so values are guaranteed to exist\n const baselineValue = baselineResult.value!; // Safe: baselineExists is true\n const deltaValue = deltaResult.value!; // Safe: deltaExists is true\n\n // Check if values are identical\n if (skipUnchanged && this._areValuesIdentical(baselineValue, deltaValue)) {\n this._logger.detail(`${resourceId}: No changes detected, skipping`);\n return succeed({ type: 'skipped' as const, resourceId });\n }\n\n // Updated resource - compute delta and create partial/augment candidate\n this._logger.detail(`${resourceId}: Changes detected, computing delta`);\n return this._createDeltaCandidate(manager, resourceId, baselineValue, deltaValue, context).onSuccess(() =>\n succeed({ type: 'updated' as const, resourceId })\n );\n }\n\n /**\n * Checks if two JSON values are identical.\n * @param value1 - First value to compare.\n * @param value2 - Second value to compare.\n * @returns True if values are identical, false otherwise.\n * @internal\n */\n private _areValuesIdentical(value1: JsonValue, value2: JsonValue): boolean {\n return JSON.stringify(value1) === JSON.stringify(value2);\n }\n\n /**\n * Creates a new resource candidate for a newly discovered resource.\n * Uses full/replace merge method since this is a completely new resource.\n *\n * @param manager - The resource manager to update.\n * @param resourceId - The resource ID for the new resource.\n * @param value - The resolved value for the new resource.\n * @param context - The context used for resolution.\n * @returns `Success` if the candidate was added successfully, `Failure` otherwise.\n * @internal\n */\n private _createNewResourceCandidate(\n manager: ResourceManagerBuilder,\n resourceId: ResourceId,\n value: JsonValue,\n context: Context.IContextDecl\n ): Result<void> {\n /* c8 ignore next 2 - functional code tested but coverage intermittently missed */\n if (!isJsonObject(value)) {\n return fail(`Resource value must be a JSON object, got ${typeof value}`);\n }\n\n const candidateDecl: ResourceJson.Json.ILooseResourceCandidateDecl = {\n id: resourceId,\n json: value,\n conditions: Object.keys(context).length > 0 ? context : undefined,\n isPartial: false,\n mergeMethod: 'replace',\n resourceTypeName: 'json' // Use 'json' resource type for new JSON resources\n };\n\n return manager.addLooseCandidate(candidateDecl).asResult.onSuccess(() => succeed(undefined));\n }\n\n /**\n * Creates a delta candidate for an updated resource.\n * Computes the difference between baseline and delta values and creates\n * a partial/augment candidate with only the changed properties.\n *\n * @param manager - The resource manager to update.\n * @param resourceId - The resource ID for the updated resource.\n * @param baselineValue - The baseline resolved value.\n * @param deltaValue - The delta resolved value.\n * @param context - The context used for resolution.\n * @returns `Success` if the candidate was added successfully, `Failure` otherwise.\n * @internal\n */\n private _createDeltaCandidate(\n manager: ResourceManagerBuilder,\n resourceId: ResourceId,\n baselineValue: JsonValue,\n deltaValue: JsonValue,\n context: Context.IContextDecl\n ): Result<void> {\n // Compute three-way diff to get only the changed properties\n return Diff.jsonThreeWayDiff(baselineValue, deltaValue).onSuccess((diff) => {\n if (diff.identical) {\n // This shouldn't happen if we checked for identity earlier, but be defensive\n this._logger.warn(`${resourceId}: Diff reports identical values, skipping`);\n return succeed(undefined);\n }\n\n // Use onlyInB (second object) which contains new/changed properties\n const deltaChanges = diff.onlyInB;\n\n /* c8 ignore next 2 - functional code tested but coverage intermittently missed */\n if (!isJsonObject(deltaChanges)) {\n return fail(`Delta changes must be a JSON object, got ${typeof deltaChanges}`);\n }\n\n // TODO: Handle deletions using 'augment' merge method with null values\n // Note: The 'delete' merge type is not yet implemented in ts-res, so we use 'augment'\n // with null values for deletion semantics (as used in ts-res-ui-components).\n // When the 'delete' merge type is available, this should be updated to use it.\n\n const candidateDecl: ResourceJson.Json.ILooseResourceCandidateDecl = {\n id: resourceId,\n json: deltaChanges,\n conditions: Object.keys(context).length > 0 ? context : undefined,\n isPartial: true,\n mergeMethod: 'augment',\n resourceTypeName: undefined // Will be inferred by the manager\n };\n\n return manager.addLooseCandidate(candidateDecl).asResult.onSuccess(() => succeed(undefined));\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/resources/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,UAAU,CAAC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport * from './candidateReducer';\nexport * from './candidateValue';\nexport * from './candidateValueCollector';\nexport * from './deltaGenerator';\nexport * from './resourceCandidate';\nexport * from './resource';\nexport * from './resourceBuilder';\nexport * from './resourceManagerBuilder';\nexport * from './common';\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../../src/packlets/resources/resource.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { MessageAggregator, Result, captureResult, fail, succeed } from '@fgv/ts-utils';\nimport { Helpers, ResourceId, ResourceName, Validate } from '../common';\nimport { ResourceCandidate } from './resourceCandidate';\nimport { CandidateReducer } from './candidateReducer';\nimport { ResourceType } from '../resource-types';\nimport { ConcreteDecision, AbstractDecisionCollector } from '../decisions';\nimport { IResource } from '../runtime';\nimport { IResourceDeclarationOptions, ICompiledResourceOptionsWithFilter } from './common';\nimport * as ResourceJson from '../resource-json';\nimport * as Context from '../context';\n\n/**\n * Parameters used to create a {@link Resources.Resource | Resource} object.\n * @public\n */\nexport interface IResourceCreateParams {\n /**\n * The id of the resource.\n */\n id?: string;\n /**\n * Optional {@link ResourceTypes.ResourceType | type} of the resource. If not specified, the type will be inferred\n * from the candidates.\n */\n resourceType?: ResourceType;\n /**\n * Array of {@link Resources.ResourceCandidate | candidates} for the resource.\n */\n candidates: ReadonlyArray<ResourceCandidate>;\n /**\n * {@link Decisions.AbstractDecisionCollector | AbstractDecisionCollector} used to create the optimized decision.\n */\n decisions: AbstractDecisionCollector;\n}\n\n/**\n * Represents a single logical resource, with a unique id and a set of possible\n * candidate instances.\n * @public\n */\nexport class Resource implements IResource {\n /**\n * The unique {@link ResourceId | id} of the resource.\n */\n public readonly id: ResourceId;\n\n /**\n * The name of the resource.\n */\n public readonly name: ResourceName;\n\n /**\n * The {@link ResourceTypes.ResourceType | type} of the resource.\n */\n public readonly resourceType: ResourceType;\n\n /**\n * The array of {@link Resources.ResourceCandidate | candidates} for the resource.\n */\n public readonly candidates: ReadonlyArray<ResourceCandidate>;\n /**\n * {@link Decisions.ConcreteDecision | Decision} for optimized resource resolution.\n */\n public readonly decision: ConcreteDecision;\n\n /**\n * Gets the resource type name as a string.\n */\n public get resourceTypeName(): string {\n return this.resourceType.key;\n }\n\n /**\n * Constructor for a {@link Resources.Resource | Resource} object.\n * @param params - {@link Resources.IResourceCreateParams | Parameters} used to create the resource.\n * @public\n */\n protected constructor(params: IResourceCreateParams) {\n const id = params.id ? Validate.toResourceId(params.id).orThrow() : undefined;\n this.id = Resource._validateCandidateResourceIds(id, params.candidates).orThrow();\n this.name = Helpers.getNameForResourceId(this.id).orThrow();\n this.resourceType = ResourceCandidate.validateResourceTypes(params.candidates, params.resourceType)\n .onSuccess((t) => {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (t === undefined) {\n return fail<ResourceType>(`${params.id}: no type specified and no candidates with types.`);\n }\n return succeed(t);\n })\n .orThrow();\n\n this.candidates = Resource._validateAndNormalizeCandidates(params.candidates).orThrow();\n this.decision = Resource._createOptimizedDecision(this.candidates, params.decisions).orThrow();\n }\n\n /**\n * Creates a new {@link Resources.Resource | Resource} object.\n * @param params - {@link Resources.IResourceCreateParams | Parameters} used to create the resource.\n * @returns `Success` with the new {@link Resources.Resource | Resource} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceCreateParams): Result<Resource> {\n return captureResult(() => new Resource(params));\n }\n\n /**\n * Gets the candidates for this resource that match the specified {@link Context.IValidatedContextDecl | context}.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns The array of {@link Resources.ResourceCandidate | candidates} that match the context.\n */\n public getCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceCandidate> {\n return this.candidates.filter((c) => c.canMatchPartialContext(context, options));\n }\n\n /**\n * Gets the {@link ResourceJson.Json.IChildResourceDecl | child resource declaration} for this resource.\n * @param options - {@link ResourceJson.Helpers.IDeclarationOptions | options} for the declaration.\n * @returns The {@link ResourceJson.Json.IChildResourceDecl | child resource declaration}.\n */\n public toChildResourceDecl(options?: IResourceDeclarationOptions): ResourceJson.Json.IChildResourceDecl {\n /* c8 ignore next 1 - defense in depth */\n options = options ?? {};\n const matches = this._getMatchingCandidates(options);\n\n const candidates = options.reduceQualifiers\n ? CandidateReducer.reduceToChildResourceCandidateDecls(matches, options.filterForContext).orThrow()\n : matches.map((c) => c.toChildResourceCandidateDecl());\n\n return {\n resourceTypeName: this.resourceTypeName,\n ...(candidates.length > 0 ? { candidates } : {})\n };\n }\n\n /**\n * Gets the {@link ResourceJson.Json.ILooseResourceDecl | loose resource declaration} for this resource.\n * @param options - {@link Resources.IResourceDeclarationOptions | options} for the declaration.\n * @returns The {@link ResourceJson.Json.ILooseResourceDecl | loose resource declaration}.\n */\n public toLooseResourceDecl(options?: IResourceDeclarationOptions): ResourceJson.Json.ILooseResourceDecl {\n /* c8 ignore next 1 - defense in depth */\n options = options ?? {};\n const matches = this._getMatchingCandidates(options);\n\n const candidates = options.reduceQualifiers\n ? CandidateReducer.reduceToChildResourceCandidateDecls(matches, options.filterForContext).orThrow()\n : matches.map((c) => c.toChildResourceCandidateDecl());\n\n return {\n id: this.id,\n resourceTypeName: this.resourceTypeName,\n ...(candidates.length > 0 ? { candidates } : {})\n };\n }\n\n /**\n * Converts this resource to a compiled resource representation.\n * @param options - Optional compilation options controlling the output format and filtering.\n * @returns A compiled resource object that can be used for serialization or runtime processing.\n * @public\n */\n public toCompiled(\n options?: IResourceDeclarationOptions | ICompiledResourceOptionsWithFilter\n ): ResourceJson.Compiled.ICompiledResource {\n const candidates: ResourceJson.Compiled.ICompiledCandidate[] = this._getMatchingCandidates(options).map(\n (c) => ({\n isPartial: c.isPartial,\n mergeMethod: c.mergeMethod,\n valueIndex: c.candidateValue.index!\n })\n );\n\n return {\n id: this.id,\n type: this.resourceType.index!,\n decision: this.decision.baseDecision.index!,\n candidates\n };\n }\n\n /**\n * Validates that all candidates have the same id as the resource.\n * @param resourceId - The expected id of the resource.\n * @param candidates - The array of candidates to validate.\n * @returns `Success` with the resource id if all candidates have the same id,\n * `Failure` with an error message otherwise.\n * @internal\n */\n private static _validateCandidateResourceIds(\n resourceId: ResourceId | undefined,\n candidates: ReadonlyArray<ResourceCandidate>\n ): Result<ResourceId> {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (!resourceId && candidates.length === 0) {\n return fail('unknown: no resource id and no candidates.');\n }\n resourceId = resourceId ?? candidates[0].id;\n\n const mismatched = candidates.filter((c) => c.id !== resourceId).map((c) => c.id);\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (mismatched.length > 0) {\n return fail(`${resourceId}: candidates with mismatched ids ${mismatched.join(', ')}.`);\n }\n return succeed(resourceId);\n }\n\n /**\n * Creates an optimized decision for the given candidates using the decisions collector.\n * @param candidates - The validated and normalized candidates to create a decision for.\n * @param decisions - The {@link Decisions.AbstractDecisionCollector | AbstractDecisionCollector} to use.\n * @returns `Success` with the {@link Decisions.ConcreteDecision | ConcreteDecision} if successful,\n * `Failure` with an error message otherwise.\n * @internal\n */\n private static _createOptimizedDecision(\n candidates: ReadonlyArray<ResourceCandidate>,\n decisions: AbstractDecisionCollector\n ): Result<ConcreteDecision> {\n const decisionCandidates = candidates.map((c) => ({\n conditionSet: c.conditions,\n value: c.json\n }));\n\n return ConcreteDecision.create({\n decisions,\n candidates: decisionCandidates\n });\n }\n\n /**\n * Validates and normalizes an array of {@link Resources.ResourceCandidate | candidates}. Fails if there\n * are multiple candidates for the same set of conditions.\n * @param candidates - The array of candidates to validate.\n * @returns `Success` with the validated and sorted array of candidates if successful,\n * `Failure` with an error message otherwise.\n * @internal\n */\n private static _validateAndNormalizeCandidates(\n candidates: ReadonlyArray<ResourceCandidate>\n ): Result<ReadonlyArray<ResourceCandidate>> {\n const errors = new MessageAggregator();\n const validated: Map<string, ResourceCandidate> = new Map();\n\n for (const candidate of candidates) {\n const conditionSetString = candidate.conditions.toString();\n const existing = validated.get(conditionSetString);\n if (existing) {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (!ResourceCandidate.equal(candidate, existing)) {\n errors.addMessage(`${candidate.id}: duplicate candidates for ${conditionSetString}.`);\n }\n } else {\n validated.set(conditionSetString, candidate);\n }\n }\n return errors.returnOrReport(\n succeed(Array.from(validated.values()).sort(ResourceCandidate.compare).reverse())\n );\n }\n\n /**\n * Gets the appropriate candidates based on filtering options.\n * If a validated filter context is provided, returns only matching candidates.\n * Otherwise returns all candidates.\n * @param options - Options that may contain a validated filter context\n * @returns The filtered array of candidates\n * @internal\n */\n protected _getMatchingCandidates(\n options?: IResourceDeclarationOptions | ICompiledResourceOptionsWithFilter\n ): ReadonlyArray<ResourceCandidate> {\n /* c8 ignore next 5 - functional code path tested but coverage intermittently missed */\n if (options?.filterForContext) {\n return this.candidates.filter((candidate) =>\n candidate.canMatchPartialContext(options.filterForContext!, { partialContextMatch: true })\n );\n }\n return this.candidates;\n }\n}\n"]}
@@ -81,7 +81,7 @@ export class ResourceBuilder {
81
81
  /**
82
82
  * Given a {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}, creates and adds a
83
83
  * {@link Resources.ResourceCandidate | candidate} to the resource being built.
84
- * @param candidate - The {@link ResourceJson.Json.IChildResourceCandidateDecl | IChildResourceCandidateDecl} to add to the
84
+ * @param childDecl - The {@link ResourceJson.Json.IChildResourceCandidateDecl | IChildResourceCandidateDecl} to add to the
85
85
  * resource being built.
86
86
  * @returns `Success` with the added {@link Resources.ResourceCandidate | candidate} if successful,
87
87
  * or `Failure` with an error message if not.
@@ -113,7 +113,7 @@ export class ResourceBuilder {
113
113
  /**
114
114
  * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, creates and adds a
115
115
  * {@link Resources.ResourceCandidate | candidate} to the resource being built.
116
- * @param candidate - The {@link ResourceJson.Json.ILooseResourceCandidateDecl | IResourceCandidateDecl} to add to the
116
+ * @param decl - The {@link ResourceJson.Json.ILooseResourceCandidateDecl | IResourceCandidateDecl} to add to the
117
117
  * resource being built.
118
118
  * @returns `Success` with the added {@link Resources.ResourceCandidate | candidate} if successful,
119
119
  * or `Failure` with an error message if not. Fails with error detail 'type-mismatch' if the candidate
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceBuilder.js","sourceRoot":"","sources":["../../../src/packlets/resources/resourceBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport {\n Collections,\n DetailedResult,\n Result,\n ResultMap,\n captureResult,\n fail,\n failWithDetail,\n succeed,\n succeedWithDetail\n} from '@fgv/ts-utils';\nimport { ResourceId, Validate } from '../common';\nimport { ResourceCandidate } from './resourceCandidate';\nimport { ReadOnlyResourceTypeCollector, ResourceType } from '../resource-types';\nimport { Resource } from './resource';\nimport { ConditionSetCollector } from '../conditions';\nimport { AbstractDecisionCollector } from '../decisions';\nimport { CandidateValueCollector } from './candidateValueCollector';\nimport * as ResourceJson from '../resource-json';\nimport * as Context from '../context';\n\n/**\n * Parameters for creating a {@link Resources.ResourceBuilder}.\n * @public\n */\nexport interface IResourceBuilderCreateParams {\n id: string;\n typeName?: string;\n conditionSets: ConditionSetCollector;\n resourceTypes: ReadOnlyResourceTypeCollector;\n decisions: AbstractDecisionCollector;\n candidateValues: CandidateValueCollector;\n}\n\n/**\n * Possible result details returned by the resource builder\n * {@link Resources.ResourceBuilder.addLooseCandidate | addLooseCandidate} method.\n * @public\n */\nexport type ResourceBuilderResultDetail = Collections.ResultMapResultDetail | 'id-mismatch' | 'type-mismatch';\n\n/**\n * Represents a builder for a single logical {@link Resources.Resource | resource}. Collects candidates\n * with a common resource ID, validates them against each other and builds a {@link Resources.Resource | resource}\n * object once all candidates are collected.\n * @public\n */\nexport class ResourceBuilder {\n /**\n * The unique {@link ResourceId | id} of the resource being built.\n */\n public readonly id: ResourceId;\n\n /**\n * Supplied or inferred {@link ResourceTypes.ResourceType | type} of the resource being built.\n * If no type is supplied, the type will be inferred from the candidates - at least one candidate must\n * define resource type and all candidates must be of the same type.\n */\n public get resourceType(): ResourceType | undefined {\n return this._resourceType;\n }\n\n /**\n * Array of {@link Resources.ResourceCandidate | candidates} for the resource being built.\n */\n public get candidates(): ReadonlyArray<ResourceCandidate> {\n return Array.from(this._candidates.values()).sort(ResourceCandidate.compare).reverse();\n }\n\n /**\n * The supplied or inferred {@link ResourceTypes.ResourceType | type} of the resource\n * being built.\n */\n protected _resourceType: ResourceType | undefined;\n\n /**\n * Map of {@link Resources.ResourceCandidate | candidates} for the resource being built.\n */\n protected _candidates: ResultMap<string, ResourceCandidate>;\n\n /**\n * Map of all known {@link ResourceTypes.ResourceType | resource types}.\n */\n protected _resourceTypes: ReadOnlyResourceTypeCollector;\n\n /**\n * Common collector for {@link Conditions.ConditionSet | condition sets}.\n */\n protected _conditionSets: ConditionSetCollector;\n\n /**\n * Collector for {@link Decisions.AbstractDecision | abstract decisions}.\n */\n protected _decisions: AbstractDecisionCollector;\n\n /**\n * Collector for candidate values.\n */\n protected _candidateValues: CandidateValueCollector;\n\n /**\n * Constructor for a {@link Resources.ResourceBuilder | ResourceBuilder} object.\n * @param params - Parameters to construct the new {@link Resources.ResourceBuilder | ResourceBuilder}.\n */\n protected constructor(params: IResourceBuilderCreateParams) {\n this.id = Validate.toResourceId(params.id).orThrow();\n this._resourceTypes = params.resourceTypes;\n this._conditionSets = params.conditionSets;\n this._decisions = params.decisions;\n this._candidateValues = params.candidateValues;\n this._candidates = new ResultMap<string, ResourceCandidate>();\n if (params.typeName) {\n this._resourceType = this._resourceTypes.validating.get(params.typeName).orThrow();\n }\n }\n\n /**\n * Creates a new {@link Resources.ResourceBuilder | ResourceBuilder} object.\n * @param params - Parameters to create a new {@link Resources.ResourceBuilder | ResourceBuilder}.\n * @returns `Success` with the new {@link Resources.ResourceBuilder | ResourceBuilder} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceBuilderCreateParams): Result<ResourceBuilder> {\n return captureResult(() => new ResourceBuilder(params));\n }\n\n /**\n * Gets the {@link Resources.ResourceCandidate | candidates} that match a given {@link Context.IValidatedContextDecl | context}.\n * @param context - The {@link Context.IValidatedContextDecl | context} to get candidates for.\n * @param options - Optional {@link Context.IContextMatchOptions | context match options} to use when matching candidates.\n * @returns An array of {@link Resources.ResourceCandidate | candidates} that match the given context.\n */\n public getCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceCandidate> {\n return Array.from(this._candidates.values()).filter((candidate) =>\n candidate.canMatchPartialContext(context, options)\n );\n }\n\n /**\n * Given a {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}, creates and adds a\n * {@link Resources.ResourceCandidate | candidate} to the resource being built.\n * @param childDecl - The {@link ResourceJson.Json.IChildResourceCandidateDecl | IChildResourceCandidateDecl} to add to the\n * resource being built.\n * @returns `Success` with the added {@link Resources.ResourceCandidate | candidate} if successful,\n * or `Failure` with an error message if not.\n */\n public addChildCandidate(\n childDecl: ResourceJson.Json.IChildResourceCandidateDecl\n ): DetailedResult<ResourceCandidate, ResourceBuilderResultDetail> {\n return ResourceCandidate.create({\n id: this.id,\n resourceType: this._resourceType,\n decl: childDecl,\n conditionSets: this._conditionSets,\n candidateValues: this._candidateValues\n })\n .withDetail<ResourceBuilderResultDetail>('failure', 'success')\n .onSuccess((candidate) => {\n return this._candidates\n .getOrAdd(candidate.conditions.toString(), candidate)\n .onSuccess((added, detail) => {\n if (detail === 'exists') {\n /* c8 ignore next 5 - defensive coding: conflicting candidates with same conditions should not occur */\n /* c8 ignore next 6 - functional code tested but coverage intermittently missed */\n if (!ResourceCandidate.equal(added, candidate)) {\n return failWithDetail<ResourceCandidate, Collections.ResultMapResultDetail>(\n `${this.id}: conflicting candidates.`,\n 'exists'\n );\n }\n }\n return succeedWithDetail(added, detail);\n });\n });\n }\n\n /**\n * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, creates and adds a\n * {@link Resources.ResourceCandidate | candidate} to the resource being built.\n * @param decl - The {@link ResourceJson.Json.ILooseResourceCandidateDecl | IResourceCandidateDecl} to add to the\n * resource being built.\n * @returns `Success` with the added {@link Resources.ResourceCandidate | candidate} if successful,\n * or `Failure` with an error message if not. Fails with error detail 'type-mismatch' if the candidate\n * specifies a different resource type than previously added candidates, or with 'exists' if a candidate\n * already exists with the same conditions but different values. Succeeds with 'exists' and returns the\n * existing candidate if the candidate to be added is identical to an existing candidate.\n */\n public addLooseCandidate(\n decl: ResourceJson.Json.ILooseResourceCandidateDecl\n ): DetailedResult<ResourceCandidate, ResourceBuilderResultDetail> {\n /* c8 ignore next 6 - functional code path tested but coverage intermittently missed */\n if (decl.id !== this.id) {\n return failWithDetail<ResourceCandidate, ResourceBuilderResultDetail>(\n `${this.id}: mismatched candidate id ${decl.id}.`,\n 'id-mismatch'\n );\n }\n\n if (decl.resourceTypeName !== undefined) {\n const rt = this.setResourceType(decl.resourceTypeName);\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (rt.isFailure()) {\n return failWithDetail<ResourceCandidate, ResourceBuilderResultDetail>(rt.message, 'type-mismatch');\n }\n }\n\n return this.addChildCandidate(decl);\n }\n\n /**\n * Sets the resource type for the resource being built. Fails if a resource type has already been set\n * and it does not match the new resource type.\n * @param resourceTypeName - The name of the resource type to set.\n * @returns `Success` with the updated {@link Resources.ResourceBuilder | ResourceBuilder} object if successful,\n * or `Failure` with an error message if not.\n */\n public setResourceType(resourceTypeName: string): Result<ResourceBuilder> {\n /* c8 ignore next 2 - functional code tested but coverage intermittently missed */\n if (this._resourceType?.key === resourceTypeName) {\n return succeed(this);\n } else if (this._resourceType !== undefined) {\n /* c8 ignore next 4 - functional code tested but coverage intermittently missed */\n return fail(\n `${this.id}: conflicting resource types ${this._resourceType.key} !== ${resourceTypeName}.`\n );\n }\n return this._resourceTypes.validating.get(resourceTypeName).onSuccess((resourceType) => {\n this._resourceType = resourceType;\n return succeedWithDetail(this, 'success');\n });\n }\n\n /**\n * Builds the {@link Resources.Resource | resource} object from this builder.\n * @returns `Success` with the new {@link Resources.Resource | Resource} object if successful,\n * or `Failure` with an error message if not. Fails if no candidates have been added\n * or if the resource type is not defined.\n */\n public build(): Result<Resource> {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (this._candidates.size === 0) {\n return fail(`${this.id}: no candidates supplied.`);\n }\n\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (this._resourceType === undefined) {\n return fail(`${this.id}: no resource type supplied or inferred.`);\n }\n\n return Resource.create({\n id: this.id,\n resourceType: this._resourceType,\n candidates: this.candidates,\n decisions: this._decisions\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceCandidate.js","sourceRoot":"","sources":["../../../src/packlets/resources/resourceCandidate.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { JsonObject } from '@fgv/ts-json-base';\nimport {\n CandidateCompleteness,\n PerfectMatch,\n QualifierName,\n ResourceId,\n ResourceValueMergeMethod,\n Validate\n} from '../common';\nimport { Condition, ConditionSet, ConditionSetCollector } from '../conditions';\nimport * as ResourceJson from '../resource-json';\nimport { ResourceType } from '../resource-types';\nimport { CandidateValue } from './candidateValue';\nimport { CandidateValueCollector } from './candidateValueCollector';\nimport { captureResult, mapResults, MessageAggregator, Result, fail, succeed } from '@fgv/ts-utils';\nimport * as Context from '../context';\nimport { IResourceCandidate } from '../runtime';\n\n/**\n * Parameters to create a {@link Resources.ResourceCandidate | ResourceCandidate}.\n * @public\n */\nexport interface IResourceCandidateCreateParams {\n id: string;\n decl: ResourceJson.Json.IChildResourceCandidateDecl;\n resourceType?: ResourceType;\n parentConditions?: ReadonlyArray<Condition>;\n conditionSets: ConditionSetCollector;\n candidateValues: CandidateValueCollector;\n}\n\n/**\n * Options for creating a {@link Resources.ResourceCandidate | ResourceCandidate} declaration.\n * @remarks\n * This interface extends the {@link ResourceJson.Helpers.IDeclarationOptions | declaration options}\n * interface to include a `reduceQualifiers` option.\n * @public\n */\nexport interface ICandidateDeclOptions extends ResourceJson.Helpers.IDeclarationOptions {\n /**\n * If provided, reduces the qualifiers of the candidate by removing qualifiers that are made\n * irrelevant by the filterForContext.\n */\n qualifiersToReduce?: ReadonlySet<QualifierName>;\n}\n\n/**\n * A {@link Resources.ResourceCandidate | resource candidate} represents a single possible\n * instance value for some resource, with the conditions under which it applies\n * and instructions on how to merge it with other instances.\n * @public\n */\nexport class ResourceCandidate implements IResourceCandidate {\n /**\n * The unique identifier of the resource for which this candidate\n * is a possible instance.\n */\n public readonly id: ResourceId;\n\n /**\n * The candidate value that contains the JSON representation of the instance data.\n */\n public readonly candidateValue: CandidateValue;\n\n /**\n * The JSON representation of the instance data to be applied.\n * @remarks\n * This property provides access to the JSON data from the underlying candidate value.\n */\n public get json(): JsonObject {\n return this.candidateValue.json as JsonObject;\n }\n\n /**\n * The conditions under which this candidate applies.\n */\n public readonly conditions: ConditionSet;\n\n /**\n * True if this candidate is a partial instance.\n */\n public readonly isPartial: boolean;\n\n /**\n * The method to use when merging this candidate with other instances.\n */\n public readonly mergeMethod: ResourceValueMergeMethod;\n\n /**\n * The {@link ResourceTypes.ResourceType | resource type} for the resource to which\n * this candidate belongs.\n */\n public readonly resourceType: ResourceType | undefined;\n\n /**\n * The completeness of the candidate value.\n */\n public get completeness(): CandidateCompleteness {\n return this.isPartial ? 'partial' : 'full';\n }\n\n /**\n * Constructor for a {@link Resources.ResourceCandidate | ResourceCandidate} object.\n * @param params - Parameters to create a new {@link Resources.ResourceCandidate | ResourceCandidate}.\n * @public\n */\n protected constructor(params: IResourceCandidateCreateParams) {\n this.id = Validate.toResourceId(params.id).orThrow();\n this.candidateValue = params.candidateValues.validating.getOrAdd(params.decl.json).orThrow();\n this.conditions = ResourceCandidate._mergeConditions(\n params.conditionSets,\n params.decl.conditions,\n params.parentConditions\n ).orThrow();\n this.isPartial = params.decl.isPartial ?? false;\n this.mergeMethod = params.decl.mergeMethod ?? 'augment';\n this.resourceType = params.resourceType;\n if (this.resourceType) {\n this.resourceType.validateDeclaration(this).orThrow();\n }\n }\n\n /**\n * Creates a new {@link Resources.ResourceCandidate | ResourceCandidate} object.\n * @param params - Parameters to create a new {@link Resources.ResourceCandidate | ResourceCandidate}.\n * @returns `Success` with the new {@link Resources.ResourceCandidate | ResourceCandidate} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceCandidateCreateParams): Result<ResourceCandidate> {\n return captureResult(() => new ResourceCandidate(params));\n }\n\n /**\n * Determines if this candidate can match the supplied context (possibly partial).\n * @param context - The context to match.\n * @param options - Options to use when matching.\n * @returns `true` if the candidate can match the context, `false` otherwise.\n */\n public canMatchPartialContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): boolean {\n return this.conditions.canMatchPartialContext(context, options);\n }\n\n /**\n * Gets the {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}\n * for this candidate.\n * @param options - {@link ResourceJson.Helpers.IDeclarationOptions | options} to use when creating the declaration.\n * @returns The {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}.\n */\n public toChildResourceCandidateDecl(\n options?: ICandidateDeclOptions\n ): ResourceJson.Json.IChildResourceCandidateDecl {\n const showDefaults = options?.showDefaults === true;\n return {\n json: this.json as JsonObject,\n conditions: this.conditions.toConditionSetRecordDecl(options),\n ...(showDefaults || this.isPartial ? { isPartial: this.isPartial } : {}),\n ...(showDefaults || this.mergeMethod !== 'augment' ? { mergeMethod: this.mergeMethod } : {})\n };\n }\n\n /**\n * Gets the {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}\n * for this candidate.\n * @param options - {@link ResourceJson.Helpers.IDeclarationOptions | options} to use when creating the declaration.\n * @returns The {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}.\n */\n public toLooseResourceCandidateDecl(\n options?: ICandidateDeclOptions\n ): ResourceJson.Json.ILooseResourceCandidateDecl {\n const showDefaults = options?.showDefaults === true;\n const resourceTypeName = this.resourceType?.key;\n return {\n id: this.id.toString(),\n json: this.json as JsonObject,\n conditions: this.conditions.toConditionSetRecordDecl(options),\n ...(showDefaults || this.isPartial ? { isPartial: this.isPartial } : {}),\n ...(showDefaults || this.mergeMethod !== 'augment' ? { mergeMethod: this.mergeMethod } : {}),\n ...(resourceTypeName ? { resourceTypeName } : {})\n };\n }\n\n /**\n * Extracts the {@link ResourceTypes.ResourceType | resource type} from a list of {@link Resources.ResourceCandidate | resource candidates},\n * if present.\n * @param candidates - The list of candidates from which to extract the resource type.\n * @returns `Success` with the resource type if successful, `Success` with `undefined` if none of the candidates\n * specify a resource tap, and `Failure` with an error message if clients specify conflicting resource types.\n * @public\n */\n public static validateResourceTypes(\n candidates: ReadonlyArray<ResourceCandidate>,\n expectedType?: ResourceType\n ): Result<ResourceType | undefined> {\n const errors = new MessageAggregator();\n let selectedType: ResourceType | undefined = expectedType;\n for (const candidate of candidates) {\n if (selectedType === undefined) {\n /* c8 ignore next 1 - functional code path tested but coverage intermittently missed */\n selectedType = candidate.resourceType;\n } else if (candidate.resourceType && selectedType !== candidate.resourceType) {\n /* c8 ignore next 4 - functional code path tested but coverage intermittently missed */\n errors.addMessage(\n `${candidate.id}: resource type mismatch (${selectedType.key} != ${candidate.resourceType.key})`\n );\n }\n }\n return errors.returnOrReport(succeed(selectedType));\n }\n\n /**\n * Compares two {@link Resources.ResourceCandidate | ResourceCandidates} for sorting purposes.\n * @param rc1 - The first candidate to compare.\n * @param rc2 - The second candidate to compare.\n * @returns A negative number if `rc1` should come before `rc2`, a positive number if `rc2` should come before `rc1`,\n * or zero if they are equivalent.\n * @public\n */\n public static compare(rc1: ResourceCandidate, rc2: ResourceCandidate): number {\n return ConditionSet.compare(rc1.conditions, rc2.conditions);\n }\n\n /**\n * Compares two {@link Resources.ResourceCandidate | ResourceCandidates} for equality.\n * @param rc1 - The first candidate to compare.\n * @param rc2 - The second candidate to compare.\n * @returns `true` if the candidates are equal, `false` otherwise.\n * @public\n */\n public static equal(rc1: ResourceCandidate, rc2: ResourceCandidate): boolean {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (rc1 === rc2) {\n return true;\n }\n let equal =\n rc1.id === rc2.id &&\n rc1.isPartial === rc2.isPartial &&\n rc1.mergeMethod === rc2.mergeMethod &&\n ConditionSet.compare(rc1.conditions, rc2.conditions) === 0;\n if (equal) {\n // Compare candidate values by their keys for efficient JSON comparison\n equal = rc1.candidateValue.key === rc2.candidateValue.key;\n }\n return equal;\n }\n\n /**\n * Validates declared conditions and merges them with parent conditions.\n * @param conditionSets - The {@link Conditions.ConditionSetCollector | condition set collector}\n * to use for this candidate.\n * @param declared - The declared conditions for the candidate.\n * @param parent - The parent conditions to merge with the declared conditions.\n * @returns `Success` with the merged conditions if successful, `Failure` otherwise.\n * @internal\n */\n private static _mergeConditions(\n conditionSets: ConditionSetCollector,\n declared: ResourceJson.Json.ConditionSetDecl | undefined,\n parent: ReadonlyArray<Condition> | undefined\n ): Result<ConditionSet> {\n /* c8 ignore next 2 - code coverage is flaky */\n declared = declared ?? {};\n parent = parent ?? [];\n\n const { value: conditionDecls, message } = ResourceJson.Convert.conditionSetDecl.convert(declared);\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (message !== undefined) {\n return fail(message);\n }\n\n return mapResults(\n // get or add all declared conditions from our condition collector\n conditionDecls.map((decl) => conditionSets.conditions.validating.getOrAdd(decl))\n ).onSuccess((declaredConditions) => {\n // make sure our parent conditions all come from our condition collector too\n return mapResults(parent.map((c) => conditionSets.conditions.getOrAdd(c))).onSuccess(\n (parentConditions) => {\n const conditions = [...parentConditions, ...declaredConditions];\n return conditionSets.validating.getOrAdd(conditions);\n }\n );\n });\n }\n\n /**\n * Finds the qualifiers that are made irrelevant by the supplied filterForContext.\n * @param candidates - The candidates to find the reducible qualifiers for.\n * @param filterForContext - The filter for context to use.\n * @returns The qualifiers that are made irrelevant by the filterForContext.\n * @remarks\n * For any given set of candidates, qualifiers that match every candidate perfectly\n * are irrelevant to the filtered content and can be removed. Qualifiers that do not\n * match, that are not in the filterForContext, or which partially match at least one\n * candidate remain relevant and must not be removed.\n * @public\n */\n public static findReducibleQualifiers(\n candidates: ReadonlyArray<ResourceCandidate>,\n filterForContext: Context.IValidatedContextDecl\n ): ReadonlySet<QualifierName> | undefined {\n const qualifiersToReduce = new Set<QualifierName>(Object.keys(filterForContext) as QualifierName[]);\n for (const candidate of candidates) {\n for (const condition of candidate.conditions.conditions) {\n if (qualifiersToReduce.has(condition.qualifier.name)) {\n const match = condition.qualifier.type.matches(\n condition.value,\n filterForContext[condition.qualifier.name],\n 'matches'\n );\n if (match !== PerfectMatch) {\n qualifiersToReduce.delete(condition.qualifier.name);\n }\n }\n }\n }\n return qualifiersToReduce.size > 0 ? qualifiersToReduce : undefined;\n }\n}\n"]}
@@ -90,13 +90,13 @@ export class ResourceManagerBuilder {
90
90
  return this._resources.size;
91
91
  }
92
92
  /**
93
- * {@inheritdoc Runtime.IResourceManager.numResources}
93
+ * {@inheritDoc Runtime.IResourceManager.numResources}
94
94
  */
95
95
  get numResources() {
96
96
  return this._resources.size;
97
97
  }
98
98
  /**
99
- * {@inheritdoc Runtime.IResourceManager.numCandidates}
99
+ * {@inheritDoc Runtime.IResourceManager.numCandidates}
100
100
  */
101
101
  get numCandidates() {
102
102
  if (this._numCandidates === undefined) {
@@ -105,7 +105,7 @@ export class ResourceManagerBuilder {
105
105
  return this._numCandidates;
106
106
  }
107
107
  /**
108
- * {@inheritdoc Runtime.IResourceManager.builtResources}
108
+ * {@inheritDoc Runtime.IResourceManager.builtResources}
109
109
  */
110
110
  get builtResources() {
111
111
  return this._performBuild().orThrow();
@@ -194,7 +194,7 @@ export class ResourceManagerBuilder {
194
194
  /**
195
195
  * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, builds and adds
196
196
  * a {@link Resources.ResourceCandidate | candidate} to the manager.
197
- * @param candidate - The {@link Resources.ResourceCandidate | candidate} to add.
197
+ * @param decl - The {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration} to add.
198
198
  * @returns `Success` with the candidate if successful, or `Failure` with an error message if not.
199
199
  * @public
200
200
  */
@@ -272,7 +272,7 @@ export class ResourceManagerBuilder {
272
272
  }
273
273
  /**
274
274
  * Adds a condition set to the manager.
275
- * @param decl - The condition set declaration to add.
275
+ * @param conditions - The {@link ResourceJson.Normalized.ConditionSetDecl | condition set declaration} to add.
276
276
  * @returns `Success` with the condition set if successful, or `Failure` with an error message if not.
277
277
  * @public
278
278
  */