@spottoai/types-package 1.0.2-beta.353 → 1.0.2-beta.356

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 (182) hide show
  1. package/README.md +17 -0
  2. package/dist/aws/commitments-planning.d.ts +3 -0
  3. package/dist/aws/commitments-planning.d.ts.map +1 -0
  4. package/dist/aws/commitments-planning.js +6 -0
  5. package/dist/aws/commitments-planning.js.map +1 -0
  6. package/dist/aws/commitmentsPlanningValidation.d.ts.map +1 -1
  7. package/dist/aws/commitmentsPlanningValidation.js +2 -0
  8. package/dist/aws/commitmentsPlanningValidation.js.map +1 -1
  9. package/dist/aws/index.d.ts +2 -0
  10. package/dist/aws/index.d.ts.map +1 -1
  11. package/dist/aws/index.js +2 -0
  12. package/dist/aws/index.js.map +1 -1
  13. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts +4 -0
  14. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts.map +1 -0
  15. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js +513 -0
  16. package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js.map +1 -0
  17. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts +13 -0
  18. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts.map +1 -0
  19. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js +5 -0
  20. package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js.map +1 -0
  21. package/dist/aws/portalPublicArtifactHistoryTypes.d.ts +5 -0
  22. package/dist/aws/portalPublicArtifactHistoryTypes.d.ts.map +1 -1
  23. package/dist/aws/portalPublicArtifactHistoryTypes.js +6 -0
  24. package/dist/aws/portalPublicArtifactHistoryTypes.js.map +1 -1
  25. package/dist/aws/portalPublicArtifacts.d.ts +2 -1
  26. package/dist/aws/portalPublicArtifacts.d.ts.map +1 -1
  27. package/dist/aws/portalPublicArtifacts.js.map +1 -1
  28. package/dist/aws/publicArtifacts.d.ts +1 -1
  29. package/dist/aws/publicArtifacts.d.ts.map +1 -1
  30. package/dist/aws/publicArtifacts.js +1 -0
  31. package/dist/aws/publicArtifacts.js.map +1 -1
  32. package/dist/aws/relationships.d.ts +4 -0
  33. package/dist/aws/relationships.d.ts.map +1 -0
  34. package/dist/aws/relationships.js +6 -0
  35. package/dist/aws/relationships.js.map +1 -0
  36. package/dist/azure/commitmentsPlanning.d.ts +3 -1
  37. package/dist/azure/commitmentsPlanning.d.ts.map +1 -1
  38. package/dist/esm/accounts/accounts.js +115 -0
  39. package/dist/esm/accounts/azureSpSetup.js +1 -0
  40. package/dist/esm/accounts/azureSpSetupDurable.js +1 -0
  41. package/dist/esm/accounts/index.js +5 -0
  42. package/dist/esm/accounts/readPermissions.js +198 -0
  43. package/dist/esm/accounts/validation.js +1 -0
  44. package/dist/esm/accounts/writePermissions.js +43 -0
  45. package/dist/esm/ai/index.js +2 -0
  46. package/dist/esm/assessments/artifact.js +1 -0
  47. package/dist/esm/assessments/catalogue.js +12 -0
  48. package/dist/esm/assessments/common.js +1 -0
  49. package/dist/esm/assessments/evidence.js +1 -0
  50. package/dist/esm/assessments/export.js +1 -0
  51. package/dist/esm/assessments/index.js +10 -0
  52. package/dist/esm/assessments/queue.js +2 -0
  53. package/dist/esm/assessments/review.js +1 -0
  54. package/dist/esm/assessments/run.js +1 -0
  55. package/dist/esm/assessments/sow.js +1 -0
  56. package/dist/esm/assessments/status.js +23 -0
  57. package/dist/esm/aws/commitments-planning.js +1 -0
  58. package/dist/esm/aws/commitmentsPlanningValidation.js +121 -0
  59. package/dist/esm/aws/estates.js +21 -0
  60. package/dist/esm/aws/index.js +18 -0
  61. package/dist/esm/aws/onboarding.js +1 -0
  62. package/dist/esm/aws/pluginPublicArtifactBodyValidation.js +217 -0
  63. package/dist/esm/aws/pluginPublicArtifactEvidence.js +1 -0
  64. package/dist/esm/aws/pluginPublicArtifactManifestValidation.js +255 -0
  65. package/dist/esm/aws/pluginPublicArtifactSectionValidation.js +464 -0
  66. package/dist/esm/aws/pluginPublicArtifactValidation.js +2 -0
  67. package/dist/esm/aws/pluginPublicArtifactValidationHelpers.js +216 -0
  68. package/dist/esm/aws/pluginPublicArtifacts.js +109 -0
  69. package/dist/esm/aws/portalCommitmentsPlanningPublicArtifactValidation.js +509 -0
  70. package/dist/esm/aws/portalCommitmentsPlanningPublicArtifacts.js +1 -0
  71. package/dist/esm/aws/portalPublicArtifactCurrentValidation.js +328 -0
  72. package/dist/esm/aws/portalPublicArtifactEvidenceValidation.js +294 -0
  73. package/dist/esm/aws/portalPublicArtifactHistoryAiValidation.js +368 -0
  74. package/dist/esm/aws/portalPublicArtifactHistoryTypes.js +40 -0
  75. package/dist/esm/aws/portalPublicArtifactNestedEvidence.js +1 -0
  76. package/dist/esm/aws/portalPublicArtifactNestedEvidenceValidation.js +397 -0
  77. package/dist/esm/aws/portalPublicArtifactValidation.js +2 -0
  78. package/dist/esm/aws/portalPublicArtifactValidationCommon.js +139 -0
  79. package/dist/esm/aws/portalPublicArtifacts.js +73 -0
  80. package/dist/esm/aws/portalRelationshipPublicArtifactValidation.js +334 -0
  81. package/dist/esm/aws/portalRelationshipPublicArtifacts.js +59 -0
  82. package/dist/esm/aws/portalRelationshipResourceNodeTypes.js +1 -0
  83. package/dist/esm/aws/portalRelationshipResourceNodeValidation.js +368 -0
  84. package/dist/esm/aws/publicArtifacts.js +13 -0
  85. package/dist/esm/aws/relationships.js +1 -0
  86. package/dist/esm/aws/requests.js +19 -0
  87. package/dist/esm/azure/activityLogs.js +2 -0
  88. package/dist/esm/azure/advisorScore.js +1 -0
  89. package/dist/esm/azure/benefits.js +1 -0
  90. package/dist/esm/azure/billingGeneration.js +1 -0
  91. package/dist/esm/azure/billingPlots.js +4 -0
  92. package/dist/esm/azure/budgets.js +1 -0
  93. package/dist/esm/azure/commitmentsPlanning.js +1 -0
  94. package/dist/esm/azure/common.js +1 -0
  95. package/dist/esm/azure/configs.js +1 -0
  96. package/dist/esm/azure/costComposition.js +1 -0
  97. package/dist/esm/azure/dataProtection.js +5 -0
  98. package/dist/esm/azure/governance.js +14 -0
  99. package/dist/esm/azure/licensing.js +1 -0
  100. package/dist/esm/azure/metrics.js +1 -0
  101. package/dist/esm/azure/payloads.js +1 -0
  102. package/dist/esm/azure/portalArtifacts.js +1 -0
  103. package/dist/esm/azure/prices.js +1 -0
  104. package/dist/esm/azure/publicIpAddresses.js +2 -0
  105. package/dist/esm/azure/recommendationAudit.js +16 -0
  106. package/dist/esm/azure/recommendationState.js +1 -0
  107. package/dist/esm/azure/recommendationTracks.js +40 -0
  108. package/dist/esm/azure/recommendationWorkflow.js +13 -0
  109. package/dist/esm/azure/recommendations.js +10 -0
  110. package/dist/esm/azure/regulatoryCompliance.js +6 -0
  111. package/dist/esm/azure/relationships.js +2 -0
  112. package/dist/esm/azure/reportingTemplates.js +1 -0
  113. package/dist/esm/azure/reports.js +12 -0
  114. package/dist/esm/azure/resourceHealth.js +12 -0
  115. package/dist/esm/azure/resourceOptimization.js +1 -0
  116. package/dist/esm/azure/resources.js +1 -0
  117. package/dist/esm/azure/reviewChecklist.js +1 -0
  118. package/dist/esm/azure/secureScore.js +1 -0
  119. package/dist/esm/azure/security.js +1 -0
  120. package/dist/esm/azure/serviceRetirement.js +1 -0
  121. package/dist/esm/azure/serviceRetirementState.js +1 -0
  122. package/dist/esm/azure/serviceRetirementWorkManagement.js +1 -0
  123. package/dist/esm/azure/storage-inventory.js +1 -0
  124. package/dist/esm/azure/subscriptions.js +1 -0
  125. package/dist/esm/azure/views.js +32 -0
  126. package/dist/esm/azure/workManagement.js +4 -0
  127. package/dist/esm/common/artifactGeneration.js +1 -0
  128. package/dist/esm/common/capabilityPassport.js +214 -0
  129. package/dist/esm/common/index.js +7 -0
  130. package/dist/esm/common/pagination.js +1 -0
  131. package/dist/esm/common/provider.js +11 -0
  132. package/dist/esm/common/providerSyncProgress.js +1 -0
  133. package/dist/esm/common/relationships.js +1 -0
  134. package/dist/esm/common/syncProgress.js +1 -0
  135. package/dist/esm/company/billingAccount.js +1 -0
  136. package/dist/esm/company/company.js +1 -0
  137. package/dist/esm/company/companyHierarchy.js +1 -0
  138. package/dist/esm/company/companyNotes.js +38 -0
  139. package/dist/esm/company/customProperties.js +1 -0
  140. package/dist/esm/company/index.js +6 -0
  141. package/dist/esm/company/notification.js +43 -0
  142. package/dist/esm/company/survey.js +1 -0
  143. package/dist/esm/customProperties/customProperties.js +1 -0
  144. package/dist/esm/customProperties/index.js +1 -0
  145. package/dist/esm/entries/aws.js +3 -0
  146. package/dist/esm/entries/commitments-planning.js +3 -0
  147. package/dist/esm/entries/provider.js +3 -0
  148. package/dist/esm/entries/recommendations.js +3 -0
  149. package/dist/esm/entries/relationships.js +3 -0
  150. package/dist/esm/entries/root.js +3 -0
  151. package/dist/esm/events/actionGroups.js +1 -0
  152. package/dist/esm/events/alertDefinitionRun.js +1 -0
  153. package/dist/esm/events/baseAlert.js +1 -0
  154. package/dist/esm/events/cost.js +1 -0
  155. package/dist/esm/events/costAnomalies.js +1 -0
  156. package/dist/esm/events/costViews.js +1 -0
  157. package/dist/esm/events/eventStatus.js +1 -0
  158. package/dist/esm/events/index.js +8 -0
  159. package/dist/esm/events/quickAlerts.js +2 -0
  160. package/dist/esm/features-and-permissions/access.js +1 -0
  161. package/dist/esm/features-and-permissions/index.js +1 -0
  162. package/dist/esm/feedbacks/feedback.js +1 -0
  163. package/dist/esm/identity/apikey.js +1 -0
  164. package/dist/esm/identity/index.js +1 -0
  165. package/dist/esm/index.js +54 -0
  166. package/dist/esm/index.vite.js +48 -0
  167. package/dist/esm/integrations/autotask.js +1 -0
  168. package/dist/esm/integrations/azureDevOps.js +1 -0
  169. package/dist/esm/integrations/github.js +1 -0
  170. package/dist/esm/integrations/halo.js +1 -0
  171. package/dist/esm/integrations/index.js +5 -0
  172. package/dist/esm/integrations/integrationTickets.js +1 -0
  173. package/dist/esm/package.json +3 -0
  174. package/dist/esm/scheduler/index.js +1 -0
  175. package/dist/esm/scheduler/scheduler.js +1 -0
  176. package/dist/esm/tags/index.js +1 -0
  177. package/dist/esm/tags/tags.js +6 -0
  178. package/dist/esm/unknown/services.js +1 -0
  179. package/dist/esm/users/companyUser.js +2 -0
  180. package/dist/esm/users/index.js +2 -0
  181. package/dist/esm/users/user.js +1 -0
  182. package/package.json +23 -6
