@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.
- package/README.md +3 -0
- package/dist/accounts/accounts.d.ts +13 -0
- package/dist/accounts/accounts.d.ts.map +1 -1
- package/dist/accounts/azureSpSetup.d.ts +5 -0
- package/dist/accounts/azureSpSetup.d.ts.map +1 -1
- package/dist/accounts/azureSpSetup.js.map +1 -1
- package/dist/accounts/index.d.ts +1 -0
- package/dist/accounts/index.d.ts.map +1 -1
- package/dist/accounts/index.js +1 -0
- package/dist/accounts/index.js.map +1 -1
- package/dist/accounts/subscriptionWriteAccess.d.ts +76 -0
- package/dist/accounts/subscriptionWriteAccess.d.ts.map +1 -0
- package/dist/accounts/subscriptionWriteAccess.js +119 -0
- package/dist/accounts/subscriptionWriteAccess.js.map +1 -0
- package/dist/accounts/writePermissions.d.ts +17 -1
- package/dist/accounts/writePermissions.d.ts.map +1 -1
- package/dist/accounts/writePermissions.js +47 -1
- package/dist/accounts/writePermissions.js.map +1 -1
- package/dist/ai/followUps.d.ts +16 -0
- package/dist/ai/followUps.d.ts.map +1 -0
- package/dist/ai/followUps.js +21 -0
- package/dist/ai/followUps.js.map +1 -0
- package/dist/ai/grounding.d.ts +42 -5
- package/dist/ai/grounding.d.ts.map +1 -1
- package/dist/ai/grounding.js +76 -8
- package/dist/ai/grounding.js.map +1 -1
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +1 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/aws/commitments-planning.d.ts +1 -1
- package/dist/aws/commitments-planning.d.ts.map +1 -1
- package/dist/aws/commitments-planning.js +1 -0
- package/dist/aws/commitments-planning.js.map +1 -1
- package/dist/aws/commitmentsPlanningValidation.d.ts +1 -1
- package/dist/aws/commitmentsPlanningValidation.d.ts.map +1 -1
- package/dist/aws/commitmentsPlanningValidation.js +26 -25
- package/dist/aws/commitmentsPlanningValidation.js.map +1 -1
- package/dist/aws/commitmentsPlanningView.d.ts +49 -0
- package/dist/aws/commitmentsPlanningView.d.ts.map +1 -0
- package/dist/aws/{pluginPublicArtifactEvidence.js → commitmentsPlanningView.js} +1 -1
- package/dist/aws/commitmentsPlanningView.js.map +1 -0
- package/dist/aws/index.d.ts +2 -14
- package/dist/aws/index.d.ts.map +1 -1
- package/dist/aws/index.js +2 -13
- package/dist/aws/index.js.map +1 -1
- package/dist/aws/organizationCommitments.d.ts +2 -1
- package/dist/aws/organizationCommitments.d.ts.map +1 -1
- package/dist/aws/organizationCommitments.js +2 -2
- package/dist/aws/organizationCommitments.js.map +1 -1
- package/dist/aws/organizationCommitmentsApiValidation.d.ts.map +1 -1
- package/dist/aws/organizationCommitmentsApiValidation.js +64 -64
- package/dist/aws/organizationCommitmentsApiValidation.js.map +1 -1
- package/dist/aws/organizationCommitmentsValidation.d.ts.map +1 -1
- package/dist/aws/organizationCommitmentsValidation.js +45 -44
- package/dist/aws/organizationCommitmentsValidation.js.map +1 -1
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.d.ts.map +1 -1
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +79 -76
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js.map +1 -1
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts +1 -2
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts.map +1 -1
- package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.js.map +1 -1
- package/dist/aws/publicArtifacts.d.ts +2 -37
- package/dist/aws/publicArtifacts.d.ts.map +1 -1
- package/dist/aws/publicArtifacts.js +3 -1
- package/dist/aws/publicArtifacts.js.map +1 -1
- package/dist/aws/relationships.d.ts +5 -3
- package/dist/aws/relationships.d.ts.map +1 -1
- package/dist/aws/relationships.js +18 -3
- package/dist/aws/relationships.js.map +1 -1
- package/dist/aws/requests.d.ts +35 -3
- package/dist/aws/requests.d.ts.map +1 -1
- package/dist/aws/requests.js +5 -3
- package/dist/aws/requests.js.map +1 -1
- package/dist/aws/resourceGraph.d.ts +14 -0
- package/dist/aws/resourceGraph.d.ts.map +1 -0
- package/dist/aws/resourceGraph.js +68 -0
- package/dist/aws/resourceGraph.js.map +1 -0
- package/dist/aws/validationHelpers.d.ts +8 -0
- package/dist/aws/validationHelpers.d.ts.map +1 -0
- package/dist/aws/validationHelpers.js +54 -0
- package/dist/aws/validationHelpers.js.map +1 -0
- package/dist/azure/commitmentsPlanning.d.ts +15 -46
- package/dist/azure/commitmentsPlanning.d.ts.map +1 -1
- package/dist/azure/commitmentsPlanning.js +9 -0
- package/dist/azure/commitmentsPlanning.js.map +1 -1
- package/dist/azure/commitmentsPlanningValidation.d.ts +18 -0
- package/dist/azure/commitmentsPlanningValidation.d.ts.map +1 -0
- package/dist/azure/commitmentsPlanningValidation.js +50 -0
- package/dist/azure/commitmentsPlanningValidation.js.map +1 -0
- package/dist/azure/dataProtection.d.ts +40 -0
- package/dist/azure/dataProtection.d.ts.map +1 -1
- package/dist/azure/governance.d.ts +5 -0
- package/dist/azure/governance.d.ts.map +1 -1
- package/dist/azure/metrics.d.ts +2 -27
- package/dist/azure/metrics.d.ts.map +1 -1
- package/dist/azure/payloads.d.ts +24 -0
- package/dist/azure/payloads.d.ts.map +1 -1
- package/dist/azure/payloads.js +87 -0
- package/dist/azure/payloads.js.map +1 -1
- package/dist/azure/recommendationTracks.d.ts +1 -1
- package/dist/azure/recommendationTracks.d.ts.map +1 -1
- package/dist/azure/reportEvidence.d.ts +192 -11
- package/dist/azure/reportEvidence.d.ts.map +1 -1
- package/dist/azure/reportEvidence.js +9 -1
- package/dist/azure/reportEvidence.js.map +1 -1
- package/dist/azure/reportEvidenceValidation.d.ts.map +1 -1
- package/dist/azure/reportEvidenceValidation.js +201 -5
- package/dist/azure/reportEvidenceValidation.js.map +1 -1
- package/dist/azure/reportEvidenceValidationHelpers.d.ts +3 -16
- package/dist/azure/reportEvidenceValidationHelpers.d.ts.map +1 -1
- package/dist/azure/reportEvidenceValidationHelpers.js +80 -92
- package/dist/azure/reportEvidenceValidationHelpers.js.map +1 -1
- package/dist/azure/resilienceFacts.d.ts +100 -0
- package/dist/azure/resilienceFacts.d.ts.map +1 -0
- package/dist/azure/resilienceFacts.js +20 -0
- package/dist/azure/resilienceFacts.js.map +1 -0
- package/dist/azure/resilienceFactsValidation.d.ts +4 -0
- package/dist/azure/resilienceFactsValidation.d.ts.map +1 -0
- package/dist/azure/resilienceFactsValidation.js +70 -0
- package/dist/azure/resilienceFactsValidation.js.map +1 -0
- package/dist/azure/savings.d.ts +4 -2
- package/dist/azure/savings.d.ts.map +1 -1
- package/dist/azure/serviceRetirement.d.ts +21 -2
- package/dist/azure/serviceRetirement.d.ts.map +1 -1
- package/dist/azure/views.d.ts +24 -1
- package/dist/azure/views.d.ts.map +1 -1
- package/dist/azure/views.js.map +1 -1
- package/dist/common/boundedRows.d.ts +7 -0
- package/dist/common/boundedRows.d.ts.map +1 -0
- package/dist/{scheduler/scheduler.js → common/boundedRows.js} +1 -1
- package/dist/common/boundedRows.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +3 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/metricStats.d.ts +29 -0
- package/dist/common/metricStats.d.ts.map +1 -0
- package/dist/{scheduler/bastionSchedule.js → common/metricStats.js} +1 -1
- package/dist/common/metricStats.js.map +1 -0
- package/dist/common/provider.d.ts +2 -0
- package/dist/common/provider.d.ts.map +1 -1
- package/dist/common/relationships.d.ts +3 -3
- package/dist/common/relationships.d.ts.map +1 -1
- package/dist/common/resourceGraph.d.ts +137 -0
- package/dist/common/resourceGraph.d.ts.map +1 -0
- package/dist/common/resourceGraph.js +17 -0
- package/dist/common/resourceGraph.js.map +1 -0
- package/dist/common/resourceGraphValidation.d.ts +30 -0
- package/dist/common/resourceGraphValidation.d.ts.map +1 -0
- package/dist/common/resourceGraphValidation.js +369 -0
- package/dist/common/resourceGraphValidation.js.map +1 -0
- package/dist/common/resourceIdentity.d.ts +28 -0
- package/dist/common/resourceIdentity.d.ts.map +1 -0
- package/dist/common/resourceIdentity.js +35 -0
- package/dist/common/resourceIdentity.js.map +1 -0
- package/dist/common/sha256.d.ts +2 -0
- package/dist/common/sha256.d.ts.map +1 -1
- package/dist/common/sha256.js +3 -0
- package/dist/common/sha256.js.map +1 -1
- package/dist/common/utilizationStories.d.ts +695 -0
- package/dist/common/utilizationStories.d.ts.map +1 -0
- package/dist/common/utilizationStories.js +21 -0
- package/dist/common/utilizationStories.js.map +1 -0
- package/dist/common/utilizationStoriesValidation.d.ts +60 -0
- package/dist/common/utilizationStoriesValidation.d.ts.map +1 -0
- package/dist/common/utilizationStoriesValidation.js +762 -0
- package/dist/common/utilizationStoriesValidation.js.map +1 -0
- package/dist/common/validationHelpers.d.ts +37 -0
- package/dist/common/validationHelpers.d.ts.map +1 -0
- package/dist/common/validationHelpers.js +147 -0
- package/dist/common/validationHelpers.js.map +1 -0
- package/dist/esm/accounts/index.js +1 -0
- package/dist/esm/accounts/subscriptionWriteAccess.js +112 -0
- package/dist/esm/accounts/writePermissions.js +46 -0
- package/dist/esm/ai/followUps.js +16 -0
- package/dist/esm/ai/grounding.js +74 -7
- package/dist/esm/ai/index.js +1 -0
- package/dist/esm/aws/commitments-planning.js +1 -0
- package/dist/esm/aws/commitmentsPlanningValidation.js +2 -1
- package/dist/esm/aws/index.js +2 -13
- package/dist/esm/aws/organizationCommitments.js +2 -2
- package/dist/esm/aws/organizationCommitmentsApiValidation.js +5 -5
- package/dist/esm/aws/organizationCommitmentsValidation.js +2 -1
- package/dist/esm/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +8 -5
- package/dist/esm/aws/publicArtifacts.js +2 -0
- package/dist/esm/aws/relationships.js +4 -1
- package/dist/esm/aws/requests.js +4 -2
- package/dist/esm/aws/resourceGraph.js +63 -0
- package/dist/esm/aws/validationHelpers.js +46 -0
- package/dist/esm/azure/commitmentsPlanning.js +8 -1
- package/dist/esm/azure/commitmentsPlanningValidation.js +39 -0
- package/dist/esm/azure/payloads.js +84 -1
- package/dist/esm/azure/reportEvidence.js +8 -0
- package/dist/esm/azure/reportEvidenceValidation.js +202 -6
- package/dist/esm/azure/reportEvidenceValidationHelpers.js +7 -19
- package/dist/esm/azure/resilienceFacts.js +16 -0
- package/dist/esm/azure/resilienceFactsValidation.js +64 -0
- package/dist/esm/common/index.js +3 -0
- package/dist/esm/common/resourceGraph.js +13 -0
- package/dist/esm/common/resourceGraphValidation.js +365 -0
- package/dist/esm/common/resourceIdentity.js +24 -0
- package/dist/esm/common/sha256.js +2 -0
- package/dist/esm/common/utilizationStories.js +17 -0
- package/dist/esm/common/utilizationStoriesValidation.js +718 -0
- package/dist/esm/common/validationHelpers.js +115 -0
- package/dist/esm/entries/relationships.js +2 -2
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.vite.js +1 -0
- package/dist/esm/reporting/jobs/index.js +13 -0
- package/dist/esm/reporting/jobs/reportJobIdentity.js +76 -0
- package/dist/esm/reporting/jobs/reportJobMessages.js +47 -0
- package/dist/esm/reporting/jobs/reportJobRow.js +264 -0
- package/dist/esm/reporting/jobs/reportJobSpec.js +295 -0
- package/dist/esm/reporting/jobs/reportJobStatus.js +87 -0
- package/dist/esm/reporting/shared/reportTableEntities.js +41 -0
- package/dist/esm/reporting/shared/reportingDigest.js +57 -0
- package/dist/esm/reporting/shared/reportingIds.js +88 -0
- package/dist/esm/reporting/shared/reportingPaths.js +23 -0
- package/dist/esm/scheduler/index.js +4 -4
- package/dist/esm/scheduler/resourceStrategy.js +2 -0
- package/dist/esm/scheduler/resourceStrategyCapabilityValidation.js +265 -0
- package/dist/esm/scheduler/resourceStrategyContracts.js +20 -0
- package/dist/esm/scheduler/resourceStrategyFinancialValidation.js +145 -0
- package/dist/esm/scheduler/resourceStrategyPermissionValidation.js +190 -0
- package/dist/esm/scheduler/resourceStrategyScheduleValidation.js +506 -0
- package/dist/esm/scheduler/resourceStrategyValidation.js +4 -0
- package/dist/esm/scheduler/resourceStrategyValidationShared.js +261 -0
- package/dist/esm/scheduler/schedulerValidation.js +372 -0
- package/dist/esm/scheduler/weeklyAvailabilityFixtures.js +140 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/index.vite.d.ts +1 -0
- package/dist/index.vite.d.ts.map +1 -1
- package/dist/index.vite.js +1 -0
- package/dist/index.vite.js.map +1 -1
- package/dist/reporting/jobs/index.d.ts +14 -0
- package/dist/reporting/jobs/index.d.ts.map +1 -0
- package/dist/reporting/jobs/index.js +45 -0
- package/dist/reporting/jobs/index.js.map +1 -0
- package/dist/reporting/jobs/reportJobIdentity.d.ts +44 -0
- package/dist/reporting/jobs/reportJobIdentity.d.ts.map +1 -0
- package/dist/reporting/jobs/reportJobIdentity.js +88 -0
- package/dist/reporting/jobs/reportJobIdentity.js.map +1 -0
- package/dist/reporting/jobs/reportJobMessages.d.ts +30 -0
- package/dist/reporting/jobs/reportJobMessages.d.ts.map +1 -0
- package/dist/reporting/jobs/reportJobMessages.js +54 -0
- package/dist/reporting/jobs/reportJobMessages.js.map +1 -0
- package/dist/reporting/jobs/reportJobRow.d.ts +98 -0
- package/dist/reporting/jobs/reportJobRow.d.ts.map +1 -0
- package/dist/reporting/jobs/reportJobRow.js +270 -0
- package/dist/reporting/jobs/reportJobRow.js.map +1 -0
- package/dist/reporting/jobs/reportJobSpec.d.ts +92 -0
- package/dist/reporting/jobs/reportJobSpec.d.ts.map +1 -0
- package/dist/reporting/jobs/reportJobSpec.js +304 -0
- package/dist/reporting/jobs/reportJobSpec.js.map +1 -0
- package/dist/reporting/jobs/reportJobStatus.d.ts +60 -0
- package/dist/reporting/jobs/reportJobStatus.d.ts.map +1 -0
- package/dist/reporting/jobs/reportJobStatus.js +98 -0
- package/dist/reporting/jobs/reportJobStatus.js.map +1 -0
- package/dist/reporting/shared/reportTableEntities.d.ts +23 -0
- package/dist/reporting/shared/reportTableEntities.d.ts.map +1 -0
- package/dist/reporting/shared/reportTableEntities.js +47 -0
- package/dist/reporting/shared/reportTableEntities.js.map +1 -0
- package/dist/reporting/shared/reportingDigest.d.ts +6 -0
- package/dist/reporting/shared/reportingDigest.d.ts.map +1 -0
- package/dist/reporting/shared/reportingDigest.js +63 -0
- package/dist/reporting/shared/reportingDigest.js.map +1 -0
- package/dist/reporting/shared/reportingIds.d.ts +34 -0
- package/dist/reporting/shared/reportingIds.d.ts.map +1 -0
- package/dist/reporting/shared/reportingIds.js +102 -0
- package/dist/reporting/shared/reportingIds.js.map +1 -0
- package/dist/reporting/shared/reportingPaths.d.ts +14 -0
- package/dist/reporting/shared/reportingPaths.d.ts.map +1 -0
- package/dist/reporting/shared/reportingPaths.js +29 -0
- package/dist/reporting/shared/reportingPaths.js.map +1 -0
- package/dist/scheduler/index.d.ts +4 -4
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +4 -4
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/resourceStrategy.d.ts +3 -0
- package/dist/scheduler/resourceStrategy.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategy.js +19 -0
- package/dist/scheduler/resourceStrategy.js.map +1 -0
- package/dist/scheduler/resourceStrategyCapabilityValidation.d.ts +4 -0
- package/dist/scheduler/resourceStrategyCapabilityValidation.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyCapabilityValidation.js +270 -0
- package/dist/scheduler/resourceStrategyCapabilityValidation.js.map +1 -0
- package/dist/scheduler/resourceStrategyContracts.d.ts +466 -0
- package/dist/scheduler/resourceStrategyContracts.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyContracts.js +24 -0
- package/dist/scheduler/resourceStrategyContracts.js.map +1 -0
- package/dist/scheduler/resourceStrategyFinancialValidation.d.ts +5 -0
- package/dist/scheduler/resourceStrategyFinancialValidation.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyFinancialValidation.js +151 -0
- package/dist/scheduler/resourceStrategyFinancialValidation.js.map +1 -0
- package/dist/scheduler/resourceStrategyPermissionValidation.d.ts +4 -0
- package/dist/scheduler/resourceStrategyPermissionValidation.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyPermissionValidation.js +195 -0
- package/dist/scheduler/resourceStrategyPermissionValidation.js.map +1 -0
- package/dist/scheduler/resourceStrategyScheduleValidation.d.ts +14 -0
- package/dist/scheduler/resourceStrategyScheduleValidation.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyScheduleValidation.js +519 -0
- package/dist/scheduler/resourceStrategyScheduleValidation.js.map +1 -0
- package/dist/scheduler/resourceStrategyValidation.d.ts +5 -0
- package/dist/scheduler/resourceStrategyValidation.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyValidation.js +21 -0
- package/dist/scheduler/resourceStrategyValidation.js.map +1 -0
- package/dist/scheduler/resourceStrategyValidationShared.d.ts +19 -0
- package/dist/scheduler/resourceStrategyValidationShared.d.ts.map +1 -0
- package/dist/scheduler/resourceStrategyValidationShared.js +281 -0
- package/dist/scheduler/resourceStrategyValidationShared.js.map +1 -0
- package/dist/scheduler/schedulerContracts.d.ts +184 -0
- package/dist/scheduler/schedulerContracts.d.ts.map +1 -0
- package/dist/{aws/portalPublicArtifactNestedEvidence.js → scheduler/schedulerContracts.js} +1 -1
- package/dist/scheduler/schedulerContracts.js.map +1 -0
- package/dist/scheduler/schedulerValidation.d.ts +15 -0
- package/dist/scheduler/schedulerValidation.d.ts.map +1 -0
- package/dist/scheduler/schedulerValidation.js +388 -0
- package/dist/scheduler/schedulerValidation.js.map +1 -0
- package/dist/scheduler/weeklyAvailabilityFixtures.d.ts +26 -0
- package/dist/scheduler/weeklyAvailabilityFixtures.d.ts.map +1 -0
- package/dist/scheduler/weeklyAvailabilityFixtures.js +144 -0
- package/dist/scheduler/weeklyAvailabilityFixtures.js.map +1 -0
- package/package.json +26 -7
- package/dist/aws/pluginPublicArtifactBodyValidation.d.ts +0 -10
- package/dist/aws/pluginPublicArtifactBodyValidation.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactBodyValidation.js +0 -225
- package/dist/aws/pluginPublicArtifactBodyValidation.js.map +0 -1
- package/dist/aws/pluginPublicArtifactEvidence.d.ts +0 -161
- package/dist/aws/pluginPublicArtifactEvidence.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactEvidence.js.map +0 -1
- package/dist/aws/pluginPublicArtifactManifestValidation.d.ts +0 -4
- package/dist/aws/pluginPublicArtifactManifestValidation.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactManifestValidation.js +0 -259
- package/dist/aws/pluginPublicArtifactManifestValidation.js.map +0 -1
- package/dist/aws/pluginPublicArtifactSectionValidation.d.ts +0 -6
- package/dist/aws/pluginPublicArtifactSectionValidation.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactSectionValidation.js +0 -471
- package/dist/aws/pluginPublicArtifactSectionValidation.js.map +0 -1
- package/dist/aws/pluginPublicArtifactValidation.d.ts +0 -3
- package/dist/aws/pluginPublicArtifactValidation.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactValidation.js +0 -9
- package/dist/aws/pluginPublicArtifactValidation.js.map +0 -1
- package/dist/aws/pluginPublicArtifactValidationHelpers.d.ts +0 -23
- package/dist/aws/pluginPublicArtifactValidationHelpers.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifactValidationHelpers.js +0 -240
- package/dist/aws/pluginPublicArtifactValidationHelpers.js.map +0 -1
- package/dist/aws/pluginPublicArtifacts.d.ts +0 -253
- package/dist/aws/pluginPublicArtifacts.d.ts.map +0 -1
- package/dist/aws/pluginPublicArtifacts.js +0 -51
- package/dist/aws/pluginPublicArtifacts.js.map +0 -1
- package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts +0 -4
- package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.d.ts.map +0 -1
- package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js +0 -513
- package/dist/aws/portalCommitmentsPlanningPublicArtifactValidation.js.map +0 -1
- package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts +0 -13
- package/dist/aws/portalCommitmentsPlanningPublicArtifacts.d.ts.map +0 -1
- package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js +0 -5
- package/dist/aws/portalCommitmentsPlanningPublicArtifacts.js.map +0 -1
- package/dist/aws/portalPublicArtifactCurrentValidation.d.ts +0 -4
- package/dist/aws/portalPublicArtifactCurrentValidation.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactCurrentValidation.js +0 -333
- package/dist/aws/portalPublicArtifactCurrentValidation.js.map +0 -1
- package/dist/aws/portalPublicArtifactEvidenceValidation.d.ts +0 -6
- package/dist/aws/portalPublicArtifactEvidenceValidation.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactEvidenceValidation.js +0 -301
- package/dist/aws/portalPublicArtifactEvidenceValidation.js.map +0 -1
- package/dist/aws/portalPublicArtifactHistoryAiValidation.d.ts +0 -8
- package/dist/aws/portalPublicArtifactHistoryAiValidation.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactHistoryAiValidation.js +0 -377
- package/dist/aws/portalPublicArtifactHistoryAiValidation.js.map +0 -1
- package/dist/aws/portalPublicArtifactHistoryTypes.d.ts +0 -178
- package/dist/aws/portalPublicArtifactHistoryTypes.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactHistoryTypes.js +0 -44
- package/dist/aws/portalPublicArtifactHistoryTypes.js.map +0 -1
- package/dist/aws/portalPublicArtifactNestedEvidence.d.ts +0 -127
- package/dist/aws/portalPublicArtifactNestedEvidence.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactNestedEvidence.js.map +0 -1
- package/dist/aws/portalPublicArtifactNestedEvidenceValidation.d.ts +0 -6
- package/dist/aws/portalPublicArtifactNestedEvidenceValidation.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactNestedEvidenceValidation.js +0 -405
- package/dist/aws/portalPublicArtifactNestedEvidenceValidation.js.map +0 -1
- package/dist/aws/portalPublicArtifactValidation.d.ts +0 -3
- package/dist/aws/portalPublicArtifactValidation.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactValidation.js +0 -14
- package/dist/aws/portalPublicArtifactValidation.js.map +0 -1
- package/dist/aws/portalPublicArtifactValidationCommon.d.ts +0 -30
- package/dist/aws/portalPublicArtifactValidationCommon.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifactValidationCommon.js +0 -167
- package/dist/aws/portalPublicArtifactValidationCommon.js.map +0 -1
- package/dist/aws/portalPublicArtifacts.d.ts +0 -400
- package/dist/aws/portalPublicArtifacts.d.ts.map +0 -1
- package/dist/aws/portalPublicArtifacts.js +0 -85
- package/dist/aws/portalPublicArtifacts.js.map +0 -1
- package/dist/aws/portalRelationshipPublicArtifactValidation.d.ts +0 -4
- package/dist/aws/portalRelationshipPublicArtifactValidation.d.ts.map +0 -1
- package/dist/aws/portalRelationshipPublicArtifactValidation.js +0 -338
- package/dist/aws/portalRelationshipPublicArtifactValidation.js.map +0 -1
- package/dist/aws/portalRelationshipPublicArtifacts.d.ts +0 -196
- package/dist/aws/portalRelationshipPublicArtifacts.d.ts.map +0 -1
- package/dist/aws/portalRelationshipPublicArtifacts.js +0 -63
- package/dist/aws/portalRelationshipPublicArtifacts.js.map +0 -1
- package/dist/aws/portalRelationshipResourceNodeTypes.d.ts +0 -269
- package/dist/aws/portalRelationshipResourceNodeTypes.d.ts.map +0 -1
- package/dist/aws/portalRelationshipResourceNodeTypes.js +0 -3
- package/dist/aws/portalRelationshipResourceNodeTypes.js.map +0 -1
- package/dist/aws/portalRelationshipResourceNodeValidation.d.ts +0 -2
- package/dist/aws/portalRelationshipResourceNodeValidation.d.ts.map +0 -1
- package/dist/aws/portalRelationshipResourceNodeValidation.js +0 -372
- package/dist/aws/portalRelationshipResourceNodeValidation.js.map +0 -1
- package/dist/esm/aws/pluginPublicArtifactBodyValidation.js +0 -217
- package/dist/esm/aws/pluginPublicArtifactManifestValidation.js +0 -255
- package/dist/esm/aws/pluginPublicArtifactSectionValidation.js +0 -464
- package/dist/esm/aws/pluginPublicArtifactValidation.js +0 -2
- package/dist/esm/aws/pluginPublicArtifactValidationHelpers.js +0 -216
- package/dist/esm/aws/pluginPublicArtifacts.js +0 -44
- package/dist/esm/aws/portalCommitmentsPlanningPublicArtifactValidation.js +0 -509
- package/dist/esm/aws/portalCommitmentsPlanningPublicArtifacts.js +0 -1
- package/dist/esm/aws/portalPublicArtifactCurrentValidation.js +0 -328
- package/dist/esm/aws/portalPublicArtifactEvidenceValidation.js +0 -294
- package/dist/esm/aws/portalPublicArtifactHistoryAiValidation.js +0 -368
- package/dist/esm/aws/portalPublicArtifactHistoryTypes.js +0 -40
- package/dist/esm/aws/portalPublicArtifactNestedEvidenceValidation.js +0 -397
- package/dist/esm/aws/portalPublicArtifactValidation.js +0 -2
- package/dist/esm/aws/portalPublicArtifactValidationCommon.js +0 -139
- package/dist/esm/aws/portalPublicArtifacts.js +0 -73
- package/dist/esm/aws/portalRelationshipPublicArtifactValidation.js +0 -334
- package/dist/esm/aws/portalRelationshipPublicArtifacts.js +0 -59
- package/dist/esm/aws/portalRelationshipResourceNodeValidation.js +0 -368
- package/dist/esm/scheduler/bastionScheduleProfile.js +0 -206
- package/dist/esm/scheduler/bastionScheduleValidation.js +0 -401
- package/dist/esm/scheduler/scheduler.js +0 -1
- package/dist/scheduler/bastionSchedule.d.ts +0 -113
- package/dist/scheduler/bastionSchedule.d.ts.map +0 -1
- package/dist/scheduler/bastionSchedule.js.map +0 -1
- package/dist/scheduler/bastionScheduleProfile.d.ts +0 -24
- package/dist/scheduler/bastionScheduleProfile.d.ts.map +0 -1
- package/dist/scheduler/bastionScheduleProfile.js +0 -210
- package/dist/scheduler/bastionScheduleProfile.js.map +0 -1
- package/dist/scheduler/bastionScheduleValidation.d.ts +0 -10
- package/dist/scheduler/bastionScheduleValidation.d.ts.map +0 -1
- package/dist/scheduler/bastionScheduleValidation.js +0 -412
- package/dist/scheduler/bastionScheduleValidation.js.map +0 -1
- package/dist/scheduler/scheduler.d.ts +0 -267
- package/dist/scheduler/scheduler.d.ts.map +0 -1
- package/dist/scheduler/scheduler.js.map +0 -1
- /package/dist/esm/aws/{pluginPublicArtifactEvidence.js → commitmentsPlanningView.js} +0 -0
- /package/dist/esm/{aws/portalPublicArtifactNestedEvidence.js → common/boundedRows.js} +0 -0
- /package/dist/esm/{aws/portalRelationshipResourceNodeTypes.js → common/metricStats.js} +0 -0
- /package/dist/esm/scheduler/{bastionSchedule.js → schedulerContracts.js} +0 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { CAPABILITY_REASON_CODES } from './capabilityPassport.js';
|
|
2
|
+
import { RESOURCE_GRAPH_EDGE_CONFIDENCES, RESOURCE_GRAPH_EDGE_KINDS, RESOURCE_GRAPH_EVIDENCE_METHODS, RESOURCE_GRAPH_NODE_KINDS, RESOURCE_GRAPH_NODE_ROLES, RESOURCE_GRAPH_SCHEMA_VERSION, } from './resourceGraph.js';
|
|
3
|
+
import { isAttributeKey, isAttributeScalar, isKebabIdentifier } from './resourceIdentity.js';
|
|
4
|
+
import { asArray, asRecord, assertExactKeys, assertPlainJson, assertUnique, assertValue, finiteNumber, isoTimestamp, nonNegativeInteger, requiredBoolean, requiredEnum, requiredString, validateGeneration, } from './validationHelpers.js';
|
|
5
|
+
const ARTIFACT_KEYS = [
|
|
6
|
+
'schemaVersion',
|
|
7
|
+
'provider',
|
|
8
|
+
'accountId',
|
|
9
|
+
'artifactGeneration',
|
|
10
|
+
'generatedAt',
|
|
11
|
+
'scope',
|
|
12
|
+
'currency',
|
|
13
|
+
'currencySymbol',
|
|
14
|
+
'nodes',
|
|
15
|
+
'edges',
|
|
16
|
+
'unresolved',
|
|
17
|
+
'coverage',
|
|
18
|
+
'stats',
|
|
19
|
+
];
|
|
20
|
+
const NODE_KEYS = [
|
|
21
|
+
'id',
|
|
22
|
+
'kind',
|
|
23
|
+
'family',
|
|
24
|
+
'resourceType',
|
|
25
|
+
'syntheticType',
|
|
26
|
+
'region',
|
|
27
|
+
'name',
|
|
28
|
+
'displayName',
|
|
29
|
+
'icon',
|
|
30
|
+
'nativeId',
|
|
31
|
+
'role',
|
|
32
|
+
'tags',
|
|
33
|
+
'attributes',
|
|
34
|
+
'costs',
|
|
35
|
+
];
|
|
36
|
+
/** Node fields each kind may carry; anything else is rejected. */
|
|
37
|
+
const NODE_FIELDS = {
|
|
38
|
+
scope: ['nativeId', 'attributes'],
|
|
39
|
+
region: [],
|
|
40
|
+
zone: ['nativeId', 'attributes'],
|
|
41
|
+
group: ['family', 'nativeId', 'role', 'tags', 'attributes'],
|
|
42
|
+
resource: ['family', 'resourceType', 'nativeId', 'role', 'tags', 'attributes', 'costs'],
|
|
43
|
+
synthetic: ['family', 'syntheticType', 'nativeId', 'role', 'tags', 'attributes'],
|
|
44
|
+
};
|
|
45
|
+
/** Allowed `contains` parents: containment is strictly downward, so the graph stays acyclic. */
|
|
46
|
+
const CONTAINMENT_PARENTS = {
|
|
47
|
+
scope: [],
|
|
48
|
+
region: ['scope'],
|
|
49
|
+
zone: ['region'],
|
|
50
|
+
group: ['region', 'zone'],
|
|
51
|
+
resource: ['region', 'zone', 'group'],
|
|
52
|
+
synthetic: ['region', 'zone', 'group'],
|
|
53
|
+
};
|
|
54
|
+
const DEPENDENCY_KINDS = ['group', 'resource', 'synthetic'];
|
|
55
|
+
/**
|
|
56
|
+
* Validates one untrusted resource graph artifact. It checks structure and
|
|
57
|
+
* identifier formats only; families are never checked against a service list.
|
|
58
|
+
*/
|
|
59
|
+
export function validateResourceGraphArtifact(value, options) {
|
|
60
|
+
const artifact = asRecord(value, 'artifact');
|
|
61
|
+
assertExactKeys(artifact, ARTIFACT_KEYS, 'artifact');
|
|
62
|
+
assertValue(artifact.schemaVersion, RESOURCE_GRAPH_SCHEMA_VERSION, 'artifact.schemaVersion');
|
|
63
|
+
assertValue(artifact.provider, options.provider, 'artifact.provider');
|
|
64
|
+
const accountId = requiredString(artifact.accountId, 'artifact.accountId');
|
|
65
|
+
if (options.isAccountId && !options.isAccountId(accountId))
|
|
66
|
+
throw new Error('artifact.accountId is not a valid provider account id.');
|
|
67
|
+
const generation = validateGeneration(artifact.artifactGeneration, 'artifact.artifactGeneration');
|
|
68
|
+
const outputAt = Date.parse(generation.generatedAt);
|
|
69
|
+
const generatedAt = isoTimestamp(artifact.generatedAt, 'artifact.generatedAt');
|
|
70
|
+
if (Date.parse(generatedAt) > outputAt)
|
|
71
|
+
throw new Error('artifact.generatedAt must not be newer than the artifact generation.');
|
|
72
|
+
const regions = validateScope(artifact.scope, options);
|
|
73
|
+
if (artifact.currency !== undefined)
|
|
74
|
+
requiredString(artifact.currency, 'artifact.currency');
|
|
75
|
+
if (artifact.currencySymbol !== undefined)
|
|
76
|
+
requiredString(artifact.currencySymbol, 'artifact.currencySymbol');
|
|
77
|
+
const nodes = validateNodes(artifact.nodes, accountId, regions, options);
|
|
78
|
+
if (nodes.hasCosts && artifact.currency === undefined)
|
|
79
|
+
throw new Error('artifact.currency is required when nodes carry costs.');
|
|
80
|
+
const edgeCount = validateEdges(artifact.edges, nodes.byId);
|
|
81
|
+
const unresolvedCount = validateUnresolved(artifact.unresolved, nodes.byId);
|
|
82
|
+
validateCoverage(artifact.coverage, regions, outputAt, nodes.byId);
|
|
83
|
+
validateStats(artifact.stats, nodes.byId.size, edgeCount, unresolvedCount);
|
|
84
|
+
assertPublicGraphJson(artifact, options.isForbiddenKey);
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
function validateScope(value, options) {
|
|
88
|
+
const scope = asRecord(value, 'artifact.scope');
|
|
89
|
+
assertExactKeys(scope, ['regions'], 'artifact.scope');
|
|
90
|
+
const regions = asArray(scope.regions, 'artifact.scope.regions', true).map((region, index) => {
|
|
91
|
+
const field = `artifact.scope.regions[${index}]`;
|
|
92
|
+
const name = requiredString(region, field);
|
|
93
|
+
if (options.isRegion && !options.isRegion(name))
|
|
94
|
+
throw new Error(`${field} is not a valid provider Region.`);
|
|
95
|
+
return name;
|
|
96
|
+
});
|
|
97
|
+
assertUnique(regions, 'artifact.scope.regions');
|
|
98
|
+
return new Set(regions);
|
|
99
|
+
}
|
|
100
|
+
function validateNodes(value, accountId, regions, options) {
|
|
101
|
+
const byId = new Map();
|
|
102
|
+
const regionNodes = [];
|
|
103
|
+
let scopeCount = 0;
|
|
104
|
+
let hasCosts = false;
|
|
105
|
+
asArray(value, 'artifact.nodes').forEach((entry, index) => {
|
|
106
|
+
const field = `artifact.nodes[${index}]`;
|
|
107
|
+
const node = asRecord(entry, field);
|
|
108
|
+
assertExactKeys(node, NODE_KEYS, field);
|
|
109
|
+
const id = requiredString(node.id, `${field}.id`);
|
|
110
|
+
if (byId.has(id))
|
|
111
|
+
throw new Error('artifact node ids must be unique.');
|
|
112
|
+
const kind = requiredEnum(node.kind, RESOURCE_GRAPH_NODE_KINDS, `${field}.kind`);
|
|
113
|
+
const allowed = NODE_FIELDS[kind];
|
|
114
|
+
const undeclared = ['family', 'resourceType', 'syntheticType', 'nativeId', 'role', 'tags', 'attributes', 'costs'].filter(key => node[key] !== undefined && !allowed.includes(key));
|
|
115
|
+
if (undeclared.length > 0)
|
|
116
|
+
throw new Error(`${field} ${kind} nodes must not carry: ${undeclared.join(', ')}.`);
|
|
117
|
+
requiredString(node.name, `${field}.name`);
|
|
118
|
+
if (node.displayName !== undefined)
|
|
119
|
+
requiredString(node.displayName, `${field}.displayName`);
|
|
120
|
+
if (node.icon !== undefined)
|
|
121
|
+
requiredString(node.icon, `${field}.icon`);
|
|
122
|
+
let region;
|
|
123
|
+
if (kind === 'scope') {
|
|
124
|
+
scopeCount += 1;
|
|
125
|
+
if (node.region !== undefined)
|
|
126
|
+
throw new Error(`${field}.region is not allowed on the scope node.`);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
region = requiredString(node.region, `${field}.region`);
|
|
130
|
+
if (!regions.has(region))
|
|
131
|
+
throw new Error(`${field}.region is outside artifact scope.`);
|
|
132
|
+
}
|
|
133
|
+
if (kind === 'region')
|
|
134
|
+
regionNodes.push(region);
|
|
135
|
+
if (kind === 'zone')
|
|
136
|
+
options.validateZone?.(String(node.name), region, `${field}.name`);
|
|
137
|
+
if (kind === 'resource' || node.family !== undefined)
|
|
138
|
+
kebab(node.family, `${field}.family`);
|
|
139
|
+
if (kind === 'resource') {
|
|
140
|
+
const resourceType = requiredString(node.resourceType, `${field}.resourceType`);
|
|
141
|
+
if (options.isResourceType && !options.isResourceType(resourceType))
|
|
142
|
+
throw new Error(`${field}.resourceType is not a valid provider resource type.`);
|
|
143
|
+
}
|
|
144
|
+
if (kind === 'synthetic')
|
|
145
|
+
kebab(node.syntheticType, `${field}.syntheticType`);
|
|
146
|
+
if (node.role !== undefined)
|
|
147
|
+
requiredEnum(node.role, RESOURCE_GRAPH_NODE_ROLES, `${field}.role`);
|
|
148
|
+
const scope = { accountId, region };
|
|
149
|
+
if (node.nativeId !== undefined)
|
|
150
|
+
options.validateNativeId?.(requiredString(node.nativeId, `${field}.nativeId`), scope, `${field}.nativeId`);
|
|
151
|
+
if (node.tags !== undefined)
|
|
152
|
+
validateTags(node.tags, `${field}.tags`);
|
|
153
|
+
if (node.attributes !== undefined)
|
|
154
|
+
validateAttributes(node.attributes, scope, options, `${field}.attributes`);
|
|
155
|
+
if (node.costs !== undefined) {
|
|
156
|
+
validateCosts(node.costs, `${field}.costs`);
|
|
157
|
+
hasCosts = true;
|
|
158
|
+
}
|
|
159
|
+
byId.set(id, { kind, region, family: node.family === undefined ? undefined : String(node.family) });
|
|
160
|
+
});
|
|
161
|
+
if (scopeCount !== 1)
|
|
162
|
+
throw new Error('artifact must contain exactly one scope node.');
|
|
163
|
+
assertUnique(regionNodes, 'artifact Region nodes');
|
|
164
|
+
if (regionNodes.length !== regions.size)
|
|
165
|
+
throw new Error('artifact Region nodes must exactly match artifact scope Regions.');
|
|
166
|
+
return { byId, hasCosts };
|
|
167
|
+
}
|
|
168
|
+
function kebab(value, field) {
|
|
169
|
+
if (!isKebabIdentifier(value))
|
|
170
|
+
throw new Error(`${field} must be a kebab-case identifier.`);
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
function validateTags(value, field) {
|
|
174
|
+
Object.entries(asRecord(value, field)).forEach(([key, tagValue]) => {
|
|
175
|
+
if (key.length === 0)
|
|
176
|
+
throw new Error(`${field} keys must be non-empty.`);
|
|
177
|
+
if (typeof tagValue !== 'string')
|
|
178
|
+
throw new Error(`${field}.${key} must be a string.`);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function validateAttributes(value, scope, options, field) {
|
|
182
|
+
Object.entries(asRecord(value, field)).forEach(([key, item]) => {
|
|
183
|
+
const itemField = `${field}.${key}`;
|
|
184
|
+
if (!isAttributeKey(key))
|
|
185
|
+
throw new Error(`${itemField} key must be camelCase.`);
|
|
186
|
+
validateAttributeValue(item, itemField);
|
|
187
|
+
options.validateAttribute?.(key, item, scope, itemField);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function validateAttributeValue(value, field) {
|
|
191
|
+
if (isAttributeScalar(value))
|
|
192
|
+
return;
|
|
193
|
+
if (!Array.isArray(value))
|
|
194
|
+
throw new Error(`${field} must be a scalar, a scalar array, or an array of flat records.`);
|
|
195
|
+
if (value.every(isAttributeScalar))
|
|
196
|
+
return;
|
|
197
|
+
value.forEach((entry, index) => {
|
|
198
|
+
const entryField = `${field}[${index}]`;
|
|
199
|
+
Object.entries(asRecord(entry, entryField)).forEach(([key, item]) => {
|
|
200
|
+
if (!isAttributeKey(key))
|
|
201
|
+
throw new Error(`${entryField}.${key} key must be camelCase.`);
|
|
202
|
+
if (!isAttributeScalar(item))
|
|
203
|
+
throw new Error(`${entryField}.${key} must be a string, finite number, or boolean.`);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function validateCosts(value, field) {
|
|
208
|
+
const costs = asRecord(value, field);
|
|
209
|
+
assertExactKeys(costs, ['spend30d', 'spend30dAmortized'], field);
|
|
210
|
+
if (Object.keys(costs).length === 0)
|
|
211
|
+
throw new Error(`${field} must report at least one amount.`);
|
|
212
|
+
Object.entries(costs).forEach(([key, amount]) => finiteNumber(amount, `${field}.${key}`));
|
|
213
|
+
}
|
|
214
|
+
function validateEdges(value, nodes) {
|
|
215
|
+
const edges = asArray(value, 'artifact.edges');
|
|
216
|
+
const ids = new Set();
|
|
217
|
+
const parents = new Map();
|
|
218
|
+
edges.forEach((entry, index) => {
|
|
219
|
+
const field = `artifact.edges[${index}]`;
|
|
220
|
+
const edge = asRecord(entry, field);
|
|
221
|
+
assertExactKeys(edge, ['id', 'from', 'to', 'kind', 'relationshipTypes', 'confidence', 'evidence'], field);
|
|
222
|
+
const id = requiredString(edge.id, `${field}.id`);
|
|
223
|
+
if (ids.has(id))
|
|
224
|
+
throw new Error('artifact edge ids must be unique.');
|
|
225
|
+
ids.add(id);
|
|
226
|
+
const from = requiredString(edge.from, `${field}.from`);
|
|
227
|
+
const to = requiredString(edge.to, `${field}.to`);
|
|
228
|
+
const child = nodes.get(from);
|
|
229
|
+
const parent = nodes.get(to);
|
|
230
|
+
if (!child || !parent)
|
|
231
|
+
throw new Error(`${field} references a missing node.`);
|
|
232
|
+
if (from === to)
|
|
233
|
+
throw new Error(`${field} must not be a self edge.`);
|
|
234
|
+
const kind = requiredEnum(edge.kind, RESOURCE_GRAPH_EDGE_KINDS, `${field}.kind`);
|
|
235
|
+
const relationshipTypes = asArray(edge.relationshipTypes, `${field}.relationshipTypes`, true).map((type, typeIndex) => kebab(type, `${field}.relationshipTypes[${typeIndex}]`));
|
|
236
|
+
assertUnique(relationshipTypes, `${field}.relationshipTypes`);
|
|
237
|
+
requiredEnum(edge.confidence, RESOURCE_GRAPH_EDGE_CONFIDENCES, `${field}.confidence`);
|
|
238
|
+
validateEvidence(edge.evidence, `${field}.evidence`);
|
|
239
|
+
if (kind === 'contains') {
|
|
240
|
+
if (!CONTAINMENT_PARENTS[child.kind].includes(parent.kind))
|
|
241
|
+
throw new Error(`${field} ${child.kind} nodes cannot be contained by ${parent.kind} nodes; contains edges point child to parent.`);
|
|
242
|
+
if (parent.region !== undefined && child.region !== parent.region)
|
|
243
|
+
throw new Error(`${field} containment must not cross Regions.`);
|
|
244
|
+
parents.set(from, (parents.get(from) ?? 0) + 1);
|
|
245
|
+
}
|
|
246
|
+
else if (!DEPENDENCY_KINDS.includes(child.kind) || !DEPENDENCY_KINDS.includes(parent.kind)) {
|
|
247
|
+
throw new Error(`${field} depends_on edges must connect group, resource, or synthetic nodes.`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
nodes.forEach((node, id) => {
|
|
251
|
+
const expected = node.kind === 'scope' ? 0 : 1;
|
|
252
|
+
if ((parents.get(id) ?? 0) !== expected)
|
|
253
|
+
throw new Error(`artifact node ${id} must have exactly ${expected} contains parent edge${expected === 1 ? '' : 's'}.`);
|
|
254
|
+
});
|
|
255
|
+
return edges.length;
|
|
256
|
+
}
|
|
257
|
+
function validateEvidence(value, field) {
|
|
258
|
+
asArray(value, field, true).forEach((entry, index) => {
|
|
259
|
+
const itemField = `${field}[${index}]`;
|
|
260
|
+
const item = asRecord(entry, itemField);
|
|
261
|
+
assertExactKeys(item, ['method', 'sourceFamily', 'field', 'matchedValue'], itemField);
|
|
262
|
+
requiredEnum(item.method, RESOURCE_GRAPH_EVIDENCE_METHODS, `${itemField}.method`);
|
|
263
|
+
kebab(item.sourceFamily, `${itemField}.sourceFamily`);
|
|
264
|
+
if (item.field !== undefined)
|
|
265
|
+
requiredString(item.field, `${itemField}.field`);
|
|
266
|
+
if (item.matchedValue !== undefined)
|
|
267
|
+
requiredString(item.matchedValue, `${itemField}.matchedValue`);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function validateUnresolved(value, nodes) {
|
|
271
|
+
const unresolved = asArray(value, 'artifact.unresolved');
|
|
272
|
+
unresolved.forEach((entry, index) => {
|
|
273
|
+
const field = `artifact.unresolved[${index}]`;
|
|
274
|
+
const reference = asRecord(entry, field);
|
|
275
|
+
assertExactKeys(reference, ['sourceNodeId', 'relationshipType', 'sourceFamily', 'field', 'matchedValue', 'expectedTargetFamily'], field);
|
|
276
|
+
const source = nodes.get(requiredString(reference.sourceNodeId, `${field}.sourceNodeId`));
|
|
277
|
+
if (!source)
|
|
278
|
+
throw new Error(`${field}.sourceNodeId references a missing node.`);
|
|
279
|
+
kebab(reference.relationshipType, `${field}.relationshipType`);
|
|
280
|
+
const sourceFamily = kebab(reference.sourceFamily, `${field}.sourceFamily`);
|
|
281
|
+
if (source.family !== undefined && source.family !== sourceFamily)
|
|
282
|
+
throw new Error(`${field}.sourceFamily must match its source node family.`);
|
|
283
|
+
requiredString(reference.field, `${field}.field`);
|
|
284
|
+
requiredString(reference.matchedValue, `${field}.matchedValue`);
|
|
285
|
+
kebab(reference.expectedTargetFamily, `${field}.expectedTargetFamily`);
|
|
286
|
+
});
|
|
287
|
+
return unresolved.length;
|
|
288
|
+
}
|
|
289
|
+
/** Coverage is self-closing: it must declare every family that appears on a resource node. */
|
|
290
|
+
function validateCoverage(value, regions, outputAt, nodes) {
|
|
291
|
+
const coverage = asRecord(value, 'artifact.coverage');
|
|
292
|
+
assertExactKeys(coverage, ['families'], 'artifact.coverage');
|
|
293
|
+
const declared = new Map();
|
|
294
|
+
asArray(coverage.families, 'artifact.coverage.families').forEach((entry, index) => {
|
|
295
|
+
const field = `artifact.coverage.families[${index}]`;
|
|
296
|
+
const family = asRecord(entry, field);
|
|
297
|
+
assertExactKeys(family, ['family', 'regions', 'status', 'lastSuccessfulRefreshAt', 'emptyScope', 'reason'], field);
|
|
298
|
+
const name = kebab(family.family, `${field}.family`);
|
|
299
|
+
if (declared.has(name))
|
|
300
|
+
throw new Error('artifact.coverage family identities must not contain duplicates.');
|
|
301
|
+
const familyRegions = asArray(family.regions, `${field}.regions`, true).map((region, regionIndex) => requiredString(region, `${field}.regions[${regionIndex}]`));
|
|
302
|
+
assertUnique(familyRegions, `${field}.regions`);
|
|
303
|
+
if (familyRegions.some(region => !regions.has(region)))
|
|
304
|
+
throw new Error(`${field}.regions must be within artifact scope Regions.`);
|
|
305
|
+
let emptyScope = false;
|
|
306
|
+
if (requiredEnum(family.status, ['available', 'incomplete'], `${field}.status`) === 'available') {
|
|
307
|
+
const refreshedAt = isoTimestamp(family.lastSuccessfulRefreshAt, `${field}.lastSuccessfulRefreshAt`);
|
|
308
|
+
if (Date.parse(refreshedAt) > outputAt)
|
|
309
|
+
throw new Error(`${field}.lastSuccessfulRefreshAt must not be newer than the artifact generation.`);
|
|
310
|
+
emptyScope = requiredBoolean(family.emptyScope, `${field}.emptyScope`);
|
|
311
|
+
if (family.reason !== undefined)
|
|
312
|
+
throw new Error(`${field}.reason is not allowed for available coverage.`);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
requiredEnum(family.reason, CAPABILITY_REASON_CODES, `${field}.reason`);
|
|
316
|
+
if (family.lastSuccessfulRefreshAt !== undefined || family.emptyScope !== undefined)
|
|
317
|
+
throw new Error(`${field} incomplete coverage cannot claim successful refresh evidence.`);
|
|
318
|
+
}
|
|
319
|
+
declared.set(name, { regions: new Set(familyRegions), emptyScope });
|
|
320
|
+
});
|
|
321
|
+
nodes.forEach((node, id) => {
|
|
322
|
+
if (node.kind !== 'resource')
|
|
323
|
+
return;
|
|
324
|
+
const family = declared.get(node.family);
|
|
325
|
+
if (!family)
|
|
326
|
+
throw new Error(`artifact.coverage must declare family ${node.family} of resource node ${id}.`);
|
|
327
|
+
if (!family.regions.has(node.region))
|
|
328
|
+
throw new Error(`artifact.coverage for ${node.family} must include Region ${node.region}.`);
|
|
329
|
+
if (family.emptyScope)
|
|
330
|
+
throw new Error(`artifact.coverage for ${node.family} claims an empty scope but resource node ${id} exists.`);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function validateStats(value, nodeCount, edgeCount, unresolvedCount) {
|
|
334
|
+
const stats = asRecord(value, 'artifact.stats');
|
|
335
|
+
assertExactKeys(stats, ['totalNodes', 'totalEdges', 'unresolvedCount', 'truncated', 'truncation', 'buildMs', 'snapshotBytes'], 'artifact.stats');
|
|
336
|
+
assertValue(nonNegativeInteger(stats.totalNodes, 'artifact.stats.totalNodes'), nodeCount, 'artifact.stats.totalNodes');
|
|
337
|
+
assertValue(nonNegativeInteger(stats.totalEdges, 'artifact.stats.totalEdges'), edgeCount, 'artifact.stats.totalEdges');
|
|
338
|
+
assertValue(nonNegativeInteger(stats.unresolvedCount, 'artifact.stats.unresolvedCount'), unresolvedCount, 'artifact.stats.unresolvedCount');
|
|
339
|
+
if (requiredBoolean(stats.truncated, 'artifact.stats.truncated')) {
|
|
340
|
+
const truncation = asRecord(stats.truncation, 'artifact.stats.truncation');
|
|
341
|
+
const counts = ['edgesDroppedCount', 'unresolvedDroppedCount', 'tagsRemovedFromNodeCount'];
|
|
342
|
+
assertExactKeys(truncation, ['reason', ...counts], 'artifact.stats.truncation');
|
|
343
|
+
assertValue(truncation.reason, 'snapshot-size-limit', 'artifact.stats.truncation.reason');
|
|
344
|
+
if (counts.map(key => nonNegativeInteger(truncation[key], `artifact.stats.truncation.${key}`)).every(count => count === 0))
|
|
345
|
+
throw new Error('artifact.stats.truncation must report at least one omitted item.');
|
|
346
|
+
}
|
|
347
|
+
else if (stats.truncation !== undefined) {
|
|
348
|
+
throw new Error('artifact.stats.truncation is only allowed when truncated is true.');
|
|
349
|
+
}
|
|
350
|
+
if (stats.buildMs !== undefined)
|
|
351
|
+
nonNegativeInteger(stats.buildMs, 'artifact.stats.buildMs');
|
|
352
|
+
if (stats.snapshotBytes !== undefined)
|
|
353
|
+
nonNegativeInteger(stats.snapshotBytes, 'artifact.stats.snapshotBytes');
|
|
354
|
+
}
|
|
355
|
+
/** Rejects non-plain JSON everywhere, applying the provider key guard with attribute context. */
|
|
356
|
+
function assertPublicGraphJson(artifact, isForbiddenKey) {
|
|
357
|
+
const { nodes, ...envelope } = artifact;
|
|
358
|
+
assertPlainJson(envelope, 'artifact', key => isForbiddenKey?.(key, false) ?? false);
|
|
359
|
+
nodes.forEach((node, index) => {
|
|
360
|
+
const { attributes, ...rest } = node;
|
|
361
|
+
assertPlainJson(rest, `artifact.nodes[${index}]`, key => isForbiddenKey?.(key, false) ?? false);
|
|
362
|
+
if (attributes !== undefined)
|
|
363
|
+
assertPlainJson(attributes, `artifact.nodes[${index}].attributes`, key => isForbiddenKey?.(key, true) ?? false);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-neutral resource identity vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Families, relationship types, and synthetic types are open kebab-case
|
|
5
|
+
* identifiers so a provider can add a service without a package change.
|
|
6
|
+
* Validators check identifier format only, never membership in a list.
|
|
7
|
+
*/
|
|
8
|
+
export const KEBAB_IDENTIFIER_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
9
|
+
export const ATTRIBUTE_KEY_PATTERN = /^[a-z][A-Za-z0-9]*$/;
|
|
10
|
+
export const isKebabIdentifier = (value) => typeof value === 'string' && KEBAB_IDENTIFIER_PATTERN.test(value);
|
|
11
|
+
export const isResourceFamilyId = (value) => isKebabIdentifier(value);
|
|
12
|
+
export const isCapabilitySourceId = (value) => isKebabIdentifier(value);
|
|
13
|
+
export const isAttributeKey = (value) => typeof value === 'string' && ATTRIBUTE_KEY_PATTERN.test(value);
|
|
14
|
+
export const isAttributeScalar = (value) => typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value));
|
|
15
|
+
const isPlainRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
16
|
+
const isAttributeRecord = (value) => isPlainRecord(value) && Object.entries(value).every(([key, item]) => isAttributeKey(key) && isAttributeScalar(item));
|
|
17
|
+
export const isAttributeValue = (value) => {
|
|
18
|
+
if (isAttributeScalar(value))
|
|
19
|
+
return true;
|
|
20
|
+
if (!Array.isArray(value))
|
|
21
|
+
return false;
|
|
22
|
+
return value.every(isAttributeScalar) || value.every(isAttributeRecord);
|
|
23
|
+
};
|
|
24
|
+
export const isResourceAttributes = (value) => isPlainRecord(value) && Object.entries(value).every(([key, item]) => isAttributeKey(key) && isAttributeValue(item));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const STORY_KEYS = [
|
|
2
|
+
'oversized-resources',
|
|
3
|
+
'right-sku',
|
|
4
|
+
'schedule-candidates',
|
|
5
|
+
'resilience-recovery',
|
|
6
|
+
'hybrid-benefit',
|
|
7
|
+
'commitments',
|
|
8
|
+
];
|
|
9
|
+
export const STORY_LIMITS = {
|
|
10
|
+
sectionRows: 1000,
|
|
11
|
+
sampleRows: 50,
|
|
12
|
+
windowDays: 30,
|
|
13
|
+
weeklyGridDays: 7,
|
|
14
|
+
weeklyGridHours: 24,
|
|
15
|
+
/** Story fingerprints retained per monthly history period (all stories together). */
|
|
16
|
+
historyFingerprints: 2000,
|
|
17
|
+
};
|