@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,115 @@
|
|
|
1
|
+
export const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
2
|
+
export const isString = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
3
|
+
export const isOptionalString = (value) => value === undefined || isString(value);
|
|
4
|
+
export const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
|
|
5
|
+
export const isOptionalFiniteNumber = (value) => value === undefined || isFiniteNumber(value);
|
|
6
|
+
export const isOptionalBoolean = (value) => value === undefined || typeof value === 'boolean';
|
|
7
|
+
export const isCount = (value) => isFiniteNumber(value) && Number.isInteger(value) && value >= 0;
|
|
8
|
+
export const isDateTime = (value) => isString(value) && Number.isFinite(Date.parse(value));
|
|
9
|
+
export const isStringArray = (value) => Array.isArray(value) && value.every(isString);
|
|
10
|
+
export const isCountRecord = (value) => isRecord(value) && Object.values(value).every(isCount);
|
|
11
|
+
export const countTotal = (value) => Object.values(value).reduce((total, count) => total + count, 0);
|
|
12
|
+
export const hasOptionalStrings = (value, keys) => keys.every(key => isOptionalString(value[key]));
|
|
13
|
+
export const hasOptionalNumbers = (value, keys) => keys.every(key => isOptionalFiniteNumber(value[key]));
|
|
14
|
+
export const isBoundedRows = (value, limit, isRow) => {
|
|
15
|
+
if (!isRecord(value) || !isCount(value.totalCount) || !isCount(value.omittedCount) || !Array.isArray(value.rows))
|
|
16
|
+
return false;
|
|
17
|
+
return value.rows.length <= limit && value.rows.every(isRow) && value.totalCount === value.rows.length + value.omittedCount;
|
|
18
|
+
};
|
|
19
|
+
/*
|
|
20
|
+
* Throwing assertion primitives for exact-shape boundary validators. Each
|
|
21
|
+
* failure names the offending field path so rejections are diagnosable.
|
|
22
|
+
*/
|
|
23
|
+
const ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
|
|
24
|
+
export function asRecord(value, field) {
|
|
25
|
+
if (!isRecord(value))
|
|
26
|
+
throw new Error(`${field} must be a JSON object.`);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
export function asArray(value, field, nonEmpty = false) {
|
|
30
|
+
if (!Array.isArray(value) || (nonEmpty && value.length === 0))
|
|
31
|
+
throw new Error(`${field} must be ${nonEmpty ? 'a non-empty' : 'an'} array.`);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
export function requiredString(value, field) {
|
|
35
|
+
if (typeof value !== 'string' || value.trim() !== value || value.length === 0)
|
|
36
|
+
throw new Error(`${field} must be a non-empty trimmed string.`);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
export function requiredEnum(value, values, field) {
|
|
40
|
+
if (typeof value !== 'string' || !values.includes(value))
|
|
41
|
+
throw new Error(`${field} is not declared.`);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
export function requiredBoolean(value, field) {
|
|
45
|
+
if (typeof value !== 'boolean')
|
|
46
|
+
throw new Error(`${field} must be a boolean.`);
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
export function nonNegativeInteger(value, field) {
|
|
50
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0)
|
|
51
|
+
throw new Error(`${field} must be a non-negative safe integer.`);
|
|
52
|
+
return Number(value);
|
|
53
|
+
}
|
|
54
|
+
export function finiteNumber(value, field) {
|
|
55
|
+
if (!isFiniteNumber(value))
|
|
56
|
+
throw new Error(`${field} must be a finite number.`);
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
export function isoTimestamp(value, field) {
|
|
60
|
+
const timestamp = requiredString(value, field);
|
|
61
|
+
if (!ISO_TIMESTAMP_PATTERN.test(timestamp) || Number.isNaN(Date.parse(timestamp)))
|
|
62
|
+
throw new Error(`${field} must be an ISO UTC timestamp.`);
|
|
63
|
+
return timestamp;
|
|
64
|
+
}
|
|
65
|
+
export function assertExactKeys(value, allowed, field) {
|
|
66
|
+
const allowedKeys = new Set(allowed);
|
|
67
|
+
const unknown = Object.keys(value).filter(key => !allowedKeys.has(key));
|
|
68
|
+
if (unknown.length > 0)
|
|
69
|
+
throw new Error(`${field} contains undeclared fields: ${unknown.sort().join(', ')}.`);
|
|
70
|
+
}
|
|
71
|
+
export function assertValue(actual, expected, field) {
|
|
72
|
+
if (actual !== expected)
|
|
73
|
+
throw new Error(`${field} must match its exact binding.`);
|
|
74
|
+
}
|
|
75
|
+
export function assertUnique(values, field) {
|
|
76
|
+
if (new Set(values).size !== values.length)
|
|
77
|
+
throw new Error(`${field} must not contain duplicates.`);
|
|
78
|
+
}
|
|
79
|
+
export function requiredPublicIdentifier(value, field) {
|
|
80
|
+
const identifier = requiredString(value, field);
|
|
81
|
+
if (identifier.includes('/') || identifier.includes('\\') || identifier.includes('://') || identifier.includes('..'))
|
|
82
|
+
throw new Error(`${field} must not contain a physical path or URI.`);
|
|
83
|
+
return identifier;
|
|
84
|
+
}
|
|
85
|
+
/** Validates an exact `ArtifactGeneration` identity. */
|
|
86
|
+
export function validateGeneration(value, field) {
|
|
87
|
+
const generation = asRecord(value, field);
|
|
88
|
+
assertExactKeys(generation, ['runId', 'generatedAt'], field);
|
|
89
|
+
return {
|
|
90
|
+
runId: requiredPublicIdentifier(generation.runId, `${field}.runId`),
|
|
91
|
+
generatedAt: isoTimestamp(generation.generatedAt, `${field}.generatedAt`),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Rejects non-JSON values and non-plain objects; `isForbiddenKey` rejects keys at every depth. */
|
|
95
|
+
export function assertPlainJson(value, field, isForbiddenKey = () => false) {
|
|
96
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
97
|
+
return;
|
|
98
|
+
if (typeof value === 'number') {
|
|
99
|
+
if (!Number.isFinite(value))
|
|
100
|
+
throw new Error(`${field} must contain only finite JSON numbers.`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (Array.isArray(value)) {
|
|
104
|
+
value.forEach((item, index) => assertPlainJson(item, `${field}[${index}]`, isForbiddenKey));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!value || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype) {
|
|
108
|
+
throw new Error(`${field} must contain only plain JSON values.`);
|
|
109
|
+
}
|
|
110
|
+
for (const [key, child] of Object.entries(value)) {
|
|
111
|
+
if (isForbiddenKey(key))
|
|
112
|
+
throw new Error(`${field}.${key} is not allowed in a public artifact.`);
|
|
113
|
+
assertPlainJson(child, `${field}.${key}`, isForbiddenKey);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from '../aws/
|
|
2
|
-
import * as namespace from '../aws/
|
|
1
|
+
export * from '../aws/relationships.js';
|
|
2
|
+
import * as namespace from '../aws/relationships.js';
|
|
3
3
|
export default namespace;
|
package/dist/esm/index.js
CHANGED
|
@@ -15,12 +15,15 @@ export * from './azure/artifactRunReference.js';
|
|
|
15
15
|
export * from './azure/billingPlots.js';
|
|
16
16
|
export * from './azure/benefits.js';
|
|
17
17
|
export * from './azure/commitmentsPlanning.js';
|
|
18
|
+
export * from './azure/commitmentsPlanningValidation.js';
|
|
18
19
|
export * from './azure/licensing.js';
|
|
19
20
|
export * from './azure/configs.js';
|
|
20
21
|
export * from './azure/metrics.js';
|
|
21
22
|
export * from './azure/payloads.js';
|
|
22
23
|
export * from './azure/portalArtifacts.js';
|
|
23
24
|
export * from './azure/dataProtection.js';
|
|
25
|
+
export * from './azure/resilienceFacts.js';
|
|
26
|
+
export * from './azure/resilienceFactsValidation.js';
|
|
24
27
|
export * from './azure/prices.js';
|
|
25
28
|
export * from './azure/relationships.js';
|
|
26
29
|
export * from './azure/recommendations.js';
|
|
@@ -34,6 +37,8 @@ export * from './azure/resources.js';
|
|
|
34
37
|
export * from './azure/reports.js';
|
|
35
38
|
export * from './azure/reportEvidence.js';
|
|
36
39
|
export * from './azure/reportEvidenceValidation.js';
|
|
40
|
+
export * from './common/utilizationStories.js';
|
|
41
|
+
export * from './common/utilizationStoriesValidation.js';
|
|
37
42
|
export * from './azure/reportDailySpend.js';
|
|
38
43
|
export * from './azure/reportDailySpendValidation.js';
|
|
39
44
|
export * from './azure/reportSpend.js';
|
package/dist/esm/index.vite.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from './azure/budgets.js';
|
|
|
5
5
|
export * from './azure/billingPlots.js';
|
|
6
6
|
export * from './azure/benefits.js';
|
|
7
7
|
export * from './azure/commitmentsPlanning.js';
|
|
8
|
+
export * from './azure/commitmentsPlanningValidation.js';
|
|
8
9
|
export * from './azure/licensing.js';
|
|
9
10
|
export * from './azure/configs.js';
|
|
10
11
|
export * from './azure/metrics.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@spottoai/types-package/reporting-jobs`: background report job contracts shared by the API, cloud-engine and
|
|
3
|
+
* reportworker (types-package/specs/reporting/reporting-scheduler-types.md, Part A).
|
|
4
|
+
*/
|
|
5
|
+
export * from './reportJobSpec.js';
|
|
6
|
+
export * from './reportJobIdentity.js';
|
|
7
|
+
export * from './reportJobMessages.js';
|
|
8
|
+
export * from './reportJobStatus.js';
|
|
9
|
+
export * from './reportJobRow.js';
|
|
10
|
+
export { sha256Hex, SHA256_HEX_PATTERN } from '../shared/reportingDigest.js';
|
|
11
|
+
export { isIanaTimeZone, isIsoUtcTimestamp, isReportEntityId, isReportGuid, isReportJobCompanyId, REPORT_ENTITY_ID_PATTERN, REPORT_JOB_COMPANY_ID_MAX_LENGTH, } from '../shared/reportingIds.js';
|
|
12
|
+
export { normalizeReportTableEntity, REPORT_TABLE_SYSTEM_FIELDS, toReportTableSdkEntity } from '../shared/reportTableEntities.js';
|
|
13
|
+
export { isReportFileName, sanitizeReportingPathSegment } from '../shared/reportingPaths.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background report job identity (core/specs/reporting/reporting-scheduler.md, "Report job table").
|
|
3
|
+
*
|
|
4
|
+
* `jobId = {reverseTime19}-{reportType}-{scopeHash}` is the `reportjobs` RowKey and the generated report's ID.
|
|
5
|
+
* The API and cloud-engine must derive it identically, so both use these functions.
|
|
6
|
+
*/
|
|
7
|
+
import { sha256Hex } from '../shared/reportingDigest.js';
|
|
8
|
+
import { isIsoUtcTimestamp, isReportEntityId, isReportGuid, isReportJobCompanyId } from '../shared/reportingIds.js';
|
|
9
|
+
import { isReportJobReportType, normalizeReportSubscriptionIds } from './reportJobSpec.js';
|
|
10
|
+
/** The `recommendationsevents` reverse-time convention: 19 nines minus Unix milliseconds, zero-padded to 19 digits. */
|
|
11
|
+
export const REPORT_JOB_MAX_REVERSE_TIME = BigInt('9999999999999999999');
|
|
12
|
+
/** Latest instant accepted (9999-12-31T23:59:59.999Z). */
|
|
13
|
+
export const REPORT_JOB_MAX_INSTANT_MS = 253402300799999;
|
|
14
|
+
export const REPORT_JOB_ID_PATTERN = /^(\d{19})-(sdm|architecture-assessment)-([0-9a-f]{16})$/;
|
|
15
|
+
export const REPORT_JOB_SCOPE_HASH_PATTERN = /^[0-9a-f]{16}$/;
|
|
16
|
+
/** Strings must be exact UTC ISO timestamps (`toISOString` form), so the result never depends on the host time zone. */
|
|
17
|
+
const toInstantMs = (instant) => {
|
|
18
|
+
if (typeof instant === 'string' && !isIsoUtcTimestamp(instant))
|
|
19
|
+
throw new RangeError('Report job instant strings must be UTC ISO timestamps (YYYY-MM-DDTHH:mm:ss.sssZ).');
|
|
20
|
+
const ms = instant instanceof Date ? instant.getTime() : typeof instant === 'number' ? instant : Date.parse(instant);
|
|
21
|
+
if (!Number.isInteger(ms) || ms < 0 || ms > REPORT_JOB_MAX_INSTANT_MS)
|
|
22
|
+
throw new RangeError('Report job instant must be a valid time between 1970 and 9999.');
|
|
23
|
+
return ms;
|
|
24
|
+
};
|
|
25
|
+
export const buildReverseTime19 = (instant) => (REPORT_JOB_MAX_REVERSE_TIME - BigInt(toInstantMs(instant))).toString().padStart(19, '0');
|
|
26
|
+
/** The instant a reverse time encodes, or `null` when it is not a valid 19-digit reverse time. */
|
|
27
|
+
export const parseReverseTime19 = (value) => {
|
|
28
|
+
if (typeof value !== 'string' || !/^\d{19}$/.test(value))
|
|
29
|
+
return null;
|
|
30
|
+
const ms = REPORT_JOB_MAX_REVERSE_TIME - BigInt(value);
|
|
31
|
+
if (ms < BigInt(0) || ms > BigInt(REPORT_JOB_MAX_INSTANT_MS))
|
|
32
|
+
return null;
|
|
33
|
+
return new Date(Number(ms));
|
|
34
|
+
};
|
|
35
|
+
/** First 16 hex characters of SHA-256 over the sorted, lower-cased subscription IDs joined with `,` (then `|{scheduleId}`). */
|
|
36
|
+
export const buildReportJobScopeHash = async ({ subscriptionIds, scheduleId }) => {
|
|
37
|
+
if (subscriptionIds.length === 0 || !subscriptionIds.every(id => typeof id === 'string' && isReportGuid(id.trim()))) {
|
|
38
|
+
throw new Error('Report job scope hash needs at least one valid subscription ID.');
|
|
39
|
+
}
|
|
40
|
+
if (scheduleId !== undefined && !isReportEntityId(scheduleId))
|
|
41
|
+
throw new Error('Report job scope hash: invalid schedule ID.');
|
|
42
|
+
const preimage = normalizeReportSubscriptionIds(subscriptionIds).join(',') + (scheduleId === undefined ? '' : `|${scheduleId}`);
|
|
43
|
+
return (await sha256Hex(preimage)).slice(0, 16);
|
|
44
|
+
};
|
|
45
|
+
export const buildReportJobId = ({ instant, reportType, scopeHash }) => {
|
|
46
|
+
if (!isReportJobReportType(reportType))
|
|
47
|
+
throw new Error('Report job ID: invalid report type.');
|
|
48
|
+
if (!REPORT_JOB_SCOPE_HASH_PATTERN.test(scopeHash))
|
|
49
|
+
throw new Error('Report job ID: invalid scope hash.');
|
|
50
|
+
return `${buildReverseTime19(instant)}-${reportType}-${scopeHash}`;
|
|
51
|
+
};
|
|
52
|
+
export const parseReportJobId = (jobId) => {
|
|
53
|
+
if (typeof jobId !== 'string')
|
|
54
|
+
return null;
|
|
55
|
+
const match = REPORT_JOB_ID_PATTERN.exec(jobId);
|
|
56
|
+
if (!match)
|
|
57
|
+
return null;
|
|
58
|
+
const instant = parseReverseTime19(match[1]);
|
|
59
|
+
if (!instant)
|
|
60
|
+
return null;
|
|
61
|
+
return { reverseTime19: match[1], instant, reportType: match[2], scopeHash: match[3] };
|
|
62
|
+
};
|
|
63
|
+
export const isReportJobId = (value) => parseReportJobId(value) !== null;
|
|
64
|
+
/** Derives `scopeHash` and `jobId` together. */
|
|
65
|
+
export const deriveReportJobIdentity = async (input) => {
|
|
66
|
+
const scopeHash = await buildReportJobScopeHash(input);
|
|
67
|
+
return { jobId: buildReportJobId({ instant: input.instant, reportType: input.reportType, scopeHash }), scopeHash };
|
|
68
|
+
};
|
|
69
|
+
/** Service Bus `MessageId` for `ReportJobRequestedV1`: `report-job:{companyId}:{jobId}`. */
|
|
70
|
+
export const buildReportJobMessageId = (companyId, jobId) => {
|
|
71
|
+
if (!isReportJobCompanyId(companyId))
|
|
72
|
+
throw new Error('Report job message ID: invalid company ID.');
|
|
73
|
+
if (!isReportJobId(jobId))
|
|
74
|
+
throw new Error('Report job message ID: invalid job ID.');
|
|
75
|
+
return `report-job:${companyId}:${jobId}`;
|
|
76
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reports` queue message (core/specs/reporting/reporting-scheduler.md, "Queue message").
|
|
3
|
+
*
|
|
4
|
+
* The message is a pointer only: the worker reads everything else from the `reportjobs` row. Each region has its
|
|
5
|
+
* own queue, table and worker, so the message carries no region.
|
|
6
|
+
*/
|
|
7
|
+
import { hasExactlyKeys, isBoundedPlainText, isPlainRecord, isReportJobCompanyId } from '../shared/reportingIds.js';
|
|
8
|
+
import { buildReportJobMessageId, isReportJobId } from './reportJobIdentity.js';
|
|
9
|
+
export const REPORT_JOB_REQUESTED_MESSAGE_TYPE = 'report-job.requested';
|
|
10
|
+
/** Upper bound for the serialised message body. */
|
|
11
|
+
export const REPORT_JOB_REQUESTED_MAX_BYTES = 4 * 1024;
|
|
12
|
+
const MESSAGE_KEYS = ['schemaVersion', 'messageType', 'companyId', 'jobId', 'correlationId'];
|
|
13
|
+
/** Strict guard: exact keys, valid identifiers, bounded size. Never throws. */
|
|
14
|
+
export const isReportJobRequestedV1 = (value) => {
|
|
15
|
+
try {
|
|
16
|
+
if (!isPlainRecord(value) || !hasExactlyKeys(value, MESSAGE_KEYS))
|
|
17
|
+
return false;
|
|
18
|
+
return (value.schemaVersion === 1 &&
|
|
19
|
+
value.messageType === REPORT_JOB_REQUESTED_MESSAGE_TYPE &&
|
|
20
|
+
isReportJobCompanyId(value.companyId) &&
|
|
21
|
+
isReportJobId(value.jobId) &&
|
|
22
|
+
isBoundedPlainText(value.correlationId, 128) &&
|
|
23
|
+
JSON.stringify(value).length <= REPORT_JOB_REQUESTED_MAX_BYTES);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export const createReportJobRequestedV1 = ({ companyId, jobId, correlationId }) => {
|
|
30
|
+
const message = {
|
|
31
|
+
schemaVersion: 1,
|
|
32
|
+
messageType: REPORT_JOB_REQUESTED_MESSAGE_TYPE,
|
|
33
|
+
companyId,
|
|
34
|
+
jobId,
|
|
35
|
+
correlationId: correlationId ?? jobId,
|
|
36
|
+
};
|
|
37
|
+
if (!isReportJobRequestedV1(message))
|
|
38
|
+
throw new Error('Invalid report job requested message.');
|
|
39
|
+
return message;
|
|
40
|
+
};
|
|
41
|
+
/** Service Bus properties for a `ReportJobRequestedV1` send: the shared MessageId drives duplicate detection. */
|
|
42
|
+
export const buildReportJobRequestedBrokerProperties = (message) => ({
|
|
43
|
+
messageId: buildReportJobMessageId(message.companyId, message.jobId),
|
|
44
|
+
correlationId: message.jobId,
|
|
45
|
+
contentType: 'application/json',
|
|
46
|
+
subject: REPORT_JOB_REQUESTED_MESSAGE_TYPE,
|
|
47
|
+
});
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reportjobs` row (core/specs/reporting/reporting-scheduler.md, "Report job table").
|
|
3
|
+
*
|
|
4
|
+
* PartitionKey = companyId, RowKey = jobId. Three writers own disjoint field groups and merge with ETag
|
|
5
|
+
* compare-and-swap: the producer (insert only), reportworker and, from phase 6, cloud-engine's notifier.
|
|
6
|
+
* The row carries no region (each region has its own table, queue and worker) and no time zone (reportworker uses
|
|
7
|
+
* the company's `preferredTimezone`, else UTC). The row never holds e-mail addresses, document content, source data, Blob paths or credentials.
|
|
8
|
+
*/
|
|
9
|
+
import { sha256Hex, SHA256_HEX_PATTERN } from '../shared/reportingDigest.js';
|
|
10
|
+
import { isReportFileName } from '../shared/reportingPaths.js';
|
|
11
|
+
import { hasExactlyKeys, isBoundedPlainText, isIsoUtcTimestamp, isPlainRecord, isReportEntityId, isReportJobCompanyId, utf8ByteLength, } from '../shared/reportingIds.js';
|
|
12
|
+
import { normalizeReportTableEntity } from '../shared/reportTableEntities.js';
|
|
13
|
+
import { buildReportJobScopeHash, deriveReportJobIdentity, parseReportJobId } from './reportJobIdentity.js';
|
|
14
|
+
import { parseReportJobRequestJson, REPORT_JOB_SPEC_MAX_BYTES, serializeReportJobSpecV1, } from './reportJobSpec.js';
|
|
15
|
+
import { isReportJobFailureCode, isReportJobFailureStage, isReportJobNotificationStatus, isReportJobStatus, REPORT_JOB_FAILURE_STAGE_BY_CODE, } from './reportJobStatus.js';
|
|
16
|
+
export const REPORT_JOB_ROW_SCHEMA_VERSION = 1;
|
|
17
|
+
export const REPORT_JOB_TRIGGERS = ['api', 'schedule'];
|
|
18
|
+
/** UTF-8 byte limit of `sourceCoverageSummary` (a JSON object). */
|
|
19
|
+
export const REPORT_JOB_COVERAGE_SUMMARY_MAX_BYTES = 8 * 1024;
|
|
20
|
+
export const REPORT_JOB_PRODUCER_FIELDS = [
|
|
21
|
+
'PartitionKey',
|
|
22
|
+
'RowKey',
|
|
23
|
+
'schemaVersion',
|
|
24
|
+
'jobId',
|
|
25
|
+
'companyId',
|
|
26
|
+
'reportType',
|
|
27
|
+
'trigger',
|
|
28
|
+
'scheduleId',
|
|
29
|
+
'definitionRevision',
|
|
30
|
+
'scheduledForUtc',
|
|
31
|
+
'requestedAtUtc',
|
|
32
|
+
'requestedByUserId',
|
|
33
|
+
'coalescedOccurrenceCount',
|
|
34
|
+
'requestJson',
|
|
35
|
+
'requestSha256',
|
|
36
|
+
'fileName',
|
|
37
|
+
'notificationPolicyId',
|
|
38
|
+
];
|
|
39
|
+
export const REPORT_JOB_WORKER_FIELDS = [
|
|
40
|
+
'status',
|
|
41
|
+
'attemptCount',
|
|
42
|
+
'leaseOwner',
|
|
43
|
+
'leaseExpiresAtUtc',
|
|
44
|
+
'startedAtUtc',
|
|
45
|
+
'lastAttemptAtUtc',
|
|
46
|
+
'sourceObservedAtUtc',
|
|
47
|
+
'sourceSnapshotSha256',
|
|
48
|
+
'sourceCoverageSummary',
|
|
49
|
+
'generatedAtUtc',
|
|
50
|
+
'artifactContentSha256',
|
|
51
|
+
'artifactBytes',
|
|
52
|
+
'completedAtUtc',
|
|
53
|
+
'failureStage',
|
|
54
|
+
'failureCode',
|
|
55
|
+
'lastTransientErrorCode',
|
|
56
|
+
];
|
|
57
|
+
export const REPORT_JOB_NOTIFICATION_FIELDS = ['notificationStatus'];
|
|
58
|
+
const REQUIRED_FIELDS = [
|
|
59
|
+
'PartitionKey',
|
|
60
|
+
'RowKey',
|
|
61
|
+
'schemaVersion',
|
|
62
|
+
'jobId',
|
|
63
|
+
'companyId',
|
|
64
|
+
'reportType',
|
|
65
|
+
'trigger',
|
|
66
|
+
'requestedAtUtc',
|
|
67
|
+
'requestJson',
|
|
68
|
+
'requestSha256',
|
|
69
|
+
'fileName',
|
|
70
|
+
'status',
|
|
71
|
+
'attemptCount',
|
|
72
|
+
'notificationStatus',
|
|
73
|
+
];
|
|
74
|
+
const OPTIONAL_FIELDS = [...REPORT_JOB_PRODUCER_FIELDS, ...REPORT_JOB_WORKER_FIELDS, ...REPORT_JOB_NOTIFICATION_FIELDS].filter(field => !REQUIRED_FIELDS.includes(field));
|
|
75
|
+
/** Statuses reached only after the source snapshot is durable. */
|
|
76
|
+
const SNAPSHOT_STATUSES = ['source-ready', 'generated', 'completed', 'completed-with-notification-errors'];
|
|
77
|
+
/** Statuses reached only after the artifact is durable. */
|
|
78
|
+
const ARTIFACT_STATUSES = ['generated', 'completed', 'completed-with-notification-errors'];
|
|
79
|
+
const isCount = (value) => typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 2147483647;
|
|
80
|
+
const isSha = (value) => typeof value === 'string' && SHA256_HEX_PATTERN.test(value);
|
|
81
|
+
const isText = (limit) => (value) => isBoundedPlainText(value, limit);
|
|
82
|
+
const isOptional = (value, check) => value === undefined || check(value);
|
|
83
|
+
const isCoverageSummary = (value) => {
|
|
84
|
+
if (typeof value !== 'string' || utf8ByteLength(value) > REPORT_JOB_COVERAGE_SUMMARY_MAX_BYTES)
|
|
85
|
+
return false;
|
|
86
|
+
try {
|
|
87
|
+
const parsed = JSON.parse(value);
|
|
88
|
+
return typeof parsed === 'object' && parsed !== null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
/** `row` is already normalised (REST key casing, no system properties, no null values). */
|
|
95
|
+
const validateShape = (row, errors) => {
|
|
96
|
+
const check = (field, ok) => {
|
|
97
|
+
if (!ok)
|
|
98
|
+
errors.push(`${field}: invalid`);
|
|
99
|
+
};
|
|
100
|
+
if (!hasExactlyKeys(row, REQUIRED_FIELDS, OPTIONAL_FIELDS)) {
|
|
101
|
+
const unknown = Object.keys(row).filter(key => !REQUIRED_FIELDS.includes(key) && !OPTIONAL_FIELDS.includes(key));
|
|
102
|
+
const missing = REQUIRED_FIELDS.filter(key => row[key] === undefined);
|
|
103
|
+
if (unknown.length > 0)
|
|
104
|
+
errors.push(`row: unknown fields ${unknown.join(', ')}`);
|
|
105
|
+
if (missing.length > 0)
|
|
106
|
+
errors.push(`row: missing fields ${missing.join(', ')}`);
|
|
107
|
+
}
|
|
108
|
+
check('companyId', isReportJobCompanyId(row.companyId) && row.PartitionKey === row.companyId);
|
|
109
|
+
const parsedId = parseReportJobId(row.jobId);
|
|
110
|
+
check('jobId', parsedId !== null && row.RowKey === row.jobId);
|
|
111
|
+
check('reportType', parsedId !== null && row.reportType === parsedId.reportType);
|
|
112
|
+
check('trigger', row.trigger === 'api' || row.trigger === 'schedule');
|
|
113
|
+
check('requestedAtUtc', isIsoUtcTimestamp(row.requestedAtUtc));
|
|
114
|
+
check('requestJson', typeof row.requestJson === 'string' && utf8ByteLength(row.requestJson) <= REPORT_JOB_SPEC_MAX_BYTES);
|
|
115
|
+
check('requestSha256', isSha(row.requestSha256));
|
|
116
|
+
check('fileName', isReportFileName(row.fileName));
|
|
117
|
+
// Requesters are identified by user ID, never by e-mail address.
|
|
118
|
+
check('requestedByUserId', isOptional(row.requestedByUserId, value => isText(128)(value) && !value.includes('@')));
|
|
119
|
+
check('notificationPolicyId', isOptional(row.notificationPolicyId, isReportEntityId));
|
|
120
|
+
check('coalescedOccurrenceCount', isOptional(row.coalescedOccurrenceCount, value => isCount(value) && value >= 1));
|
|
121
|
+
if (row.trigger === 'schedule') {
|
|
122
|
+
check('scheduleId', isReportEntityId(row.scheduleId));
|
|
123
|
+
check('definitionRevision', isCount(row.definitionRevision) && row.definitionRevision >= 1);
|
|
124
|
+
check('scheduledForUtc', isIsoUtcTimestamp(row.scheduledForUtc));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
check('scheduleId', row.scheduleId === undefined);
|
|
128
|
+
check('definitionRevision', row.definitionRevision === undefined);
|
|
129
|
+
check('scheduledForUtc', row.scheduledForUtc === undefined);
|
|
130
|
+
check('coalescedOccurrenceCount', row.coalescedOccurrenceCount === undefined);
|
|
131
|
+
}
|
|
132
|
+
const instant = row.trigger === 'schedule' ? row.scheduledForUtc : row.requestedAtUtc;
|
|
133
|
+
check('jobId', parsedId !== null && typeof instant === 'string' && parsedId.instant.toISOString() === instant);
|
|
134
|
+
check('status', isReportJobStatus(row.status));
|
|
135
|
+
check('attemptCount', isCount(row.attemptCount));
|
|
136
|
+
check('notificationStatus', isReportJobNotificationStatus(row.notificationStatus));
|
|
137
|
+
for (const field of ['leaseExpiresAtUtc', 'startedAtUtc', 'lastAttemptAtUtc', 'sourceObservedAtUtc', 'generatedAtUtc', 'completedAtUtc']) {
|
|
138
|
+
check(field, isOptional(row[field], isIsoUtcTimestamp));
|
|
139
|
+
}
|
|
140
|
+
check('leaseOwner', isOptional(row.leaseOwner, isText(256)));
|
|
141
|
+
check('sourceSnapshotSha256', isOptional(row.sourceSnapshotSha256, isSha));
|
|
142
|
+
check('artifactContentSha256', isOptional(row.artifactContentSha256, isSha));
|
|
143
|
+
check('artifactBytes', isOptional(row.artifactBytes, value => isCount(value) && value >= 1));
|
|
144
|
+
check('sourceCoverageSummary', isOptional(row.sourceCoverageSummary, isCoverageSummary));
|
|
145
|
+
check('failureStage', isOptional(row.failureStage, isReportJobFailureStage));
|
|
146
|
+
check('failureCode', isOptional(row.failureCode, isReportJobFailureCode));
|
|
147
|
+
check('lastTransientErrorCode', isOptional(row.lastTransientErrorCode, isText(128)));
|
|
148
|
+
// Cross-field rules: the status milestone and the fields that prove it agree.
|
|
149
|
+
if (!isReportJobStatus(row.status))
|
|
150
|
+
return;
|
|
151
|
+
const status = row.status;
|
|
152
|
+
if (status === 'failed') {
|
|
153
|
+
check('failureCode', isReportJobFailureCode(row.failureCode));
|
|
154
|
+
check('failureStage', isReportJobFailureStage(row.failureStage));
|
|
155
|
+
if (isReportJobFailureCode(row.failureCode) && isReportJobFailureStage(row.failureStage)) {
|
|
156
|
+
const expected = REPORT_JOB_FAILURE_STAGE_BY_CODE[row.failureCode];
|
|
157
|
+
check('failureStage', expected === null || expected === row.failureStage);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
check('failureCode', row.failureCode === undefined);
|
|
162
|
+
check('failureStage', row.failureStage === undefined);
|
|
163
|
+
}
|
|
164
|
+
if (SNAPSHOT_STATUSES.includes(status)) {
|
|
165
|
+
check('sourceSnapshotSha256', isSha(row.sourceSnapshotSha256));
|
|
166
|
+
check('sourceObservedAtUtc', isIsoUtcTimestamp(row.sourceObservedAtUtc));
|
|
167
|
+
}
|
|
168
|
+
if (ARTIFACT_STATUSES.includes(status)) {
|
|
169
|
+
check('artifactContentSha256', isSha(row.artifactContentSha256));
|
|
170
|
+
check('artifactBytes', isCount(row.artifactBytes) && row.artifactBytes >= 1);
|
|
171
|
+
check('generatedAtUtc', isIsoUtcTimestamp(row.generatedAtUtc));
|
|
172
|
+
}
|
|
173
|
+
if (status === 'completed' || status === 'completed-with-notification-errors')
|
|
174
|
+
check('completedAtUtc', isIsoUtcTimestamp(row.completedAtUtc));
|
|
175
|
+
if (status === 'accepted')
|
|
176
|
+
check('attemptCount', row.attemptCount === 0);
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Validates a stored row and its request. Accepts REST (`PartitionKey`) and `@azure/data-tables` (`partitionKey`)
|
|
180
|
+
* key casing and ignores Table system properties. Checks keys against the body, the job ID against the trigger's
|
|
181
|
+
* instant, status against the fields that prove it, the report type and scope hash against the spec, the request's
|
|
182
|
+
* canonical form and `requestSha256`. Returns the row in REST casing. Never throws.
|
|
183
|
+
*/
|
|
184
|
+
export const parseReportJobRowV1 = async (entity) => {
|
|
185
|
+
try {
|
|
186
|
+
if (!isPlainRecord(entity))
|
|
187
|
+
return { ok: false, code: 'request-invalid', errors: ['row: must be an object'] };
|
|
188
|
+
const normalized = normalizeReportTableEntity(entity);
|
|
189
|
+
if (normalized.schemaVersion !== REPORT_JOB_ROW_SCHEMA_VERSION) {
|
|
190
|
+
return { ok: false, code: 'unsupported-schema-version', errors: ['schemaVersion: unsupported'] };
|
|
191
|
+
}
|
|
192
|
+
const errors = [];
|
|
193
|
+
validateShape(normalized, errors);
|
|
194
|
+
if (errors.length > 0)
|
|
195
|
+
return { ok: false, code: 'request-invalid', errors: Array.from(new Set(errors)) };
|
|
196
|
+
const row = normalized;
|
|
197
|
+
if ((await sha256Hex(row.requestJson)) !== row.requestSha256) {
|
|
198
|
+
return { ok: false, code: 'request-hash-mismatch', errors: ['requestSha256: does not match requestJson'] };
|
|
199
|
+
}
|
|
200
|
+
const spec = parseReportJobRequestJson(row.requestJson);
|
|
201
|
+
if (!spec.ok)
|
|
202
|
+
return { ok: false, code: 'request-invalid', errors: spec.errors };
|
|
203
|
+
if (spec.value.reportType !== row.reportType)
|
|
204
|
+
return { ok: false, code: 'request-invalid', errors: ['reportType: does not match the request'] };
|
|
205
|
+
const scopeHash = await buildReportJobScopeHash({
|
|
206
|
+
subscriptionIds: spec.value.scope.subscriptionIds,
|
|
207
|
+
scheduleId: row.trigger === 'schedule' ? row.scheduleId : undefined,
|
|
208
|
+
});
|
|
209
|
+
if (parseReportJobId(row.jobId)?.scopeHash !== scopeHash) {
|
|
210
|
+
return { ok: false, code: 'request-invalid', errors: ['jobId: scope hash does not match the request'] };
|
|
211
|
+
}
|
|
212
|
+
return { ok: true, row, spec: spec.value };
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return { ok: false, code: 'request-invalid', errors: ['row: unreadable'] };
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Builds the row a producer inserts (status `accepted`, attempt 0, notification `none`), with the job ID derived
|
|
220
|
+
* from the trigger's instant and the request. The result is validated with `parseReportJobRowV1`; invalid input throws.
|
|
221
|
+
*/
|
|
222
|
+
export const buildReportJobRowV1 = async (input) => {
|
|
223
|
+
const requestJson = serializeReportJobSpecV1(input.spec);
|
|
224
|
+
const spec = parseReportJobRequestJson(requestJson);
|
|
225
|
+
if (!spec.ok)
|
|
226
|
+
throw new Error(`Invalid report job spec: ${spec.errors.join('; ')}`);
|
|
227
|
+
const schedule = input.trigger === 'schedule' ? input : undefined;
|
|
228
|
+
const { jobId } = await deriveReportJobIdentity({
|
|
229
|
+
instant: schedule ? schedule.scheduledForUtc : input.requestedAtUtc,
|
|
230
|
+
reportType: spec.value.reportType,
|
|
231
|
+
subscriptionIds: spec.value.scope.subscriptionIds,
|
|
232
|
+
scheduleId: schedule?.scheduleId,
|
|
233
|
+
});
|
|
234
|
+
const row = {
|
|
235
|
+
PartitionKey: input.companyId,
|
|
236
|
+
RowKey: jobId,
|
|
237
|
+
schemaVersion: 1,
|
|
238
|
+
jobId,
|
|
239
|
+
companyId: input.companyId,
|
|
240
|
+
reportType: spec.value.reportType,
|
|
241
|
+
trigger: input.trigger,
|
|
242
|
+
...(schedule
|
|
243
|
+
? {
|
|
244
|
+
scheduleId: schedule.scheduleId,
|
|
245
|
+
definitionRevision: schedule.definitionRevision,
|
|
246
|
+
scheduledForUtc: schedule.scheduledForUtc,
|
|
247
|
+
...(schedule.coalescedOccurrenceCount === undefined ? {} : { coalescedOccurrenceCount: schedule.coalescedOccurrenceCount }),
|
|
248
|
+
}
|
|
249
|
+
: {}),
|
|
250
|
+
requestedAtUtc: input.requestedAtUtc,
|
|
251
|
+
...(input.requestedByUserId === undefined ? {} : { requestedByUserId: input.requestedByUserId }),
|
|
252
|
+
requestJson,
|
|
253
|
+
requestSha256: await sha256Hex(requestJson),
|
|
254
|
+
fileName: input.fileName,
|
|
255
|
+
...(input.notificationPolicyId === undefined ? {} : { notificationPolicyId: input.notificationPolicyId }),
|
|
256
|
+
status: 'accepted',
|
|
257
|
+
attemptCount: 0,
|
|
258
|
+
notificationStatus: 'none',
|
|
259
|
+
};
|
|
260
|
+
const parsed = await parseReportJobRowV1(row);
|
|
261
|
+
if (!parsed.ok)
|
|
262
|
+
throw new Error(`Invalid report job row: ${parsed.errors.join('; ')}`);
|
|
263
|
+
return row;
|
|
264
|
+
};
|