@spottoai/types-package 1.0.2-dev1138.12 → 1.0.2-dev1138.14

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 (453) hide show
  1. package/README.md +3 -0
  2. package/dist/accounts/accounts.d.ts +13 -0
  3. package/dist/accounts/accounts.d.ts.map +1 -1
  4. package/dist/accounts/azureSpSetup.d.ts +5 -0
  5. package/dist/accounts/azureSpSetup.d.ts.map +1 -1
  6. package/dist/accounts/azureSpSetup.js.map +1 -1
  7. package/dist/accounts/index.d.ts +1 -0
  8. package/dist/accounts/index.d.ts.map +1 -1
  9. package/dist/accounts/index.js +1 -0
  10. package/dist/accounts/index.js.map +1 -1
  11. package/dist/accounts/subscriptionWriteAccess.d.ts +76 -0
  12. package/dist/accounts/subscriptionWriteAccess.d.ts.map +1 -0
  13. package/dist/accounts/subscriptionWriteAccess.js +119 -0
  14. package/dist/accounts/subscriptionWriteAccess.js.map +1 -0
  15. package/dist/accounts/writePermissions.d.ts +17 -1
  16. package/dist/accounts/writePermissions.d.ts.map +1 -1
  17. package/dist/accounts/writePermissions.js +47 -1
  18. package/dist/accounts/writePermissions.js.map +1 -1
  19. package/dist/ai/followUps.d.ts +16 -0
  20. package/dist/ai/followUps.d.ts.map +1 -0
  21. package/dist/ai/followUps.js +21 -0
  22. package/dist/ai/followUps.js.map +1 -0
  23. package/dist/ai/grounding.d.ts +42 -5
  24. package/dist/ai/grounding.d.ts.map +1 -1
  25. package/dist/ai/grounding.js +76 -8
  26. package/dist/ai/grounding.js.map +1 -1
  27. package/dist/ai/index.d.ts +4 -0
  28. package/dist/ai/index.d.ts.map +1 -1
  29. package/dist/ai/index.js +1 -0
  30. package/dist/ai/index.js.map +1 -1
  31. package/dist/aws/commitments-planning.d.ts +1 -1
  32. package/dist/aws/commitments-planning.d.ts.map +1 -1
  33. package/dist/aws/commitments-planning.js +1 -0
  34. package/dist/aws/commitments-planning.js.map +1 -1
  35. package/dist/aws/commitmentsPlanningValidation.d.ts +1 -1
  36. package/dist/aws/commitmentsPlanningValidation.d.ts.map +1 -1
  37. package/dist/aws/commitmentsPlanningValidation.js +26 -25
  38. package/dist/aws/commitmentsPlanningValidation.js.map +1 -1
  39. package/dist/aws/commitmentsPlanningView.d.ts +49 -0
  40. package/dist/aws/commitmentsPlanningView.d.ts.map +1 -0
  41. package/dist/aws/{pluginPublicArtifactEvidence.js → commitmentsPlanningView.js} +1 -1
  42. package/dist/aws/commitmentsPlanningView.js.map +1 -0
  43. package/dist/aws/index.d.ts +2 -14
  44. package/dist/aws/index.d.ts.map +1 -1
  45. package/dist/aws/index.js +2 -13
  46. package/dist/aws/index.js.map +1 -1
  47. package/dist/aws/organizationCommitments.d.ts +2 -1
  48. package/dist/aws/organizationCommitments.d.ts.map +1 -1
  49. package/dist/aws/organizationCommitments.js +2 -2
  50. package/dist/aws/organizationCommitments.js.map +1 -1
  51. package/dist/aws/organizationCommitmentsApiValidation.d.ts.map +1 -1
  52. package/dist/aws/organizationCommitmentsApiValidation.js +64 -64
  53. package/dist/aws/organizationCommitmentsApiValidation.js.map +1 -1
  54. package/dist/aws/organizationCommitmentsValidation.d.ts.map +1 -1
  55. package/dist/aws/organizationCommitmentsValidation.js +45 -44
  56. package/dist/aws/organizationCommitmentsValidation.js.map +1 -1
  57. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.d.ts.map +1 -1
  58. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +79 -76
  59. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js.map +1 -1
  60. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts +1 -2
  61. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts.map +1 -1
  62. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.js.map +1 -1
  63. package/dist/aws/publicArtifacts.d.ts +2 -37
  64. package/dist/aws/publicArtifacts.d.ts.map +1 -1
  65. package/dist/aws/publicArtifacts.js +3 -1
  66. package/dist/aws/publicArtifacts.js.map +1 -1
  67. package/dist/aws/relationships.d.ts +5 -3
  68. package/dist/aws/relationships.d.ts.map +1 -1
  69. package/dist/aws/relationships.js +18 -3
  70. package/dist/aws/relationships.js.map +1 -1
  71. package/dist/aws/requests.d.ts +35 -3
  72. package/dist/aws/requests.d.ts.map +1 -1
  73. package/dist/aws/requests.js +5 -3
  74. package/dist/aws/requests.js.map +1 -1
  75. package/dist/aws/resourceGraph.d.ts +14 -0
  76. package/dist/aws/resourceGraph.d.ts.map +1 -0
  77. package/dist/aws/resourceGraph.js +68 -0
  78. package/dist/aws/resourceGraph.js.map +1 -0
  79. package/dist/aws/validationHelpers.d.ts +8 -0
  80. package/dist/aws/validationHelpers.d.ts.map +1 -0
  81. package/dist/aws/validationHelpers.js +54 -0
  82. package/dist/aws/validationHelpers.js.map +1 -0
  83. package/dist/azure/commitmentsPlanning.d.ts +15 -46
  84. package/dist/azure/commitmentsPlanning.d.ts.map +1 -1
  85. package/dist/azure/commitmentsPlanning.js +9 -0
  86. package/dist/azure/commitmentsPlanning.js.map +1 -1
  87. package/dist/azure/commitmentsPlanningValidation.d.ts +18 -0
  88. package/dist/azure/commitmentsPlanningValidation.d.ts.map +1 -0
  89. package/dist/azure/commitmentsPlanningValidation.js +50 -0
  90. package/dist/azure/commitmentsPlanningValidation.js.map +1 -0
  91. package/dist/azure/dataProtection.d.ts +40 -0
  92. package/dist/azure/dataProtection.d.ts.map +1 -1
  93. package/dist/azure/governance.d.ts +5 -0
  94. package/dist/azure/governance.d.ts.map +1 -1
  95. package/dist/azure/metrics.d.ts +2 -27
  96. package/dist/azure/metrics.d.ts.map +1 -1
  97. package/dist/azure/payloads.d.ts +24 -0
  98. package/dist/azure/payloads.d.ts.map +1 -1
  99. package/dist/azure/payloads.js +87 -0
  100. package/dist/azure/payloads.js.map +1 -1
  101. package/dist/azure/recommendationTracks.d.ts +1 -1
  102. package/dist/azure/recommendationTracks.d.ts.map +1 -1
  103. package/dist/azure/reportEvidence.d.ts +192 -11
  104. package/dist/azure/reportEvidence.d.ts.map +1 -1
  105. package/dist/azure/reportEvidence.js +9 -1
  106. package/dist/azure/reportEvidence.js.map +1 -1
  107. package/dist/azure/reportEvidenceValidation.d.ts.map +1 -1
  108. package/dist/azure/reportEvidenceValidation.js +201 -5
  109. package/dist/azure/reportEvidenceValidation.js.map +1 -1
  110. package/dist/azure/reportEvidenceValidationHelpers.d.ts +3 -16
  111. package/dist/azure/reportEvidenceValidationHelpers.d.ts.map +1 -1
  112. package/dist/azure/reportEvidenceValidationHelpers.js +80 -92
  113. package/dist/azure/reportEvidenceValidationHelpers.js.map +1 -1
  114. package/dist/azure/resilienceFacts.d.ts +100 -0
  115. package/dist/azure/resilienceFacts.d.ts.map +1 -0
  116. package/dist/azure/resilienceFacts.js +20 -0
  117. package/dist/azure/resilienceFacts.js.map +1 -0
  118. package/dist/azure/resilienceFactsValidation.d.ts +4 -0
  119. package/dist/azure/resilienceFactsValidation.d.ts.map +1 -0
  120. package/dist/azure/resilienceFactsValidation.js +70 -0
  121. package/dist/azure/resilienceFactsValidation.js.map +1 -0
  122. package/dist/azure/savings.d.ts +4 -2
  123. package/dist/azure/savings.d.ts.map +1 -1
  124. package/dist/azure/serviceRetirement.d.ts +21 -2
  125. package/dist/azure/serviceRetirement.d.ts.map +1 -1
  126. package/dist/azure/views.d.ts +24 -1
  127. package/dist/azure/views.d.ts.map +1 -1
  128. package/dist/azure/views.js.map +1 -1
  129. package/dist/common/boundedRows.d.ts +7 -0
  130. package/dist/common/boundedRows.d.ts.map +1 -0
  131. package/dist/{scheduler/scheduler.js → common/boundedRows.js} +1 -1
  132. package/dist/common/boundedRows.js.map +1 -0
  133. package/dist/common/index.d.ts +3 -0
  134. package/dist/common/index.d.ts.map +1 -1
  135. package/dist/common/index.js +3 -0
  136. package/dist/common/index.js.map +1 -1
  137. package/dist/common/metricStats.d.ts +29 -0
  138. package/dist/common/metricStats.d.ts.map +1 -0
  139. package/dist/{scheduler/bastionSchedule.js → common/metricStats.js} +1 -1
  140. package/dist/common/metricStats.js.map +1 -0
  141. package/dist/common/provider.d.ts +2 -0
  142. package/dist/common/provider.d.ts.map +1 -1
  143. package/dist/common/relationships.d.ts +3 -3
  144. package/dist/common/relationships.d.ts.map +1 -1
  145. package/dist/common/resourceGraph.d.ts +137 -0
  146. package/dist/common/resourceGraph.d.ts.map +1 -0
  147. package/dist/common/resourceGraph.js +17 -0
  148. package/dist/common/resourceGraph.js.map +1 -0
  149. package/dist/common/resourceGraphValidation.d.ts +30 -0
  150. package/dist/common/resourceGraphValidation.d.ts.map +1 -0
  151. package/dist/common/resourceGraphValidation.js +369 -0
  152. package/dist/common/resourceGraphValidation.js.map +1 -0
  153. package/dist/common/resourceIdentity.d.ts +28 -0
  154. package/dist/common/resourceIdentity.d.ts.map +1 -0
  155. package/dist/common/resourceIdentity.js +35 -0
  156. package/dist/common/resourceIdentity.js.map +1 -0
  157. package/dist/common/sha256.d.ts +2 -0
  158. package/dist/common/sha256.d.ts.map +1 -1
  159. package/dist/common/sha256.js +3 -0
  160. package/dist/common/sha256.js.map +1 -1
  161. package/dist/common/utilizationStories.d.ts +695 -0
  162. package/dist/common/utilizationStories.d.ts.map +1 -0
  163. package/dist/common/utilizationStories.js +21 -0
  164. package/dist/common/utilizationStories.js.map +1 -0
  165. package/dist/common/utilizationStoriesValidation.d.ts +60 -0
  166. package/dist/common/utilizationStoriesValidation.d.ts.map +1 -0
  167. package/dist/common/utilizationStoriesValidation.js +762 -0
  168. package/dist/common/utilizationStoriesValidation.js.map +1 -0
  169. package/dist/common/validationHelpers.d.ts +37 -0
  170. package/dist/common/validationHelpers.d.ts.map +1 -0
  171. package/dist/common/validationHelpers.js +147 -0
  172. package/dist/common/validationHelpers.js.map +1 -0
  173. package/dist/esm/accounts/index.js +1 -0
  174. package/dist/esm/accounts/subscriptionWriteAccess.js +112 -0
  175. package/dist/esm/accounts/writePermissions.js +46 -0
  176. package/dist/esm/ai/followUps.js +16 -0
  177. package/dist/esm/ai/grounding.js +74 -7
  178. package/dist/esm/ai/index.js +1 -0
  179. package/dist/esm/aws/commitments-planning.js +1 -0
  180. package/dist/esm/aws/commitmentsPlanningValidation.js +2 -1
  181. package/dist/esm/aws/index.js +2 -13
  182. package/dist/esm/aws/organizationCommitments.js +2 -2
  183. package/dist/esm/aws/organizationCommitmentsApiValidation.js +5 -5
  184. package/dist/esm/aws/organizationCommitmentsValidation.js +2 -1
  185. package/dist/esm/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +8 -5
  186. package/dist/esm/aws/publicArtifacts.js +2 -0
  187. package/dist/esm/aws/relationships.js +4 -1
  188. package/dist/esm/aws/requests.js +4 -2
  189. package/dist/esm/aws/resourceGraph.js +63 -0
  190. package/dist/esm/aws/validationHelpers.js +46 -0
  191. package/dist/esm/azure/commitmentsPlanning.js +8 -1
  192. package/dist/esm/azure/commitmentsPlanningValidation.js +39 -0
  193. package/dist/esm/azure/payloads.js +84 -1
  194. package/dist/esm/azure/reportEvidence.js +8 -0
  195. package/dist/esm/azure/reportEvidenceValidation.js +202 -6
  196. package/dist/esm/azure/reportEvidenceValidationHelpers.js +7 -19
  197. package/dist/esm/azure/resilienceFacts.js +16 -0
  198. package/dist/esm/azure/resilienceFactsValidation.js +64 -0
  199. package/dist/esm/common/index.js +3 -0
  200. package/dist/esm/common/resourceGraph.js +13 -0
  201. package/dist/esm/common/resourceGraphValidation.js +365 -0
  202. package/dist/esm/common/resourceIdentity.js +24 -0
  203. package/dist/esm/common/sha256.js +2 -0
  204. package/dist/esm/common/utilizationStories.js +17 -0
  205. package/dist/esm/common/utilizationStoriesValidation.js +718 -0
  206. package/dist/esm/common/validationHelpers.js +115 -0
  207. package/dist/esm/entries/relationships.js +2 -2
  208. package/dist/esm/index.js +5 -0
  209. package/dist/esm/index.vite.js +1 -0
  210. package/dist/esm/reporting/jobs/index.js +13 -0
  211. package/dist/esm/reporting/jobs/reportJobIdentity.js +76 -0
  212. package/dist/esm/reporting/jobs/reportJobMessages.js +47 -0
  213. package/dist/esm/reporting/jobs/reportJobRow.js +264 -0
  214. package/dist/esm/reporting/jobs/reportJobSpec.js +295 -0
  215. package/dist/esm/reporting/jobs/reportJobStatus.js +87 -0
  216. package/dist/esm/reporting/shared/reportTableEntities.js +41 -0
  217. package/dist/esm/reporting/shared/reportingDigest.js +57 -0
  218. package/dist/esm/reporting/shared/reportingIds.js +88 -0
  219. package/dist/esm/reporting/shared/reportingPaths.js +23 -0
  220. package/dist/esm/scheduler/index.js +4 -4
  221. package/dist/esm/scheduler/resourceStrategy.js +2 -0
  222. package/dist/esm/scheduler/resourceStrategyCapabilityValidation.js +265 -0
  223. package/dist/esm/scheduler/resourceStrategyContracts.js +20 -0
  224. package/dist/esm/scheduler/resourceStrategyFinancialValidation.js +145 -0
  225. package/dist/esm/scheduler/resourceStrategyPermissionValidation.js +190 -0
  226. package/dist/esm/scheduler/resourceStrategyScheduleValidation.js +506 -0
  227. package/dist/esm/scheduler/resourceStrategyValidation.js +4 -0
  228. package/dist/esm/scheduler/resourceStrategyValidationShared.js +261 -0
  229. package/dist/esm/scheduler/schedulerValidation.js +372 -0
  230. package/dist/esm/scheduler/weeklyAvailabilityFixtures.js +140 -0
  231. package/dist/index.d.ts +5 -0
  232. package/dist/index.d.ts.map +1 -1
  233. package/dist/index.js +5 -0
  234. package/dist/index.js.map +1 -1
  235. package/dist/index.vite.d.ts +1 -0
  236. package/dist/index.vite.d.ts.map +1 -1
  237. package/dist/index.vite.js +1 -0
  238. package/dist/index.vite.js.map +1 -1
  239. package/dist/reporting/jobs/index.d.ts +14 -0
  240. package/dist/reporting/jobs/index.d.ts.map +1 -0
  241. package/dist/reporting/jobs/index.js +45 -0
  242. package/dist/reporting/jobs/index.js.map +1 -0
  243. package/dist/reporting/jobs/reportJobIdentity.d.ts +44 -0
  244. package/dist/reporting/jobs/reportJobIdentity.d.ts.map +1 -0
  245. package/dist/reporting/jobs/reportJobIdentity.js +88 -0
  246. package/dist/reporting/jobs/reportJobIdentity.js.map +1 -0
  247. package/dist/reporting/jobs/reportJobMessages.d.ts +30 -0
  248. package/dist/reporting/jobs/reportJobMessages.d.ts.map +1 -0
  249. package/dist/reporting/jobs/reportJobMessages.js +54 -0
  250. package/dist/reporting/jobs/reportJobMessages.js.map +1 -0
  251. package/dist/reporting/jobs/reportJobRow.d.ts +98 -0
  252. package/dist/reporting/jobs/reportJobRow.d.ts.map +1 -0
  253. package/dist/reporting/jobs/reportJobRow.js +270 -0
  254. package/dist/reporting/jobs/reportJobRow.js.map +1 -0
  255. package/dist/reporting/jobs/reportJobSpec.d.ts +92 -0
  256. package/dist/reporting/jobs/reportJobSpec.d.ts.map +1 -0
  257. package/dist/reporting/jobs/reportJobSpec.js +304 -0
  258. package/dist/reporting/jobs/reportJobSpec.js.map +1 -0
  259. package/dist/reporting/jobs/reportJobStatus.d.ts +60 -0
  260. package/dist/reporting/jobs/reportJobStatus.d.ts.map +1 -0
  261. package/dist/reporting/jobs/reportJobStatus.js +98 -0
  262. package/dist/reporting/jobs/reportJobStatus.js.map +1 -0
  263. package/dist/reporting/shared/reportTableEntities.d.ts +23 -0
  264. package/dist/reporting/shared/reportTableEntities.d.ts.map +1 -0
  265. package/dist/reporting/shared/reportTableEntities.js +47 -0
  266. package/dist/reporting/shared/reportTableEntities.js.map +1 -0
  267. package/dist/reporting/shared/reportingDigest.d.ts +6 -0
  268. package/dist/reporting/shared/reportingDigest.d.ts.map +1 -0
  269. package/dist/reporting/shared/reportingDigest.js +63 -0
  270. package/dist/reporting/shared/reportingDigest.js.map +1 -0
  271. package/dist/reporting/shared/reportingIds.d.ts +34 -0
  272. package/dist/reporting/shared/reportingIds.d.ts.map +1 -0
  273. package/dist/reporting/shared/reportingIds.js +102 -0
  274. package/dist/reporting/shared/reportingIds.js.map +1 -0
  275. package/dist/reporting/shared/reportingPaths.d.ts +14 -0
  276. package/dist/reporting/shared/reportingPaths.d.ts.map +1 -0
  277. package/dist/reporting/shared/reportingPaths.js +29 -0
  278. package/dist/reporting/shared/reportingPaths.js.map +1 -0
  279. package/dist/scheduler/index.d.ts +4 -4
  280. package/dist/scheduler/index.d.ts.map +1 -1
  281. package/dist/scheduler/index.js +4 -4
  282. package/dist/scheduler/index.js.map +1 -1
  283. package/dist/scheduler/resourceStrategy.d.ts +3 -0
  284. package/dist/scheduler/resourceStrategy.d.ts.map +1 -0
  285. package/dist/scheduler/resourceStrategy.js +19 -0
  286. package/dist/scheduler/resourceStrategy.js.map +1 -0
  287. package/dist/scheduler/resourceStrategyCapabilityValidation.d.ts +4 -0
  288. package/dist/scheduler/resourceStrategyCapabilityValidation.d.ts.map +1 -0
  289. package/dist/scheduler/resourceStrategyCapabilityValidation.js +270 -0
  290. package/dist/scheduler/resourceStrategyCapabilityValidation.js.map +1 -0
  291. package/dist/scheduler/resourceStrategyContracts.d.ts +466 -0
  292. package/dist/scheduler/resourceStrategyContracts.d.ts.map +1 -0
  293. package/dist/scheduler/resourceStrategyContracts.js +24 -0
  294. package/dist/scheduler/resourceStrategyContracts.js.map +1 -0
  295. package/dist/scheduler/resourceStrategyFinancialValidation.d.ts +5 -0
  296. package/dist/scheduler/resourceStrategyFinancialValidation.d.ts.map +1 -0
  297. package/dist/scheduler/resourceStrategyFinancialValidation.js +151 -0
  298. package/dist/scheduler/resourceStrategyFinancialValidation.js.map +1 -0
  299. package/dist/scheduler/resourceStrategyPermissionValidation.d.ts +4 -0
  300. package/dist/scheduler/resourceStrategyPermissionValidation.d.ts.map +1 -0
  301. package/dist/scheduler/resourceStrategyPermissionValidation.js +195 -0
  302. package/dist/scheduler/resourceStrategyPermissionValidation.js.map +1 -0
  303. package/dist/scheduler/resourceStrategyScheduleValidation.d.ts +14 -0
  304. package/dist/scheduler/resourceStrategyScheduleValidation.d.ts.map +1 -0
  305. package/dist/scheduler/resourceStrategyScheduleValidation.js +519 -0
  306. package/dist/scheduler/resourceStrategyScheduleValidation.js.map +1 -0
  307. package/dist/scheduler/resourceStrategyValidation.d.ts +5 -0
  308. package/dist/scheduler/resourceStrategyValidation.d.ts.map +1 -0
  309. package/dist/scheduler/resourceStrategyValidation.js +21 -0
  310. package/dist/scheduler/resourceStrategyValidation.js.map +1 -0
  311. package/dist/scheduler/resourceStrategyValidationShared.d.ts +19 -0
  312. package/dist/scheduler/resourceStrategyValidationShared.d.ts.map +1 -0
  313. package/dist/scheduler/resourceStrategyValidationShared.js +281 -0
  314. package/dist/scheduler/resourceStrategyValidationShared.js.map +1 -0
  315. package/dist/scheduler/schedulerContracts.d.ts +184 -0
  316. package/dist/scheduler/schedulerContracts.d.ts.map +1 -0
  317. package/dist/{aws/portalPublicArtifactNestedEvidence.js → scheduler/schedulerContracts.js} +1 -1
  318. package/dist/scheduler/schedulerContracts.js.map +1 -0
  319. package/dist/scheduler/schedulerValidation.d.ts +15 -0
  320. package/dist/scheduler/schedulerValidation.d.ts.map +1 -0
  321. package/dist/scheduler/schedulerValidation.js +388 -0
  322. package/dist/scheduler/schedulerValidation.js.map +1 -0
  323. package/dist/scheduler/weeklyAvailabilityFixtures.d.ts +26 -0
  324. package/dist/scheduler/weeklyAvailabilityFixtures.d.ts.map +1 -0
  325. package/dist/scheduler/weeklyAvailabilityFixtures.js +144 -0
  326. package/dist/scheduler/weeklyAvailabilityFixtures.js.map +1 -0
  327. package/package.json +26 -7
  328. package/dist/aws/pluginPublicArtifactBodyValidation.d.ts +0 -10
  329. package/dist/aws/pluginPublicArtifactBodyValidation.d.ts.map +0 -1
  330. package/dist/aws/pluginPublicArtifactBodyValidation.js +0 -225
  331. package/dist/aws/pluginPublicArtifactBodyValidation.js.map +0 -1
  332. package/dist/aws/pluginPublicArtifactEvidence.d.ts +0 -161
  333. package/dist/aws/pluginPublicArtifactEvidence.d.ts.map +0 -1
  334. package/dist/aws/pluginPublicArtifactEvidence.js.map +0 -1
  335. package/dist/aws/pluginPublicArtifactManifestValidation.d.ts +0 -4
  336. package/dist/aws/pluginPublicArtifactManifestValidation.d.ts.map +0 -1
  337. package/dist/aws/pluginPublicArtifactManifestValidation.js +0 -259
  338. package/dist/aws/pluginPublicArtifactManifestValidation.js.map +0 -1
  339. package/dist/aws/pluginPublicArtifactSectionValidation.d.ts +0 -6
  340. package/dist/aws/pluginPublicArtifactSectionValidation.d.ts.map +0 -1
  341. package/dist/aws/pluginPublicArtifactSectionValidation.js +0 -471
  342. package/dist/aws/pluginPublicArtifactSectionValidation.js.map +0 -1
  343. package/dist/aws/pluginPublicArtifactValidation.d.ts +0 -3
  344. package/dist/aws/pluginPublicArtifactValidation.d.ts.map +0 -1
  345. package/dist/aws/pluginPublicArtifactValidation.js +0 -9
  346. package/dist/aws/pluginPublicArtifactValidation.js.map +0 -1
  347. package/dist/aws/pluginPublicArtifactValidationHelpers.d.ts +0 -23
  348. package/dist/aws/pluginPublicArtifactValidationHelpers.d.ts.map +0 -1
  349. package/dist/aws/pluginPublicArtifactValidationHelpers.js +0 -240
  350. package/dist/aws/pluginPublicArtifactValidationHelpers.js.map +0 -1
  351. package/dist/aws/pluginPublicArtifacts.d.ts +0 -253
  352. package/dist/aws/pluginPublicArtifacts.d.ts.map +0 -1
  353. package/dist/aws/pluginPublicArtifacts.js +0 -51
  354. package/dist/aws/pluginPublicArtifacts.js.map +0 -1
  355. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts +0 -4
  356. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts.map +0 -1
  357. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js +0 -513
  358. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js.map +0 -1
  359. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts +0 -13
  360. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts.map +0 -1
  361. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js +0 -5
  362. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js.map +0 -1
  363. package/dist/aws/portalPublicArtifactCurrentValidation.d.ts +0 -4
  364. package/dist/aws/portalPublicArtifactCurrentValidation.d.ts.map +0 -1
  365. package/dist/aws/portalPublicArtifactCurrentValidation.js +0 -333
  366. package/dist/aws/portalPublicArtifactCurrentValidation.js.map +0 -1
  367. package/dist/aws/portalPublicArtifactEvidenceValidation.d.ts +0 -6
  368. package/dist/aws/portalPublicArtifactEvidenceValidation.d.ts.map +0 -1
  369. package/dist/aws/portalPublicArtifactEvidenceValidation.js +0 -301
  370. package/dist/aws/portalPublicArtifactEvidenceValidation.js.map +0 -1
  371. package/dist/aws/portalPublicArtifactHistoryAiValidation.d.ts +0 -8
  372. package/dist/aws/portalPublicArtifactHistoryAiValidation.d.ts.map +0 -1
  373. package/dist/aws/portalPublicArtifactHistoryAiValidation.js +0 -377
  374. package/dist/aws/portalPublicArtifactHistoryAiValidation.js.map +0 -1
  375. package/dist/aws/portalPublicArtifactHistoryTypes.d.ts +0 -178
  376. package/dist/aws/portalPublicArtifactHistoryTypes.d.ts.map +0 -1
  377. package/dist/aws/portalPublicArtifactHistoryTypes.js +0 -44
  378. package/dist/aws/portalPublicArtifactHistoryTypes.js.map +0 -1
  379. package/dist/aws/portalPublicArtifactNestedEvidence.d.ts +0 -127
  380. package/dist/aws/portalPublicArtifactNestedEvidence.d.ts.map +0 -1
  381. package/dist/aws/portalPublicArtifactNestedEvidence.js.map +0 -1
  382. package/dist/aws/portalPublicArtifactNestedEvidenceValidation.d.ts +0 -6
  383. package/dist/aws/portalPublicArtifactNestedEvidenceValidation.d.ts.map +0 -1
  384. package/dist/aws/portalPublicArtifactNestedEvidenceValidation.js +0 -405
  385. package/dist/aws/portalPublicArtifactNestedEvidenceValidation.js.map +0 -1
  386. package/dist/aws/portalPublicArtifactValidation.d.ts +0 -3
  387. package/dist/aws/portalPublicArtifactValidation.d.ts.map +0 -1
  388. package/dist/aws/portalPublicArtifactValidation.js +0 -14
  389. package/dist/aws/portalPublicArtifactValidation.js.map +0 -1
  390. package/dist/aws/portalPublicArtifactValidationCommon.d.ts +0 -30
  391. package/dist/aws/portalPublicArtifactValidationCommon.d.ts.map +0 -1
  392. package/dist/aws/portalPublicArtifactValidationCommon.js +0 -167
  393. package/dist/aws/portalPublicArtifactValidationCommon.js.map +0 -1
  394. package/dist/aws/portalPublicArtifacts.d.ts +0 -400
  395. package/dist/aws/portalPublicArtifacts.d.ts.map +0 -1
  396. package/dist/aws/portalPublicArtifacts.js +0 -85
  397. package/dist/aws/portalPublicArtifacts.js.map +0 -1
  398. package/dist/aws/portalRelationshipPublicArtifactValidation.d.ts +0 -4
  399. package/dist/aws/portalRelationshipPublicArtifactValidation.d.ts.map +0 -1
  400. package/dist/aws/portalRelationshipPublicArtifactValidation.js +0 -338
  401. package/dist/aws/portalRelationshipPublicArtifactValidation.js.map +0 -1
  402. package/dist/aws/portalRelationshipPublicArtifacts.d.ts +0 -196
  403. package/dist/aws/portalRelationshipPublicArtifacts.d.ts.map +0 -1
  404. package/dist/aws/portalRelationshipPublicArtifacts.js +0 -63
  405. package/dist/aws/portalRelationshipPublicArtifacts.js.map +0 -1
  406. package/dist/aws/portalRelationshipResourceNodeTypes.d.ts +0 -269
  407. package/dist/aws/portalRelationshipResourceNodeTypes.d.ts.map +0 -1
  408. package/dist/aws/portalRelationshipResourceNodeTypes.js +0 -3
  409. package/dist/aws/portalRelationshipResourceNodeTypes.js.map +0 -1
  410. package/dist/aws/portalRelationshipResourceNodeValidation.d.ts +0 -2
  411. package/dist/aws/portalRelationshipResourceNodeValidation.d.ts.map +0 -1
  412. package/dist/aws/portalRelationshipResourceNodeValidation.js +0 -372
  413. package/dist/aws/portalRelationshipResourceNodeValidation.js.map +0 -1
  414. package/dist/esm/aws/pluginPublicArtifactBodyValidation.js +0 -217
  415. package/dist/esm/aws/pluginPublicArtifactManifestValidation.js +0 -255
  416. package/dist/esm/aws/pluginPublicArtifactSectionValidation.js +0 -464
  417. package/dist/esm/aws/pluginPublicArtifactValidation.js +0 -2
  418. package/dist/esm/aws/pluginPublicArtifactValidationHelpers.js +0 -216
  419. package/dist/esm/aws/pluginPublicArtifacts.js +0 -44
  420. package/dist/esm/aws/portalCommitmentsPlanningPublicArtifactValidation.js +0 -509
  421. package/dist/esm/aws/portalCommitmentsPlanningPublicArtifacts.js +0 -1
  422. package/dist/esm/aws/portalPublicArtifactCurrentValidation.js +0 -328
  423. package/dist/esm/aws/portalPublicArtifactEvidenceValidation.js +0 -294
  424. package/dist/esm/aws/portalPublicArtifactHistoryAiValidation.js +0 -368
  425. package/dist/esm/aws/portalPublicArtifactHistoryTypes.js +0 -40
  426. package/dist/esm/aws/portalPublicArtifactNestedEvidenceValidation.js +0 -397
  427. package/dist/esm/aws/portalPublicArtifactValidation.js +0 -2
  428. package/dist/esm/aws/portalPublicArtifactValidationCommon.js +0 -139
  429. package/dist/esm/aws/portalPublicArtifacts.js +0 -73
  430. package/dist/esm/aws/portalRelationshipPublicArtifactValidation.js +0 -334
  431. package/dist/esm/aws/portalRelationshipPublicArtifacts.js +0 -59
  432. package/dist/esm/aws/portalRelationshipResourceNodeValidation.js +0 -368
  433. package/dist/esm/scheduler/bastionScheduleProfile.js +0 -206
  434. package/dist/esm/scheduler/bastionScheduleValidation.js +0 -401
  435. package/dist/esm/scheduler/scheduler.js +0 -1
  436. package/dist/scheduler/bastionSchedule.d.ts +0 -113
  437. package/dist/scheduler/bastionSchedule.d.ts.map +0 -1
  438. package/dist/scheduler/bastionSchedule.js.map +0 -1
  439. package/dist/scheduler/bastionScheduleProfile.d.ts +0 -24
  440. package/dist/scheduler/bastionScheduleProfile.d.ts.map +0 -1
  441. package/dist/scheduler/bastionScheduleProfile.js +0 -210
  442. package/dist/scheduler/bastionScheduleProfile.js.map +0 -1
  443. package/dist/scheduler/bastionScheduleValidation.d.ts +0 -10
  444. package/dist/scheduler/bastionScheduleValidation.d.ts.map +0 -1
  445. package/dist/scheduler/bastionScheduleValidation.js +0 -412
  446. package/dist/scheduler/bastionScheduleValidation.js.map +0 -1
  447. package/dist/scheduler/scheduler.d.ts +0 -267
  448. package/dist/scheduler/scheduler.d.ts.map +0 -1
  449. package/dist/scheduler/scheduler.js.map +0 -1
  450. /package/dist/esm/aws/{pluginPublicArtifactEvidence.js → commitmentsPlanningView.js} +0 -0
  451. /package/dist/esm/{aws/portalPublicArtifactNestedEvidence.js → common/boundedRows.js} +0 -0
  452. /package/dist/esm/{aws/portalRelationshipResourceNodeTypes.js → common/metricStats.js} +0 -0
  453. /package/dist/esm/scheduler/{bastionSchedule.js → schedulerContracts.js} +0 -0
