@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,216 @@
1
+ import { AWS_FORBIDDEN_CREDENTIAL_FIELDS } from './requests.js';
2
+ const FORBIDDEN_PUBLIC_KEYS = new Set([
3
+ ...AWS_FORBIDDEN_CREDENTIAL_FIELDS,
4
+ 'externalId',
5
+ 'roleArn',
6
+ 'secretArn',
7
+ 'secretReference',
8
+ 'credentialReference',
9
+ 'storagePath',
10
+ 'sourcePath',
11
+ 'path',
12
+ 'blobPath',
13
+ 'containerPath',
14
+ 'chunk',
15
+ 'chunks',
16
+ 'lease',
17
+ 'retries',
18
+ 'retry',
19
+ 'refreshState',
20
+ 'lastRefreshExecutionRequestId',
21
+ 'lastRefreshExecutionRequestedAt',
22
+ 'prompt',
23
+ 'promptInput',
24
+ 'sourceBytes',
25
+ 'maxSourceBytes',
26
+ 'bedrockRegion',
27
+ 'guardrailId',
28
+ 'guardrailVersion',
29
+ 'etag',
30
+ 'eTag',
31
+ 'retiredAt',
32
+ ]);
33
+ const NORMALIZED_FORBIDDEN_PUBLIC_KEYS = new Set(Array.from(FORBIDDEN_PUBLIC_KEYS, key => key.toLowerCase()));
34
+ const FORBIDDEN_PUBLIC_KEY_PATTERN = /^(?:source|storage|blob|container)(?:path|uri|url|key)$|^s3(?:bucket|key|uri|url)$/i;
35
+ const SHA256_PATTERN = /^[a-f0-9]{64}$/;
36
+ const ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
37
+ export function asRecord(value, field) {
38
+ if (!value || typeof value !== 'object' || Array.isArray(value))
39
+ throw new Error(`${field} must be a JSON object.`);
40
+ return value;
41
+ }
42
+ export function requiredArray(value, field) {
43
+ if (!Array.isArray(value) || value.length === 0)
44
+ throw new Error(`${field} must be a non-empty array.`);
45
+ return value;
46
+ }
47
+ export function stringArray(value, field) {
48
+ if (!Array.isArray(value))
49
+ throw new Error(`${field} must be an array.`);
50
+ const strings = value.map((item, index) => requiredString(item, `${field}[${index}]`));
51
+ if (new Set(strings).size !== strings.length)
52
+ throw new Error(`${field} must not contain duplicates.`);
53
+ const sorted = [...strings].sort((left, right) => left.localeCompare(right));
54
+ if (JSON.stringify(strings) !== JSON.stringify(sorted))
55
+ throw new Error(`${field} must be sorted.`);
56
+ return strings;
57
+ }
58
+ export function requiredString(value, field) {
59
+ if (typeof value !== 'string' || value.trim() !== value || value.length === 0)
60
+ throw new Error(`${field} must be a non-empty trimmed string.`);
61
+ return value;
62
+ }
63
+ export function isoTimestamp(value, field) {
64
+ const timestamp = requiredString(value, field);
65
+ if (!ISO_TIMESTAMP_PATTERN.test(timestamp) || Number.isNaN(Date.parse(timestamp)))
66
+ throw new Error(`${field} must be an ISO UTC timestamp.`);
67
+ return timestamp;
68
+ }
69
+ export function sha256(value, field) {
70
+ const digest = requiredString(value, field);
71
+ if (!SHA256_PATTERN.test(digest))
72
+ throw new Error(`${field} must be a lowercase hexadecimal SHA-256.`);
73
+ return digest;
74
+ }
75
+ export function requiredEnum(value, values, field) {
76
+ if (typeof value !== 'string' || !values.includes(value))
77
+ throw new Error(`${field} is not declared.`);
78
+ return value;
79
+ }
80
+ export function optionalEnum(value, values, field) {
81
+ if (value !== undefined)
82
+ requiredEnum(value, values, field);
83
+ }
84
+ export function optionalRecord(value, field) {
85
+ if (value !== undefined)
86
+ asRecord(value, field);
87
+ }
88
+ export function assertAccount(value, accountId, field) {
89
+ assertValue(value, accountId, field);
90
+ if (!/^\d{12}$/.test(accountId))
91
+ throw new Error(`${field} must be a 12-digit AWS account id.`);
92
+ }
93
+ export function assertExactKeys(value, allowed, field) {
94
+ const allowedKeys = new Set(allowed);
95
+ const unknown = Object.keys(value).filter(key => !allowedKeys.has(key));
96
+ if (unknown.length > 0)
97
+ throw new Error(`${field} contains undeclared fields: ${unknown.sort().join(', ')}.`);
98
+ }
99
+ export function assertNoForbiddenKeys(value, field) {
100
+ if (Array.isArray(value)) {
101
+ value.forEach((item, index) => assertNoForbiddenKeys(item, `${field}[${index}]`));
102
+ return;
103
+ }
104
+ if (!value || typeof value !== 'object')
105
+ return;
106
+ for (const [key, child] of Object.entries(value)) {
107
+ if (isForbiddenPublicKey(key))
108
+ throw new Error(`${field}.${key} is not allowed in a public artifact.`);
109
+ assertNoForbiddenKeys(child, `${field}.${key}`);
110
+ }
111
+ }
112
+ /** Rejects non-JSON values, non-plain objects, and forbidden public keys recursively. */
113
+ export function assertPublicJson(value, field) {
114
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
115
+ return;
116
+ if (typeof value === 'number') {
117
+ if (!Number.isFinite(value))
118
+ throw new Error(`${field} must contain only finite JSON numbers.`);
119
+ return;
120
+ }
121
+ if (Array.isArray(value)) {
122
+ value.forEach((item, index) => assertPublicJson(item, `${field}[${index}]`));
123
+ return;
124
+ }
125
+ if (!value || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype) {
126
+ throw new Error(`${field} must contain only plain JSON values.`);
127
+ }
128
+ for (const [key, child] of Object.entries(value)) {
129
+ if (isForbiddenPublicKey(key))
130
+ throw new Error(`${field}.${key} is not allowed in a public artifact.`);
131
+ assertPublicJson(child, `${field}.${key}`);
132
+ }
133
+ }
134
+ function isForbiddenPublicKey(key) {
135
+ return NORMALIZED_FORBIDDEN_PUBLIC_KEYS.has(key.toLowerCase()) || FORBIDDEN_PUBLIC_KEY_PATTERN.test(key);
136
+ }
137
+ export function assertRequiredKeys(value, required, field) {
138
+ const missing = required.filter(key => !(key in value));
139
+ if (missing.length > 0)
140
+ throw new Error(`${field} is missing required fields: ${missing.join(', ')}.`);
141
+ }
142
+ export function assertValue(actual, expected, field) {
143
+ if (actual !== expected)
144
+ throw new Error(`${field} must match its exact binding.`);
145
+ }
146
+ export function assertJsonEqual(actual, expected, field) {
147
+ if (JSON.stringify(actual) !== JSON.stringify(expected))
148
+ throw new Error(`${field} must match its exact binding.`);
149
+ }
150
+ export function validateDescriptor(value, field) {
151
+ const descriptor = asRecord(value, field);
152
+ assertExactKeys(descriptor, ['name', 'mediaType', 'contentEncoding', 'byteLength', 'sha256'], field);
153
+ requiredString(descriptor.name, `${field}.name`);
154
+ assertValue(descriptor.mediaType, 'application/json', `${field}.mediaType`);
155
+ requiredEnum(descriptor.contentEncoding, ['identity', 'gzip'], `${field}.contentEncoding`);
156
+ if (!Number.isSafeInteger(descriptor.byteLength) || Number(descriptor.byteLength) < 0)
157
+ throw new Error(`${field}.byteLength must be a non-negative safe integer.`);
158
+ sha256(descriptor.sha256, `${field}.sha256`);
159
+ }
160
+ export function validateBilling(value, field = 'target.billing') {
161
+ const billing = asRecord(value, field);
162
+ if (billing.source === 'cur') {
163
+ assertExactKeys(billing, ['source', 'reportName', 'billingPeriod'], field);
164
+ requiredString(billing.reportName, `${field}.reportName`);
165
+ }
166
+ else if (billing.source === 'cur-2.0-data-exports') {
167
+ assertExactKeys(billing, ['source', 'exportName', 'billingPeriod'], field);
168
+ requiredString(billing.exportName, `${field}.exportName`);
169
+ }
170
+ else {
171
+ throw new Error(`${field}.source is not declared.`);
172
+ }
173
+ const period = asRecord(billing.billingPeriod, `${field}.billingPeriod`);
174
+ assertExactKeys(period, ['start', 'end'], `${field}.billingPeriod`);
175
+ calendarDate(period.start, `${field}.billingPeriod.start`);
176
+ calendarDate(period.end, `${field}.billingPeriod.end`);
177
+ if (String(period.start) > String(period.end))
178
+ throw new Error(`${field}.billingPeriod start must not exceed end.`);
179
+ }
180
+ function calendarDate(value, field) {
181
+ const date = requiredString(value, field);
182
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(date) || Number.isNaN(Date.parse(`${date}T00:00:00.000Z`)))
183
+ throw new Error(`${field} must be a valid calendar date.`);
184
+ if (new Date(`${date}T00:00:00.000Z`).toISOString().slice(0, 10) !== date)
185
+ throw new Error(`${field} must be a valid calendar date.`);
186
+ return date;
187
+ }
188
+ export function validateSelector(value, field) {
189
+ const selector = asRecord(value, field);
190
+ if (selector.kind === 'stable-key') {
191
+ assertExactKeys(selector, ['kind', 'stableKey'], field);
192
+ requiredString(selector.stableKey, `${field}.stableKey`);
193
+ }
194
+ else if (selector.kind === 'resource-arn') {
195
+ assertExactKeys(selector, ['kind', 'resourceArn'], field);
196
+ requiredString(selector.resourceArn, `${field}.resourceArn`);
197
+ }
198
+ else {
199
+ throw new Error(`${field}.kind is not declared.`);
200
+ }
201
+ }
202
+ export function validateMetricWindow(value, field) {
203
+ const window = asRecord(value, field);
204
+ assertExactKeys(window, ['start', 'end'], field);
205
+ isoTimestamp(window.start, `${field}.start`);
206
+ isoTimestamp(window.end, `${field}.end`);
207
+ if (String(window.start) > String(window.end))
208
+ throw new Error(`${field}.start must not exceed end.`);
209
+ }
210
+ export function validateTagRuleScope(value) {
211
+ if (value === undefined)
212
+ return;
213
+ const scope = asRecord(value, 'tagRuleScope');
214
+ assertExactKeys(scope, ['companyId'], 'tagRuleScope');
215
+ requiredString(scope.companyId, 'tagRuleScope.companyId');
216
+ }
@@ -0,0 +1,109 @@
1
+ export const AWS_PLUGIN_PUBLIC_ARTIFACT_SCHEMA_VERSION = 1;
2
+ export const AWS_PLUGIN_SOURCE_ARTIFACT_TYPES = [
3
+ 'account-summary',
4
+ 'resource-collection',
5
+ 'ai-cost-summary',
6
+ 'relationships',
7
+ 'lifecycle',
8
+ 'recommendations',
9
+ 'recommendation-actionability',
10
+ 'commitment-analysis',
11
+ 'reliability',
12
+ 'account-governance',
13
+ ];
14
+ export const AWS_PLUGIN_SUBSCRIPTION_SECTIONS = [
15
+ 'account-summary',
16
+ 'resources',
17
+ 'ai-cost-summary',
18
+ 'service-retirement',
19
+ 'recommendations',
20
+ 'commitment-analysis',
21
+ 'reliability',
22
+ 'account-governance',
23
+ ];
24
+ export const AWS_PLUGIN_RESOURCE_SECTIONS = ['resource', 'relationships', 'service-retirement', 'recommendations'];
25
+ /** Builds the path-free subscription logical name from a target-key SHA-256. */
26
+ export function buildAwsPluginSubscriptionLogicalName(targetKeySha256) {
27
+ return `plugin-subscription--${normalizeSha256(targetKeySha256, 'targetKeySha256')}.json.gz`;
28
+ }
29
+ /** Builds the path-free resource logical name from stable and target SHA-256 values. */
30
+ export function buildAwsPluginResourceLogicalName(stableKeySha256, targetKeySha256) {
31
+ return `plugin-resource--${normalizeSha256(stableKeySha256, 'stableKeySha256')}--${normalizeSha256(targetKeySha256, 'targetKeySha256')}.json.gz`;
32
+ }
33
+ /** Browser-safe SHA-256 used to bind stable and target identity to logical names. */
34
+ export function sha256AwsPluginIdentity(value) {
35
+ const words = [];
36
+ const bytes = [];
37
+ for (const character of value) {
38
+ const codePoint = character.codePointAt(0) ?? 0;
39
+ if (codePoint < 0x80)
40
+ bytes.push(codePoint);
41
+ else if (codePoint < 0x800)
42
+ bytes.push(0xc0 | (codePoint >>> 6), 0x80 | (codePoint & 0x3f));
43
+ else if (codePoint < 0x10000)
44
+ bytes.push(0xe0 | (codePoint >>> 12), 0x80 | ((codePoint >>> 6) & 0x3f), 0x80 | (codePoint & 0x3f));
45
+ else {
46
+ bytes.push(0xf0 | (codePoint >>> 18), 0x80 | ((codePoint >>> 12) & 0x3f), 0x80 | ((codePoint >>> 6) & 0x3f), 0x80 | (codePoint & 0x3f));
47
+ }
48
+ }
49
+ const bitLength = bytes.length * 8;
50
+ for (const byte of bytes)
51
+ words.push(byte);
52
+ words.push(0x80);
53
+ while (words.length % 64 !== 56)
54
+ words.push(0);
55
+ for (let index = 7; index >= 0; index--)
56
+ words.push(Math.floor(bitLength / 2 ** (index * 8)) & 0xff);
57
+ const state = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
58
+ const constants = [
59
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
60
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
61
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
62
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
63
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
64
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
65
+ ];
66
+ const rotate = (word, bits) => (word >>> bits) | (word << (32 - bits));
67
+ for (let offset = 0; offset < words.length; offset += 64) {
68
+ const schedule = new Array(64);
69
+ for (let index = 0; index < 16; index++) {
70
+ const at = offset + index * 4;
71
+ schedule[index] = (words[at] << 24) | (words[at + 1] << 16) | (words[at + 2] << 8) | words[at + 3];
72
+ }
73
+ for (let index = 16; index < 64; index++) {
74
+ const previous = schedule[index - 15];
75
+ const recent = schedule[index - 2];
76
+ const small0 = rotate(previous, 7) ^ rotate(previous, 18) ^ (previous >>> 3);
77
+ const small1 = rotate(recent, 17) ^ rotate(recent, 19) ^ (recent >>> 10);
78
+ schedule[index] = (schedule[index - 16] + small0 + schedule[index - 7] + small1) | 0;
79
+ }
80
+ let [a, b, c, d, e, f, g, h] = state;
81
+ for (let index = 0; index < 64; index++) {
82
+ const large1 = rotate(e, 6) ^ rotate(e, 11) ^ rotate(e, 25);
83
+ const choose = (e & f) ^ (~e & g);
84
+ const temporary1 = (h + large1 + choose + constants[index] + schedule[index]) | 0;
85
+ const large0 = rotate(a, 2) ^ rotate(a, 13) ^ rotate(a, 22);
86
+ const majority = (a & b) ^ (a & c) ^ (b & c);
87
+ const temporary2 = (large0 + majority) | 0;
88
+ h = g;
89
+ g = f;
90
+ f = e;
91
+ e = (d + temporary1) | 0;
92
+ d = c;
93
+ c = b;
94
+ b = a;
95
+ a = (temporary1 + temporary2) | 0;
96
+ }
97
+ [a, b, c, d, e, f, g, h].forEach((word, index) => {
98
+ state[index] = (state[index] + word) | 0;
99
+ });
100
+ }
101
+ return state.map(word => (word >>> 0).toString(16).padStart(8, '0')).join('');
102
+ }
103
+ function normalizeSha256(value, field) {
104
+ const normalized = value.trim().toLowerCase();
105
+ if (!/^[a-f0-9]{64}$/.test(normalized)) {
106
+ throw new Error(`${field} must be a lowercase hexadecimal SHA-256.`);
107
+ }
108
+ return normalized;
109
+ }