@@ -0,0 +1,217 @@
1
+ import { AWS_PLUGIN_PUBLIC_ARTIFACT_SCHEMA_VERSION, buildAwsPluginResourceLogicalName, buildAwsPluginSubscriptionLogicalName, sha256AwsPluginIdentity, } from './pluginPublicArtifacts.js';
2
+ import { AWS_PUBLIC_ARTIFACT_SCHEMA_VERSION } from './publicArtifacts.js';
3
+ import { asRecord, assertAccount, assertExactKeys, assertJsonEqual, assertPublicJson, assertValue, isoTimestamp, optionalEnum, requiredEnum, requiredString, sha256, stringArray, validateBilling, validateMetricWindow, validateSelector, validateTagRuleScope, } from './pluginPublicArtifactValidationHelpers.js';
4
+ import { validateResourceSections, validateSubscriptionSections } from './pluginPublicArtifactSectionValidation.js';
5
+ export { validateSourceBinding } from './pluginPublicArtifactSectionValidation.js';
6
+ /** Validates and returns one lossless AWS plugin subscription-detail body. */
7
+ export function validateAwsPluginSubscriptionDetailArtifact(value) {
8
+ const artifact = asRecord(value, 'artifact');
9
+ assertExactKeys(artifact, [
10
+ 'schemaVersion',
11
+ 'pluginSchemaVersion',
12
+ 'provider',
13
+ 'accountId',
14
+ 'artifactType',
15
+ 'artifactGeneration',
16
+ 'generatedAt',
17
+ 'logicalName',
18
+ 'target',
19
+ 'sections',
20
+ ], 'artifact');
21
+ validateArtifactEnvelope(artifact, 'plugin-subscription');
22
+ const target = validateTarget(artifact.target, 'subscription-detail');
23
+ const accountId = requiredString(artifact.accountId, 'artifact.accountId');
24
+ assertAccount(target.accountId, accountId, 'artifact.target.accountId');
25
+ assertValue(artifact.logicalName, buildAwsPluginSubscriptionLogicalName(target.targetKeySha256), 'artifact.logicalName');
26
+ validateSubscriptionSections(artifact.sections, target, requiredString(artifact.generatedAt, 'artifact.generatedAt'));
27
+ assertPublicJson(artifact, 'artifact');
28
+ return value;
29
+ }
30
+ /** Validates and returns one lossless AWS plugin resource-detail body. */
31
+ export function validateAwsPluginResourceDetailArtifact(value) {
32
+ const artifact = asRecord(value, 'artifact');
33
+ assertExactKeys(artifact, [
34
+ 'schemaVersion',
35
+ 'pluginSchemaVersion',
36
+ 'provider',
37
+ 'accountId',
38
+ 'artifactType',
39
+ 'artifactGeneration',
40
+ 'generatedAt',
41
+ 'logicalName',
42
+ 'target',
43
+ 'selector',
44
+ 'stableKey',
45
+ 'sections',
46
+ ], 'artifact');
47
+ validateArtifactEnvelope(artifact, 'plugin-resource');
48
+ const target = validateTarget(artifact.target, 'resource-detail');
49
+ const accountId = requiredString(artifact.accountId, 'artifact.accountId');
50
+ assertAccount(target.accountId, accountId, 'artifact.target.accountId');
51
+ assertValue(artifact.logicalName, buildAwsPluginResourceLogicalName(target.stableKeySha256, target.targetKeySha256), 'artifact.logicalName');
52
+ assertJsonEqual(artifact.selector, target.selector, 'artifact.selector');
53
+ assertValue(artifact.stableKey, target.stableKey, 'artifact.stableKey');
54
+ validateResourceSections(artifact.sections, target, requiredString(artifact.generatedAt, 'artifact.generatedAt'));
55
+ assertPublicJson(artifact, 'artifact');
56
+ return value;
57
+ }
58
+ function validateArtifactEnvelope(artifact, artifactType) {
59
+ assertValue(artifact.schemaVersion, AWS_PUBLIC_ARTIFACT_SCHEMA_VERSION, 'artifact.schemaVersion');
60
+ assertValue(artifact.pluginSchemaVersion, AWS_PLUGIN_PUBLIC_ARTIFACT_SCHEMA_VERSION, 'artifact.pluginSchemaVersion');
61
+ assertValue(artifact.provider, 'aws', 'artifact.provider');
62
+ requiredString(artifact.accountId, 'artifact.accountId');
63
+ assertValue(artifact.artifactType, artifactType, 'artifact.artifactType');
64
+ const generation = validateGeneration(artifact.artifactGeneration, 'artifact.artifactGeneration');
65
+ assertValue(isoTimestamp(artifact.generatedAt, 'artifact.generatedAt'), generation.generatedAt, 'artifact.generatedAt');
66
+ }
67
+ function validateGeneration(value, field) {
68
+ const generation = asRecord(value, field);
69
+ assertExactKeys(generation, ['runId', 'generatedAt'], field);
70
+ return {
71
+ runId: requiredString(generation.runId, `${field}.runId`),
72
+ generatedAt: isoTimestamp(generation.generatedAt, `${field}.generatedAt`),
73
+ };
74
+ }
75
+ export function validateTarget(value, kind) {
76
+ const target = asRecord(value, 'target');
77
+ assertValue(target.kind, kind, 'target.kind');
78
+ assertValue(target.provider, 'aws', 'target.provider');
79
+ requiredString(target.accountId, 'target.accountId');
80
+ requiredString(target.targetKey, 'target.targetKey');
81
+ sha256(target.targetKeySha256, 'target.targetKeySha256');
82
+ assertValue(target.targetKeySha256, sha256AwsPluginIdentity(requiredString(target.targetKey, 'target.targetKey')), 'target.targetKeySha256');
83
+ validateBilling(target.billing);
84
+ stringArray(target.resourceRegions, 'target.resourceRegions');
85
+ validateMetricWindow(target.metricTimeWindow, 'target.metricTimeWindow');
86
+ validateRecommendationScopes(target.recommendationScopes, requiredString(target.accountId, 'target.accountId'));
87
+ if (kind === 'subscription-detail') {
88
+ assertExactKeys(target, [
89
+ 'kind',
90
+ 'provider',
91
+ 'accountId',
92
+ 'targetKey',
93
+ 'targetKeySha256',
94
+ 'accountSummaryTargetKey',
95
+ 'resourceCollectionTargetKey',
96
+ 'recommendationsTargetKey',
97
+ 'aiCostSummaryTargetKey',
98
+ 'serviceRetirementTargetKey',
99
+ 'commitmentAnalysisTargetKey',
100
+ 'reliabilityTargetKey',
101
+ 'accountGovernanceTargetKey',
102
+ 'billing',
103
+ 'resourceRegions',
104
+ 'metricTimeWindow',
105
+ 'aiCostSummaryAudience',
106
+ 'serviceRetirementRegions',
107
+ 'recommendationScopes',
108
+ 'commitmentAnalysis',
109
+ 'reliability',
110
+ 'accountGovernance',
111
+ ], 'target');
112
+ optionalEnum(target.aiCostSummaryAudience, ['portal', 'plugin'], 'target.aiCostSummaryAudience');
113
+ requiredString(target.accountSummaryTargetKey, 'target.accountSummaryTargetKey');
114
+ requiredString(target.resourceCollectionTargetKey, 'target.resourceCollectionTargetKey');
115
+ requiredString(target.recommendationsTargetKey, 'target.recommendationsTargetKey');
116
+ requiredString(target.serviceRetirementTargetKey, 'target.serviceRetirementTargetKey');
117
+ validateOptionalTargetKey(target.aiCostSummaryTargetKey, target.aiCostSummaryAudience !== undefined, 'target.aiCostSummaryTargetKey');
118
+ validateOptionalTargetKey(target.commitmentAnalysisTargetKey, target.commitmentAnalysis !== undefined, 'target.commitmentAnalysisTargetKey');
119
+ validateOptionalTargetKey(target.reliabilityTargetKey, target.reliability !== undefined, 'target.reliabilityTargetKey');
120
+ validateOptionalTargetKey(target.accountGovernanceTargetKey, target.accountGovernance !== undefined, 'target.accountGovernanceTargetKey');
121
+ stringArray(target.serviceRetirementRegions, 'target.serviceRetirementRegions');
122
+ validateCommitmentAnalysisTarget(target.commitmentAnalysis);
123
+ validateReliabilityTarget(target.reliability);
124
+ validateAccountGovernanceTarget(target.accountGovernance);
125
+ }
126
+ else {
127
+ assertExactKeys(target, [
128
+ 'kind',
129
+ 'provider',
130
+ 'accountId',
131
+ 'targetKey',
132
+ 'targetKeySha256',
133
+ 'resourceCollectionTargetKey',
134
+ 'recommendationsTargetKey',
135
+ 'billing',
136
+ 'resourceRegions',
137
+ 'metricTimeWindow',
138
+ 'tagRuleScope',
139
+ 'selector',
140
+ 'stableKey',
141
+ 'stableKeySha256',
142
+ 'relationshipTargetKey',
143
+ 'serviceRetirementTargetKey',
144
+ 'recommendationScopes',
145
+ ], 'target');
146
+ validateTagRuleScope(target.tagRuleScope);
147
+ requiredString(target.resourceCollectionTargetKey, 'target.resourceCollectionTargetKey');
148
+ requiredString(target.recommendationsTargetKey, 'target.recommendationsTargetKey');
149
+ validateSelector(target.selector, 'target.selector');
150
+ const stableKey = requiredString(target.stableKey, 'target.stableKey');
151
+ if (asRecord(target.selector, 'target.selector').kind === 'stable-key') {
152
+ assertValue(asRecord(target.selector, 'target.selector').stableKey, stableKey, 'target.selector.stableKey');
153
+ }
154
+ sha256(target.stableKeySha256, 'target.stableKeySha256');
155
+ assertValue(target.stableKeySha256, sha256AwsPluginIdentity(stableKey), 'target.stableKeySha256');
156
+ requiredString(target.relationshipTargetKey, 'target.relationshipTargetKey');
157
+ requiredString(target.serviceRetirementTargetKey, 'target.serviceRetirementTargetKey');
158
+ }
159
+ return value;
160
+ }
161
+ function validateOptionalTargetKey(value, required, field) {
162
+ if (required)
163
+ requiredString(value, field);
164
+ else if (value !== undefined)
165
+ throw new Error(`${field} requires its corresponding optional target.`);
166
+ }
167
+ function validateCommitmentAnalysisTarget(value) {
168
+ if (value === undefined)
169
+ return;
170
+ const target = asRecord(value, 'target.commitmentAnalysis');
171
+ assertExactKeys(target, ['resourceRegions', 'maxBenefitEntries'], 'target.commitmentAnalysis');
172
+ stringArray(target.resourceRegions, 'target.commitmentAnalysis.resourceRegions');
173
+ if (!Number.isSafeInteger(target.maxBenefitEntries) || Number(target.maxBenefitEntries) <= 0) {
174
+ throw new Error('target.commitmentAnalysis.maxBenefitEntries must be a positive safe integer.');
175
+ }
176
+ }
177
+ function validateReliabilityTarget(value) {
178
+ if (value === undefined)
179
+ return;
180
+ const target = asRecord(value, 'target.reliability');
181
+ assertExactKeys(target, ['includeTemplateContent', 'includeScoring', 'maxResultsPerSection', 'sectionScopeKeys'], 'target.reliability');
182
+ if (target.includeTemplateContent !== undefined)
183
+ assertValue(target.includeTemplateContent, true, 'target.reliability.includeTemplateContent');
184
+ if (target.includeScoring !== undefined)
185
+ assertValue(target.includeScoring, true, 'target.reliability.includeScoring');
186
+ if (!Number.isSafeInteger(target.maxResultsPerSection) || Number(target.maxResultsPerSection) <= 0) {
187
+ throw new Error('target.reliability.maxResultsPerSection must be a positive safe integer.');
188
+ }
189
+ stringArray(target.sectionScopeKeys, 'target.reliability.sectionScopeKeys');
190
+ }
191
+ function validateAccountGovernanceTarget(value) {
192
+ if (value === undefined)
193
+ return;
194
+ const target = asRecord(value, 'target.accountGovernance');
195
+ assertExactKeys(target, ['apiRegion'], 'target.accountGovernance');
196
+ requiredString(target.apiRegion, 'target.accountGovernance.apiRegion');
197
+ }
198
+ function validateRecommendationScopes(value, accountId) {
199
+ if (!Array.isArray(value))
200
+ throw new Error('target.recommendationScopes must be an array.');
201
+ const scopes = value;
202
+ scopes.forEach((value, index) => {
203
+ const field = `target.recommendationScopes[${index}]`;
204
+ const scope = asRecord(value, field);
205
+ assertExactKeys(scope, ['source', 'scope', 'accountId', 'scopeDiscriminator', 'computeOptimizerFamily', 'resourceRegions', 'targetKey', 'actionabilityTargetKey'], field);
206
+ requiredEnum(scope.source, ['custom', 'compute-optimizer', 'cost-optimization-hub', 'resilience-hub', 'security-hub', 'trusted-advisor', 'well-architected'], `${field}.source`);
207
+ assertValue(scope.scope, 'account', `${field}.scope`);
208
+ assertAccount(scope.accountId, accountId, `${field}.accountId`);
209
+ if (scope.scopeDiscriminator !== undefined)
210
+ requiredString(scope.scopeDiscriminator, `${field}.scopeDiscriminator`);
211
+ if (scope.computeOptimizerFamily !== undefined)
212
+ requiredString(scope.computeOptimizerFamily, `${field}.computeOptimizerFamily`);
213
+ stringArray(scope.resourceRegions, `${field}.resourceRegions`);
214
+ requiredString(scope.targetKey, `${field}.targetKey`);
215
+ requiredString(scope.actionabilityTargetKey, `${field}.actionabilityTargetKey`);
216
+ });
217
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,255 @@
1
+ import { AWS_PLUGIN_PUBLIC_ARTIFACT_SCHEMA_VERSION, buildAwsPluginResourceLogicalName, buildAwsPluginSubscriptionLogicalName, } from './pluginPublicArtifacts.js';
2
+ import { validateSourceBinding, validateTarget } from './pluginPublicArtifactBodyValidation.js';
3
+ import { validateSourceBindingForTarget } from './pluginPublicArtifactSectionValidation.js';
4
+ import { asRecord, assertAccount, assertExactKeys, assertJsonEqual, assertValue, isoTimestamp, requiredArray, requiredEnum, requiredString, sha256, validateDescriptor, } from './pluginPublicArtifactValidationHelpers.js';
5
+ /** Validates complete active-set identity and targeted carry-forward semantics. */
6
+ export function validateAwsPluginGenerationManifest(value) {
7
+ const manifest = asRecord(value, 'manifest');
8
+ assertExactKeys(manifest, [
9
+ 'schemaVersion',
10
+ 'status',
11
+ 'provider',
12
+ 'accountId',
13
+ 'artifactGeneration',
14
+ 'requestBinding',
15
+ 'operation',
16
+ 'previousGeneration',
17
+ 'members',
18
+ 'counts',
19
+ 'completedAt',
20
+ ], 'manifest');
21
+ assertValue(manifest.schemaVersion, AWS_PLUGIN_PUBLIC_ARTIFACT_SCHEMA_VERSION, 'manifest.schemaVersion');
22
+ assertValue(manifest.status, 'completed', 'manifest.status');
23
+ assertValue(manifest.provider, 'aws', 'manifest.provider');
24
+ const accountId = requiredString(manifest.accountId, 'manifest.accountId');
25
+ assertAccount(accountId, accountId, 'manifest.accountId');
26
+ const generation = validateGeneration(manifest.artifactGeneration);
27
+ const request = validateRequestBinding(manifest.requestBinding);
28
+ assertValue(request.requestedAt, generation.generatedAt, 'manifest.requestBinding.requestedAt');
29
+ const completedAt = isoTimestamp(manifest.completedAt, 'manifest.completedAt');
30
+ if (completedAt < generation.generatedAt)
31
+ throw new Error('manifest.completedAt cannot precede the output generation time.');
32
+ const operation = validateOperation(manifest.operation, accountId);
33
+ const previous = validatePreviousGeneration(manifest.previousGeneration, accountId);
34
+ const members = requiredArray(manifest.members, 'manifest.members').map((member, index) => validateMember(member, accountId, generation.generatedAt, `manifest.members[${index}]`));
35
+ assertUniqueLogicalNames(members);
36
+ validateCounts(manifest.counts, members);
37
+ validateTransition(operation, previous, members);
38
+ return value;
39
+ }
40
+ function validateGeneration(value) {
41
+ const generation = asRecord(value, 'manifest.artifactGeneration');
42
+ assertExactKeys(generation, ['runId', 'generatedAt'], 'manifest.artifactGeneration');
43
+ return {
44
+ runId: requiredString(generation.runId, 'manifest.artifactGeneration.runId'),
45
+ generatedAt: isoTimestamp(generation.generatedAt, 'manifest.artifactGeneration.generatedAt'),
46
+ };
47
+ }
48
+ function validateRequestBinding(value) {
49
+ const request = asRecord(value, 'manifest.requestBinding');
50
+ assertExactKeys(request, ['requestId', 'requestedAt'], 'manifest.requestBinding');
51
+ return {
52
+ requestId: requiredString(request.requestId, 'manifest.requestBinding.requestId'),
53
+ requestedAt: isoTimestamp(request.requestedAt, 'manifest.requestBinding.requestedAt'),
54
+ };
55
+ }
56
+ function validateOperation(value, accountId) {
57
+ const operation = asRecord(value, 'manifest.operation');
58
+ if (operation.kind === 'full') {
59
+ assertExactKeys(operation, ['kind'], 'manifest.operation');
60
+ return operation;
61
+ }
62
+ const kind = requiredEnum(operation.kind, ['targeted-replacement', 'targeted-retirement'], 'manifest.operation.kind');
63
+ assertExactKeys(operation, ['kind', 'target'], 'manifest.operation');
64
+ const targetRecord = asRecord(operation.target, 'manifest.operation.target');
65
+ const target = targetRecord.kind === 'subscription-detail'
66
+ ? validateTarget(operation.target, 'subscription-detail')
67
+ : validateTarget(operation.target, 'resource-detail');
68
+ if (targetRecord.kind !== 'subscription-detail' && targetRecord.kind !== 'resource-detail')
69
+ throw new Error('manifest.operation.target.kind is not declared.');
70
+ assertAccount(target.accountId, accountId, 'manifest.operation.target.accountId');
71
+ return { kind, target };
72
+ }
73
+ function validateMember(value, accountId, outputGeneratedAt, field) {
74
+ const member = asRecord(value, field);
75
+ const common = ['state', 'publication', 'provider', 'accountId', 'logicalName', 'artifactType', 'target'];
76
+ assertValue(member.provider, 'aws', `${field}.provider`);
77
+ assertAccount(member.accountId, accountId, `${field}.accountId`);
78
+ const artifactType = requiredEnum(member.artifactType, ['plugin-subscription', 'plugin-resource'], `${field}.artifactType`);
79
+ const target = artifactType === 'plugin-subscription' ? validateTarget(member.target, 'subscription-detail') : validateTarget(member.target, 'resource-detail');
80
+ assertAccount(target.accountId, accountId, `${field}.target.accountId`);
81
+ const logicalName = validateLogicalName(member.logicalName, target, `${field}.logicalName`);
82
+ if (member.state === 'active') {
83
+ assertExactKeys(member, [...common, 'artifact', 'sourceGenerations'], field);
84
+ requiredEnum(member.publication, ['replaced', 'carried-forward'], `${field}.publication`);
85
+ validateDescriptor(member.artifact, `${field}.artifact`);
86
+ const descriptor = asRecord(member.artifact, `${field}.artifact`);
87
+ assertValue(descriptor.name, logicalName, `${field}.artifact.name`);
88
+ const sourceIdentities = new Set();
89
+ const sourceBindings = [];
90
+ requiredArray(member.sourceGenerations, `${field}.sourceGenerations`).forEach((source, index) => {
91
+ const sourceRecord = asRecord(source, `${field}.sourceGenerations[${index}]`);
92
+ const binding = validateSourceBinding(source, accountId, requiredString(sourceRecord.section, `${field}.sourceGenerations[${index}].section`), `${field}.sourceGenerations[${index}]`);
93
+ if (binding.generatedAt > outputGeneratedAt)
94
+ throw new Error(`${field}.sourceGenerations[${index}].generatedAt cannot exceed output time.`);
95
+ validateSourceBindingForTarget(binding, target, `${field}.sourceGenerations[${index}]`);
96
+ const identity = [binding.section, binding.sourceArtifactType, binding.generationId, binding.targetKey, binding.artifactSha256].join('|');
97
+ if (sourceIdentities.has(identity))
98
+ throw new Error(`${field}.sourceGenerations contains duplicate source bindings.`);
99
+ sourceIdentities.add(identity);
100
+ sourceBindings.push(binding);
101
+ });
102
+ validateCompleteSourceSet(sourceBindings, target, field);
103
+ }
104
+ else if (member.state === 'retired') {
105
+ assertExactKeys(member, [...common, 'priorArtifactSha256', 'retiredAt'], field);
106
+ assertValue(member.publication, 'retired', `${field}.publication`);
107
+ sha256(member.priorArtifactSha256, `${field}.priorArtifactSha256`);
108
+ isoTimestamp(member.retiredAt, `${field}.retiredAt`);
109
+ }
110
+ else {
111
+ throw new Error(`${field}.state is not declared.`);
112
+ }
113
+ return value;
114
+ }
115
+ function validateCompleteSourceSet(sources, target, field) {
116
+ const expected = [];
117
+ const add = (section, sourceType, targetKey) => {
118
+ if (targetKey)
119
+ expected.push(`${section}|${sourceType}|${targetKey}`);
120
+ };
121
+ if (target.kind === 'subscription-detail') {
122
+ add('account-summary', 'account-summary', target.accountSummaryTargetKey);
123
+ add('resources', 'resource-collection', target.resourceCollectionTargetKey);
124
+ add('service-retirement', 'lifecycle', target.serviceRetirementTargetKey);
125
+ add('ai-cost-summary', 'ai-cost-summary', target.aiCostSummaryTargetKey);
126
+ add('commitment-analysis', 'commitment-analysis', target.commitmentAnalysisTargetKey);
127
+ add('reliability', 'reliability', target.reliabilityTargetKey);
128
+ add('account-governance', 'account-governance', target.accountGovernanceTargetKey);
129
+ }
130
+ else {
131
+ add('resource', 'resource-collection', target.resourceCollectionTargetKey);
132
+ add('relationships', 'relationships', target.relationshipTargetKey);
133
+ add('service-retirement', 'lifecycle', target.serviceRetirementTargetKey);
134
+ }
135
+ target.recommendationScopes.forEach(scope => {
136
+ add('recommendations', 'recommendations', scope.targetKey);
137
+ add('recommendations', 'recommendation-actionability', scope.actionabilityTargetKey);
138
+ });
139
+ const actual = sources.map(source => `${source.section}|${source.sourceArtifactType}|${source.targetKey}`);
140
+ assertJsonEqual([...actual].sort(), [...expected].sort(), `${field}.sourceGenerations complete source set`);
141
+ }
142
+ function validatePreviousGeneration(value, accountId) {
143
+ if (value === undefined)
144
+ return new Map();
145
+ const previous = asRecord(value, 'manifest.previousGeneration');
146
+ assertExactKeys(previous, ['provider', 'accountId', 'runId', 'manifestSha256', 'members'], 'manifest.previousGeneration');
147
+ assertValue(previous.provider, 'aws', 'manifest.previousGeneration.provider');
148
+ assertAccount(previous.accountId, accountId, 'manifest.previousGeneration.accountId');
149
+ requiredString(previous.runId, 'manifest.previousGeneration.runId');
150
+ sha256(previous.manifestSha256, 'manifest.previousGeneration.manifestSha256');
151
+ const result = new Map();
152
+ requiredArray(previous.members, 'manifest.previousGeneration.members').forEach((value, index) => {
153
+ const field = `manifest.previousGeneration.members[${index}]`;
154
+ const member = asRecord(value, field);
155
+ assertExactKeys(member, ['provider', 'accountId', 'logicalName', 'artifactType', 'targetKeySha256', 'stableKeySha256', 'artifactSha256'], field);
156
+ assertValue(member.provider, 'aws', `${field}.provider`);
157
+ assertAccount(member.accountId, accountId, `${field}.accountId`);
158
+ const name = requiredString(member.logicalName, `${field}.logicalName`);
159
+ if (result.has(name))
160
+ throw new Error('manifest.previousGeneration.members has duplicate logicalName values.');
161
+ requiredEnum(member.artifactType, ['plugin-subscription', 'plugin-resource'], `${field}.artifactType`);
162
+ sha256(member.targetKeySha256, `${field}.targetKeySha256`);
163
+ if (member.stableKeySha256 !== undefined)
164
+ sha256(member.stableKeySha256, `${field}.stableKeySha256`);
165
+ sha256(member.artifactSha256, `${field}.artifactSha256`);
166
+ result.set(name, member);
167
+ });
168
+ return result;
169
+ }
170
+ function validateTransition(operation, previous, members) {
171
+ if (operation.kind === 'full')
172
+ return;
173
+ if (previous.size === 0)
174
+ throw new Error('Targeted publication requires previousGeneration.members.');
175
+ const target = operation.target;
176
+ const targetName = logicalNameForTarget(target);
177
+ const current = new Map(members.map(member => [member.logicalName, member]));
178
+ for (const [name, prior] of previous) {
179
+ const member = current.get(name);
180
+ if (!member)
181
+ throw new Error(`Targeted publication omitted prior member ${name}.`);
182
+ if (name === targetName) {
183
+ assertTargetPublication(operation.kind, member);
184
+ assertPriorIdentity(member, prior, name);
185
+ continue;
186
+ }
187
+ if (member.state !== 'active' || member.publication !== 'carried-forward')
188
+ throw new Error(`Untargeted member ${name} must be carried forward.`);
189
+ assertPriorIdentity(member, prior, name);
190
+ }
191
+ const targetMember = current.get(targetName);
192
+ if (!targetMember)
193
+ throw new Error('Targeted publication omitted its target member.');
194
+ if (!previous.has(targetName)) {
195
+ if (operation.kind === 'targeted-retirement')
196
+ throw new Error('Cannot retire a target absent from the previous active set.');
197
+ assertTargetPublication(operation.kind, targetMember);
198
+ }
199
+ for (const member of members) {
200
+ if (!previous.has(member.logicalName) && member.logicalName !== targetName)
201
+ throw new Error(`Targeted publication contains undeclared member ${member.logicalName}.`);
202
+ }
203
+ }
204
+ function assertPriorIdentity(member, prior, name) {
205
+ assertValue(member.artifactType, prior.artifactType, `${name}.artifactType`);
206
+ assertValue(member.target.targetKeySha256, prior.targetKeySha256, `${name}.target.targetKeySha256`);
207
+ if (member.target.kind === 'resource-detail') {
208
+ assertValue(member.target.stableKeySha256, prior.stableKeySha256, `${name}.target.stableKeySha256`);
209
+ }
210
+ else if (prior.stableKeySha256 !== undefined) {
211
+ throw new Error(`${name}.stableKeySha256 is ambiguous for a subscription artifact.`);
212
+ }
213
+ if (member.state === 'active') {
214
+ if (member.publication === 'carried-forward') {
215
+ assertValue(member.artifact.sha256, prior.artifactSha256, `${name}.artifact.sha256`);
216
+ }
217
+ }
218
+ else {
219
+ assertValue(member.priorArtifactSha256, prior.artifactSha256, `${name}.priorArtifactSha256`);
220
+ }
221
+ }
222
+ function assertTargetPublication(kind, member) {
223
+ const expected = kind === 'targeted-retirement' ? 'retired' : 'replaced';
224
+ if (member.publication !== expected)
225
+ throw new Error(`Target member publication must be ${expected}.`);
226
+ }
227
+ function validateCounts(value, members) {
228
+ const counts = asRecord(value, 'manifest.counts');
229
+ assertExactKeys(counts, ['active', 'replaced', 'carriedForward', 'retired'], 'manifest.counts');
230
+ const expected = {
231
+ active: members.filter(member => member.state === 'active').length,
232
+ replaced: members.filter(member => member.publication === 'replaced').length,
233
+ carriedForward: members.filter(member => member.publication === 'carried-forward').length,
234
+ retired: members.filter(member => member.state === 'retired').length,
235
+ };
236
+ for (const [key, count] of Object.entries(expected))
237
+ assertValue(counts[key], count, `manifest.counts.${key}`);
238
+ }
239
+ function validateLogicalName(value, target, field) {
240
+ const expected = logicalNameForTarget(target);
241
+ assertValue(value, expected, field);
242
+ if (/[\\/]/.test(expected) || expected.includes('..'))
243
+ throw new Error(`${field} must be path-free.`);
244
+ return expected;
245
+ }
246
+ function logicalNameForTarget(target) {
247
+ return target.kind === 'subscription-detail'
248
+ ? buildAwsPluginSubscriptionLogicalName(target.targetKeySha256)
249
+ : buildAwsPluginResourceLogicalName(target.stableKeySha256, target.targetKeySha256);
250
+ }
251
+ function assertUniqueLogicalNames(members) {
252
+ const names = members.map(member => member.logicalName);
253
+ if (new Set(names).size !== names.length)
254
+ throw new Error('manifest.members contains duplicate logicalName values.');
255
+ }