@@ -0,0 +1,718 @@
1
+ import { isBoundedRows, isCount, isDateTime, isFiniteNumber, isRecord, isString, isStringArray } from './validationHelpers.js';
2
+ import { STORY_KEYS, STORY_LIMITS, } from './utilizationStories.js';
3
+ const PROVIDERS = new Set(['azure', 'aws']);
4
+ const METRIC_ROLES = new Set(['primary', 'secondary', 'context']);
5
+ const DIMENSION_POLICIES = new Set(['average', 'sum', 'max', 'split']);
6
+ const METRIC_VISUALS = new Set(['sparkline', 'trend', 'capacity-bar', 'mix-bar', 'event-strip']);
7
+ const BILLED_ON = new Set(['allocated', 'used', 'included']);
8
+ const AXIS_MAX_SOURCES = new Set(['config', 'capacity', 'observed']);
9
+ const SCALE_MODES = new Set(['fixed', 'autoscale', 'serverless']);
10
+ const RUN_MODES = new Set(['stop-start', 'auto-pause', 'scale-to-zero', 'always-on']);
11
+ const RUNNING_BASES = new Set(['power-state', 'billing-hours', 'metric-presence']);
12
+ const SIZING_VERDICTS = new Set(['oversized', 'undersized', 'busy', 'rebalance', 'mostly-off', 'idle', 'no-telemetry', 'fits', 'unknown']);
13
+ const SCHEDULE_FITS = new Set(['good', 'fair', 'low', 'done', 'insufficient-data', 'not-applicable']);
14
+ const SCHEDULE_FITS_REQUIRING_CORROBORATION = new Set(['good', 'fair', 'low']);
15
+ const SCHEDULE_ACTIONS = new Set(['stop', 'pause', 'scale']);
16
+ const TELEMETRY_STATUSES = new Set(['collected', 'partial', 'no-series', 'unavailable']);
17
+ const CONFIDENCES = new Set(['high', 'medium', 'low']);
18
+ const BENEFIT_TYPES = new Set(['reservation', 'savings-plan']);
19
+ const SKU_OPTION_KINDS = new Set(['same-shape', 'fits-usage', 'trade-off', 'cross-platform']);
20
+ const SKU_CAPABILITY_SEVERITIES = new Set(['info', 'warning', 'unknown']);
21
+ const SKU_CAPABILITY_BASES = new Set(['sku-capability', 'current-setting', 'active-vcpu-capability', 'unknown']);
22
+ const SKU_CAPABILITY_MATERIALITIES = new Set(['used', 'not-used', 'unknown']);
23
+ const RIGHT_SIZE_ASSESSMENT_STATUSES = new Set(['recommended', 'no-change', 'insufficient-data', 'not-supported']);
24
+ const CAPABILITY_STATES = new Set(['enabled', 'disabled', 'partial', 'unknown', 'not-applicable']);
25
+ const RIGHT_SKU_VERDICTS = new Set(['modernise', 'downsize', 'consider', 'keep', 'blocked-by-commitment']);
26
+ const SKU_SAVINGS_BASES = new Set(['list', 'billed']);
27
+ const COMMITMENT_BLOCK_REASONS = new Set(['reservation', 'cost-not-lower']);
28
+ const RIGHT_SIZE_REJECTION_REASONS = new Set(['observed-fit', 'no-saving']);
29
+ const SIGNAL_ACTION_REASONS = new Set(['observed-fit', 'no-saving', 'blocked-by-commitment']);
30
+ const BACKUP_RUN_STATES = new Set(['ok', 'failed', null]);
31
+ const STORY_KEY_SET = new Set(STORY_KEYS);
32
+ const STORY_CELL_KINDS = new Set([
33
+ 'text',
34
+ 'number',
35
+ 'money',
36
+ 'percent',
37
+ 'mark',
38
+ 'dot',
39
+ 'sparkline',
40
+ 'dual',
41
+ 'capacity-bar',
42
+ 'mix-bar',
43
+ 'event-strip',
44
+ 'weekly-grid',
45
+ ]);
46
+ const SERIES_ROLES = new Set(['primary', 'secondary']);
47
+ const STATUS_TONES = new Set(['good', 'warn', 'bad', 'neutral', 'muted']);
48
+ const COLUMN_ROLE_CLASSES = new Set(['res', 'prim', 'sec', 'nums', 'cap', 'read', 'cost', 'save', 'dual']);
49
+ const PRODUCERS = new Set(['parser', 'strategy']);
50
+ const isNullableNumber = (value) => value === null || isFiniteNumber(value);
51
+ const isOptionalNullableNumber = (value) => value === undefined || isNullableNumber(value);
52
+ const isNullableString = (value) => value === null || isString(value);
53
+ const isNullableInteger = (value) => value === null || (isFiniteNumber(value) && Number.isInteger(value));
54
+ const isText = (value) => typeof value === 'string';
55
+ const isOptionalText = (value) => value === undefined || isText(value);
56
+ const isBoolean = (value) => typeof value === 'boolean';
57
+ const isNullableSeries = (value) => Array.isArray(value) && value.every(isNullableNumber);
58
+ const isPercentage = (value) => isFiniteNumber(value) && value >= 0 && value <= 100;
59
+ const isNullablePercentage = (value) => value === null || isPercentage(value);
60
+ const isPriority = (value) => isCount(value) && value >= 1 && value <= 5;
61
+ const isStringRecord = (value) => isRecord(value) && Object.values(value).every(isText);
62
+ const isNumberRecord = (value) => isRecord(value) && Object.values(value).every(isFiniteNumber);
63
+ const inSet = (set, value) => set.has(value);
64
+ const isWeeklyGrid = (value) => Array.isArray(value) &&
65
+ value.length === STORY_LIMITS.weeklyGridDays &&
66
+ value.every(day => isNullableSeries(day) && day.length === STORY_LIMITS.weeklyGridHours);
67
+ const METRIC_STATS_FIELDS = [
68
+ 'average',
69
+ 'median',
70
+ 'p50',
71
+ 'p75',
72
+ 'p90',
73
+ 'p95',
74
+ 'p99',
75
+ 'min',
76
+ 'max',
77
+ 'frequency',
78
+ 'trend',
79
+ 'variance',
80
+ 'count',
81
+ 'totalDataPoints',
82
+ 'runningDataPoints',
83
+ 'nonRunningDataPoints',
84
+ 'runningTimePercentage',
85
+ 'longestRunningStreak',
86
+ 'longestDowntimeStreak',
87
+ 'averageUptimeStreak',
88
+ 'averageDowntimeStreak',
89
+ ];
90
+ const METRIC_STATS_OPTIONAL_FIELDS = ['uptime', 'peakHours', 'offPeakHours'];
91
+ const isMetricStats = (value) => isRecord(value) &&
92
+ METRIC_STATS_FIELDS.every(key => isFiniteNumber(value[key])) &&
93
+ METRIC_STATS_OPTIONAL_FIELDS.every(key => value[key] === undefined || isFiniteNumber(value[key]));
94
+ export const isMetricSparkline = (value, days) => {
95
+ if (!isRecord(value) || !isString(value.key) || !isString(value.metricName))
96
+ return false;
97
+ if (!inSet(METRIC_ROLES, value.role) || !inSet(METRIC_VISUALS, value.visual) || !isText(value.unit))
98
+ return false;
99
+ if (!isNullableNumber(value.axisMax) || (value.axisMaxSource !== undefined && !inSet(AXIS_MAX_SOURCES, value.axisMaxSource)))
100
+ return false;
101
+ if (value.billedOn !== undefined && !inSet(BILLED_ON, value.billedOn))
102
+ return false;
103
+ if (value.dimensions !== undefined &&
104
+ (!isRecord(value.dimensions) ||
105
+ !inSet(DIMENSION_POLICIES, value.dimensions.policy) ||
106
+ !isOptionalText(value.dimensions.name) ||
107
+ !isOptionalText(value.dimensions.value) ||
108
+ !isCount(value.dimensions.seriesCount)))
109
+ return false;
110
+ if (!isDateTime(value.start) || value.bucket !== 'P1D')
111
+ return false;
112
+ if (!isNullableSeries(value.avg) || !isNullableSeries(value.p95) || !isNullableSeries(value.max))
113
+ return false;
114
+ if (value.avg.length !== value.p95.length || value.avg.length !== value.max.length)
115
+ return false;
116
+ if (days !== undefined && value.avg.length !== days)
117
+ return false;
118
+ return isMetricStats(value.stats) && isCount(value.sourcePoints);
119
+ };
120
+ export const isCapacityScalingDescriptor = (value) => {
121
+ if (!isRecord(value) || !(value.autoscaleEnabled === null || isBoolean(value.autoscaleEnabled)))
122
+ return false;
123
+ if (!isNullableNumber(value.minimumUnits) ||
124
+ !isNullableNumber(value.defaultUnits) ||
125
+ !isNullableNumber(value.maximumUnits) ||
126
+ !isNullableString(value.source))
127
+ return false;
128
+ const minimum = value.minimumUnits;
129
+ const defaultUnits = value.defaultUnits;
130
+ const maximum = value.maximumUnits;
131
+ if ([minimum, defaultUnits, maximum].some(units => units !== null && units < 0))
132
+ return false;
133
+ if (minimum !== null && maximum !== null && minimum > maximum)
134
+ return false;
135
+ if (defaultUnits !== null && minimum !== null && defaultUnits < minimum)
136
+ return false;
137
+ if (defaultUnits !== null && maximum !== null && defaultUnits > maximum)
138
+ return false;
139
+ return true;
140
+ };
141
+ export const isCapacityDescriptor = (value) => {
142
+ if (!isRecord(value) ||
143
+ !isNullableString(value.sku) ||
144
+ !isNullableString(value.tier) ||
145
+ !isNullableNumber(value.units) ||
146
+ !isText(value.unitName) ||
147
+ !isOptionalNullableNumber(value.memoryGB) ||
148
+ !inSet(SCALE_MODES, value.scaleMode) ||
149
+ !isText(value.label))
150
+ return false;
151
+ if (value.scaling === undefined)
152
+ return true;
153
+ if (!isCapacityScalingDescriptor(value.scaling))
154
+ return false;
155
+ if (value.scaling.autoscaleEnabled === true && value.scaleMode !== 'autoscale')
156
+ return false;
157
+ if (value.scaling.autoscaleEnabled === false && value.scaleMode !== 'fixed')
158
+ return false;
159
+ return true;
160
+ };
161
+ const isHourShare = (value) => isRecord(value) && isNullableNumber(value.runningShare) && isNullableNumber(value.usageMean);
162
+ export const isRunningProfile = (value, days) => {
163
+ if (!isRecord(value) || !isString(value.signalMetric) || !inSet(RUNNING_BASES, value.basis))
164
+ return false;
165
+ if (!Array.isArray(value.corroboration) || !value.corroboration.every(basis => inSet(RUNNING_BASES, basis)))
166
+ return false;
167
+ if (value.corroboration.includes(value.basis))
168
+ return false;
169
+ if (!isNullableSeries(value.daily) || (days !== undefined && value.daily.length !== days) || !isNullableNumber(value.share))
170
+ return false;
171
+ if (value.weekly === undefined)
172
+ return true;
173
+ const weekly = value.weekly;
174
+ return (isRecord(weekly) &&
175
+ isString(weekly.timezone) &&
176
+ isWeeklyGrid(weekly.running) &&
177
+ isWeeklyGrid(weekly.usage) &&
178
+ isHourShare(weekly.businessHours) &&
179
+ isHourShare(weekly.offHours));
180
+ };
181
+ /** A running signal derived from metric presence alone is not evidence of stopped time; it needs an independent source. */
182
+ export const isCorroboratedRunningProfile = (value) => value.basis !== 'metric-presence' || value.corroboration.some(basis => basis !== 'metric-presence');
183
+ export const isCommitmentBenefit = (value) => isRecord(value) &&
184
+ isNullableString(value.benefitId) &&
185
+ isNullableString(value.benefitName) &&
186
+ (value.benefitId !== null || value.benefitName !== null) &&
187
+ inSet(BENEFIT_TYPES, value.benefitType) &&
188
+ isNullableString(value.status) &&
189
+ isNullableString(value.expiryDate) &&
190
+ (value.expiryDate === null || isDateTime(value.expiryDate)) &&
191
+ isNullableInteger(value.daysToExpiry) &&
192
+ (value.expiryDate !== null || value.daysToExpiry === null);
193
+ export const isCommitmentCoverage = (value) => isRecord(value) &&
194
+ isNullableNumber(value.coveragePercent) &&
195
+ Array.isArray(value.benefitTypes) &&
196
+ value.benefitTypes.every(type => inSet(BENEFIT_TYPES, type)) &&
197
+ Array.isArray(value.benefitNames) &&
198
+ value.benefitNames.every(isText) &&
199
+ (value.benefits === undefined || (Array.isArray(value.benefits) && value.benefits.every(isCommitmentBenefit))) &&
200
+ isNullableNumber(value.coveredCost) &&
201
+ isNullableNumber(value.uncoveredCost) &&
202
+ isDateTime(value.windowStart) &&
203
+ isDateTime(value.windowEnd);
204
+ export const isEvidenceWindow = (value) => isRecord(value) &&
205
+ isDateTime(value.windowStart) &&
206
+ isDateTime(value.windowEnd) &&
207
+ isCount(value.days) &&
208
+ isCount(value.sampleCount) &&
209
+ inSet(TELEMETRY_STATUSES, value.telemetry) &&
210
+ inSet(CONFIDENCES, value.confidence);
211
+ const isVerdictReason = (value) => isRecord(value) && isString(value.rule) && isRecord(value.values) && Object.values(value.values).every(isNullableNumber);
212
+ /** Optional basis and billed figure: a billed-basis summary's `billedSavingsPercent` must equal its `savingsPercent`. */
213
+ export const isSkuOptionSummary = (value) => isRecord(value) &&
214
+ inSet(SKU_OPTION_KINDS, value.kind) &&
215
+ isString(value.label) &&
216
+ isNullableNumber(value.savingsPercent) &&
217
+ (value.savingsBasis === undefined || inSet(SKU_SAVINGS_BASES, value.savingsBasis)) &&
218
+ (value.billedSavingsPercent === undefined || isNullablePercentage(value.billedSavingsPercent)) &&
219
+ (value.savingsBasis !== 'billed' || value.billedSavingsPercent === undefined || Object.is(value.billedSavingsPercent, value.savingsPercent));
220
+ /** An estimate marker plus at least one non-negative projected p95 percentage (may exceed 100). */
221
+ export const isSkuProjectedUsage = (value) => isRecord(value) &&
222
+ value.estimate === true &&
223
+ (value.cpuP95 !== undefined || value.memoryP95 !== undefined) &&
224
+ [value.cpuP95, value.memoryP95].every(p95 => p95 === undefined || (isFiniteNumber(p95) && p95 >= 0));
225
+ export const isCommitmentBlock = (value) => isRecord(value) &&
226
+ inSet(COMMITMENT_BLOCK_REASONS, value.reason) &&
227
+ isNullablePercentage(value.coveragePercent) &&
228
+ isNullableString(value.benefitName) &&
229
+ (value.expiryDate === null || isDateTime(value.expiryDate)) &&
230
+ isOptionalNullableNumber(value.expectedOptionCost) &&
231
+ isOptionalNullableNumber(value.billedSpend);
232
+ export const isRightSizeRejection = (value) => isRecord(value) && inSet(RIGHT_SIZE_REJECTION_REASONS, value.reason) && isString(value.sku);
233
+ const isSkuCapabilityScalar = (value) => value === null || isText(value) || isFiniteNumber(value) || isBoolean(value);
234
+ const isSkuCapabilityValue = (value) => isSkuCapabilityScalar(value) || (Array.isArray(value) && value.every(isSkuCapabilityScalar));
235
+ const isSkuCapabilityImpact = (value) => isRecord(value) &&
236
+ isString(value.key) &&
237
+ isOptionalText(value.label) &&
238
+ inSet(SKU_CAPABILITY_SEVERITIES, value.severity) &&
239
+ inSet(SKU_CAPABILITY_BASES, value.basis) &&
240
+ inSet(SKU_CAPABILITY_MATERIALITIES, value.materiality) &&
241
+ (value.currentValue === undefined || isSkuCapabilityValue(value.currentValue)) &&
242
+ (value.alternativeValue === undefined || isSkuCapabilityValue(value.alternativeValue)) &&
243
+ isOptionalText(value.message);
244
+ export const isSkuOption = (value) => isRecord(value) &&
245
+ inSet(SKU_OPTION_KINDS, value.kind) &&
246
+ isString(value.sku) &&
247
+ isString(value.label) &&
248
+ (value.capacity === undefined ||
249
+ (isRecord(value.capacity) && isNullableNumber(value.capacity.units) && isOptionalNullableNumber(value.capacity.memoryGB))) &&
250
+ isNullableNumber(value.monthlyCost) &&
251
+ isString(value.currency) &&
252
+ isNullableNumber(value.savingsPercent) &&
253
+ isNullableNumber(value.savingsMonthly) &&
254
+ isStringArray(value.lostCapabilities) &&
255
+ (value.capabilityImpacts === undefined ||
256
+ (Array.isArray(value.capabilityImpacts) &&
257
+ value.capabilityImpacts.every(isSkuCapabilityImpact) &&
258
+ new Set(value.capabilityImpacts.map(impact => impact.key)).size === value.capabilityImpacts.length)) &&
259
+ (value.confidence === undefined || inSet(CONFIDENCES, value.confidence)) &&
260
+ (value.savingsBasis === undefined || inSet(SKU_SAVINGS_BASES, value.savingsBasis)) &&
261
+ (value.projected === undefined || isSkuProjectedUsage(value.projected));
262
+ export const isUtilizationProfile = (value, days) => {
263
+ if (!isRecord(value) || !inSet(PROVIDERS, value.provider) || !isString(value.family) || !isCapacityDescriptor(value.capacity))
264
+ return false;
265
+ if (!inSet(RUN_MODES, value.runMode) || !inSet(SIZING_VERDICTS, value.verdict) || !inSet(SCHEDULE_FITS, value.scheduleFit))
266
+ return false;
267
+ if (!isEvidenceWindow(value.evidenceWindow) || !isString(value.fingerprint))
268
+ return false;
269
+ const evidenceWindow = value.evidenceWindow;
270
+ const windowDays = days ?? evidenceWindow.days;
271
+ if (!Array.isArray(value.metrics) || !value.metrics.every(metric => isMetricSparkline(metric, windowDays)))
272
+ return false;
273
+ if (value.running !== undefined && !isRunningProfile(value.running, windowDays))
274
+ return false;
275
+ if (!Array.isArray(value.verdictReasons) || !value.verdictReasons.every(isVerdictReason) || !isStringArray(value.evidence))
276
+ return false;
277
+ if (value.scheduleAction !== undefined && !inSet(SCHEDULE_ACTIONS, value.scheduleAction))
278
+ return false;
279
+ if (value.coverage !== undefined && !isCommitmentCoverage(value.coverage))
280
+ return false;
281
+ if (value.ownerResourceId !== undefined && !isString(value.ownerResourceId))
282
+ return false;
283
+ const needsCorroboration = inSet(SCHEDULE_FITS_REQUIRING_CORROBORATION, value.scheduleFit) || value.verdict === 'mostly-off';
284
+ if (needsCorroboration) {
285
+ if (evidenceWindow.telemetry !== 'collected')
286
+ return false;
287
+ if (value.running === undefined || !isCorroboratedRunningProfile(value.running))
288
+ return false;
289
+ }
290
+ return true;
291
+ };
292
+ const isSignalSeries = (value) => isRecord(value) && isString(value.key) && isNullableNumber(value.p95) && isNullableSeries(value.sparkline);
293
+ export const isUtilizationSignal = (value) => {
294
+ if (!isRecord(value) || !inSet(SIZING_VERDICTS, value.verdict) || !inSet(SCHEDULE_FITS, value.scheduleFit))
295
+ return false;
296
+ if (!isSignalSeries(value.primary) || !inSet(TELEMETRY_STATUSES, value.telemetry))
297
+ return false;
298
+ const needsCorroboration = inSet(SCHEDULE_FITS_REQUIRING_CORROBORATION, value.scheduleFit) || value.verdict === 'mostly-off';
299
+ if (needsCorroboration && value.telemetry !== 'collected')
300
+ return false;
301
+ if (value.actionable !== undefined && !isBoolean(value.actionable))
302
+ return false;
303
+ if (value.actionReason !== undefined && (value.actionable !== false || !inSet(SIGNAL_ACTION_REASONS, value.actionReason)))
304
+ return false;
305
+ if (value.secondary !== undefined) {
306
+ if (!isSignalSeries(value.secondary))
307
+ return false;
308
+ const primaryLength = value.primary.sparkline.length;
309
+ if (value.secondary.sparkline.length !== primaryLength)
310
+ return false;
311
+ }
312
+ if (value.coverage !== undefined &&
313
+ (!isRecord(value.coverage) ||
314
+ !isNullableNumber(value.coverage.coveragePercent) ||
315
+ !Array.isArray(value.coverage.benefitTypes) ||
316
+ !value.coverage.benefitTypes.every(type => inSet(BENEFIT_TYPES, type))))
317
+ return false;
318
+ return value.betterSku === undefined || isSkuOptionSummary(value.betterSku);
319
+ };
320
+ const isCapabilityDetails = (value) => isRecord(value) && Object.values(value).every(detail => detail === null || isText(detail) || isFiniteNumber(detail) || isBoolean(detail));
321
+ export const isProtectionCapability = (value) => isRecord(value) &&
322
+ isString(value.key) &&
323
+ inSet(CAPABILITY_STATES, value.state) &&
324
+ isBoolean(value.required) &&
325
+ isText(value.label) &&
326
+ (value.details === undefined || isCapabilityDetails(value.details)) &&
327
+ isOptionalNullableNumber(value.costIfEnabled) &&
328
+ isRecord(value.evidence) &&
329
+ isString(value.evidence.source) &&
330
+ (value.evidence.observedAt === undefined || value.evidence.observedAt === null || isDateTime(value.evidence.observedAt));
331
+ export const isProtectionProfile = (value) => isRecord(value) &&
332
+ inSet(PROVIDERS, value.provider) &&
333
+ Array.isArray(value.capabilities) &&
334
+ value.capabilities.every(isProtectionCapability) &&
335
+ isStringArray(value.missingRequired) &&
336
+ isOptionalNullableNumber(value.slaPercent);
337
+ // ---- Cells
338
+ const isSparklineCell = (value) => inSet(SERIES_ROLES, value.role) &&
339
+ isNullableSeries(value.values) &&
340
+ isNullableNumber(value.axisMax) &&
341
+ isText(value.unit) &&
342
+ isNullableNumber(value.p95) &&
343
+ isText(value.label);
344
+ export const isStoryCell = (value) => {
345
+ if (!isRecord(value) || !inSet(STORY_CELL_KINDS, value.kind))
346
+ return false;
347
+ switch (value.kind) {
348
+ case 'text':
349
+ return (value.value === null || isText(value.value)) && (value.detail === undefined || value.detail === null || isText(value.detail));
350
+ case 'number':
351
+ return isNullableNumber(value.value) && isOptionalText(value.unit) && (value.decimals === undefined || isCount(value.decimals));
352
+ case 'money':
353
+ return (isNullableNumber(value.value) &&
354
+ isString(value.currency) &&
355
+ (value.secondaryValue === undefined || isNullableNumber(value.secondaryValue)) &&
356
+ isOptionalText(value.secondaryLabel));
357
+ case 'percent':
358
+ return isNullableNumber(value.value);
359
+ case 'mark':
360
+ return (isString(value.state) && isText(value.label) && inSet(STATUS_TONES, value.tone) && isOptionalText(value.icon) && isOptionalText(value.hint));
361
+ case 'dot':
362
+ return isBoolean(value.present) && inSet(STATUS_TONES, value.tone) && isOptionalText(value.label) && isOptionalText(value.hint);
363
+ case 'sparkline':
364
+ return isSparklineCell(value);
365
+ case 'dual':
366
+ return (isRecord(value.primary) &&
367
+ value.primary.kind === 'sparkline' &&
368
+ isSparklineCell(value.primary) &&
369
+ (value.secondary === null ||
370
+ (isRecord(value.secondary) &&
371
+ value.secondary.kind === 'sparkline' &&
372
+ isSparklineCell(value.secondary) &&
373
+ value.secondary.values.length === value.primary.values.length)));
374
+ case 'capacity-bar':
375
+ return isNullableNumber(value.used) && isNullableNumber(value.total) && isText(value.unit) && isText(value.label);
376
+ case 'mix-bar':
377
+ return (Array.isArray(value.parts) &&
378
+ value.parts.every(part => isRecord(part) && isString(part.key) && isText(part.label) && isFiniteNumber(part.value)) &&
379
+ isText(value.unit) &&
380
+ isFiniteNumber(value.total));
381
+ case 'event-strip':
382
+ return (Array.isArray(value.events) &&
383
+ value.events.every(event => inSet(BACKUP_RUN_STATES, event)) &&
384
+ isDateTime(value.start) &&
385
+ isOptionalText(value.label));
386
+ case 'weekly-grid':
387
+ return (isString(value.timezone) && isWeeklyGrid(value.running) && isNullableNumber(value.businessHoursShare) && isNullableNumber(value.offHoursShare));
388
+ default:
389
+ return false;
390
+ }
391
+ };
392
+ export const isStoryColumn = (value) => isRecord(value) &&
393
+ isString(value.key) &&
394
+ isText(value.label) &&
395
+ inSet(STORY_CELL_KINDS, value.cell) &&
396
+ isPriority(value.priority) &&
397
+ (value.roleClass === undefined || inSet(COLUMN_ROLE_CLASSES, value.roleClass)) &&
398
+ isOptionalText(value.hint);
399
+ /** Every column has a cell on the row, and the cell's kind matches the column's renderer. */
400
+ export const hasCellsForColumns = (row, columns) => columns.every(column => {
401
+ const cell = row.cells[column.key];
402
+ return cell !== undefined && cell.kind === column.cell;
403
+ });
404
+ // ---- Rows
405
+ /** Re-widen a narrowed row so story-specific fields can be inspected without index-signature casts. */
406
+ const fields = (value) => value;
407
+ /** An AWS account has no tenant, so an AWS story row may carry an empty `tenantId`; every other provider requires one. */
408
+ const isTenantId = (value, provider) => (provider === 'aws' ? isText(value) : isString(value));
409
+ const isStoryRowBase = (value, provider) => isRecord(value) &&
410
+ ['resourceId', 'name', 'type', 'subscriptionId', 'companyId', 'currency', 'fingerprint'].every(key => isString(value[key])) &&
411
+ isTenantId(value.tenantId, provider) &&
412
+ isText(value.location) &&
413
+ isNullableNumber(value.spend30d) &&
414
+ isNullableNumber(value.savingsMax) &&
415
+ (value.ownerResourceId === undefined || isString(value.ownerResourceId)) &&
416
+ (value.actionable === undefined || isBoolean(value.actionable)) &&
417
+ // An informational row asks for nothing, so it publishes no saving.
418
+ (value.actionable !== false || value.savingsMax === null) &&
419
+ isRecord(value.cells) &&
420
+ Object.values(value.cells).every(isStoryCell);
421
+ export const isOversizedResourceRow = (value, days, provider) => {
422
+ if (!isStoryRowBase(value, provider))
423
+ return false;
424
+ const row = fields(value);
425
+ if (!isUtilizationProfile(row.profile, days) || (row.betterSku !== undefined && !isSkuOptionSummary(row.betterSku)))
426
+ return false;
427
+ if (row.recommendedOption !== undefined && !isSkuOption(row.recommendedOption))
428
+ return false;
429
+ if (row.vmComputeCostComparison !== undefined) {
430
+ const comparison = row.vmComputeCostComparison;
431
+ if (value.type.toLowerCase() !== 'microsoft.compute/virtualmachines' ||
432
+ !isRecord(comparison) ||
433
+ comparison.basis !== 'billed-compute' ||
434
+ !isFiniteNumber(comparison.currentCost) ||
435
+ !isFiniteNumber(comparison.targetCost) ||
436
+ comparison.currentCost < comparison.targetCost ||
437
+ comparison.targetCost < 0 ||
438
+ comparison.currency !== value.currency ||
439
+ !isFiniteNumber(comparison.windowDays) ||
440
+ !Number.isInteger(comparison.windowDays) ||
441
+ comparison.windowDays <= 0 ||
442
+ value.savingsMax === null ||
443
+ Math.abs(comparison.currentCost - comparison.targetCost - value.savingsMax) > 0.01 ||
444
+ row.recommendedOption === undefined)
445
+ return false;
446
+ }
447
+ if (row.rightSizeStatus !== undefined && !inSet(RIGHT_SIZE_ASSESSMENT_STATUSES, row.rightSizeStatus))
448
+ return false;
449
+ const hasRecommendation = row.betterSku !== undefined || row.recommendedOption !== undefined;
450
+ if (row.rightSizeStatus === 'recommended' && !hasRecommendation)
451
+ return false;
452
+ if (row.rightSizeStatus !== undefined && row.rightSizeStatus !== 'recommended' && hasRecommendation)
453
+ return false;
454
+ if (row.betterSku !== undefined && row.recommendedOption !== undefined) {
455
+ const summary = row.betterSku;
456
+ const option = row.recommendedOption;
457
+ if (summary.kind !== option.kind || summary.label !== option.label || !Object.is(summary.savingsPercent, option.savingsPercent))
458
+ return false;
459
+ if (summary.savingsBasis !== undefined && option.savingsBasis !== undefined && summary.savingsBasis !== option.savingsBasis)
460
+ return false;
461
+ }
462
+ if (row.rightSizeRejection !== undefined && (!isRightSizeRejection(row.rightSizeRejection) || hasRecommendation))
463
+ return false;
464
+ // A blocked resize is still the recommended size, but it cannot lower the bill now: no saving, never actionable.
465
+ if (row.commitmentBlock !== undefined) {
466
+ if (!isCommitmentBlock(row.commitmentBlock) || !hasRecommendation || row.savingsMax !== null || row.actionable === true)
467
+ return false;
468
+ }
469
+ return true;
470
+ };
471
+ /** `blocked-by-commitment` and `commitmentBlock` go together; a blocked row publishes no saving and is not actionable. */
472
+ const isCoherentCommitmentBlock = (row) => {
473
+ const blocked = row.verdict === 'blocked-by-commitment';
474
+ if (!blocked)
475
+ return row.commitmentBlock === undefined;
476
+ return isCommitmentBlock(row.commitmentBlock) && row.savingsMax === null && row.actionable !== true;
477
+ };
478
+ export const isRightSkuRow = (value, days, provider) => {
479
+ if (!isStoryRowBase(value, provider))
480
+ return false;
481
+ const row = fields(value);
482
+ return (isSkuOption(row.current) &&
483
+ Array.isArray(row.options) &&
484
+ row.options.every(isSkuOption) &&
485
+ inSet(RIGHT_SKU_VERDICTS, row.verdict) &&
486
+ isRecord(row.usage) &&
487
+ isNullableNumber(row.usage.primaryP95) &&
488
+ isNullableNumber(row.usage.secondaryP95) &&
489
+ inSet(TELEMETRY_STATUSES, row.usage.telemetry) &&
490
+ (row.profile === undefined || isUtilizationProfile(row.profile, days)) &&
491
+ isCoherentCommitmentBlock(row));
492
+ };
493
+ /** Schedule candidates always carry a corroborated weekly running profile. */
494
+ export const isScheduleCandidateRow = (value, days, provider) => {
495
+ if (!isStoryRowBase(value, provider))
496
+ return false;
497
+ const row = fields(value);
498
+ if (!isUtilizationProfile(row.profile, days) || !inSet(SCHEDULE_ACTIONS, row.action))
499
+ return false;
500
+ const profile = row.profile;
501
+ return profile.running !== undefined && profile.running.weekly !== undefined && isCorroboratedRunningProfile(profile.running);
502
+ };
503
+ const resilienceRow = (value, provider) => {
504
+ if (!isStoryRowBase(value, provider))
505
+ return false;
506
+ const row = fields(value);
507
+ return (isProtectionProfile(row.protection) &&
508
+ (row.backupRuns === undefined || (Array.isArray(row.backupRuns) && row.backupRuns.every(run => inSet(BACKUP_RUN_STATES, run)))) &&
509
+ (row.lastRecoveryPointAt === undefined || row.lastRecoveryPointAt === null || isDateTime(row.lastRecoveryPointAt)) &&
510
+ isOptionalNullableNumber(row.uptimeDays) &&
511
+ (row.activeHealthEvents === undefined || isCount(row.activeHealthEvents)));
512
+ };
513
+ const hybridBenefitRow = (value, provider) => {
514
+ if (!isStoryRowBase(value, provider))
515
+ return false;
516
+ const row = fields(value);
517
+ return (['productFamily', 'serviceModel', 'configurationStatus', 'technicalEligibilityStatus', 'coverageStatus', 'entitlementStatus'].every(key => isString(row[key])) &&
518
+ isNullableString(row.edition) &&
519
+ isNullableNumber(row.vCpuCount) &&
520
+ isRecord(row.decision) &&
521
+ isString(row.decision.status) &&
522
+ isText(row.decision.headline) &&
523
+ isNullableNumber(row.decision.paybackMonths) &&
524
+ isString(row.decision.confidence) &&
525
+ isStringArray(row.reasonCodes) &&
526
+ isNullableNumber(row.licenceObservedStableDays));
527
+ };
528
+ const commitmentRow = (value, provider) => {
529
+ if (!isStoryRowBase(value, provider))
530
+ return false;
531
+ const row = fields(value);
532
+ return (isCommitmentCoverage(row.coverage) &&
533
+ (row.utilization === undefined || (isRecord(row.utilization) && isString(row.utilization.primaryKey) && isNullableNumber(row.utilization.p95))));
534
+ };
535
+ export const isResilienceRow = (value) => resilienceRow(value);
536
+ export const isHybridBenefitRow = (value) => hybridBenefitRow(value);
537
+ export const isCommitmentRow = (value) => commitmentRow(value);
538
+ /** Row guard for a story key; unknown keys reject every row. `provider: 'aws'` admits rows with an empty `tenantId`. */
539
+ export const storyRowGuard = (storyKey, days, provider) => {
540
+ switch (storyKey) {
541
+ case 'oversized-resources':
542
+ return (row) => isOversizedResourceRow(row, days, provider);
543
+ case 'right-sku':
544
+ return (row) => isRightSkuRow(row, days, provider);
545
+ case 'schedule-candidates':
546
+ return (row) => isScheduleCandidateRow(row, days, provider);
547
+ case 'resilience-recovery':
548
+ return (row) => resilienceRow(row, provider);
549
+ case 'hybrid-benefit':
550
+ return (row) => hybridBenefitRow(row, provider);
551
+ case 'commitments':
552
+ return (row) => commitmentRow(row, provider);
553
+ default:
554
+ return (_row) => false;
555
+ }
556
+ };
557
+ export const isStorySummary = (value) => isRecord(value) &&
558
+ isRecord(value.counts) &&
559
+ Object.values(value.counts).every(isCount) &&
560
+ (value.actionable === undefined ||
561
+ (isCount(value.actionable) && (value.counts.resources === undefined || value.actionable <= value.counts.resources))) &&
562
+ isNumberRecord(value.spend) &&
563
+ isString(value.currency) &&
564
+ isOptionalText(value.note);
565
+ const isStorySectionFinancials = (value) => value === undefined || (isRecord(value) && isFiniteNumber(value.spend30d) && isFiniteNumber(value.savingsMax) && isString(value.currency));
566
+ export const isStorySection = (value, storyKey, limit, days, provider) => {
567
+ if (!isRecord(value) || !isString(value.resourceType) || !isString(value.family))
568
+ return false;
569
+ if (!isStorySectionFinancials(value.financials))
570
+ return false;
571
+ if (!Array.isArray(value.columns) || !value.columns.every(isStoryColumn))
572
+ return false;
573
+ if (new Set(value.columns.map(column => column.key)).size !== value.columns.length)
574
+ return false;
575
+ if (!isBoundedRows(value, limit, storyRowGuard(storyKey, days, provider)))
576
+ return false;
577
+ const columns = value.columns;
578
+ return value.rows.every(row => hasCellsForColumns(row, columns));
579
+ };
580
+ /**
581
+ * A section of a summary-view projection (`view: 'summary'`): the produced columns and counts with the rows removed,
582
+ * so `rows` must be empty while `totalCount` / `omittedCount` keep the values the engine wrote.
583
+ */
584
+ export const isStorySummarySection = (value) => {
585
+ if (!isRecord(value) || !isString(value.resourceType) || !isString(value.family))
586
+ return false;
587
+ if (!isStorySectionFinancials(value.financials))
588
+ return false;
589
+ if (!Array.isArray(value.columns) || !value.columns.every(isStoryColumn))
590
+ return false;
591
+ if (new Set(value.columns.map(column => column.key)).size !== value.columns.length)
592
+ return false;
593
+ return (Array.isArray(value.rows) &&
594
+ value.rows.length === 0 &&
595
+ isCount(value.totalCount) &&
596
+ isCount(value.omittedCount) &&
597
+ value.omittedCount <= value.totalCount &&
598
+ value.totalCount - value.omittedCount <= STORY_LIMITS.sectionRows);
599
+ };
600
+ /** Every row of an artifact belongs to the artifact's scope; a row from another company, tenant or subscription is rejected. */
601
+ export const isRowInScope = (row, scope) => row.companyId === scope.companyId && row.tenantId === scope.tenantId && row.subscriptionId === scope.subscriptionId;
602
+ const sectionFinancialsMatchCurrency = (sections, currency) => sections.every(section => section.financials === undefined || section.financials.currency === currency);
603
+ const isScope = (value) => isRecord(value) &&
604
+ (value.provider === undefined || inSet(PROVIDERS, value.provider)) &&
605
+ ['companyId', 'subscriptionId', 'currency'].every(key => isString(value[key])) &&
606
+ isTenantId(value.tenantId, value.provider) &&
607
+ isText(value.displayName);
608
+ export const isStoryArtifact = (value, storyKey) => {
609
+ if (!isRecord(value) || !isString(value.storyKey) || !STORY_KEY_SET.has(value.storyKey))
610
+ return false;
611
+ if (storyKey !== undefined && value.storyKey !== storyKey)
612
+ return false;
613
+ if (!isScope(value.scope))
614
+ return false;
615
+ if (!isRecord(value.generation) || !isString(value.generation.sourceRunId) || !isDateTime(value.generation.generatedAt))
616
+ return false;
617
+ if (!isRecord(value.window) ||
618
+ !isDateTime(value.window.start) ||
619
+ !isDateTime(value.window.end) ||
620
+ !isCount(value.window.days) ||
621
+ value.window.days < 1 ||
622
+ !isString(value.window.timezone))
623
+ return false;
624
+ if (!isStorySummary(value.summary))
625
+ return false;
626
+ const days = value.window.days;
627
+ const key = value.storyKey;
628
+ if (value.view !== undefined && value.view !== 'summary')
629
+ return false;
630
+ const summaryCurrency = value.summary.currency;
631
+ if (value.view === 'summary') {
632
+ return (Array.isArray(value.sections) &&
633
+ value.sections.every(isStorySummarySection) &&
634
+ sectionFinancialsMatchCurrency(value.sections, summaryCurrency));
635
+ }
636
+ const scope = value.scope;
637
+ if (!Array.isArray(value.sections) ||
638
+ !value.sections.every(section => isStorySection(section, key, STORY_LIMITS.sectionRows, days, scope.provider)))
639
+ return false;
640
+ const sections = value.sections;
641
+ return sectionFinancialsMatchCurrency(sections, summaryCurrency) && sections.every(section => section.rows.every(row => isRowInScope(row, scope)));
642
+ };
643
+ /** Bounded sample embedded in the evidence pack; rows are validated for `storyKey`, window days are not known here. */
644
+ export const isStorySample = (value, storyKey) => {
645
+ if (!isRecord(value) || !isStorySummary(value.summary) || !Array.isArray(value.sections))
646
+ return false;
647
+ if (!value.sections.every(section => isStorySection(section, storyKey, STORY_LIMITS.sampleRows)))
648
+ return false;
649
+ return sectionFinancialsMatchCurrency(value.sections, value.summary.currency);
650
+ };
651
+ export const isStoryFingerprint = (value) => isRecord(value) &&
652
+ isString(value.storyKey) &&
653
+ STORY_KEY_SET.has(value.storyKey) &&
654
+ isString(value.resourceId) &&
655
+ isString(value.fingerprint) &&
656
+ isNullableNumber(value.savingsMax);
657
+ /** Bounded, de-duplicated (storyKey + fingerprint) fingerprint rows for one history period. */
658
+ export const isStoryFingerprintRows = (value) => isBoundedRows(value, STORY_LIMITS.historyFingerprints, isStoryFingerprint) &&
659
+ new Set(value.rows.map(row => `${row.storyKey}|${row.fingerprint}`)).size === value.rows.length;
660
+ export const isReportingStories = (value) => isRecord(value) && Object.entries(value).every(([key, sample]) => STORY_KEY_SET.has(key) && isStorySample(sample, key));
661
+ // ---- Engine config schemas
662
+ export const isUtilizationMetricEntry = (value) => isRecord(value) &&
663
+ isString(value.key) &&
664
+ isString(value.metricName) &&
665
+ isOptionalText(value.collection) &&
666
+ inSet(METRIC_ROLES, value.role) &&
667
+ (value.visual === undefined || inSet(METRIC_VISUALS, value.visual)) &&
668
+ isOptionalText(value.unit) &&
669
+ (value.axisMax === undefined || isFiniteNumber(value.axisMax)) &&
670
+ isOptionalText(value.axisMaxExpression) &&
671
+ (value.billedOn === undefined || inSet(BILLED_ON, value.billedOn)) &&
672
+ isOptionalText(value.transform) &&
673
+ isOptionalText(value.requires) &&
674
+ isOptionalText(value.when) &&
675
+ (value.dimensions === undefined ||
676
+ (isRecord(value.dimensions) && inSet(DIMENSION_POLICIES, value.dimensions.policy) && isOptionalText(value.dimensions.name))) &&
677
+ (value.priority === undefined || isPriority(value.priority));
678
+ const isMetricEntries = (value) => Array.isArray(value) && value.every(isUtilizationMetricEntry);
679
+ export const isUtilizationProfileEntry = (value) => isRecord(value) &&
680
+ isString(value.family) &&
681
+ (value.producer === undefined || inSet(PRODUCERS, value.producer)) &&
682
+ isOptionalText(value.capacityLabel) &&
683
+ inSet(RUN_MODES, value.runMode) &&
684
+ (value.runningSignal === undefined || isNullableString(value.runningSignal)) &&
685
+ (value.scheduleFit === undefined || isBoolean(value.scheduleFit) || inSet(SCHEDULE_ACTIONS, value.scheduleFit)) &&
686
+ (value.variants === undefined ||
687
+ (Array.isArray(value.variants) &&
688
+ value.variants.every(variant => isRecord(variant) &&
689
+ isString(variant.when) &&
690
+ isMetricEntries(variant.metrics) &&
691
+ (variant.verdictRules === undefined || isStringRecord(variant.verdictRules))))) &&
692
+ (value.metrics === undefined || isMetricEntries(value.metrics)) &&
693
+ (value.verdictRules === undefined || isStringRecord(value.verdictRules)) &&
694
+ (value.skuAlternatives === undefined ||
695
+ (isRecord(value.skuAlternatives) &&
696
+ isString(value.skuAlternatives.source) &&
697
+ (value.skuAlternatives.capabilityKeys === undefined || isStringArray(value.skuAlternatives.capabilityKeys))));
698
+ export const isUtilizationProfileConfig = (value) => isRecord(value) &&
699
+ value.version === 1 &&
700
+ isRecord(value.defaults) &&
701
+ isCount(value.defaults.windowDays) &&
702
+ value.defaults.windowDays >= 1 &&
703
+ value.defaults.bucket === 'P1D' &&
704
+ isBoolean(value.defaults.weeklyProfile) &&
705
+ isStringRecord(value.defaults.verdictRules) &&
706
+ isRecord(value.profiles) &&
707
+ Object.entries(value.profiles).every(([type, entry]) => type === type.toLowerCase() && isUtilizationProfileEntry(entry));
708
+ export const isResilienceProfileConfig = (value) => isRecord(value) &&
709
+ value.version === 1 &&
710
+ isRecord(value.profiles) &&
711
+ Object.entries(value.profiles).every(([type, entry]) => type === type.toLowerCase() &&
712
+ isRecord(entry) &&
713
+ Array.isArray(entry.capabilities) &&
714
+ entry.capabilities.every(capability => isRecord(capability) &&
715
+ isString(capability.key) &&
716
+ isBoolean(capability.required) &&
717
+ isString(capability.source) &&
718
+ isOptionalText(capability.sla)));